From: Felix Fietkau Date: Thu, 2 Feb 2017 11:02:22 +0000 (+0100) Subject: mac80211: update to wireless-testing 2017-01-31 X-Git-Tag: v18.06.0-rc1~3784 X-Git-Url: https://git.librecmc.org/?a=commitdiff_plain;h=649e766a64a0d001f040dfc225c601b3d0af6f40;p=oweals%2Fopenwrt.git mac80211: update to wireless-testing 2017-01-31 Signed-off-by: Felix Fietkau --- diff --git a/package/kernel/mac80211/Makefile b/package/kernel/mac80211/Makefile index 245114397f..5a591e4b83 100644 --- a/package/kernel/mac80211/Makefile +++ b/package/kernel/mac80211/Makefile @@ -10,13 +10,13 @@ include $(INCLUDE_DIR)/kernel.mk PKG_NAME:=mac80211 -PKG_VERSION:=2016-10-08 +PKG_VERSION:=2017-01-31 PKG_RELEASE:=1 PKG_SOURCE_URL:=http://mirror2.openwrt.org/sources PKG_BACKPORT_VERSION:= -PKG_HASH:=4f6350e3b75815060bfdf47ef266ad613c7bfea5b7b1dc4552dee69e1bebe4fb +PKG_HASH:=75e6d39e34cf156212a2509172a4a62b673b69eb4a1d9aaa565f7fa719fa2317 -PKG_SOURCE:=compat-wireless-$(PKG_VERSION)$(PKG_BACKPORT_VERSION).tar.bz2 +PKG_SOURCE:=compat-wireless-$(PKG_VERSION)$(PKG_BACKPORT_VERSION).tar.xz PKG_BUILD_DIR:=$(KERNEL_BUILD_DIR)/compat-wireless-$(PKG_VERSION) PKG_BUILD_PARALLEL:=1 diff --git a/package/kernel/mac80211/patches/002-change_allconfig.patch b/package/kernel/mac80211/patches/002-change_allconfig.patch index bd5bebfa45..a071ae6370 100644 --- a/package/kernel/mac80211/patches/002-change_allconfig.patch +++ b/package/kernel/mac80211/patches/002-change_allconfig.patch @@ -1,6 +1,6 @@ --- a/kconf/conf.c +++ b/kconf/conf.c -@@ -593,40 +593,12 @@ int main(int ac, char **av) +@@ -594,40 +594,12 @@ int main(int ac, char **av) case oldconfig: case listnewconfig: case olddefconfig: @@ -44,7 +44,7 @@ break; --- a/kconf/confdata.c +++ b/kconf/confdata.c -@@ -1169,6 +1169,8 @@ bool conf_set_all_new_symbols(enum conf_ +@@ -1170,6 +1170,8 @@ bool conf_set_all_new_symbols(enum conf_ } bool has_changed = false; @@ -53,7 +53,7 @@ for_all_symbols(i, sym) { if (sym_has_value(sym) || (sym->flags & SYMBOL_VALID)) continue; -@@ -1212,8 +1214,6 @@ bool conf_set_all_new_symbols(enum conf_ +@@ -1213,8 +1215,6 @@ bool conf_set_all_new_symbols(enum conf_ } diff --git a/package/kernel/mac80211/patches/004-fix_duplicate_skcipher_backport.patch b/package/kernel/mac80211/patches/004-fix_duplicate_skcipher_backport.patch deleted file mode 100644 index 38b31795a4..0000000000 --- a/package/kernel/mac80211/patches/004-fix_duplicate_skcipher_backport.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- a/compat/Makefile -+++ b/compat/Makefile -@@ -35,8 +35,6 @@ compat-$(CPTCFG_KERNEL_4_6) += backport- - - compat-$(CPTCFG_BPAUTO_BUILD_CRYPTO_CCM) += crypto-ccm.o - compat-$(CPTCFG_BPAUTO_CRYPTO_SKCIPHER) += crypto-skcipher.o --skcipher-objs += crypto-skcipher.o --obj-$(CPTCFG_BPAUTO_CRYPTO_SKCIPHER) += skcipher.o - compat-$(CPTCFG_BPAUTO_BUILD_WANT_DEV_COREDUMP) += drivers-base-devcoredump.o - compat-$(CPTCFG_BPAUTO_RHASHTABLE) += lib-rhashtable.o - cordic-objs += lib-cordic.o diff --git a/package/kernel/mac80211/patches/004-kconfig_backport_fix.patch b/package/kernel/mac80211/patches/004-kconfig_backport_fix.patch new file mode 100644 index 0000000000..f11029844c --- /dev/null +++ b/package/kernel/mac80211/patches/004-kconfig_backport_fix.patch @@ -0,0 +1,28 @@ +--- a/backport-include/linux/kconfig.h ++++ b/backport-include/linux/kconfig.h +@@ -5,6 +5,8 @@ + #include_next + #endif + ++#if LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0) ++ + #ifndef __ARG_PLACEHOLDER_1 + #define __ARG_PLACEHOLDER_1 0, + #define config_enabled(cfg) _config_enabled(cfg) +@@ -16,6 +18,7 @@ + * 3.1 - 3.3 had a broken version of this, so undef + * (they didn't have __ARG_PLACEHOLDER_1) + */ ++ + #undef IS_ENABLED + #define IS_ENABLED(option) \ + (config_enabled(option) || config_enabled(option##_MODULE)) +@@ -24,6 +27,8 @@ + #undef IS_BUILTIN + #define IS_BUILTIN(option) config_enabled(option) + ++#endif ++ + #ifndef IS_REACHABLE + /* + * IS_REACHABLE(CONFIG_FOO) evaluates to 1 if the currently compiled diff --git a/package/kernel/mac80211/patches/005-backport_skb_get_hash_perturb.patch b/package/kernel/mac80211/patches/005-backport_skb_get_hash_perturb.patch deleted file mode 100644 index 29bccc1e99..0000000000 --- a/package/kernel/mac80211/patches/005-backport_skb_get_hash_perturb.patch +++ /dev/null @@ -1,22 +0,0 @@ ---- a/backport-include/linux/skbuff.h -+++ b/backport-include/linux/skbuff.h -@@ -305,6 +305,19 @@ static inline void skb_free_frag(void *d - { - put_page(virt_to_head_page(data)); - } -+ -+#include -+#include -+ -+static inline u32 skb_get_hash_perturb(struct sk_buff *skb, u32 key) -+{ -+ struct flow_keys keys; -+ -+ skb_flow_dissect(skb, &keys); -+ return jhash_3words((__force u32)keys.dst, -+ (__force u32)keys.src ^ keys.ip_proto, -+ (__force u32)keys.ports, key); -+} - #endif - - #endif /* __BACKPORT_SKBUFF_H */ diff --git a/package/kernel/mac80211/patches/005-revert-devcoredump.patch b/package/kernel/mac80211/patches/005-revert-devcoredump.patch new file mode 100644 index 0000000000..ff460900ff --- /dev/null +++ b/package/kernel/mac80211/patches/005-revert-devcoredump.patch @@ -0,0 +1,152 @@ +--- a/compat/Makefile ++++ b/compat/Makefile +@@ -35,8 +35,6 @@ compat-$(CPTCFG_KERNEL_4_6) += backport- + + compat-$(CPTCFG_BPAUTO_BUILD_CRYPTO_CCM) += crypto-ccm.o + compat-$(CPTCFG_BPAUTO_CRYPTO_SKCIPHER) += crypto-skcipher.o +-skcipher-objs += crypto-skcipher.o +-obj-$(CPTCFG_BPAUTO_CRYPTO_SKCIPHER) += skcipher.o + compat-$(CPTCFG_BPAUTO_BUILD_WANT_DEV_COREDUMP) += drivers-base-devcoredump.o + compat-$(CPTCFG_BPAUTO_RHASHTABLE) += lib-rhashtable.o + cordic-objs += lib-cordic.o +--- a/compat/drivers-base-devcoredump.c ++++ b/compat/drivers-base-devcoredump.c +@@ -31,6 +31,7 @@ + #include + #include + #include ++#include "backports.h" + + static struct class devcd_class; + +@@ -40,6 +41,10 @@ static bool devcd_disabled; + /* if data isn't read by userspace after 5 minutes then delete it */ + #define DEVCD_TIMEOUT (HZ * 60 * 5) + ++#if LINUX_VERSION_CODE < KERNEL_VERSION(3,11,0) ++static struct bin_attribute devcd_attr_data; ++#endif ++ + struct devcd_entry { + struct device devcd_dev; + void *data; +@@ -69,8 +74,7 @@ static void devcd_dev_release(struct dev + * a struct device to know when it goes away? + */ + if (devcd->failing_dev->kobj.sd) +- sysfs_delete_link(&devcd->failing_dev->kobj, &dev->kobj, +- "devcoredump"); ++ sysfs_remove_link(&devcd->failing_dev->kobj, "devcoredump"); + + put_device(devcd->failing_dev); + kfree(devcd); +@@ -82,6 +86,9 @@ static void devcd_del(struct work_struct + + devcd = container_of(wk, struct devcd_entry, del_wk.work); + ++#if LINUX_VERSION_CODE < KERNEL_VERSION(3,11,0) ++ device_remove_bin_file(&devcd->devcd_dev, &devcd_attr_data); ++#endif + device_del(&devcd->devcd_dev); + put_device(&devcd->devcd_dev); + } +@@ -115,6 +122,7 @@ static struct bin_attribute devcd_attr_d + .write = devcd_data_write, + }; + ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,11,0) + static struct bin_attribute *devcd_dev_bin_attrs[] = { + &devcd_attr_data, NULL, + }; +@@ -126,6 +134,7 @@ static const struct attribute_group devc + static const struct attribute_group *devcd_dev_groups[] = { + &devcd_dev_group, NULL, + }; ++#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3,11,0) */ + + static int devcd_free(struct device *dev, void *data) + { +@@ -160,18 +169,11 @@ static ssize_t disabled_store(struct cla + + return count; + } +-static CLASS_ATTR_RW(disabled); + +-static struct attribute *devcd_class_attrs[] = { +- &class_attr_disabled.attr, +- NULL, ++static struct class_attribute devcd_class_attrs[] = { ++ __ATTR_RW(disabled), ++ __ATTR_NULL + }; +-#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,11,0) +-ATTRIBUTE_GROUPS(devcd_class); +-#else +-#define BP_ATTR_GRP_STRUCT device_attribute +-ATTRIBUTE_GROUPS_BACKPORT(devcd_class); +-#endif + + static struct class devcd_class = { + .name = "devcoredump", +@@ -179,10 +181,8 @@ static struct class devcd_class = { + .dev_release = devcd_dev_release, + #if LINUX_VERSION_CODE >= KERNEL_VERSION(3,11,0) + .dev_groups = devcd_dev_groups, +-#else +- .dev_attrs = devcd_class_dev_attrs, + #endif +- .class_groups = devcd_class_groups, ++ .class_attrs = devcd_class_attrs, + }; + + static ssize_t devcd_readv(char *buffer, loff_t offset, size_t count, +@@ -325,6 +325,11 @@ void dev_coredumpm(struct device *dev, s + if (device_add(&devcd->devcd_dev)) + goto put_device; + ++#if LINUX_VERSION_CODE < KERNEL_VERSION(3,11,0) ++ if (device_create_bin_file(&devcd->devcd_dev, &devcd_attr_data)) ++ goto put_device; ++#endif ++ + if (sysfs_create_link(&devcd->devcd_dev.kobj, &dev->kobj, + "failing_device")) + /* nothing - symlink will be missing */; +@@ -367,16 +372,13 @@ void dev_coredumpsg(struct device *dev, + } + EXPORT_SYMBOL_GPL(dev_coredumpsg); + +-static int __init devcoredump_init(void) ++int __init devcoredump_init(void) + { +- init_devcd_class_attrs(); + return class_register(&devcd_class); + } +-__initcall(devcoredump_init); + +-static void __exit devcoredump_exit(void) ++void __exit devcoredump_exit(void) + { + class_for_each_device(&devcd_class, NULL, NULL, devcd_free); + class_unregister(&devcd_class); + } +-__exitcall(devcoredump_exit); +--- a/include/linux/backport-devcoredump.h ++++ b/include/linux/backport-devcoredump.h +@@ -66,7 +66,7 @@ static inline void _devcd_free_sgtable(s + } + + +-#ifdef CONFIG_DEV_COREDUMP ++#ifdef CPTCFG_BPAUTO_WANT_DEV_COREDUMP + void dev_coredumpv(struct device *dev, void *data, size_t datalen, + gfp_t gfp); + +@@ -100,6 +100,6 @@ static inline void dev_coredumpsg(struct + { + _devcd_free_sgtable(table); + } +-#endif /* CONFIG_DEV_COREDUMP */ ++#endif /* CPTCFG_BPAUTO_WANT_DEV_COREDUMP */ + + #endif /* __DEVCOREDUMP_H */ diff --git a/package/kernel/mac80211/patches/006-revert-ktime-changes.patch b/package/kernel/mac80211/patches/006-revert-ktime-changes.patch new file mode 100644 index 0000000000..b839eb4c8d --- /dev/null +++ b/package/kernel/mac80211/patches/006-revert-ktime-changes.patch @@ -0,0 +1,20 @@ +--- a/drivers/net/wireless/ralink/rt2x00/rt2800usb.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2800usb.c +@@ -177,7 +177,7 @@ static bool rt2800usb_tx_sta_fifo_read_c + if (rt2800usb_txstatus_pending(rt2x00dev)) { + /* Read register after 1 ms */ + hrtimer_start(&rt2x00dev->txstatus_timer, +- TXSTATUS_READ_INTERVAL, ++ ktime_set(0, TXSTATUS_READ_INTERVAL), + HRTIMER_MODE_REL); + return false; + } +@@ -204,7 +204,7 @@ static void rt2800usb_async_read_tx_stat + + /* Read TX_STA_FIFO register after 2 ms */ + hrtimer_start(&rt2x00dev->txstatus_timer, +- 2 * TXSTATUS_READ_INTERVAL, ++ ktime_set(0, 2*TXSTATUS_READ_INTERVAL), + HRTIMER_MODE_REL); + } + diff --git a/package/kernel/mac80211/patches/007-revert-genetlink-changes.patch b/package/kernel/mac80211/patches/007-revert-genetlink-changes.patch new file mode 100644 index 0000000000..1a85106bc2 --- /dev/null +++ b/package/kernel/mac80211/patches/007-revert-genetlink-changes.patch @@ -0,0 +1,266 @@ +--- a/net/wireless/nl80211.c ++++ b/net/wireless/nl80211.c +@@ -32,8 +32,22 @@ static int nl80211_crypto_settings(struc + struct cfg80211_crypto_settings *settings, + int cipher_limit); + ++static int nl80211_pre_doit(const struct genl_ops *ops, struct sk_buff *skb, ++ struct genl_info *info); ++static void nl80211_post_doit(const struct genl_ops *ops, struct sk_buff *skb, ++ struct genl_info *info); ++ + /* the netlink family */ +-static struct genl_family nl80211_fam; ++static struct genl_family nl80211_fam = { ++ .id = GENL_ID_GENERATE, /* don't bother with a hardcoded ID */ ++ .name = NL80211_GENL_NAME, /* have users key off the name instead */ ++ .hdrsize = 0, /* no private header */ ++ .version = 1, /* no particular meaning now */ ++ .maxattr = NL80211_ATTR_MAX, ++ .netnsok = true, ++ .pre_doit = nl80211_pre_doit, ++ .post_doit = nl80211_post_doit, ++}; + + /* multicast groups */ + enum nl80211_multicast_groups { +@@ -549,14 +563,13 @@ static int nl80211_prepare_wdev_dump(str + + if (!cb->args[0]) { + err = nlmsg_parse(cb->nlh, GENL_HDRLEN + nl80211_fam.hdrsize, +- genl_family_attrbuf(&nl80211_fam), +- nl80211_fam.maxattr, nl80211_policy); ++ nl80211_fam.attrbuf, nl80211_fam.maxattr, ++ nl80211_policy); + if (err) + goto out_unlock; + +- *wdev = __cfg80211_wdev_from_attrs( +- sock_net(skb->sk), +- genl_family_attrbuf(&nl80211_fam)); ++ *wdev = __cfg80211_wdev_from_attrs(sock_net(skb->sk), ++ nl80211_fam.attrbuf); + if (IS_ERR(*wdev)) { + err = PTR_ERR(*wdev); + goto out_unlock; +@@ -1903,7 +1916,7 @@ static int nl80211_dump_wiphy_parse(stru + struct netlink_callback *cb, + struct nl80211_dump_wiphy_state *state) + { +- struct nlattr **tb = genl_family_attrbuf(&nl80211_fam); ++ struct nlattr **tb = nl80211_fam.attrbuf; + int ret = nlmsg_parse(cb->nlh, GENL_HDRLEN + nl80211_fam.hdrsize, + tb, nl80211_fam.maxattr, nl80211_policy); + /* ignore parse errors for backward compatibility */ +@@ -7733,7 +7746,6 @@ static int nl80211_send_survey(struct sk + + static int nl80211_dump_survey(struct sk_buff *skb, struct netlink_callback *cb) + { +- struct nlattr **attrbuf = genl_family_attrbuf(&nl80211_fam); + struct survey_info survey; + struct cfg80211_registered_device *rdev; + struct wireless_dev *wdev; +@@ -7746,7 +7758,7 @@ static int nl80211_dump_survey(struct sk + return res; + + /* prepare_wdev_dump parsed the attributes */ +- radio_stats = attrbuf[NL80211_ATTR_SURVEY_RADIO_STATS]; ++ radio_stats = nl80211_fam.attrbuf[NL80211_ATTR_SURVEY_RADIO_STATS]; + + if (!wdev->netdev) { + res = -EINVAL; +@@ -8594,14 +8606,14 @@ static int nl80211_testmode_dump(struct + */ + phy_idx = cb->args[0] - 1; + } else { +- struct nlattr **attrbuf = genl_family_attrbuf(&nl80211_fam); +- + err = nlmsg_parse(cb->nlh, GENL_HDRLEN + nl80211_fam.hdrsize, +- attrbuf, nl80211_fam.maxattr, nl80211_policy); ++ nl80211_fam.attrbuf, nl80211_fam.maxattr, ++ nl80211_policy); + if (err) + goto out_err; + +- rdev = __cfg80211_rdev_from_attrs(sock_net(skb->sk), attrbuf); ++ rdev = __cfg80211_rdev_from_attrs(sock_net(skb->sk), ++ nl80211_fam.attrbuf); + if (IS_ERR(rdev)) { + err = PTR_ERR(rdev); + goto out_err; +@@ -8609,8 +8621,9 @@ static int nl80211_testmode_dump(struct + phy_idx = rdev->wiphy_idx; + rdev = NULL; + +- if (attrbuf[NL80211_ATTR_TESTDATA]) +- cb->args[1] = (long)attrbuf[NL80211_ATTR_TESTDATA]; ++ if (nl80211_fam.attrbuf[NL80211_ATTR_TESTDATA]) ++ cb->args[1] = ++ (long)nl80211_fam.attrbuf[NL80211_ATTR_TESTDATA]; + } + + if (cb->args[1]) { +@@ -10814,7 +10827,8 @@ static int handle_nan_filter(struct nlat + + i = 0; + nla_for_each_nested(attr, attr_filter, rem) { +- filter[i].filter = nla_memdup(attr, GFP_KERNEL); ++ filter[i].filter = kmemdup(nla_data(attr), nla_len(attr), ++ GFP_KERNEL); + filter[i].len = nla_len(attr); + i++; + } +@@ -11450,7 +11464,6 @@ static int nl80211_prepare_vendor_dump(s + struct cfg80211_registered_device **rdev, + struct wireless_dev **wdev) + { +- struct nlattr **attrbuf = genl_family_attrbuf(&nl80211_fam); + u32 vid, subcmd; + unsigned int i; + int vcmd_idx = -1; +@@ -11486,28 +11499,31 @@ static int nl80211_prepare_vendor_dump(s + } + + err = nlmsg_parse(cb->nlh, GENL_HDRLEN + nl80211_fam.hdrsize, +- attrbuf, nl80211_fam.maxattr, nl80211_policy); ++ nl80211_fam.attrbuf, nl80211_fam.maxattr, ++ nl80211_policy); + if (err) + goto out_unlock; + +- if (!attrbuf[NL80211_ATTR_VENDOR_ID] || +- !attrbuf[NL80211_ATTR_VENDOR_SUBCMD]) { ++ if (!nl80211_fam.attrbuf[NL80211_ATTR_VENDOR_ID] || ++ !nl80211_fam.attrbuf[NL80211_ATTR_VENDOR_SUBCMD]) { + err = -EINVAL; + goto out_unlock; + } + +- *wdev = __cfg80211_wdev_from_attrs(sock_net(skb->sk), attrbuf); ++ *wdev = __cfg80211_wdev_from_attrs(sock_net(skb->sk), ++ nl80211_fam.attrbuf); + if (IS_ERR(*wdev)) + *wdev = NULL; + +- *rdev = __cfg80211_rdev_from_attrs(sock_net(skb->sk), attrbuf); ++ *rdev = __cfg80211_rdev_from_attrs(sock_net(skb->sk), ++ nl80211_fam.attrbuf); + if (IS_ERR(*rdev)) { + err = PTR_ERR(*rdev); + goto out_unlock; + } + +- vid = nla_get_u32(attrbuf[NL80211_ATTR_VENDOR_ID]); +- subcmd = nla_get_u32(attrbuf[NL80211_ATTR_VENDOR_SUBCMD]); ++ vid = nla_get_u32(nl80211_fam.attrbuf[NL80211_ATTR_VENDOR_ID]); ++ subcmd = nla_get_u32(nl80211_fam.attrbuf[NL80211_ATTR_VENDOR_SUBCMD]); + + for (i = 0; i < (*rdev)->wiphy.n_vendor_commands; i++) { + const struct wiphy_vendor_command *vcmd; +@@ -11531,9 +11547,9 @@ static int nl80211_prepare_vendor_dump(s + goto out_unlock; + } + +- if (attrbuf[NL80211_ATTR_VENDOR_DATA]) { +- data = nla_data(attrbuf[NL80211_ATTR_VENDOR_DATA]); +- data_len = nla_len(attrbuf[NL80211_ATTR_VENDOR_DATA]); ++ if (nl80211_fam.attrbuf[NL80211_ATTR_VENDOR_DATA]) { ++ data = nla_data(nl80211_fam.attrbuf[NL80211_ATTR_VENDOR_DATA]); ++ data_len = nla_len(nl80211_fam.attrbuf[NL80211_ATTR_VENDOR_DATA]); + } + + /* 0 is the first index - add 1 to parse only once */ +@@ -12795,21 +12811,6 @@ static __genl_const struct genl_ops nl80 + }, + }; + +-static struct genl_family nl80211_fam __ro_after_init = { +- .name = NL80211_GENL_NAME, /* have users key off the name instead */ +- .hdrsize = 0, /* no private header */ +- .version = 1, /* no particular meaning now */ +- .maxattr = NL80211_ATTR_MAX, +- .netnsok = true, +- .pre_doit = nl80211_pre_doit, +- .post_doit = nl80211_post_doit, +- .module = THIS_MODULE, +- .ops = nl80211_ops, +- .n_ops = ARRAY_SIZE(nl80211_ops), +- .mcgrps = nl80211_mcgrps, +- .n_mcgrps = ARRAY_SIZE(nl80211_mcgrps), +-}; +- + /* notification functions */ + + void nl80211_notify_wiphy(struct cfg80211_registered_device *rdev, +@@ -14759,11 +14760,12 @@ void nl80211_send_ap_stopped(struct wire + + /* initialisation/exit functions */ + +-int __init nl80211_init(void) ++int nl80211_init(void) + { + int err; + +- err = genl_register_family(&nl80211_fam); ++ err = genl_register_family_with_ops_groups(&nl80211_fam, nl80211_ops, ++ nl80211_mcgrps); + if (err) + return err; + +--- a/drivers/net/wireless/mac80211_hwsim.c ++++ b/drivers/net/wireless/mac80211_hwsim.c +@@ -587,8 +587,15 @@ struct hwsim_radiotap_ack_hdr { + __le16 rt_chbitmask; + } __packed; + +-/* MAC80211_HWSIM netlink family */ +-static struct genl_family hwsim_genl_family; ++/* MAC80211_HWSIM netlinf family */ ++static struct genl_family hwsim_genl_family = { ++ .id = GENL_ID_GENERATE, ++ .hdrsize = 0, ++ .name = "MAC80211_HWSIM", ++ .version = 1, ++ .maxattr = HWSIM_ATTR_MAX, ++ .netnsok = true, ++}; + + enum hwsim_multicast_groups { + HWSIM_MCGRP_CONFIG, +@@ -3250,18 +3257,6 @@ static __genl_const struct genl_ops hwsi + }, + }; + +-static struct genl_family hwsim_genl_family __ro_after_init = { +- .name = "MAC80211_HWSIM", +- .version = 1, +- .maxattr = HWSIM_ATTR_MAX, +- .netnsok = true, +- .module = THIS_MODULE, +- .ops = hwsim_ops, +- .n_ops = ARRAY_SIZE(hwsim_ops), +- .mcgrps = hwsim_mcgrps, +- .n_mcgrps = ARRAY_SIZE(hwsim_mcgrps), +-}; +- + static void destroy_radio(struct work_struct *work) + { + struct mac80211_hwsim_data *data = +@@ -3309,13 +3304,15 @@ static struct notifier_block hwsim_netli + .notifier_call = mac80211_hwsim_netlink_notify, + }; + +-static int __init hwsim_init_netlink(void) ++static int hwsim_init_netlink(void) + { + int rc; + + printk(KERN_INFO "mac80211_hwsim: initializing netlink\n"); + +- rc = genl_register_family(&hwsim_genl_family); ++ rc = genl_register_family_with_ops_groups(&hwsim_genl_family, ++ hwsim_ops, ++ hwsim_mcgrps); + if (rc) + goto failure; + diff --git a/package/kernel/mac80211/patches/008-revert-ndo_stats64-cleanup.patch b/package/kernel/mac80211/patches/008-revert-ndo_stats64-cleanup.patch new file mode 100644 index 0000000000..0f6f0f919f --- /dev/null +++ b/package/kernel/mac80211/patches/008-revert-ndo_stats64-cleanup.patch @@ -0,0 +1,20 @@ +--- a/net/mac80211/iface.c ++++ b/net/mac80211/iface.c +@@ -1133,7 +1133,7 @@ static u16 ieee80211_netdev_select_queue + return ieee80211_select_queue(IEEE80211_DEV_TO_SUB_IF(dev), skb); + } + +-static void ++static struct rtnl_link_stats64 * + ieee80211_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats) + { + int i; +@@ -1158,6 +1158,8 @@ ieee80211_get_stats64(struct net_device + stats->rx_bytes += rx_bytes; + stats->tx_bytes += tx_bytes; + } ++ ++ return stats; + } + + static const struct net_device_ops ieee80211_dataif_ops = { diff --git a/package/kernel/mac80211/patches/009-revert-mtu-changes.patch b/package/kernel/mac80211/patches/009-revert-mtu-changes.patch new file mode 100644 index 0000000000..f5e2757d3f --- /dev/null +++ b/package/kernel/mac80211/patches/009-revert-mtu-changes.patch @@ -0,0 +1,338 @@ +--- a/net/mac80211/iface.c ++++ b/net/mac80211/iface.c +@@ -151,6 +151,15 @@ void ieee80211_recalc_idle(struct ieee80 + ieee80211_hw_config(local, change); + } + ++static int ieee80211_change_mtu(struct net_device *dev, int new_mtu) ++{ ++ if (new_mtu < 256 || new_mtu > IEEE80211_MAX_DATA_LEN) ++ return -EINVAL; ++ ++ dev->mtu = new_mtu; ++ return 0; ++} ++ + static int ieee80211_verify_mac(struct ieee80211_sub_if_data *sdata, u8 *addr, + bool check_dup) + { +@@ -1168,6 +1177,7 @@ static const struct net_device_ops ieee8 + .ndo_uninit = ieee80211_uninit, + .ndo_start_xmit = ieee80211_subif_start_xmit, + .ndo_set_rx_mode = ieee80211_set_multicast_list, ++ .ndo_change_mtu = ieee80211_change_mtu, + .ndo_set_mac_address = ieee80211_change_mac, + .ndo_select_queue = ieee80211_netdev_select_queue, + .ndo_get_stats64 = ieee80211_get_stats64, +@@ -1211,6 +1221,7 @@ static const struct net_device_ops ieee8 + .ndo_uninit = ieee80211_uninit, + .ndo_start_xmit = ieee80211_monitor_start_xmit, + .ndo_set_rx_mode = ieee80211_set_multicast_list, ++ .ndo_change_mtu = ieee80211_change_mtu, + .ndo_set_mac_address = ieee80211_change_mac, + .ndo_select_queue = ieee80211_monitor_select_queue, + .ndo_get_stats64 = ieee80211_get_stats64, +@@ -1919,10 +1930,6 @@ int ieee80211_if_add(struct ieee80211_lo + + netdev_set_default_ethtool_ops(ndev, &ieee80211_ethtool_ops); + +- /* MTU range: 256 - 2304 */ +- ndev->min_mtu = 256; +- ndev->max_mtu = IEEE80211_MAX_DATA_LEN; +- + ret = register_netdevice(ndev); + if (ret) { + ieee80211_if_free(ndev); +--- a/drivers/net/wireless/ath/wil6210/netdev.c ++++ b/drivers/net/wireless/ath/wil6210/netdev.c +@@ -42,6 +42,21 @@ static int wil_stop(struct net_device *n + return wil_down(wil); + } + ++static int wil_change_mtu(struct net_device *ndev, int new_mtu) ++{ ++ struct wil6210_priv *wil = ndev_to_wil(ndev); ++ ++ if (new_mtu < 68 || new_mtu > mtu_max) { ++ wil_err(wil, "invalid MTU %d\n", new_mtu); ++ return -EINVAL; ++ } ++ ++ wil_dbg_misc(wil, "change MTU %d -> %d\n", ndev->mtu, new_mtu); ++ ndev->mtu = new_mtu; ++ ++ return 0; ++} ++ + static int wil_do_ioctl(struct net_device *ndev, struct ifreq *ifr, int cmd) + { + struct wil6210_priv *wil = ndev_to_wil(ndev); +@@ -55,6 +70,7 @@ static const struct net_device_ops wil_n + .ndo_start_xmit = wil_start_xmit, + .ndo_set_mac_address = eth_mac_addr, + .ndo_validate_addr = eth_validate_addr, ++ .ndo_change_mtu = wil_change_mtu, + .ndo_do_ioctl = wil_do_ioctl, + }; + +@@ -111,7 +127,6 @@ static int wil6210_netdev_poll_tx(struct + static void wil_dev_setup(struct net_device *dev) + { + ether_setup(dev); +- dev->max_mtu = mtu_max; + dev->tx_queue_len = WIL_TX_Q_LEN_DEFAULT; + } + +--- a/drivers/net/wireless/atmel/atmel.c ++++ b/drivers/net/wireless/atmel/atmel.c +@@ -1295,6 +1295,14 @@ static struct iw_statistics *atmel_get_w + return &priv->wstats; + } + ++static int atmel_change_mtu(struct net_device *dev, int new_mtu) ++{ ++ if ((new_mtu < 68) || (new_mtu > 2312)) ++ return -EINVAL; ++ dev->mtu = new_mtu; ++ return 0; ++} ++ + static int atmel_set_mac_address(struct net_device *dev, void *p) + { + struct sockaddr *addr = p; +@@ -1498,6 +1506,7 @@ static const struct file_operations atme + static const struct net_device_ops atmel_netdev_ops = { + .ndo_open = atmel_open, + .ndo_stop = atmel_close, ++ .ndo_change_mtu = atmel_change_mtu, + .ndo_set_mac_address = atmel_set_mac_address, + .ndo_start_xmit = start_tx, + .ndo_do_ioctl = atmel_ioctl, +@@ -1591,10 +1600,6 @@ struct net_device *init_atmel_card(unsig + dev->irq = irq; + dev->base_addr = port; + +- /* MTU range: 68 - 2312 */ +- dev->min_mtu = 68; +- dev->max_mtu = MAX_WIRELESS_BODY - ETH_FCS_LEN; +- + SET_NETDEV_DEV(dev, sys_dev); + + if ((rc = request_irq(dev->irq, service_interrupt, IRQF_SHARED, dev->name, dev))) { +--- a/drivers/net/wireless/cisco/airo.c ++++ b/drivers/net/wireless/cisco/airo.c +@@ -2329,6 +2329,14 @@ static int airo_set_mac_address(struct n + return 0; + } + ++static int airo_change_mtu(struct net_device *dev, int new_mtu) ++{ ++ if ((new_mtu < 68) || (new_mtu > 2400)) ++ return -EINVAL; ++ dev->mtu = new_mtu; ++ return 0; ++} ++ + static LIST_HEAD(airo_devices); + + static void add_airo_dev(struct airo_info *ai) +@@ -2648,6 +2656,7 @@ static const struct net_device_ops airo1 + .ndo_get_stats = airo_get_stats, + .ndo_set_mac_address = airo_set_mac_address, + .ndo_do_ioctl = airo_ioctl, ++ .ndo_change_mtu = airo_change_mtu, + }; + + static void wifi_setup(struct net_device *dev) +@@ -2659,8 +2668,6 @@ static void wifi_setup(struct net_device + dev->type = ARPHRD_IEEE80211; + dev->hard_header_len = ETH_HLEN; + dev->mtu = AIRO_DEF_MTU; +- dev->min_mtu = 68; +- dev->max_mtu = MIC_MSGLEN_MAX; + dev->addr_len = ETH_ALEN; + dev->tx_queue_len = 100; + +@@ -2747,6 +2754,7 @@ static const struct net_device_ops airo_ + .ndo_set_rx_mode = airo_set_multicast_list, + .ndo_set_mac_address = airo_set_mac_address, + .ndo_do_ioctl = airo_ioctl, ++ .ndo_change_mtu = airo_change_mtu, + .ndo_validate_addr = eth_validate_addr, + }; + +@@ -2758,6 +2766,7 @@ static const struct net_device_ops mpi_n + .ndo_set_rx_mode = airo_set_multicast_list, + .ndo_set_mac_address = airo_set_mac_address, + .ndo_do_ioctl = airo_ioctl, ++ .ndo_change_mtu = airo_change_mtu, + .ndo_validate_addr = eth_validate_addr, + }; + +@@ -2813,7 +2822,6 @@ static struct net_device *_init_airo_car + dev->irq = irq; + dev->base_addr = port; + dev->priv_flags &= ~IFF_TX_SKB_SHARING; +- dev->max_mtu = MIC_MSGLEN_MAX; + + SET_NETDEV_DEV(dev, dmdev); + +--- a/drivers/net/wireless/intel/ipw2x00/ipw2100.c ++++ b/drivers/net/wireless/intel/ipw2x00/ipw2100.c +@@ -6039,6 +6039,7 @@ static const struct net_device_ops ipw21 + .ndo_open = ipw2100_open, + .ndo_stop = ipw2100_close, + .ndo_start_xmit = libipw_xmit, ++ .ndo_change_mtu = libipw_change_mtu, + .ndo_tx_timeout = ipw2100_tx_timeout, + .ndo_set_mac_address = ipw2100_set_address, + .ndo_validate_addr = eth_validate_addr, +@@ -6074,8 +6075,6 @@ static struct net_device *ipw2100_alloc_ + dev->wireless_data = &priv->wireless_data; + dev->watchdog_timeo = 3 * HZ; + dev->irq = 0; +- dev->min_mtu = 68; +- dev->max_mtu = LIBIPW_DATA_LEN; + + /* NOTE: We don't use the wireless_handlers hook + * in dev as the system will start throwing WX requests +--- a/drivers/net/wireless/intel/ipw2x00/ipw2200.c ++++ b/drivers/net/wireless/intel/ipw2x00/ipw2200.c +@@ -11561,6 +11561,7 @@ static const struct net_device_ops ipw_p + .ndo_open = ipw_prom_open, + .ndo_stop = ipw_prom_stop, + .ndo_start_xmit = ipw_prom_hard_start_xmit, ++ .ndo_change_mtu = libipw_change_mtu, + .ndo_set_mac_address = eth_mac_addr, + .ndo_validate_addr = eth_validate_addr, + }; +@@ -11586,9 +11587,6 @@ static int ipw_prom_alloc(struct ipw_pri + priv->prom_net_dev->type = ARPHRD_IEEE80211_RADIOTAP; + priv->prom_net_dev->netdev_ops = &ipw_prom_netdev_ops; + +- priv->prom_net_dev->min_mtu = 68; +- priv->prom_net_dev->max_mtu = LIBIPW_DATA_LEN; +- + priv->prom_priv->ieee->iw_mode = IW_MODE_MONITOR; + SET_NETDEV_DEV(priv->prom_net_dev, &priv->pci_dev->dev); + +@@ -11621,6 +11619,7 @@ static const struct net_device_ops ipw_n + .ndo_set_rx_mode = ipw_net_set_multicast_list, + .ndo_set_mac_address = ipw_net_set_mac_address, + .ndo_start_xmit = libipw_xmit, ++ .ndo_change_mtu = libipw_change_mtu, + .ndo_validate_addr = eth_validate_addr, + }; + +@@ -11730,9 +11729,6 @@ static int ipw_pci_probe(struct pci_dev + net_dev->wireless_handlers = &ipw_wx_handler_def; + net_dev->ethtool_ops = &ipw_ethtool_ops; + +- net_dev->min_mtu = 68; +- net_dev->max_mtu = LIBIPW_DATA_LEN; +- + err = sysfs_create_group(&pdev->dev.kobj, &ipw_attribute_group); + if (err) { + IPW_ERROR("failed to create sysfs device attributes\n"); +--- a/drivers/net/wireless/intel/ipw2x00/libipw.h ++++ b/drivers/net/wireless/intel/ipw2x00/libipw.h +@@ -948,6 +948,7 @@ static inline int libipw_is_cck_rate(u8 + /* libipw.c */ + void free_libipw(struct net_device *dev, int monitor); + struct net_device *alloc_libipw(int sizeof_priv, int monitor); ++int libipw_change_mtu(struct net_device *dev, int new_mtu); + + void libipw_networks_age(struct libipw_device *ieee, unsigned long age_secs); + +--- a/drivers/net/wireless/intel/ipw2x00/libipw_module.c ++++ b/drivers/net/wireless/intel/ipw2x00/libipw_module.c +@@ -118,6 +118,15 @@ static void libipw_networks_initialize(s + &ieee->network_free_list); + } + ++int libipw_change_mtu(struct net_device *dev, int new_mtu) ++{ ++ if ((new_mtu < 68) || (new_mtu > LIBIPW_DATA_LEN)) ++ return -EINVAL; ++ dev->mtu = new_mtu; ++ return 0; ++} ++EXPORT_SYMBOL(libipw_change_mtu); ++ + struct net_device *alloc_libipw(int sizeof_priv, int monitor) + { + struct libipw_device *ieee; +--- a/drivers/net/wireless/intersil/hostap/hostap_main.c ++++ b/drivers/net/wireless/intersil/hostap/hostap_main.c +@@ -765,6 +765,16 @@ static void hostap_set_multicast_list(st + } + + ++static int prism2_change_mtu(struct net_device *dev, int new_mtu) ++{ ++ if (new_mtu < PRISM2_MIN_MTU || new_mtu > PRISM2_MAX_MTU) ++ return -EINVAL; ++ ++ dev->mtu = new_mtu; ++ return 0; ++} ++ ++ + static void prism2_tx_timeout(struct net_device *dev) + { + struct hostap_interface *iface; +@@ -803,6 +813,7 @@ static const struct net_device_ops hosta + .ndo_do_ioctl = hostap_ioctl, + .ndo_set_mac_address = prism2_set_mac_address, + .ndo_set_rx_mode = hostap_set_multicast_list, ++ .ndo_change_mtu = prism2_change_mtu, + .ndo_tx_timeout = prism2_tx_timeout, + .ndo_validate_addr = eth_validate_addr, + }; +@@ -815,6 +826,7 @@ static const struct net_device_ops hosta + .ndo_do_ioctl = hostap_ioctl, + .ndo_set_mac_address = prism2_set_mac_address, + .ndo_set_rx_mode = hostap_set_multicast_list, ++ .ndo_change_mtu = prism2_change_mtu, + .ndo_tx_timeout = prism2_tx_timeout, + .ndo_validate_addr = eth_validate_addr, + }; +@@ -827,6 +839,7 @@ static const struct net_device_ops hosta + .ndo_do_ioctl = hostap_ioctl, + .ndo_set_mac_address = prism2_set_mac_address, + .ndo_set_rx_mode = hostap_set_multicast_list, ++ .ndo_change_mtu = prism2_change_mtu, + .ndo_tx_timeout = prism2_tx_timeout, + .ndo_validate_addr = eth_validate_addr, + }; +@@ -838,8 +851,6 @@ void hostap_setup_dev(struct net_device + + iface = netdev_priv(dev); + ether_setup(dev); +- dev->min_mtu = PRISM2_MIN_MTU; +- dev->max_mtu = PRISM2_MAX_MTU; + dev->priv_flags &= ~IFF_TX_SKB_SHARING; + + /* kernel callbacks */ +--- a/drivers/net/wireless/intersil/orinoco/main.c ++++ b/drivers/net/wireless/intersil/orinoco/main.c +@@ -322,6 +322,9 @@ int orinoco_change_mtu(struct net_device + { + struct orinoco_private *priv = ndev_priv(dev); + ++ if ((new_mtu < ORINOCO_MIN_MTU) || (new_mtu > ORINOCO_MAX_MTU)) ++ return -EINVAL; ++ + /* MTU + encapsulation + header length */ + if ((new_mtu + ENCAPS_OVERHEAD + sizeof(struct ieee80211_hdr)) > + (priv->nicbuf_size - ETH_HLEN)) +@@ -2285,9 +2288,6 @@ int orinoco_if_add(struct orinoco_privat + dev->base_addr = base_addr; + dev->irq = irq; + +- dev->min_mtu = ORINOCO_MIN_MTU; +- dev->max_mtu = ORINOCO_MAX_MTU; +- + SET_NETDEV_DEV(dev, priv->dev); + ret = register_netdev(dev); + if (ret) diff --git a/package/kernel/mac80211/patches/060-no_local_ssb_bcma.patch b/package/kernel/mac80211/patches/060-no_local_ssb_bcma.patch index 4df5ac57f0..527938f015 100644 --- a/package/kernel/mac80211/patches/060-no_local_ssb_bcma.patch +++ b/package/kernel/mac80211/patches/060-no_local_ssb_bcma.patch @@ -1,6 +1,6 @@ --- a/.local-symbols +++ b/.local-symbols -@@ -477,45 +477,6 @@ USB_IPHETH= +@@ -482,45 +482,6 @@ USB_IPHETH= USB_SIERRA_NET= USB_VL600= USB_NET_CH9200= @@ -88,7 +88,7 @@ gpiodev = bus->chipco.dev ? : pcidev; --- a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/Makefile +++ b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/Makefile -@@ -43,6 +43,6 @@ brcmsmac-y := \ +@@ -42,6 +42,6 @@ brcmsmac-y := \ brcms_trace_events.o \ debug.o diff --git a/package/kernel/mac80211/patches/100-remove-cryptoapi-dependencies.patch b/package/kernel/mac80211/patches/100-remove-cryptoapi-dependencies.patch index fbe22e51b7..7eb3d99c07 100644 --- a/package/kernel/mac80211/patches/100-remove-cryptoapi-dependencies.patch +++ b/package/kernel/mac80211/patches/100-remove-cryptoapi-dependencies.patch @@ -18,12 +18,12 @@ - aes_gcm.o \ aes_cmac.o \ - aes_gmac.o \ + fils_aead.o \ cfg.o \ ethtool.o \ - rx.o \ --- a/net/mac80211/aes_ccm.c +++ b/net/mac80211/aes_ccm.c -@@ -13,89 +13,132 @@ +@@ -13,103 +13,132 @@ #include #include #include @@ -33,76 +33,101 @@ #include "key.h" #include "aes_ccm.h" --void ieee80211_aes_ccm_encrypt(struct crypto_aead *tfm, u8 *b_0, u8 *aad, -- u8 *data, size_t data_len, u8 *mic, -- size_t mic_len) +-int ieee80211_aes_ccm_encrypt(struct crypto_aead *tfm, u8 *b_0, u8 *aad, +- u8 *data, size_t data_len, u8 *mic, +- size_t mic_len) +static void aes_ccm_prepare(struct crypto_cipher *tfm, u8 *b_0, u8 *aad, u8 *s_0, + u8 *a, u8 *b) { - struct scatterlist sg[3]; +- struct aead_request *aead_req; +- int reqsize = sizeof(*aead_req) + crypto_aead_reqsize(tfm); +- u8 *__aad; + int i; -+ + +- aead_req = kzalloc(reqsize + CCM_AAD_LEN, GFP_ATOMIC); +- if (!aead_req) +- return -ENOMEM; + crypto_cipher_encrypt_one(tfm, b, b_0); -+ + +- __aad = (u8 *)aead_req + reqsize; +- memcpy(__aad, aad, CCM_AAD_LEN); + /* Extra Authenticate-only data (always two AES blocks) */ + for (i = 0; i < AES_BLOCK_SIZE; i++) + aad[i] ^= b[i]; + crypto_cipher_encrypt_one(tfm, b, aad); -+ + +- sg_init_table(sg, 3); +- sg_set_buf(&sg[0], &__aad[2], be16_to_cpup((__be16 *)__aad)); +- sg_set_buf(&sg[1], data, data_len); +- sg_set_buf(&sg[2], mic, mic_len); + aad += AES_BLOCK_SIZE; -+ + +- aead_request_set_tfm(aead_req, tfm); +- aead_request_set_crypt(aead_req, sg, sg, data_len, b_0); +- aead_request_set_ad(aead_req, sg[0].length); + for (i = 0; i < AES_BLOCK_SIZE; i++) + aad[i] ^= b[i]; + crypto_cipher_encrypt_one(tfm, a, aad); -- char aead_req_data[sizeof(struct aead_request) + -- crypto_aead_reqsize(tfm)] -- __aligned(__alignof__(struct aead_request)); -- struct aead_request *aead_req = (void *) aead_req_data; +- crypto_aead_encrypt(aead_req); +- kzfree(aead_req); + /* Mask out bits from auth-only-b_0 */ + b_0[0] &= 0x07; -- memset(aead_req, 0, sizeof(aead_req_data)); +- return 0; + /* S_0 is used to encrypt T (= MIC) */ + b_0[14] = 0; + b_0[15] = 0; + crypto_cipher_encrypt_one(tfm, s_0, b_0); -+} - -- sg_init_table(sg, 3); -- sg_set_buf(&sg[0], &aad[2], be16_to_cpup((__be16 *)aad)); -- sg_set_buf(&sg[1], data, data_len); -- sg_set_buf(&sg[2], mic, mic_len); + } -- aead_request_set_tfm(aead_req, tfm); -- aead_request_set_crypt(aead_req, sg, sg, data_len, b_0); -- aead_request_set_ad(aead_req, sg[0].length); +-int ieee80211_aes_ccm_decrypt(struct crypto_aead *tfm, u8 *b_0, u8 *aad, +- u8 *data, size_t data_len, u8 *mic, +- size_t mic_len) ++ +void ieee80211_aes_ccm_encrypt(struct crypto_cipher *tfm, u8 *b_0, u8 *aad, + u8 *data, size_t data_len, u8 *mic, + size_t mic_len) -+{ + { +- struct scatterlist sg[3]; +- struct aead_request *aead_req; +- int reqsize = sizeof(*aead_req) + crypto_aead_reqsize(tfm); +- u8 *__aad; +- int err; + int i, j, last_len, num_blocks; + u8 b[AES_BLOCK_SIZE]; + u8 s_0[AES_BLOCK_SIZE]; + u8 e[AES_BLOCK_SIZE]; + u8 *pos, *cpos; -+ + +- if (data_len == 0) +- return -EINVAL; + num_blocks = DIV_ROUND_UP(data_len, AES_BLOCK_SIZE); + last_len = data_len % AES_BLOCK_SIZE; + aes_ccm_prepare(tfm, b_0, aad, s_0, b, b); -+ + +- aead_req = kzalloc(reqsize + CCM_AAD_LEN, GFP_ATOMIC); +- if (!aead_req) +- return -ENOMEM; + /* Process payload blocks */ + pos = data; + cpos = data; + for (j = 1; j <= num_blocks; j++) { + int blen = (j == num_blocks && last_len) ? + last_len : AES_BLOCK_SIZE; -+ + +- __aad = (u8 *)aead_req + reqsize; +- memcpy(__aad, aad, CCM_AAD_LEN); + /* Authentication followed by encryption */ + for (i = 0; i < blen; i++) + b[i] ^= pos[i]; + crypto_cipher_encrypt_one(tfm, b, b); -+ + +- sg_init_table(sg, 3); +- sg_set_buf(&sg[0], &__aad[2], be16_to_cpup((__be16 *)__aad)); +- sg_set_buf(&sg[1], data, data_len); +- sg_set_buf(&sg[2], mic, mic_len); + b_0[14] = (j >> 8) & 0xff; + b_0[15] = j & 0xff; + crypto_cipher_encrypt_one(tfm, e, b_0); @@ -110,41 +135,26 @@ + *cpos++ = *pos++ ^ e[i]; + } -- crypto_aead_encrypt(aead_req); +- aead_request_set_tfm(aead_req, tfm); +- aead_request_set_crypt(aead_req, sg, sg, data_len + mic_len, b_0); +- aead_request_set_ad(aead_req, sg[0].length); + for (i = 0; i < mic_len; i++) + mic[i] = b[i] ^ s_0[i]; - } ++} --int ieee80211_aes_ccm_decrypt(struct crypto_aead *tfm, u8 *b_0, u8 *aad, +- err = crypto_aead_decrypt(aead_req); +- kzfree(aead_req); +int ieee80211_aes_ccm_decrypt(struct crypto_cipher *tfm, u8 *b_0, u8 *aad, - u8 *data, size_t data_len, u8 *mic, - size_t mic_len) - { -- struct scatterlist sg[3]; -- char aead_req_data[sizeof(struct aead_request) + -- crypto_aead_reqsize(tfm)] -- __aligned(__alignof__(struct aead_request)); -- struct aead_request *aead_req = (void *) aead_req_data; -- -- if (data_len == 0) -- return -EINVAL; -- -- memset(aead_req, 0, sizeof(aead_req_data)); -- -- sg_init_table(sg, 3); -- sg_set_buf(&sg[0], &aad[2], be16_to_cpup((__be16 *)aad)); -- sg_set_buf(&sg[1], data, data_len); -- sg_set_buf(&sg[2], mic, mic_len); -- -- aead_request_set_tfm(aead_req, tfm); -- aead_request_set_crypt(aead_req, sg, sg, data_len + mic_len, b_0); -- aead_request_set_ad(aead_req, sg[0].length); ++ u8 *data, size_t data_len, u8 *mic, ++ size_t mic_len) ++{ + int i, j, last_len, num_blocks; + u8 *pos, *cpos; + u8 a[AES_BLOCK_SIZE]; + u8 b[AES_BLOCK_SIZE]; + u8 s_0[AES_BLOCK_SIZE]; -+ + +- return err; + num_blocks = DIV_ROUND_UP(data_len, AES_BLOCK_SIZE); + last_len = data_len % AES_BLOCK_SIZE; + aes_ccm_prepare(tfm, b_0, aad, s_0, a, b); @@ -171,8 +181,7 @@ + if ((mic[i] ^ s_0[i]) != a[i]) + return -1; + } - -- return crypto_aead_decrypt(aead_req); ++ + return 0; } @@ -185,12 +194,12 @@ { - struct crypto_aead *tfm; - int err; -+ struct crypto_cipher *tfm; - +- - tfm = crypto_alloc_aead("ccm(aes)", 0, CRYPTO_ALG_ASYNC); - if (IS_ERR(tfm)) - return tfm; -- ++ struct crypto_cipher *tfm; + - err = crypto_aead_setkey(tfm, key, key_len); - if (err) - goto free_aead; @@ -215,73 +224,11 @@ - crypto_free_aead(tfm); + crypto_free_cipher(tfm); } ---- a/net/mac80211/aes_ccm.h -+++ b/net/mac80211/aes_ccm.h -@@ -12,15 +12,15 @@ - - #include - --struct crypto_aead *ieee80211_aes_key_setup_encrypt(const u8 key[], -- size_t key_len, -- size_t mic_len); --void ieee80211_aes_ccm_encrypt(struct crypto_aead *tfm, u8 *b_0, u8 *aad, -+struct crypto_cipher *ieee80211_aes_key_setup_encrypt(const u8 key[], -+ size_t key_len, -+ size_t mic_len); -+void ieee80211_aes_ccm_encrypt(struct crypto_cipher *tfm, u8 *b_0, u8 *aad, - u8 *data, size_t data_len, u8 *mic, - size_t mic_len); --int ieee80211_aes_ccm_decrypt(struct crypto_aead *tfm, u8 *b_0, u8 *aad, -+int ieee80211_aes_ccm_decrypt(struct crypto_cipher *tfm, u8 *b_0, u8 *aad, - u8 *data, size_t data_len, u8 *mic, - size_t mic_len); --void ieee80211_aes_key_free(struct crypto_aead *tfm); -+void ieee80211_aes_key_free(struct crypto_cipher *tfm); - - #endif /* AES_CCM_H */ ---- a/net/mac80211/aes_gcm.h -+++ b/net/mac80211/aes_gcm.h -@@ -11,12 +11,28 @@ - - #include - --void ieee80211_aes_gcm_encrypt(struct crypto_aead *tfm, u8 *j_0, u8 *aad, -- u8 *data, size_t data_len, u8 *mic); --int ieee80211_aes_gcm_decrypt(struct crypto_aead *tfm, u8 *j_0, u8 *aad, -- u8 *data, size_t data_len, u8 *mic); --struct crypto_aead *ieee80211_aes_gcm_key_setup_encrypt(const u8 key[], -- size_t key_len); --void ieee80211_aes_gcm_key_free(struct crypto_aead *tfm); -+static inline void -+ieee80211_aes_gcm_encrypt(struct crypto_aead *tfm, u8 *j_0, u8 *aad, -+ u8 *data, size_t data_len, u8 *mic) -+{ -+} -+ -+static inline int -+ieee80211_aes_gcm_decrypt(struct crypto_aead *tfm, u8 *j_0, u8 *aad, -+ u8 *data, size_t data_len, u8 *mic) -+{ -+ return -EOPNOTSUPP; -+} -+ -+static inline struct crypto_aead * -+ieee80211_aes_gcm_key_setup_encrypt(const u8 key[], size_t key_len) -+{ -+ return NULL; -+} -+ -+static inline void -+ieee80211_aes_gcm_key_free(struct crypto_aead *tfm) -+{ -+} - - #endif /* AES_GCM_H */ --- a/net/mac80211/aes_gmac.h +++ b/net/mac80211/aes_gmac.h -@@ -11,10 +11,22 @@ - - #include +@@ -15,10 +15,22 @@ + #define GMAC_MIC_LEN 16 + #define GMAC_NONCE_LEN 12 -struct crypto_aead *ieee80211_aes_gmac_key_setup(const u8 key[], - size_t key_len); @@ -320,7 +267,7 @@ struct { --- a/net/mac80211/wpa.c +++ b/net/mac80211/wpa.c -@@ -304,7 +304,8 @@ ieee80211_crypto_tkip_decrypt(struct iee +@@ -305,7 +305,8 @@ ieee80211_crypto_tkip_decrypt(struct iee } @@ -330,7 +277,7 @@ { __le16 mask_fc; int a4_included, mgmt; -@@ -334,14 +335,8 @@ static void ccmp_special_blocks(struct s +@@ -335,14 +336,8 @@ static void ccmp_special_blocks(struct s else qos_tid = 0; @@ -347,7 +294,7 @@ /* Nonce: Nonce Flags | A2 | PN * Nonce Flags: Priority (b0..b3) | Management (b4) | Reserved (b5..b7) -@@ -349,6 +344,8 @@ static void ccmp_special_blocks(struct s +@@ -350,6 +345,8 @@ static void ccmp_special_blocks(struct s b_0[1] = qos_tid | (mgmt << 4); memcpy(&b_0[2], hdr->addr2, ETH_ALEN); memcpy(&b_0[8], pn, IEEE80211_CCMP_PN_LEN); @@ -356,16 +303,31 @@ /* AAD (extra authenticate-only data) / masked 802.11 header * FC | A1 | A2 | A3 | SC | [A4] | [QC] */ -@@ -460,7 +457,7 @@ static int ccmp_encrypt_skb(struct ieee8 +@@ -406,7 +403,7 @@ static int ccmp_encrypt_skb(struct ieee8 + u8 *pos; + u8 pn[6]; + u64 pn64; +- u8 aad[CCM_AAD_LEN]; ++ u8 aad[2 * AES_BLOCK_SIZE]; + u8 b_0[AES_BLOCK_SIZE]; + + if (info->control.hw_key && +@@ -461,9 +458,11 @@ static int ccmp_encrypt_skb(struct ieee8 return 0; pos += IEEE80211_CCMP_HDR_LEN; - ccmp_special_blocks(skb, pn, b_0, aad); +- return ieee80211_aes_ccm_encrypt(key->u.ccmp.tfm, b_0, aad, pos, len, +- skb_put(skb, mic_len), mic_len); + ccmp_special_blocks(skb, pn, b_0, aad, len); - ieee80211_aes_ccm_encrypt(key->u.ccmp.tfm, b_0, aad, pos, len, - skb_put(skb, mic_len), mic_len); ++ ieee80211_aes_ccm_encrypt(key->u.ccmp.tfm, b_0, aad, pos, len, ++ skb_put(skb, mic_len), mic_len); ++ ++ return 0; + } + -@@ -537,7 +534,7 @@ ieee80211_crypto_ccmp_decrypt(struct iee +@@ -536,7 +535,7 @@ ieee80211_crypto_ccmp_decrypt(struct iee u8 aad[2 * AES_BLOCK_SIZE]; u8 b_0[AES_BLOCK_SIZE]; /* hardware didn't decrypt/verify MIC */ @@ -374,3 +336,113 @@ if (ieee80211_aes_ccm_decrypt( key->u.ccmp.tfm, b_0, aad, +@@ -638,7 +637,7 @@ static int gcmp_encrypt_skb(struct ieee8 + u8 *pos; + u8 pn[6]; + u64 pn64; +- u8 aad[GCM_AAD_LEN]; ++ u8 aad[2 * AES_BLOCK_SIZE]; + u8 j_0[AES_BLOCK_SIZE]; + + if (info->control.hw_key && +@@ -695,8 +694,10 @@ static int gcmp_encrypt_skb(struct ieee8 + + pos += IEEE80211_GCMP_HDR_LEN; + gcmp_special_blocks(skb, pn, j_0, aad); +- return ieee80211_aes_gcm_encrypt(key->u.gcmp.tfm, j_0, aad, pos, len, +- skb_put(skb, IEEE80211_GCMP_MIC_LEN)); ++ ieee80211_aes_gcm_encrypt(key->u.gcmp.tfm, j_0, aad, pos, len, ++ skb_put(skb, IEEE80211_GCMP_MIC_LEN)); ++ ++ return 0; + } + + ieee80211_tx_result +@@ -1120,9 +1121,9 @@ ieee80211_crypto_aes_gmac_encrypt(struct + struct ieee80211_key *key = tx->key; + struct ieee80211_mmie_16 *mmie; + struct ieee80211_hdr *hdr; +- u8 aad[GMAC_AAD_LEN]; ++ u8 aad[20]; + u64 pn64; +- u8 nonce[GMAC_NONCE_LEN]; ++ u8 nonce[12]; + + if (WARN_ON(skb_queue_len(&tx->skbs) != 1)) + return TX_DROP; +@@ -1168,7 +1169,7 @@ ieee80211_crypto_aes_gmac_decrypt(struct + struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); + struct ieee80211_key *key = rx->key; + struct ieee80211_mmie_16 *mmie; +- u8 aad[GMAC_AAD_LEN], mic[GMAC_MIC_LEN], ipn[6], nonce[GMAC_NONCE_LEN]; ++ u8 aad[20], mic[16], ipn[6], nonce[12]; + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; + + if (!ieee80211_is_mgmt(hdr->frame_control)) +--- a/net/mac80211/aes_ccm.h ++++ b/net/mac80211/aes_ccm.h +@@ -12,17 +12,15 @@ + + #include + +-#define CCM_AAD_LEN 32 +- +-struct crypto_aead *ieee80211_aes_key_setup_encrypt(const u8 key[], +- size_t key_len, +- size_t mic_len); +-int ieee80211_aes_ccm_encrypt(struct crypto_aead *tfm, u8 *b_0, u8 *aad, +- u8 *data, size_t data_len, u8 *mic, +- size_t mic_len); +-int ieee80211_aes_ccm_decrypt(struct crypto_aead *tfm, u8 *b_0, u8 *aad, ++struct crypto_cipher *ieee80211_aes_key_setup_encrypt(const u8 key[], ++ size_t key_len, ++ size_t mic_len); ++void ieee80211_aes_ccm_encrypt(struct crypto_cipher *tfm, u8 *b_0, u8 *aad, ++ u8 *data, size_t data_len, u8 *mic, ++ size_t mic_len); ++int ieee80211_aes_ccm_decrypt(struct crypto_cipher *tfm, u8 *b_0, u8 *aad, + u8 *data, size_t data_len, u8 *mic, + size_t mic_len); +-void ieee80211_aes_key_free(struct crypto_aead *tfm); ++void ieee80211_aes_key_free(struct crypto_cipher *tfm); + + #endif /* AES_CCM_H */ +--- a/net/mac80211/aes_gcm.h ++++ b/net/mac80211/aes_gcm.h +@@ -11,14 +11,28 @@ + + #include + +-#define GCM_AAD_LEN 32 ++static inline void ++ieee80211_aes_gcm_encrypt(struct crypto_aead *tfm, u8 *j_0, u8 *aad, ++ u8 *data, size_t data_len, u8 *mic) ++{ ++} + +-int ieee80211_aes_gcm_encrypt(struct crypto_aead *tfm, u8 *j_0, u8 *aad, +- u8 *data, size_t data_len, u8 *mic); +-int ieee80211_aes_gcm_decrypt(struct crypto_aead *tfm, u8 *j_0, u8 *aad, +- u8 *data, size_t data_len, u8 *mic); +-struct crypto_aead *ieee80211_aes_gcm_key_setup_encrypt(const u8 key[], +- size_t key_len); +-void ieee80211_aes_gcm_key_free(struct crypto_aead *tfm); ++static inline int ++ieee80211_aes_gcm_decrypt(struct crypto_aead *tfm, u8 *j_0, u8 *aad, ++ u8 *data, size_t data_len, u8 *mic) ++{ ++ return -EOPNOTSUPP; ++} ++ ++static inline struct crypto_aead * ++ieee80211_aes_gcm_key_setup_encrypt(const u8 key[], size_t key_len) ++{ ++ return NULL; ++} ++ ++static inline void ++ieee80211_aes_gcm_key_free(struct crypto_aead *tfm) ++{ ++} + + #endif /* AES_GCM_H */ diff --git a/package/kernel/mac80211/patches/110-mac80211_keep_keys_on_stop_ap.patch b/package/kernel/mac80211/patches/110-mac80211_keep_keys_on_stop_ap.patch index c42b17de38..ff619129d9 100644 --- a/package/kernel/mac80211/patches/110-mac80211_keep_keys_on_stop_ap.patch +++ b/package/kernel/mac80211/patches/110-mac80211_keep_keys_on_stop_ap.patch @@ -2,7 +2,7 @@ Used for AP+STA support in OpenWrt - preserve AP mode keys across STA reconnects --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c -@@ -1016,7 +1016,6 @@ static int ieee80211_stop_ap(struct wiph +@@ -1014,7 +1014,6 @@ static int ieee80211_stop_ap(struct wiph sdata->u.ap.driver_smps_mode = IEEE80211_SMPS_OFF; __sta_info_flush(sdata, true); diff --git a/package/kernel/mac80211/patches/130-mac80211-hwsim-hrtimer-clock.patch b/package/kernel/mac80211/patches/130-mac80211-hwsim-hrtimer-clock.patch index 29d70343bb..828ed83cb7 100644 --- a/package/kernel/mac80211/patches/130-mac80211-hwsim-hrtimer-clock.patch +++ b/package/kernel/mac80211/patches/130-mac80211-hwsim-hrtimer-clock.patch @@ -1,6 +1,6 @@ --- a/drivers/net/wireless/mac80211_hwsim.c +++ b/drivers/net/wireless/mac80211_hwsim.c -@@ -2662,7 +2662,7 @@ static int mac80211_hwsim_new_radio(stru +@@ -2678,7 +2678,7 @@ static int mac80211_hwsim_new_radio(stru tasklet_hrtimer_init(&data->beacon_timer, mac80211_hwsim_beacon, diff --git a/package/kernel/mac80211/patches/150-disable_addr_notifier.patch b/package/kernel/mac80211/patches/150-disable_addr_notifier.patch index f4cb41cd30..ca1e53f8df 100644 --- a/package/kernel/mac80211/patches/150-disable_addr_notifier.patch +++ b/package/kernel/mac80211/patches/150-disable_addr_notifier.patch @@ -18,7 +18,7 @@ static int ieee80211_ifa6_changed(struct notifier_block *nb, unsigned long data, void *arg) { -@@ -1101,14 +1101,14 @@ int ieee80211_register_hw(struct ieee802 +@@ -1111,14 +1111,14 @@ int ieee80211_register_hw(struct ieee802 if (result) goto fail_flows; @@ -35,7 +35,7 @@ local->ifa6_notifier.notifier_call = ieee80211_ifa6_changed; result = register_inet6addr_notifier(&local->ifa6_notifier); if (result) -@@ -1117,13 +1117,13 @@ int ieee80211_register_hw(struct ieee802 +@@ -1127,13 +1127,13 @@ int ieee80211_register_hw(struct ieee802 return 0; @@ -52,7 +52,7 @@ fail_ifa: #endif ieee80211_txq_teardown_flows(local); -@@ -1153,10 +1153,10 @@ void ieee80211_unregister_hw(struct ieee +@@ -1163,10 +1163,10 @@ void ieee80211_unregister_hw(struct ieee tasklet_kill(&local->tx_pending_tasklet); tasklet_kill(&local->tasklet); diff --git a/package/kernel/mac80211/patches/210-ap_scan.patch b/package/kernel/mac80211/patches/210-ap_scan.patch index 94f5f397c9..3b613bba0e 100644 --- a/package/kernel/mac80211/patches/210-ap_scan.patch +++ b/package/kernel/mac80211/patches/210-ap_scan.patch @@ -1,6 +1,6 @@ --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c -@@ -2175,7 +2175,7 @@ static int ieee80211_scan(struct wiphy * +@@ -2165,7 +2165,7 @@ static int ieee80211_scan(struct wiphy * * the frames sent while scanning on other channel will be * lost) */ diff --git a/package/kernel/mac80211/patches/300-ath9k-Switch-to-using-mac80211-intermediate-software.patch b/package/kernel/mac80211/patches/300-ath9k-Switch-to-using-mac80211-intermediate-software.patch deleted file mode 100644 index b93d11696c..0000000000 --- a/package/kernel/mac80211/patches/300-ath9k-Switch-to-using-mac80211-intermediate-software.patch +++ /dev/null @@ -1,953 +0,0 @@ -From: =?UTF-8?q?Toke=20H=C3=B8iland-J=C3=B8rgensen?= -Date: Fri, 2 Sep 2016 16:00:30 +0200 -Subject: [PATCH] ath9k: Switch to using mac80211 intermediate software - queues. -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -This switches ath9k over to using the mac80211 intermediate software -queueing mechanism for data packets. It removes the queueing inside the -driver, except for the retry queue, and instead pulls from mac80211 when -a packet is needed. The retry queue is used to store a packet that was -pulled but can't be sent immediately. - -The old code path in ath_tx_start that would queue packets has been -removed completely, as has the qlen limit tunables (since there's no -longer a queue in the driver to limit). - -Based on Tim's original patch set, but reworked quite thoroughly. - -Cc: Tim Shepard -Cc: Felix Fietkau -Signed-off-by: Toke Høiland-Jørgensen ---- - ---- a/drivers/net/wireless/ath/ath9k/ath9k.h -+++ b/drivers/net/wireless/ath/ath9k/ath9k.h -@@ -91,7 +91,6 @@ int ath_descdma_setup(struct ath_softc * - #define ATH_RXBUF 512 - #define ATH_TXBUF 512 - #define ATH_TXBUF_RESERVE 5 --#define ATH_MAX_QDEPTH (ATH_TXBUF / 4 - ATH_TXBUF_RESERVE) - #define ATH_TXMAXTRY 13 - #define ATH_MAX_SW_RETRIES 30 - -@@ -145,7 +144,7 @@ int ath_descdma_setup(struct ath_softc * - #define BAW_WITHIN(_start, _bawsz, _seqno) \ - ((((_seqno) - (_start)) & 4095) < (_bawsz)) - --#define ATH_AN_2_TID(_an, _tidno) (&(_an)->tid[(_tidno)]) -+#define ATH_AN_2_TID(_an, _tidno) ath_node_to_tid(_an, _tidno) - - #define IS_HT_RATE(rate) (rate & 0x80) - #define IS_CCK_RATE(rate) ((rate >= 0x18) && (rate <= 0x1e)) -@@ -164,7 +163,6 @@ struct ath_txq { - spinlock_t axq_lock; - u32 axq_depth; - u32 axq_ampdu_depth; -- bool stopped; - bool axq_tx_inprogress; - struct list_head txq_fifo[ATH_TXFIFO_DEPTH]; - u8 txq_headidx; -@@ -232,7 +230,6 @@ struct ath_buf { - - struct ath_atx_tid { - struct list_head list; -- struct sk_buff_head buf_q; - struct sk_buff_head retry_q; - struct ath_node *an; - struct ath_txq *txq; -@@ -247,13 +244,13 @@ struct ath_atx_tid { - s8 bar_index; - bool active; - bool clear_ps_filter; -+ bool has_queued; - }; - - struct ath_node { - struct ath_softc *sc; - struct ieee80211_sta *sta; /* station struct we're part of */ - struct ieee80211_vif *vif; /* interface with which we're associated */ -- struct ath_atx_tid tid[IEEE80211_NUM_TIDS]; - - u16 maxampdu; - u8 mpdudensity; -@@ -276,7 +273,6 @@ struct ath_tx_control { - struct ath_node *an; - struct ieee80211_sta *sta; - u8 paprd; -- bool force_channel; - }; - - -@@ -293,7 +289,6 @@ struct ath_tx { - struct ath_descdma txdma; - struct ath_txq *txq_map[IEEE80211_NUM_ACS]; - struct ath_txq *uapsdq; -- u32 txq_max_pending[IEEE80211_NUM_ACS]; - u16 max_aggr_framelen[IEEE80211_NUM_ACS][4][32]; - }; - -@@ -421,6 +416,22 @@ struct ath_offchannel { - int duration; - }; - -+static inline struct ath_atx_tid * -+ath_node_to_tid(struct ath_node *an, u8 tidno) -+{ -+ struct ieee80211_sta *sta = an->sta; -+ struct ieee80211_vif *vif = an->vif; -+ struct ieee80211_txq *txq; -+ -+ BUG_ON(!vif); -+ if (sta) -+ txq = sta->txq[tidno % ARRAY_SIZE(sta->txq)]; -+ else -+ txq = vif->txq; -+ -+ return (struct ath_atx_tid *) txq->drv_priv; -+} -+ - #define case_rtn_string(val) case val: return #val - - #define ath_for_each_chanctx(_sc, _ctx) \ -@@ -575,7 +586,6 @@ void ath_tx_edma_tasklet(struct ath_soft - int ath_tx_aggr_start(struct ath_softc *sc, struct ieee80211_sta *sta, - u16 tid, u16 *ssn); - void ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid); --void ath_tx_aggr_resume(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid); - - void ath_tx_aggr_wakeup(struct ath_softc *sc, struct ath_node *an); - void ath_tx_aggr_sleep(struct ieee80211_sta *sta, struct ath_softc *sc, -@@ -585,6 +595,7 @@ void ath9k_release_buffered_frames(struc - u16 tids, int nframes, - enum ieee80211_frame_release_type reason, - bool more_data); -+void ath9k_wake_tx_queue(struct ieee80211_hw *hw, struct ieee80211_txq *queue); - - /********/ - /* VIFs */ ---- a/drivers/net/wireless/ath/ath9k/channel.c -+++ b/drivers/net/wireless/ath/ath9k/channel.c -@@ -1010,7 +1010,6 @@ static void ath_scan_send_probe(struct a - goto error; - - txctl.txq = sc->tx.txq_map[IEEE80211_AC_VO]; -- txctl.force_channel = true; - if (ath_tx_start(sc->hw, skb, &txctl)) - goto error; - -@@ -1133,7 +1132,6 @@ ath_chanctx_send_vif_ps_frame(struct ath - memset(&txctl, 0, sizeof(txctl)); - txctl.txq = sc->tx.txq_map[IEEE80211_AC_VO]; - txctl.sta = sta; -- txctl.force_channel = true; - if (ath_tx_start(sc->hw, skb, &txctl)) { - ieee80211_free_txskb(sc->hw, skb); - return false; ---- a/drivers/net/wireless/ath/ath9k/debug.c -+++ b/drivers/net/wireless/ath/ath9k/debug.c -@@ -600,7 +600,6 @@ static int read_file_xmit(struct seq_fil - PR("MPDUs XRetried: ", xretries); - PR("Aggregates: ", a_aggr); - PR("AMPDUs Queued HW:", a_queued_hw); -- PR("AMPDUs Queued SW:", a_queued_sw); - PR("AMPDUs Completed:", a_completed); - PR("AMPDUs Retried: ", a_retries); - PR("AMPDUs XRetried: ", a_xretries); -@@ -629,8 +628,7 @@ static void print_queue(struct ath_softc - seq_printf(file, "%s: %d ", "qnum", txq->axq_qnum); - seq_printf(file, "%s: %2d ", "qdepth", txq->axq_depth); - seq_printf(file, "%s: %2d ", "ampdu-depth", txq->axq_ampdu_depth); -- seq_printf(file, "%s: %3d ", "pending", txq->pending_frames); -- seq_printf(file, "%s: %d\n", "stopped", txq->stopped); -+ seq_printf(file, "%s: %3d\n", "pending", txq->pending_frames); - - ath_txq_unlock(sc, txq); - } -@@ -1208,7 +1206,6 @@ static const char ath9k_gstrings_stats[] - AMKSTR(d_tx_mpdu_xretries), - AMKSTR(d_tx_aggregates), - AMKSTR(d_tx_ampdus_queued_hw), -- AMKSTR(d_tx_ampdus_queued_sw), - AMKSTR(d_tx_ampdus_completed), - AMKSTR(d_tx_ampdu_retries), - AMKSTR(d_tx_ampdu_xretries), -@@ -1288,7 +1285,6 @@ void ath9k_get_et_stats(struct ieee80211 - AWDATA(xretries); - AWDATA(a_aggr); - AWDATA(a_queued_hw); -- AWDATA(a_queued_sw); - AWDATA(a_completed); - AWDATA(a_retries); - AWDATA(a_xretries); -@@ -1346,14 +1342,6 @@ int ath9k_init_debug(struct ath_hw *ah) - read_file_xmit); - debugfs_create_devm_seqfile(sc->dev, "queues", sc->debug.debugfs_phy, - read_file_queues); -- debugfs_create_u32("qlen_bk", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy, -- &sc->tx.txq_max_pending[IEEE80211_AC_BK]); -- debugfs_create_u32("qlen_be", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy, -- &sc->tx.txq_max_pending[IEEE80211_AC_BE]); -- debugfs_create_u32("qlen_vi", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy, -- &sc->tx.txq_max_pending[IEEE80211_AC_VI]); -- debugfs_create_u32("qlen_vo", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy, -- &sc->tx.txq_max_pending[IEEE80211_AC_VO]); - debugfs_create_devm_seqfile(sc->dev, "misc", sc->debug.debugfs_phy, - read_file_misc); - debugfs_create_devm_seqfile(sc->dev, "reset", sc->debug.debugfs_phy, ---- a/drivers/net/wireless/ath/ath9k/debug.h -+++ b/drivers/net/wireless/ath/ath9k/debug.h -@@ -147,7 +147,6 @@ struct ath_interrupt_stats { - * @completed: Total MPDUs (non-aggr) completed - * @a_aggr: Total no. of aggregates queued - * @a_queued_hw: Total AMPDUs queued to hardware -- * @a_queued_sw: Total AMPDUs queued to software queues - * @a_completed: Total AMPDUs completed - * @a_retries: No. of AMPDUs retried (SW) - * @a_xretries: No. of AMPDUs dropped due to xretries -@@ -174,7 +173,6 @@ struct ath_tx_stats { - u32 xretries; - u32 a_aggr; - u32 a_queued_hw; -- u32 a_queued_sw; - u32 a_completed; - u32 a_retries; - u32 a_xretries; ---- a/drivers/net/wireless/ath/ath9k/debug_sta.c -+++ b/drivers/net/wireless/ath/ath9k/debug_sta.c -@@ -52,8 +52,8 @@ static ssize_t read_file_node_aggr(struc - "TID", "SEQ_START", "SEQ_NEXT", "BAW_SIZE", - "BAW_HEAD", "BAW_TAIL", "BAR_IDX", "SCHED", "PAUSED"); - -- for (tidno = 0, tid = &an->tid[tidno]; -- tidno < IEEE80211_NUM_TIDS; tidno++, tid++) { -+ for (tidno = 0; tidno < IEEE80211_NUM_TIDS; tidno++) { -+ tid = ath_node_to_tid(an, tidno); - txq = tid->txq; - ath_txq_lock(sc, txq); - if (tid->active) { ---- a/drivers/net/wireless/ath/ath9k/init.c -+++ b/drivers/net/wireless/ath/ath9k/init.c -@@ -358,7 +358,6 @@ static int ath9k_init_queues(struct ath_ - for (i = 0; i < IEEE80211_NUM_ACS; i++) { - sc->tx.txq_map[i] = ath_txq_setup(sc, ATH9K_TX_QUEUE_DATA, i); - sc->tx.txq_map[i]->mac80211_qnum = i; -- sc->tx.txq_max_pending[i] = ATH_MAX_QDEPTH; - } - return 0; - } -@@ -877,6 +876,7 @@ static void ath9k_set_hw_capab(struct at - hw->max_rate_tries = 10; - hw->sta_data_size = sizeof(struct ath_node); - hw->vif_data_size = sizeof(struct ath_vif); -+ hw->txq_data_size = sizeof(struct ath_atx_tid); - hw->extra_tx_headroom = 4; - - hw->wiphy->available_antennas_rx = BIT(ah->caps.max_rxchains) - 1; ---- a/drivers/net/wireless/ath/ath9k/main.c -+++ b/drivers/net/wireless/ath/ath9k/main.c -@@ -1902,9 +1902,11 @@ static int ath9k_ampdu_action(struct iee - bool flush = false; - int ret = 0; - struct ieee80211_sta *sta = params->sta; -+ struct ath_node *an = (struct ath_node *)sta->drv_priv; - enum ieee80211_ampdu_mlme_action action = params->action; - u16 tid = params->tid; - u16 *ssn = ¶ms->ssn; -+ struct ath_atx_tid *atid; - - mutex_lock(&sc->mutex); - -@@ -1937,9 +1939,9 @@ static int ath9k_ampdu_action(struct iee - ath9k_ps_restore(sc); - break; - case IEEE80211_AMPDU_TX_OPERATIONAL: -- ath9k_ps_wakeup(sc); -- ath_tx_aggr_resume(sc, sta, tid); -- ath9k_ps_restore(sc); -+ atid = ath_node_to_tid(an, tid); -+ atid->baw_size = IEEE80211_MIN_AMPDU_BUF << -+ sta->ht_cap.ampdu_factor; - break; - default: - ath_err(ath9k_hw_common(sc->sc_ah), "Unknown AMPDU action\n"); -@@ -2701,4 +2703,5 @@ struct ieee80211_ops ath9k_ops = { - .sw_scan_start = ath9k_sw_scan_start, - .sw_scan_complete = ath9k_sw_scan_complete, - .get_txpower = ath9k_get_txpower, -+ .wake_tx_queue = ath9k_wake_tx_queue, - }; ---- a/drivers/net/wireless/ath/ath9k/xmit.c -+++ b/drivers/net/wireless/ath/ath9k/xmit.c -@@ -67,6 +67,8 @@ static struct ath_buf *ath_tx_setup_buff - struct ath_txq *txq, - struct ath_atx_tid *tid, - struct sk_buff *skb); -+static int ath_tx_prepare(struct ieee80211_hw *hw, struct sk_buff *skb, -+ struct ath_tx_control *txctl); - - enum { - MCS_HT20, -@@ -137,6 +139,26 @@ static void ath_tx_queue_tid(struct ath_ - list_add_tail(&tid->list, list); - } - -+void ath9k_wake_tx_queue(struct ieee80211_hw *hw, struct ieee80211_txq *queue) -+{ -+ struct ath_softc *sc = hw->priv; -+ struct ath_common *common = ath9k_hw_common(sc->sc_ah); -+ struct ath_atx_tid *tid = (struct ath_atx_tid *) queue->drv_priv; -+ struct ath_txq *txq = tid->txq; -+ -+ ath_dbg(common, QUEUE, "Waking TX queue: %pM (%d)\n", -+ queue->sta ? queue->sta->addr : queue->vif->addr, -+ tid->tidno); -+ -+ ath_txq_lock(sc, txq); -+ -+ tid->has_queued = true; -+ ath_tx_queue_tid(sc, txq, tid); -+ ath_txq_schedule(sc, txq); -+ -+ ath_txq_unlock(sc, txq); -+} -+ - static struct ath_frame_info *get_frame_info(struct sk_buff *skb) - { - struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); -@@ -164,7 +186,6 @@ static void ath_set_rates(struct ieee802 - static void ath_txq_skb_done(struct ath_softc *sc, struct ath_txq *txq, - struct sk_buff *skb) - { -- struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); - struct ath_frame_info *fi = get_frame_info(skb); - int q = fi->txq; - -@@ -175,14 +196,6 @@ static void ath_txq_skb_done(struct ath_ - if (WARN_ON(--txq->pending_frames < 0)) - txq->pending_frames = 0; - -- if (txq->stopped && -- txq->pending_frames < sc->tx.txq_max_pending[q]) { -- if (ath9k_is_chanctx_enabled()) -- ieee80211_wake_queue(sc->hw, info->hw_queue); -- else -- ieee80211_wake_queue(sc->hw, q); -- txq->stopped = false; -- } - } - - static struct ath_atx_tid * -@@ -192,9 +205,48 @@ ath_get_skb_tid(struct ath_softc *sc, st - return ATH_AN_2_TID(an, tidno); - } - -+static struct sk_buff * -+ath_tid_pull(struct ath_atx_tid *tid) -+{ -+ struct ieee80211_txq *txq = container_of((void*)tid, struct ieee80211_txq, drv_priv); -+ struct ath_softc *sc = tid->an->sc; -+ struct ieee80211_hw *hw = sc->hw; -+ struct ath_tx_control txctl = { -+ .txq = tid->txq, -+ .sta = tid->an->sta, -+ }; -+ struct sk_buff *skb; -+ struct ath_frame_info *fi; -+ int q; -+ -+ if (!tid->has_queued) -+ return NULL; -+ -+ skb = ieee80211_tx_dequeue(hw, txq); -+ if (!skb) { -+ tid->has_queued = false; -+ return NULL; -+ } -+ -+ if (ath_tx_prepare(hw, skb, &txctl)) { -+ ieee80211_free_txskb(hw, skb); -+ return NULL; -+ } -+ -+ q = skb_get_queue_mapping(skb); -+ if (tid->txq == sc->tx.txq_map[q]) { -+ fi = get_frame_info(skb); -+ fi->txq = q; -+ ++tid->txq->pending_frames; -+ } -+ -+ return skb; -+ } -+ -+ - static bool ath_tid_has_buffered(struct ath_atx_tid *tid) - { -- return !skb_queue_empty(&tid->buf_q) || !skb_queue_empty(&tid->retry_q); -+ return !skb_queue_empty(&tid->retry_q) || tid->has_queued; - } - - static struct sk_buff *ath_tid_dequeue(struct ath_atx_tid *tid) -@@ -203,46 +255,11 @@ static struct sk_buff *ath_tid_dequeue(s - - skb = __skb_dequeue(&tid->retry_q); - if (!skb) -- skb = __skb_dequeue(&tid->buf_q); -+ skb = ath_tid_pull(tid); - - return skb; - } - --/* -- * ath_tx_tid_change_state: -- * - clears a-mpdu flag of previous session -- * - force sequence number allocation to fix next BlockAck Window -- */ --static void --ath_tx_tid_change_state(struct ath_softc *sc, struct ath_atx_tid *tid) --{ -- struct ath_txq *txq = tid->txq; -- struct ieee80211_tx_info *tx_info; -- struct sk_buff *skb, *tskb; -- struct ath_buf *bf; -- struct ath_frame_info *fi; -- -- skb_queue_walk_safe(&tid->buf_q, skb, tskb) { -- fi = get_frame_info(skb); -- bf = fi->bf; -- -- tx_info = IEEE80211_SKB_CB(skb); -- tx_info->flags &= ~IEEE80211_TX_CTL_AMPDU; -- -- if (bf) -- continue; -- -- bf = ath_tx_setup_buffer(sc, txq, tid, skb); -- if (!bf) { -- __skb_unlink(skb, &tid->buf_q); -- ath_txq_skb_done(sc, txq, skb); -- ieee80211_free_txskb(sc->hw, skb); -- continue; -- } -- } -- --} -- - static void ath_tx_flush_tid(struct ath_softc *sc, struct ath_atx_tid *tid) - { - struct ath_txq *txq = tid->txq; -@@ -883,20 +900,16 @@ static int ath_compute_num_delims(struct - - static struct ath_buf * - ath_tx_get_tid_subframe(struct ath_softc *sc, struct ath_txq *txq, -- struct ath_atx_tid *tid, struct sk_buff_head **q) -+ struct ath_atx_tid *tid) - { - struct ieee80211_tx_info *tx_info; - struct ath_frame_info *fi; -- struct sk_buff *skb; -+ struct sk_buff *skb, *first_skb = NULL; - struct ath_buf *bf; - u16 seqno; - - while (1) { -- *q = &tid->retry_q; -- if (skb_queue_empty(*q)) -- *q = &tid->buf_q; -- -- skb = skb_peek(*q); -+ skb = ath_tid_dequeue(tid); - if (!skb) - break; - -@@ -908,7 +921,6 @@ ath_tx_get_tid_subframe(struct ath_softc - bf->bf_state.stale = false; - - if (!bf) { -- __skb_unlink(skb, *q); - ath_txq_skb_done(sc, txq, skb); - ieee80211_free_txskb(sc->hw, skb); - continue; -@@ -937,8 +949,20 @@ ath_tx_get_tid_subframe(struct ath_softc - seqno = bf->bf_state.seqno; - - /* do not step over block-ack window */ -- if (!BAW_WITHIN(tid->seq_start, tid->baw_size, seqno)) -+ if (!BAW_WITHIN(tid->seq_start, tid->baw_size, seqno)) { -+ __skb_queue_tail(&tid->retry_q, skb); -+ -+ /* If there are other skbs in the retry q, they are -+ * probably within the BAW, so loop immediately to get -+ * one of them. Otherwise the queue can get stuck. */ -+ if (!skb_queue_is_first(&tid->retry_q, skb) && -+ !WARN_ON(skb == first_skb)) { -+ if(!first_skb) /* infinite loop prevention */ -+ first_skb = skb; -+ continue; -+ } - break; -+ } - - if (tid->bar_index > ATH_BA_INDEX(tid->seq_start, seqno)) { - struct ath_tx_status ts = {}; -@@ -946,7 +970,6 @@ ath_tx_get_tid_subframe(struct ath_softc - - INIT_LIST_HEAD(&bf_head); - list_add(&bf->list, &bf_head); -- __skb_unlink(skb, *q); - ath_tx_update_baw(sc, tid, seqno); - ath_tx_complete_buf(sc, bf, txq, &bf_head, NULL, &ts, 0); - continue; -@@ -958,11 +981,10 @@ ath_tx_get_tid_subframe(struct ath_softc - return NULL; - } - --static bool -+static int - ath_tx_form_aggr(struct ath_softc *sc, struct ath_txq *txq, - struct ath_atx_tid *tid, struct list_head *bf_q, -- struct ath_buf *bf_first, struct sk_buff_head *tid_q, -- int *aggr_len) -+ struct ath_buf *bf_first) - { - #define PADBYTES(_len) ((4 - ((_len) % 4)) % 4) - struct ath_buf *bf = bf_first, *bf_prev = NULL; -@@ -972,12 +994,13 @@ ath_tx_form_aggr(struct ath_softc *sc, s - struct ieee80211_tx_info *tx_info; - struct ath_frame_info *fi; - struct sk_buff *skb; -- bool closed = false; -+ - - bf = bf_first; - aggr_limit = ath_lookup_rate(sc, bf, tid); - -- do { -+ while (bf) -+ { - skb = bf->bf_mpdu; - fi = get_frame_info(skb); - -@@ -986,12 +1009,12 @@ ath_tx_form_aggr(struct ath_softc *sc, s - if (nframes) { - if (aggr_limit < al + bpad + al_delta || - ath_lookup_legacy(bf) || nframes >= h_baw) -- break; -+ goto stop; - - tx_info = IEEE80211_SKB_CB(bf->bf_mpdu); - if ((tx_info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE) || - !(tx_info->flags & IEEE80211_TX_CTL_AMPDU)) -- break; -+ goto stop; - } - - /* add padding for previous frame to aggregation length */ -@@ -1013,20 +1036,18 @@ ath_tx_form_aggr(struct ath_softc *sc, s - ath_tx_addto_baw(sc, tid, bf); - bf->bf_state.ndelim = ndelim; - -- __skb_unlink(skb, tid_q); - list_add_tail(&bf->list, bf_q); - if (bf_prev) - bf_prev->bf_next = bf; - - bf_prev = bf; - -- bf = ath_tx_get_tid_subframe(sc, txq, tid, &tid_q); -- if (!bf) { -- closed = true; -- break; -- } -- } while (ath_tid_has_buffered(tid)); -- -+ bf = ath_tx_get_tid_subframe(sc, txq, tid); -+ } -+ goto finish; -+stop: -+ __skb_queue_tail(&tid->retry_q, bf->bf_mpdu); -+finish: - bf = bf_first; - bf->bf_lastbf = bf_prev; - -@@ -1037,9 +1058,7 @@ ath_tx_form_aggr(struct ath_softc *sc, s - TX_STAT_INC(txq->axq_qnum, a_aggr); - } - -- *aggr_len = al; -- -- return closed; -+ return al; - #undef PADBYTES - } - -@@ -1416,18 +1435,15 @@ static void ath_tx_fill_desc(struct ath_ - static void - ath_tx_form_burst(struct ath_softc *sc, struct ath_txq *txq, - struct ath_atx_tid *tid, struct list_head *bf_q, -- struct ath_buf *bf_first, struct sk_buff_head *tid_q) -+ struct ath_buf *bf_first) - { - struct ath_buf *bf = bf_first, *bf_prev = NULL; -- struct sk_buff *skb; - int nframes = 0; - - do { - struct ieee80211_tx_info *tx_info; -- skb = bf->bf_mpdu; - - nframes++; -- __skb_unlink(skb, tid_q); - list_add_tail(&bf->list, bf_q); - if (bf_prev) - bf_prev->bf_next = bf; -@@ -1436,13 +1452,15 @@ ath_tx_form_burst(struct ath_softc *sc, - if (nframes >= 2) - break; - -- bf = ath_tx_get_tid_subframe(sc, txq, tid, &tid_q); -+ bf = ath_tx_get_tid_subframe(sc, txq, tid); - if (!bf) - break; - - tx_info = IEEE80211_SKB_CB(bf->bf_mpdu); -- if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) -+ if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) { -+ __skb_queue_tail(&tid->retry_q, bf->bf_mpdu); - break; -+ } - - ath_set_rates(tid->an->vif, tid->an->sta, bf); - } while (1); -@@ -1453,34 +1471,33 @@ static bool ath_tx_sched_aggr(struct ath - { - struct ath_buf *bf; - struct ieee80211_tx_info *tx_info; -- struct sk_buff_head *tid_q; - struct list_head bf_q; - int aggr_len = 0; -- bool aggr, last = true; -+ bool aggr; - - if (!ath_tid_has_buffered(tid)) - return false; - - INIT_LIST_HEAD(&bf_q); - -- bf = ath_tx_get_tid_subframe(sc, txq, tid, &tid_q); -+ bf = ath_tx_get_tid_subframe(sc, txq, tid); - if (!bf) - return false; - - tx_info = IEEE80211_SKB_CB(bf->bf_mpdu); - aggr = !!(tx_info->flags & IEEE80211_TX_CTL_AMPDU); - if ((aggr && txq->axq_ampdu_depth >= ATH_AGGR_MIN_QDEPTH) || -- (!aggr && txq->axq_depth >= ATH_NON_AGGR_MIN_QDEPTH)) { -+ (!aggr && txq->axq_depth >= ATH_NON_AGGR_MIN_QDEPTH)) { -+ __skb_queue_tail(&tid->retry_q, bf->bf_mpdu); - *stop = true; - return false; - } - - ath_set_rates(tid->an->vif, tid->an->sta, bf); - if (aggr) -- last = ath_tx_form_aggr(sc, txq, tid, &bf_q, bf, -- tid_q, &aggr_len); -+ aggr_len = ath_tx_form_aggr(sc, txq, tid, &bf_q, bf); - else -- ath_tx_form_burst(sc, txq, tid, &bf_q, bf, tid_q); -+ ath_tx_form_burst(sc, txq, tid, &bf_q, bf); - - if (list_empty(&bf_q)) - return false; -@@ -1523,9 +1540,6 @@ int ath_tx_aggr_start(struct ath_softc * - an->mpdudensity = density; - } - -- /* force sequence number allocation for pending frames */ -- ath_tx_tid_change_state(sc, txtid); -- - txtid->active = true; - *ssn = txtid->seq_start = txtid->seq_next; - txtid->bar_index = -1; -@@ -1550,7 +1564,6 @@ void ath_tx_aggr_stop(struct ath_softc * - ath_txq_lock(sc, txq); - txtid->active = false; - ath_tx_flush_tid(sc, txtid); -- ath_tx_tid_change_state(sc, txtid); - ath_txq_unlock_complete(sc, txq); - } - -@@ -1560,14 +1573,12 @@ void ath_tx_aggr_sleep(struct ieee80211_ - struct ath_common *common = ath9k_hw_common(sc->sc_ah); - struct ath_atx_tid *tid; - struct ath_txq *txq; -- bool buffered; - int tidno; - - ath_dbg(common, XMIT, "%s called\n", __func__); - -- for (tidno = 0, tid = &an->tid[tidno]; -- tidno < IEEE80211_NUM_TIDS; tidno++, tid++) { -- -+ for (tidno = 0; tidno < IEEE80211_NUM_TIDS; tidno++) { -+ tid = ath_node_to_tid(an, tidno); - txq = tid->txq; - - ath_txq_lock(sc, txq); -@@ -1577,13 +1588,12 @@ void ath_tx_aggr_sleep(struct ieee80211_ - continue; - } - -- buffered = ath_tid_has_buffered(tid); -+ if (!skb_queue_empty(&tid->retry_q)) -+ ieee80211_sta_set_buffered(sta, tid->tidno, true); - - list_del_init(&tid->list); - - ath_txq_unlock(sc, txq); -- -- ieee80211_sta_set_buffered(sta, tidno, buffered); - } - } - -@@ -1596,49 +1606,20 @@ void ath_tx_aggr_wakeup(struct ath_softc - - ath_dbg(common, XMIT, "%s called\n", __func__); - -- for (tidno = 0, tid = &an->tid[tidno]; -- tidno < IEEE80211_NUM_TIDS; tidno++, tid++) { -- -+ for (tidno = 0; tidno < IEEE80211_NUM_TIDS; tidno++) { -+ tid = ath_node_to_tid(an, tidno); - txq = tid->txq; - - ath_txq_lock(sc, txq); - tid->clear_ps_filter = true; -- - if (ath_tid_has_buffered(tid)) { - ath_tx_queue_tid(sc, txq, tid); - ath_txq_schedule(sc, txq); - } -- - ath_txq_unlock_complete(sc, txq); - } - } - --void ath_tx_aggr_resume(struct ath_softc *sc, struct ieee80211_sta *sta, -- u16 tidno) --{ -- struct ath_common *common = ath9k_hw_common(sc->sc_ah); -- struct ath_atx_tid *tid; -- struct ath_node *an; -- struct ath_txq *txq; -- -- ath_dbg(common, XMIT, "%s called\n", __func__); -- -- an = (struct ath_node *)sta->drv_priv; -- tid = ATH_AN_2_TID(an, tidno); -- txq = tid->txq; -- -- ath_txq_lock(sc, txq); -- -- tid->baw_size = IEEE80211_MIN_AMPDU_BUF << sta->ht_cap.ampdu_factor; -- -- if (ath_tid_has_buffered(tid)) { -- ath_tx_queue_tid(sc, txq, tid); -- ath_txq_schedule(sc, txq); -- } -- -- ath_txq_unlock_complete(sc, txq); --} -- - void ath9k_release_buffered_frames(struct ieee80211_hw *hw, - struct ieee80211_sta *sta, - u16 tids, int nframes, -@@ -1651,7 +1632,6 @@ void ath9k_release_buffered_frames(struc - struct ieee80211_tx_info *info; - struct list_head bf_q; - struct ath_buf *bf_tail = NULL, *bf; -- struct sk_buff_head *tid_q; - int sent = 0; - int i; - -@@ -1666,11 +1646,10 @@ void ath9k_release_buffered_frames(struc - - ath_txq_lock(sc, tid->txq); - while (nframes > 0) { -- bf = ath_tx_get_tid_subframe(sc, sc->tx.uapsdq, tid, &tid_q); -+ bf = ath_tx_get_tid_subframe(sc, sc->tx.uapsdq, tid); - if (!bf) - break; - -- __skb_unlink(bf->bf_mpdu, tid_q); - list_add_tail(&bf->list, &bf_q); - ath_set_rates(tid->an->vif, tid->an->sta, bf); - if (bf_isampdu(bf)) { -@@ -1685,7 +1664,7 @@ void ath9k_release_buffered_frames(struc - sent++; - TX_STAT_INC(txq->axq_qnum, a_queued_hw); - -- if (an->sta && !ath_tid_has_buffered(tid)) -+ if (an->sta && skb_queue_empty(&tid->retry_q)) - ieee80211_sta_set_buffered(an->sta, i, false); - } - ath_txq_unlock_complete(sc, tid->txq); -@@ -1914,13 +1893,7 @@ bool ath_drain_all_txq(struct ath_softc - if (!ATH_TXQ_SETUP(sc, i)) - continue; - -- /* -- * The caller will resume queues with ieee80211_wake_queues. -- * Mark the queue as not stopped to prevent ath_tx_complete -- * from waking the queue too early. -- */ - txq = &sc->tx.txq[i]; -- txq->stopped = false; - ath_draintxq(sc, txq); - } - -@@ -2319,16 +2292,14 @@ int ath_tx_start(struct ieee80211_hw *hw - struct ath_softc *sc = hw->priv; - struct ath_txq *txq = txctl->txq; - struct ath_atx_tid *tid = NULL; -+ struct ath_node *an = NULL; - struct ath_buf *bf; -- bool queue, skip_uapsd = false, ps_resp; -+ bool ps_resp; - int q, ret; - - if (vif) - avp = (void *)vif->drv_priv; - -- if (info->flags & IEEE80211_TX_CTL_TX_OFFCHAN) -- txctl->force_channel = true; -- - ps_resp = !!(info->control.flags & IEEE80211_TX_CTRL_PS_RESPONSE); - - ret = ath_tx_prepare(hw, skb, txctl); -@@ -2343,63 +2314,18 @@ int ath_tx_start(struct ieee80211_hw *hw - - q = skb_get_queue_mapping(skb); - -- ath_txq_lock(sc, txq); -- if (txq == sc->tx.txq_map[q]) { -- fi->txq = q; -- if (++txq->pending_frames > sc->tx.txq_max_pending[q] && -- !txq->stopped) { -- if (ath9k_is_chanctx_enabled()) -- ieee80211_stop_queue(sc->hw, info->hw_queue); -- else -- ieee80211_stop_queue(sc->hw, q); -- txq->stopped = true; -- } -- } -- -- queue = ieee80211_is_data_present(hdr->frame_control); -- -- /* If chanctx, queue all null frames while NOA could be there */ -- if (ath9k_is_chanctx_enabled() && -- ieee80211_is_nullfunc(hdr->frame_control) && -- !txctl->force_channel) -- queue = true; -- -- /* Force queueing of all frames that belong to a virtual interface on -- * a different channel context, to ensure that they are sent on the -- * correct channel. -- */ -- if (((avp && avp->chanctx != sc->cur_chan) || -- sc->cur_chan->stopped) && !txctl->force_channel) { -- if (!txctl->an) -- txctl->an = &avp->mcast_node; -- queue = true; -- skip_uapsd = true; -- } -- -- if (txctl->an && queue) -- tid = ath_get_skb_tid(sc, txctl->an, skb); -- -- if (!skip_uapsd && ps_resp) { -- ath_txq_unlock(sc, txq); -+ if (ps_resp) - txq = sc->tx.uapsdq; -- ath_txq_lock(sc, txq); -- } else if (txctl->an && queue) { -- WARN_ON(tid->txq != txctl->txq); - -- if (info->flags & IEEE80211_TX_CTL_CLEAR_PS_FILT) -- tid->clear_ps_filter = true; -- -- /* -- * Add this frame to software queue for scheduling later -- * for aggregation. -- */ -- TX_STAT_INC(txq->axq_qnum, a_queued_sw); -- __skb_queue_tail(&tid->buf_q, skb); -- if (!txctl->an->sleeping) -- ath_tx_queue_tid(sc, txq, tid); -+ if (txctl->sta) { -+ an = (struct ath_node *) sta->drv_priv; -+ tid = ath_get_skb_tid(sc, an, skb); -+ } - -- ath_txq_schedule(sc, txq); -- goto out; -+ ath_txq_lock(sc, txq); -+ if (txq == sc->tx.txq_map[q]) { -+ fi->txq = q; -+ ++txq->pending_frames; - } - - bf = ath_tx_setup_buffer(sc, txq, tid, skb); -@@ -2892,9 +2818,8 @@ void ath_tx_node_init(struct ath_softc * - struct ath_atx_tid *tid; - int tidno, acno; - -- for (tidno = 0, tid = &an->tid[tidno]; -- tidno < IEEE80211_NUM_TIDS; -- tidno++, tid++) { -+ for (tidno = 0; tidno < IEEE80211_NUM_TIDS; tidno++) { -+ tid = ath_node_to_tid(an, tidno); - tid->an = an; - tid->tidno = tidno; - tid->seq_start = tid->seq_next = 0; -@@ -2902,11 +2827,14 @@ void ath_tx_node_init(struct ath_softc * - tid->baw_head = tid->baw_tail = 0; - tid->active = false; - tid->clear_ps_filter = true; -- __skb_queue_head_init(&tid->buf_q); -+ tid->has_queued = false; - __skb_queue_head_init(&tid->retry_q); - INIT_LIST_HEAD(&tid->list); - acno = TID_TO_WME_AC(tidno); - tid->txq = sc->tx.txq_map[acno]; -+ -+ if (!an->sta) -+ break; /* just one multicast ath_atx_tid */ - } - } - -@@ -2916,9 +2844,8 @@ void ath_tx_node_cleanup(struct ath_soft - struct ath_txq *txq; - int tidno; - -- for (tidno = 0, tid = &an->tid[tidno]; -- tidno < IEEE80211_NUM_TIDS; tidno++, tid++) { -- -+ for (tidno = 0; tidno < IEEE80211_NUM_TIDS; tidno++) { -+ tid = ath_node_to_tid(an, tidno); - txq = tid->txq; - - ath_txq_lock(sc, txq); -@@ -2930,6 +2857,9 @@ void ath_tx_node_cleanup(struct ath_soft - tid->active = false; - - ath_txq_unlock(sc, txq); -+ -+ if (!an->sta) -+ break; /* just one multicast ath_atx_tid */ - } - } - diff --git a/package/kernel/mac80211/patches/300-ath9k_hw-reset-AHB-WMAC-interface-on-AR91xx.patch b/package/kernel/mac80211/patches/300-ath9k_hw-reset-AHB-WMAC-interface-on-AR91xx.patch new file mode 100644 index 0000000000..a7bcfa549b --- /dev/null +++ b/package/kernel/mac80211/patches/300-ath9k_hw-reset-AHB-WMAC-interface-on-AR91xx.patch @@ -0,0 +1,25 @@ +From: Felix Fietkau +Date: Sat, 9 Jul 2016 15:25:24 +0200 +Subject: [PATCH] ath9k_hw: reset AHB-WMAC interface on AR91xx + +Should fix a few stability issues + +Signed-off-by: Felix Fietkau +--- + +--- a/drivers/net/wireless/ath/ath9k/hw.c ++++ b/drivers/net/wireless/ath/ath9k/hw.c +@@ -1394,8 +1394,12 @@ static bool ath9k_hw_set_reset(struct at + if (!AR_SREV_9100(ah)) + REG_WRITE(ah, AR_RC, 0); + +- if (AR_SREV_9100(ah)) ++ if (AR_SREV_9100(ah)) { ++ /* Reset the AHB-WMAC interface */ ++ if (ah->external_reset) ++ ah->external_reset(); + udelay(50); ++ } + + return true; + } diff --git a/package/kernel/mac80211/patches/301-ath9k-force-rx_clear-when-disabling-rx.patch b/package/kernel/mac80211/patches/301-ath9k-force-rx_clear-when-disabling-rx.patch deleted file mode 100644 index 098bda7e93..0000000000 --- a/package/kernel/mac80211/patches/301-ath9k-force-rx_clear-when-disabling-rx.patch +++ /dev/null @@ -1,35 +0,0 @@ -From: Felix Fietkau -Date: Sun, 7 Jun 2015 13:53:35 +0200 -Subject: [PATCH] ath9k: force rx_clear when disabling rx - -This makes stopping Rx more reliable and should reduce the frequency of -Rx related DMA stop warnings. Don't use rx_clear in TX99 mode. - -Cc: stable@vger.kernel.org -Signed-off-by: Felix Fietkau -Signed-off-by: Helmut Schaa ---- - ---- a/drivers/net/wireless/ath/ath9k/mac.c -+++ b/drivers/net/wireless/ath/ath9k/mac.c -@@ -677,13 +677,18 @@ void ath9k_hw_startpcureceive(struct ath - - ath9k_ani_reset(ah, is_scanning); - -- REG_CLR_BIT(ah, AR_DIAG_SW, (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT)); -+ REG_CLR_BIT(ah, AR_DIAG_SW, -+ AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT | AR_DIAG_FORCE_RX_CLEAR); - } - EXPORT_SYMBOL(ath9k_hw_startpcureceive); - - void ath9k_hw_abortpcurecv(struct ath_hw *ah) - { -- REG_SET_BIT(ah, AR_DIAG_SW, AR_DIAG_RX_ABORT | AR_DIAG_RX_DIS); -+ u32 reg = AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT; -+ -+ if (!config_enabled(CPTCFG_ATH9K_TX99)) -+ reg |= AR_DIAG_FORCE_RX_CLEAR; -+ REG_SET_BIT(ah, AR_DIAG_SW, reg); - - ath9k_hw_disable_mib_counters(ah); - } diff --git a/package/kernel/mac80211/patches/301-ath9k_hw-issue-external-reset-for-QCA955x.patch b/package/kernel/mac80211/patches/301-ath9k_hw-issue-external-reset-for-QCA955x.patch new file mode 100644 index 0000000000..34d7d3b1cf --- /dev/null +++ b/package/kernel/mac80211/patches/301-ath9k_hw-issue-external-reset-for-QCA955x.patch @@ -0,0 +1,126 @@ +From: Felix Fietkau +Date: Sat, 9 Jul 2016 15:26:44 +0200 +Subject: [PATCH] ath9k_hw: issue external reset for QCA955x + +The RTC interface on the SoC needs to be reset along with the rest of +the WMAC. + +Signed-off-by: Felix Fietkau +--- + +--- a/drivers/net/wireless/ath/ath9k/hw.c ++++ b/drivers/net/wireless/ath/ath9k/hw.c +@@ -1271,39 +1271,56 @@ void ath9k_hw_get_delta_slope_vals(struc + *coef_exponent = coef_exp - 16; + } + +-/* AR9330 WAR: +- * call external reset function to reset WMAC if: +- * - doing a cold reset +- * - we have pending frames in the TX queues. +- */ +-static bool ath9k_hw_ar9330_reset_war(struct ath_hw *ah, int type) ++static bool ath9k_hw_need_external_reset(struct ath_hw *ah, int type) + { +- int i, npend = 0; ++ int i; + +- for (i = 0; i < AR_NUM_QCU; i++) { +- npend = ath9k_hw_numtxpending(ah, i); +- if (npend) +- break; ++ if (type == ATH9K_RESET_COLD) ++ return true; ++ ++ if (AR_SREV_9550(ah)) ++ return true; ++ ++ /* AR9330 WAR: ++ * call external reset function to reset WMAC if: ++ * - doing a cold reset ++ * - we have pending frames in the TX queues. ++ */ ++ if (AR_SREV_9330(ah)) { ++ for (i = 0; i < AR_NUM_QCU; i++) { ++ if (ath9k_hw_numtxpending(ah, i)) ++ return true; ++ } + } + +- if (ah->external_reset && +- (npend || type == ATH9K_RESET_COLD)) { +- int reset_err = 0; ++ return false; ++} + +- ath_dbg(ath9k_hw_common(ah), RESET, +- "reset MAC via external reset\n"); ++static bool ath9k_hw_external_reset(struct ath_hw *ah, int type) ++{ ++ int err; + +- reset_err = ah->external_reset(); +- if (reset_err) { +- ath_err(ath9k_hw_common(ah), +- "External reset failed, err=%d\n", +- reset_err); +- return false; +- } ++ if (!ah->external_reset || !ath9k_hw_need_external_reset(ah, type)) ++ return true; + +- REG_WRITE(ah, AR_RTC_RESET, 1); ++ ath_dbg(ath9k_hw_common(ah), RESET, ++ "reset MAC via external reset\n"); ++ ++ err = ah->external_reset(); ++ if (err) { ++ ath_err(ath9k_hw_common(ah), ++ "External reset failed, err=%d\n", err); ++ return false; ++ } ++ ++ if (AR_SREV_9550(ah)) { ++ REG_WRITE(ah, AR_RTC_RESET, 0); ++ udelay(10); + } + ++ REG_WRITE(ah, AR_RTC_RESET, 1); ++ udelay(10); ++ + return true; + } + +@@ -1356,24 +1373,24 @@ static bool ath9k_hw_set_reset(struct at + rst_flags |= AR_RTC_RC_MAC_COLD; + } + +- if (AR_SREV_9330(ah)) { +- if (!ath9k_hw_ar9330_reset_war(ah, type)) +- return false; +- } +- + if (ath9k_hw_mci_is_enabled(ah)) + ar9003_mci_check_gpm_offset(ah); + + /* DMA HALT added to resolve ar9300 and ar9580 bus error during +- * RTC_RC reg read ++ * RTC_RC reg read. Also needed for AR9550 external reset + */ +- if (AR_SREV_9300(ah) || AR_SREV_9580(ah)) { ++ if (AR_SREV_9300(ah) || AR_SREV_9580(ah) || AR_SREV_9550(ah)) { + REG_SET_BIT(ah, AR_CFG, AR_CFG_HALT_REQ); + ath9k_hw_wait(ah, AR_CFG, AR_CFG_HALT_ACK, AR_CFG_HALT_ACK, + 20 * AH_WAIT_TIMEOUT); +- REG_CLR_BIT(ah, AR_CFG, AR_CFG_HALT_REQ); + } + ++ if (!AR_SREV_9100(ah)) ++ ath9k_hw_external_reset(ah, type); ++ ++ if (AR_SREV_9300(ah) || AR_SREV_9580(ah)) ++ REG_CLR_BIT(ah, AR_CFG, AR_CFG_HALT_REQ); ++ + REG_WRITE(ah, AR_RTC_RC, rst_flags); + + REGWRITE_BUFFER_FLUSH(ah); diff --git a/package/kernel/mac80211/patches/302-ath9k-limit-retries-for-powersave-response-frames.patch b/package/kernel/mac80211/patches/302-ath9k-limit-retries-for-powersave-response-frames.patch deleted file mode 100644 index 8c19ea22f4..0000000000 --- a/package/kernel/mac80211/patches/302-ath9k-limit-retries-for-powersave-response-frames.patch +++ /dev/null @@ -1,96 +0,0 @@ -From: Felix Fietkau -Date: Thu, 2 Jul 2015 15:20:56 +0200 -Subject: [PATCH] ath9k: limit retries for powersave response frames - -In some cases, the channel might be busy enough that an ath9k AP's -response to PS-Poll frames might be too slow and the station has already -gone to sleep. To avoid wasting too much airtime on this, limit the -number of retries on such frames and ensure that no sample rate gets -used. - -Signed-off-by: Felix Fietkau ---- - ---- a/drivers/net/wireless/ath/ath9k/xmit.c -+++ b/drivers/net/wireless/ath/ath9k/xmit.c -@@ -177,10 +177,25 @@ static void ath_send_bar(struct ath_atx_ - } - - static void ath_set_rates(struct ieee80211_vif *vif, struct ieee80211_sta *sta, -- struct ath_buf *bf) -+ struct ath_buf *bf, bool ps) - { -+ struct ieee80211_tx_info *info = IEEE80211_SKB_CB(bf->bf_mpdu); -+ -+ if (ps) { -+ /* Clear the first rate to avoid using a sample rate for PS frames */ -+ info->control.rates[0].idx = -1; -+ info->control.rates[0].count = 0; -+ } -+ - ieee80211_get_tx_rates(vif, sta, bf->bf_mpdu, bf->rates, - ARRAY_SIZE(bf->rates)); -+ if (!ps) -+ return; -+ -+ if (bf->rates[0].count > 2) -+ bf->rates[0].count = 2; -+ -+ bf->rates[1].idx = -1; - } - - static void ath_txq_skb_done(struct ath_softc *sc, struct ath_txq *txq, -@@ -1462,7 +1477,7 @@ ath_tx_form_burst(struct ath_softc *sc, - break; - } - -- ath_set_rates(tid->an->vif, tid->an->sta, bf); -+ ath_set_rates(tid->an->vif, tid->an->sta, bf, false); - } while (1); - } - -@@ -1493,7 +1508,7 @@ static bool ath_tx_sched_aggr(struct ath - return false; - } - -- ath_set_rates(tid->an->vif, tid->an->sta, bf); -+ ath_set_rates(tid->an->vif, tid->an->sta, bf, false); - if (aggr) - aggr_len = ath_tx_form_aggr(sc, txq, tid, &bf_q, bf); - else -@@ -1651,7 +1666,7 @@ void ath9k_release_buffered_frames(struc - break; - - list_add_tail(&bf->list, &bf_q); -- ath_set_rates(tid->an->vif, tid->an->sta, bf); -+ ath_set_rates(tid->an->vif, tid->an->sta, bf, true); - if (bf_isampdu(bf)) { - ath_tx_addto_baw(sc, tid, bf); - bf->bf_state.bf_type &= ~BUF_AGGR; -@@ -2343,7 +2358,7 @@ int ath_tx_start(struct ieee80211_hw *hw - if (txctl->paprd) - bf->bf_state.bfs_paprd_timestamp = jiffies; - -- ath_set_rates(vif, sta, bf); -+ ath_set_rates(vif, sta, bf, ps_resp); - ath_tx_send_normal(sc, txq, tid, skb); - - out: -@@ -2382,7 +2397,7 @@ void ath_tx_cabq(struct ieee80211_hw *hw - break; - - bf->bf_lastbf = bf; -- ath_set_rates(vif, NULL, bf); -+ ath_set_rates(vif, NULL, bf, false); - ath_buf_set_rate(sc, bf, &info, fi->framelen, false); - duration += info.rates[0].PktDuration; - if (bf_tail) -@@ -2898,7 +2913,7 @@ int ath9k_tx99_send(struct ath_softc *sc - return -EINVAL; - } - -- ath_set_rates(sc->tx99_vif, NULL, bf); -+ ath_set_rates(sc->tx99_vif, NULL, bf, false); - - ath9k_hw_set_desc_link(sc->sc_ah, bf->bf_desc, bf->bf_daddr); - ath9k_hw_tx99_start(sc->sc_ah, txctl->txq->axq_qnum); diff --git a/package/kernel/mac80211/patches/302-ath9k_hw-set-spectral-scan-enable-bit-on-trigger-for.patch b/package/kernel/mac80211/patches/302-ath9k_hw-set-spectral-scan-enable-bit-on-trigger-for.patch new file mode 100644 index 0000000000..dfe9aae268 --- /dev/null +++ b/package/kernel/mac80211/patches/302-ath9k_hw-set-spectral-scan-enable-bit-on-trigger-for.patch @@ -0,0 +1,21 @@ +From: Felix Fietkau +Date: Mon, 11 Jul 2016 12:07:40 +0200 +Subject: [PATCH] ath9k_hw: set spectral scan enable bit on trigger for + AR9003+ + +AR9002 code and QCA AR9003+ code do the same. + +Signed-off-by: Felix Fietkau +--- + +--- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c ++++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c +@@ -1800,6 +1800,8 @@ static void ar9003_hw_spectral_scan_conf + + static void ar9003_hw_spectral_scan_trigger(struct ath_hw *ah) + { ++ REG_SET_BIT(ah, AR_PHY_SPECTRAL_SCAN, ++ AR_PHY_SPECTRAL_SCAN_ENABLE); + /* Activate spectral scan */ + REG_SET_BIT(ah, AR_PHY_SPECTRAL_SCAN, + AR_PHY_SPECTRAL_SCAN_ACTIVE); diff --git a/package/kernel/mac80211/patches/303-Revert-ath9k-interpret-requested-txpower-in-EIRP-dom.patch b/package/kernel/mac80211/patches/303-Revert-ath9k-interpret-requested-txpower-in-EIRP-dom.patch deleted file mode 100644 index 57f45c1c93..0000000000 --- a/package/kernel/mac80211/patches/303-Revert-ath9k-interpret-requested-txpower-in-EIRP-dom.patch +++ /dev/null @@ -1,37 +0,0 @@ -From: Felix Fietkau -Date: Sat, 14 May 2016 14:51:02 +0200 -Subject: [PATCH] Revert "ath9k: interpret requested txpower in EIRP - domain" - -This reverts commit 71f5137bf010c6faffab50c0ec15374c59c4a411. ---- - ---- a/drivers/net/wireless/ath/ath9k/hw.c -+++ b/drivers/net/wireless/ath/ath9k/hw.c -@@ -2910,7 +2910,8 @@ void ath9k_hw_apply_txpower(struct ath_h - { - struct ath_regulatory *reg = ath9k_hw_regulatory(ah); - struct ieee80211_channel *channel; -- int chan_pwr, new_pwr; -+ int chan_pwr, new_pwr, max_gain; -+ int ant_gain, ant_reduction = 0; - - if (!chan) - return; -@@ -2918,10 +2919,15 @@ void ath9k_hw_apply_txpower(struct ath_h - channel = chan->chan; - chan_pwr = min_t(int, channel->max_power * 2, MAX_RATE_POWER); - new_pwr = min_t(int, chan_pwr, reg->power_limit); -+ max_gain = chan_pwr - new_pwr + channel->max_antenna_gain * 2; -+ -+ ant_gain = get_antenna_gain(ah, chan); -+ if (ant_gain > max_gain) -+ ant_reduction = ant_gain - max_gain; - - ah->eep_ops->set_txpower(ah, chan, - ath9k_regd_get_ctl(reg, chan), -- get_antenna_gain(ah, chan), new_pwr, test); -+ ant_reduction, new_pwr, test); - } - - void ath9k_hw_set_txpowerlimit(struct ath_hw *ah, u32 limit, bool test) diff --git a/package/kernel/mac80211/patches/303-ath9k-don-t-run-periodic-and-nf-calibation-at-the-sa.patch b/package/kernel/mac80211/patches/303-ath9k-don-t-run-periodic-and-nf-calibation-at-the-sa.patch new file mode 100644 index 0000000000..22f5154146 --- /dev/null +++ b/package/kernel/mac80211/patches/303-ath9k-don-t-run-periodic-and-nf-calibation-at-the-sa.patch @@ -0,0 +1,27 @@ +From: Felix Fietkau +Date: Tue, 27 Dec 2016 23:16:23 +0100 +Subject: [PATCH] ath9k: don't run periodic and nf calibation at the same + time + +The checks already prevents periodic cal from being started while noise +floor calibration runs. It is missing checks for the other way around. + +Signed-off-by: Felix Fietkau +--- + +--- a/drivers/net/wireless/ath/ath9k/ar9002_calib.c ++++ b/drivers/net/wireless/ath/ath9k/ar9002_calib.c +@@ -676,10 +676,10 @@ static int ar9002_hw_calibrate(struct at + return 0; + + ah->cal_list_curr = currCal = currCal->calNext; +- if (currCal->calState == CAL_WAITING) { ++ if (currCal->calState == CAL_WAITING) + ath9k_hw_reset_calibration(ah, currCal); +- return 0; +- } ++ ++ return 0; + } + + /* Do NF cal only at longer intervals */ diff --git a/package/kernel/mac80211/patches/304-ath9k-force-rx_clear-when-disabling-rx.patch b/package/kernel/mac80211/patches/304-ath9k-force-rx_clear-when-disabling-rx.patch new file mode 100644 index 0000000000..eb6862db6d --- /dev/null +++ b/package/kernel/mac80211/patches/304-ath9k-force-rx_clear-when-disabling-rx.patch @@ -0,0 +1,35 @@ +From: Felix Fietkau +Date: Sun, 7 Jun 2015 13:53:35 +0200 +Subject: [PATCH] ath9k: force rx_clear when disabling rx + +This makes stopping Rx more reliable and should reduce the frequency of +Rx related DMA stop warnings. Don't use rx_clear in TX99 mode. + +Cc: stable@vger.kernel.org +Signed-off-by: Felix Fietkau +Signed-off-by: Helmut Schaa +--- + +--- a/drivers/net/wireless/ath/ath9k/mac.c ++++ b/drivers/net/wireless/ath/ath9k/mac.c +@@ -677,13 +677,18 @@ void ath9k_hw_startpcureceive(struct ath + + ath9k_ani_reset(ah, is_scanning); + +- REG_CLR_BIT(ah, AR_DIAG_SW, (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT)); ++ REG_CLR_BIT(ah, AR_DIAG_SW, ++ AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT | AR_DIAG_FORCE_RX_CLEAR); + } + EXPORT_SYMBOL(ath9k_hw_startpcureceive); + + void ath9k_hw_abortpcurecv(struct ath_hw *ah) + { +- REG_SET_BIT(ah, AR_DIAG_SW, AR_DIAG_RX_ABORT | AR_DIAG_RX_DIS); ++ u32 reg = AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT; ++ ++ if (!IS_ENABLED(CPTCFG_ATH9K_TX99)) ++ reg |= AR_DIAG_FORCE_RX_CLEAR; ++ REG_SET_BIT(ah, AR_DIAG_SW, reg); + + ath9k_hw_disable_mib_counters(ah); + } diff --git a/package/kernel/mac80211/patches/304-mac80211-add-hdrlen-to-ieee80211_tx_data.patch b/package/kernel/mac80211/patches/304-mac80211-add-hdrlen-to-ieee80211_tx_data.patch deleted file mode 100644 index 72e81ee1b0..0000000000 --- a/package/kernel/mac80211/patches/304-mac80211-add-hdrlen-to-ieee80211_tx_data.patch +++ /dev/null @@ -1,219 +0,0 @@ -From: Janusz Dziedzic -Date: Fri, 19 Feb 2016 11:01:49 +0100 -Subject: [PATCH] mac80211: add hdrlen to ieee80211_tx_data - -Add hdrlen to ieee80211_tx_data and use this -when wep/ccmd/tkip. This is preparation for -aligned4 code. - -Signed-off-by: Janusz Dziedzic ---- - ---- a/net/mac80211/ieee80211_i.h -+++ b/net/mac80211/ieee80211_i.h -@@ -175,6 +175,7 @@ struct ieee80211_tx_data { - struct ieee80211_tx_rate rate; - - unsigned int flags; -+ unsigned int hdrlen; - }; - - ---- a/net/mac80211/tx.c -+++ b/net/mac80211/tx.c -@@ -955,7 +955,7 @@ ieee80211_tx_h_fragment(struct ieee80211 - struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); - struct ieee80211_hdr *hdr = (void *)skb->data; - int frag_threshold = tx->local->hw.wiphy->frag_threshold; -- int hdrlen; -+ int hdrlen = tx->hdrlen; - int fragnum; - - /* no matter what happens, tx->skb moves to tx->skbs */ -@@ -976,8 +976,6 @@ ieee80211_tx_h_fragment(struct ieee80211 - if (WARN_ON(info->flags & IEEE80211_TX_CTL_AMPDU)) - return TX_DROP; - -- hdrlen = ieee80211_hdrlen(hdr->frame_control); -- - /* internal error, why isn't DONTFRAG set? */ - if (WARN_ON(skb->len + FCS_LEN <= frag_threshold)) - return TX_DROP; -@@ -1209,6 +1207,8 @@ ieee80211_tx_prepare(struct ieee80211_su - - hdr = (struct ieee80211_hdr *) skb->data; - -+ tx->hdrlen = ieee80211_hdrlen(hdr->frame_control); -+ - if (likely(sta)) { - if (!IS_ERR(sta)) - tx->sta = sta; -@@ -3414,6 +3414,7 @@ begin: - tx.local = local; - tx.skb = skb; - tx.sdata = vif_to_sdata(info->control.vif); -+ tx.hdrlen = ieee80211_padded_hdrlen(hw, hdr->frame_control); - - if (txq->sta) - tx.sta = container_of(txq->sta, struct sta_info, sta); -@@ -3584,6 +3585,7 @@ ieee80211_build_data_template(struct iee - hdr = (void *)skb->data; - tx.sta = sta_info_get(sdata, hdr->addr1); - tx.skb = skb; -+ tx.hdrlen = ieee80211_padded_hdrlen(&tx.local->hw, hdr->frame_control); - - if (ieee80211_tx_h_select_key(&tx) != TX_CONTINUE) { - rcu_read_unlock(); ---- a/net/mac80211/util.c -+++ b/net/mac80211/util.c -@@ -1227,6 +1227,7 @@ void ieee80211_send_auth(struct ieee8021 - struct ieee80211_local *local = sdata->local; - struct sk_buff *skb; - struct ieee80211_mgmt *mgmt; -+ unsigned int hdrlen; - int err; - - /* 24 + 6 = header + auth_algo + auth_transaction + status_code */ -@@ -1251,8 +1252,10 @@ void ieee80211_send_auth(struct ieee8021 - memcpy(skb_put(skb, extra_len), extra, extra_len); - - if (auth_alg == WLAN_AUTH_SHARED_KEY && transaction == 3) { -+ hdrlen = ieee80211_hdrlen(mgmt->frame_control); - mgmt->frame_control |= cpu_to_le16(IEEE80211_FCTL_PROTECTED); -- err = ieee80211_wep_encrypt(local, skb, key, key_len, key_idx); -+ err = ieee80211_wep_encrypt(local, skb, hdrlen, key, -+ key_len, key_idx); - WARN_ON(err); - } - ---- a/net/mac80211/wep.c -+++ b/net/mac80211/wep.c -@@ -89,11 +89,11 @@ static void ieee80211_wep_get_iv(struct - - static u8 *ieee80211_wep_add_iv(struct ieee80211_local *local, - struct sk_buff *skb, -+ unsigned int hdrlen, - int keylen, int keyidx) - { - struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; - struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); -- unsigned int hdrlen; - u8 *newhdr; - - hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_PROTECTED); -@@ -101,7 +101,6 @@ static u8 *ieee80211_wep_add_iv(struct i - if (WARN_ON(skb_headroom(skb) < IEEE80211_WEP_IV_LEN)) - return NULL; - -- hdrlen = ieee80211_hdrlen(hdr->frame_control); - newhdr = skb_push(skb, IEEE80211_WEP_IV_LEN); - memmove(newhdr, newhdr + IEEE80211_WEP_IV_LEN, hdrlen); - -@@ -160,6 +159,7 @@ int ieee80211_wep_encrypt_data(struct cr - */ - int ieee80211_wep_encrypt(struct ieee80211_local *local, - struct sk_buff *skb, -+ unsigned int hdrlen, - const u8 *key, int keylen, int keyidx) - { - u8 *iv; -@@ -169,7 +169,7 @@ int ieee80211_wep_encrypt(struct ieee802 - if (WARN_ON(skb_tailroom(skb) < IEEE80211_WEP_ICV_LEN)) - return -1; - -- iv = ieee80211_wep_add_iv(local, skb, keylen, keyidx); -+ iv = ieee80211_wep_add_iv(local, skb, hdrlen, keylen, keyidx); - if (!iv) - return -1; - -@@ -306,13 +306,14 @@ static int wep_encrypt_skb(struct ieee80 - struct ieee80211_key_conf *hw_key = info->control.hw_key; - - if (!hw_key) { -- if (ieee80211_wep_encrypt(tx->local, skb, tx->key->conf.key, -+ if (ieee80211_wep_encrypt(tx->local, skb, tx->hdrlen, -+ tx->key->conf.key, - tx->key->conf.keylen, - tx->key->conf.keyidx)) - return -1; - } else if ((hw_key->flags & IEEE80211_KEY_FLAG_GENERATE_IV) || - (hw_key->flags & IEEE80211_KEY_FLAG_PUT_IV_SPACE)) { -- if (!ieee80211_wep_add_iv(tx->local, skb, -+ if (!ieee80211_wep_add_iv(tx->local, skb, tx->hdrlen, - tx->key->conf.keylen, - tx->key->conf.keyidx)) - return -1; ---- a/net/mac80211/wep.h -+++ b/net/mac80211/wep.h -@@ -22,6 +22,7 @@ int ieee80211_wep_encrypt_data(struct cr - size_t klen, u8 *data, size_t data_len); - int ieee80211_wep_encrypt(struct ieee80211_local *local, - struct sk_buff *skb, -+ unsigned int hdrlen, - const u8 *key, int keylen, int keyidx); - int ieee80211_wep_decrypt_data(struct crypto_cipher *tfm, u8 *rc4key, - size_t klen, u8 *data, size_t data_len); ---- a/net/mac80211/wpa.c -+++ b/net/mac80211/wpa.c -@@ -43,7 +43,7 @@ ieee80211_tx_h_michael_mic_add(struct ie - skb->len < 24 || !ieee80211_is_data_present(hdr->frame_control)) - return TX_CONTINUE; - -- hdrlen = ieee80211_hdrlen(hdr->frame_control); -+ hdrlen = tx->hdrlen; - if (skb->len < hdrlen) - return TX_DROP; - -@@ -186,7 +186,6 @@ mic_fail_no_key: - - static int tkip_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb) - { -- struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; - struct ieee80211_key *key = tx->key; - struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); - unsigned int hdrlen; -@@ -201,7 +200,7 @@ static int tkip_encrypt_skb(struct ieee8 - return 0; - } - -- hdrlen = ieee80211_hdrlen(hdr->frame_control); -+ hdrlen = tx->hdrlen; - len = skb->len - hdrlen; - - if (info->control.hw_key) -@@ -418,7 +417,7 @@ static int ccmp_encrypt_skb(struct ieee8 - return 0; - } - -- hdrlen = ieee80211_hdrlen(hdr->frame_control); -+ hdrlen = tx->hdrlen; - len = skb->len - hdrlen; - - if (info->control.hw_key) -@@ -651,7 +650,7 @@ static int gcmp_encrypt_skb(struct ieee8 - return 0; - } - -- hdrlen = ieee80211_hdrlen(hdr->frame_control); -+ hdrlen = tx->hdrlen; - len = skb->len - hdrlen; - - if (info->control.hw_key) -@@ -791,7 +790,6 @@ static ieee80211_tx_result - ieee80211_crypto_cs_encrypt(struct ieee80211_tx_data *tx, - struct sk_buff *skb) - { -- struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; - struct ieee80211_key *key = tx->key; - struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); - int hdrlen; -@@ -807,8 +805,7 @@ ieee80211_crypto_cs_encrypt(struct ieee8 - pskb_expand_head(skb, iv_len, 0, GFP_ATOMIC))) - return TX_DROP; - -- hdrlen = ieee80211_hdrlen(hdr->frame_control); -- -+ hdrlen = tx->hdrlen; - pos = skb_push(skb, iv_len); - memmove(pos, pos + iv_len, hdrlen); - diff --git a/package/kernel/mac80211/patches/305-ath9k-limit-retries-for-powersave-response-frames.patch b/package/kernel/mac80211/patches/305-ath9k-limit-retries-for-powersave-response-frames.patch new file mode 100644 index 0000000000..5923594be3 --- /dev/null +++ b/package/kernel/mac80211/patches/305-ath9k-limit-retries-for-powersave-response-frames.patch @@ -0,0 +1,96 @@ +From: Felix Fietkau +Date: Thu, 2 Jul 2015 15:20:56 +0200 +Subject: [PATCH] ath9k: limit retries for powersave response frames + +In some cases, the channel might be busy enough that an ath9k AP's +response to PS-Poll frames might be too slow and the station has already +gone to sleep. To avoid wasting too much airtime on this, limit the +number of retries on such frames and ensure that no sample rate gets +used. + +Signed-off-by: Felix Fietkau +--- + +--- a/drivers/net/wireless/ath/ath9k/xmit.c ++++ b/drivers/net/wireless/ath/ath9k/xmit.c +@@ -188,10 +188,25 @@ static void ath_send_bar(struct ath_atx_ + } + + static void ath_set_rates(struct ieee80211_vif *vif, struct ieee80211_sta *sta, +- struct ath_buf *bf) ++ struct ath_buf *bf, bool ps) + { ++ struct ieee80211_tx_info *info = IEEE80211_SKB_CB(bf->bf_mpdu); ++ ++ if (ps) { ++ /* Clear the first rate to avoid using a sample rate for PS frames */ ++ info->control.rates[0].idx = -1; ++ info->control.rates[0].count = 0; ++ } ++ + ieee80211_get_tx_rates(vif, sta, bf->bf_mpdu, bf->rates, + ARRAY_SIZE(bf->rates)); ++ if (!ps) ++ return; ++ ++ if (bf->rates[0].count > 2) ++ bf->rates[0].count = 2; ++ ++ bf->rates[1].idx = -1; + } + + static void ath_txq_skb_done(struct ath_softc *sc, struct ath_txq *txq, +@@ -1522,7 +1537,7 @@ ath_tx_form_burst(struct ath_softc *sc, + break; + } + +- ath_set_rates(tid->an->vif, tid->an->sta, bf); ++ ath_set_rates(tid->an->vif, tid->an->sta, bf, false); + } while (1); + } + +@@ -1552,7 +1567,7 @@ static bool ath_tx_sched_aggr(struct ath + return false; + } + +- ath_set_rates(tid->an->vif, tid->an->sta, bf); ++ ath_set_rates(tid->an->vif, tid->an->sta, bf, false); + if (aggr) + aggr_len = ath_tx_form_aggr(sc, txq, tid, &bf_q, bf); + else +@@ -1710,7 +1725,7 @@ void ath9k_release_buffered_frames(struc + break; + + list_add_tail(&bf->list, &bf_q); +- ath_set_rates(tid->an->vif, tid->an->sta, bf); ++ ath_set_rates(tid->an->vif, tid->an->sta, bf, true); + if (bf_isampdu(bf)) { + ath_tx_addto_baw(sc, tid, bf); + bf->bf_state.bf_type &= ~BUF_AGGR; +@@ -2410,7 +2425,7 @@ int ath_tx_start(struct ieee80211_hw *hw + if (txctl->paprd) + bf->bf_state.bfs_paprd_timestamp = jiffies; + +- ath_set_rates(vif, sta, bf); ++ ath_set_rates(vif, sta, bf, ps_resp); + ath_tx_send_normal(sc, txq, tid, skb); + + out: +@@ -2449,7 +2464,7 @@ void ath_tx_cabq(struct ieee80211_hw *hw + break; + + bf->bf_lastbf = bf; +- ath_set_rates(vif, NULL, bf); ++ ath_set_rates(vif, NULL, bf, false); + ath_buf_set_rate(sc, bf, &info, fi->framelen, false); + duration += info.rates[0].PktDuration; + if (bf_tail) +@@ -2968,7 +2983,7 @@ int ath9k_tx99_send(struct ath_softc *sc + return -EINVAL; + } + +- ath_set_rates(sc->tx99_vif, NULL, bf); ++ ath_set_rates(sc->tx99_vif, NULL, bf, false); + + ath9k_hw_set_desc_link(sc->sc_ah, bf->bf_desc, bf->bf_daddr); + ath9k_hw_tx99_start(sc->sc_ah, txctl->txq->axq_qnum); diff --git a/package/kernel/mac80211/patches/305-mac80211-add-NEED_ALIGNED4_SKBS-hw-flag.patch b/package/kernel/mac80211/patches/305-mac80211-add-NEED_ALIGNED4_SKBS-hw-flag.patch deleted file mode 100644 index 704e7f7815..0000000000 --- a/package/kernel/mac80211/patches/305-mac80211-add-NEED_ALIGNED4_SKBS-hw-flag.patch +++ /dev/null @@ -1,233 +0,0 @@ -From: Janusz Dziedzic -Date: Fri, 19 Feb 2016 11:01:50 +0100 -Subject: [PATCH] mac80211: add NEED_ALIGNED4_SKBS hw flag - -HW/driver should set NEED_ALIGNED4_SKBS flag in case -require aligned skbs to four-byte boundaries. -This affect only TX direction. - -Padding is added after ieee80211_hdr, before IV/LLC. - -Before we have to do memmove(hdrlen) twice in the -dirver. Once before we pass this to HW and next -in tx completion (to be sure monitor will report -this tx frame correctly). - -With this patch we can skip this memmove() and save CPU. - -Currently this was tested with ath9k, both hw/sw crypt for -wep/tkip/ccmp. - -Signed-off-by: Janusz Dziedzic ---- - ---- a/include/net/mac80211.h -+++ b/include/net/mac80211.h -@@ -2025,6 +2025,9 @@ struct ieee80211_txq { - * drivers, mac80211 packet loss mechanism will not be triggered and driver - * is completely depending on firmware event for station kickout. - * -+ * @IEEE80211_HW_NEEDS_ALIGNED4_SKBS: Driver need aligned skbs to four-byte. -+ * Padding will be added after ieee80211_hdr, before IV/LLC. -+ * - * @NUM_IEEE80211_HW_FLAGS: number of hardware flags, used for sizing arrays - */ - enum ieee80211_hw_flags { -@@ -2066,6 +2069,7 @@ enum ieee80211_hw_flags { - IEEE80211_HW_TX_AMSDU, - IEEE80211_HW_TX_FRAG_LIST, - IEEE80211_HW_REPORTS_LOW_ACK, -+ IEEE80211_HW_NEEDS_ALIGNED4_SKBS, - - /* keep last, obviously */ - NUM_IEEE80211_HW_FLAGS ---- a/net/mac80211/debugfs.c -+++ b/net/mac80211/debugfs.c -@@ -210,6 +210,7 @@ static const char *hw_flag_names[] = { - FLAG(TX_AMSDU), - FLAG(TX_FRAG_LIST), - FLAG(REPORTS_LOW_ACK), -+ FLAG(NEEDS_ALIGNED4_SKBS), - #undef FLAG - }; - ---- a/net/mac80211/ieee80211_i.h -+++ b/net/mac80211/ieee80211_i.h -@@ -1529,6 +1529,29 @@ ieee80211_have_rx_timestamp(struct ieee8 - return false; - } - -+static inline unsigned int -+ieee80211_hdr_padsize(struct ieee80211_hw *hw, unsigned int hdrlen) -+{ -+ /* -+ * While hdrlen is already aligned to two-byte boundaries, -+ * simple check with & 2 will return correct padsize. -+ */ -+ if (ieee80211_hw_check(hw, NEEDS_ALIGNED4_SKBS)) -+ return hdrlen & 2; -+ return 0; -+} -+ -+static inline unsigned int -+ieee80211_padded_hdrlen(struct ieee80211_hw *hw, __le16 fc) -+{ -+ unsigned int hdrlen; -+ -+ hdrlen = ieee80211_hdrlen(fc); -+ hdrlen += ieee80211_hdr_padsize(hw, hdrlen); -+ -+ return hdrlen; -+} -+ - u64 ieee80211_calculate_rx_timestamp(struct ieee80211_local *local, - struct ieee80211_rx_status *status, - unsigned int mpdu_len, ---- a/net/mac80211/sta_info.h -+++ b/net/mac80211/sta_info.h -@@ -282,7 +282,7 @@ struct ieee80211_fast_tx { - u8 hdr_len; - u8 sa_offs, da_offs, pn_offs; - u8 band; -- u8 hdr[30 + 2 + IEEE80211_FAST_XMIT_MAX_IV + -+ u8 hdr[30 + 2 + 2 + IEEE80211_FAST_XMIT_MAX_IV + - sizeof(rfc1042_header)] __aligned(2); - - struct rcu_head rcu_head; ---- a/net/mac80211/status.c -+++ b/net/mac80211/status.c -@@ -689,9 +689,22 @@ void ieee80211_tx_monitor(struct ieee802 - struct sk_buff *skb2; - struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); - struct ieee80211_sub_if_data *sdata; -+ struct ieee80211_hdr *hdr = (void *)skb->data; - struct net_device *prev_dev = NULL; -+ unsigned int hdrlen, padsize; - int rtap_len; - -+ /* Remove padding if was added */ -+ if (ieee80211_hw_check(&local->hw, NEEDS_ALIGNED4_SKBS)) { -+ hdrlen = ieee80211_hdrlen(hdr->frame_control); -+ padsize = ieee80211_hdr_padsize(&local->hw, hdrlen); -+ -+ if (padsize && skb->len > hdrlen + padsize) { -+ memmove(skb->data + padsize, skb->data, hdrlen); -+ skb_pull(skb, padsize); -+ } -+ } -+ - /* send frame to monitor interfaces now */ - rtap_len = ieee80211_tx_radiotap_len(info); - if (WARN_ON_ONCE(skb_headroom(skb) < rtap_len)) { ---- a/net/mac80211/tkip.c -+++ b/net/mac80211/tkip.c -@@ -201,10 +201,12 @@ void ieee80211_get_tkip_p2k(struct ieee8 - { - struct ieee80211_key *key = (struct ieee80211_key *) - container_of(keyconf, struct ieee80211_key, conf); -+ struct ieee80211_hw *hw = &key->local->hw; - const u8 *tk = &key->conf.key[NL80211_TKIP_DATA_OFFSET_ENCR_KEY]; - struct tkip_ctx *ctx = &key->u.tkip.tx; - struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; -- const u8 *data = (u8 *)hdr + ieee80211_hdrlen(hdr->frame_control); -+ const u8 *data = (u8 *)hdr + ieee80211_padded_hdrlen(hw, -+ hdr->frame_control); - u32 iv32 = get_unaligned_le32(&data[4]); - u16 iv16 = data[2] | (data[0] << 8); - ---- a/net/mac80211/tx.c -+++ b/net/mac80211/tx.c -@@ -1206,8 +1206,7 @@ ieee80211_tx_prepare(struct ieee80211_su - info->flags &= ~IEEE80211_TX_INTFL_NEED_TXPROCESSING; - - hdr = (struct ieee80211_hdr *) skb->data; -- -- tx->hdrlen = ieee80211_hdrlen(hdr->frame_control); -+ tx->hdrlen = ieee80211_padded_hdrlen(&local->hw, hdr->frame_control); - - if (likely(sta)) { - if (!IS_ERR(sta)) -@@ -2158,7 +2157,7 @@ netdev_tx_t ieee80211_monitor_start_xmit - goto fail; - - hdr = (struct ieee80211_hdr *)(skb->data + len_rthdr); -- hdrlen = ieee80211_hdrlen(hdr->frame_control); -+ hdrlen = ieee80211_padded_hdrlen(&local->hw, hdr->frame_control); - - if (skb->len < len_rthdr + hdrlen) - goto fail; -@@ -2376,7 +2375,7 @@ static struct sk_buff *ieee80211_build_h - struct ieee80211_chanctx_conf *chanctx_conf; - struct ieee80211_sub_if_data *ap_sdata; - enum nl80211_band band; -- int ret; -+ int padsize, ret; - - if (IS_ERR(sta)) - sta = NULL; -@@ -2596,6 +2595,9 @@ static struct sk_buff *ieee80211_build_h - hdrlen += 2; - } - -+ /* Check aligned4 skb required */ -+ padsize = ieee80211_hdr_padsize(&sdata->local->hw, hdrlen); -+ - /* - * Drop unicast frames to unauthorised stations unless they are - * EAPOL frames from the local station. -@@ -2676,6 +2678,7 @@ static struct sk_buff *ieee80211_build_h - - skb_pull(skb, skip_header_bytes); - head_need = hdrlen + encaps_len + meshhdrlen - skb_headroom(skb); -+ head_need += padsize; - - /* - * So we need to modify the skb header and hence need a copy of -@@ -2708,6 +2711,9 @@ static struct sk_buff *ieee80211_build_h - memcpy(skb_push(skb, meshhdrlen), &mesh_hdr, meshhdrlen); - #endif - -+ if (padsize) -+ memset(skb_push(skb, padsize), 0, padsize); -+ - if (ieee80211_is_data_qos(fc)) { - __le16 *qos_control; - -@@ -2883,6 +2889,9 @@ void ieee80211_check_fast_xmit(struct st - fc |= cpu_to_le16(IEEE80211_STYPE_QOS_DATA); - } - -+ /* Check aligned4 skb required */ -+ build.hdr_len += ieee80211_hdr_padsize(&local->hw, build.hdr_len); -+ - /* We store the key here so there's no point in using rcu_dereference() - * but that's fine because the code that changes the pointers will call - * this function after doing so. For a single CPU that would be enough, -@@ -3436,7 +3445,7 @@ begin: - - if (tx.key && - (tx.key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV)) -- pn_offs = ieee80211_hdrlen(hdr->frame_control); -+ pn_offs = tx.hdrlen; - - ieee80211_xmit_fast_finish(sta->sdata, sta, pn_offs, - tx.key, skb); ---- a/net/mac80211/util.c -+++ b/net/mac80211/util.c -@@ -1225,6 +1225,7 @@ void ieee80211_send_auth(struct ieee8021 - u32 tx_flags) - { - struct ieee80211_local *local = sdata->local; -+ struct ieee80211_hw *hw = &local->hw; - struct sk_buff *skb; - struct ieee80211_mgmt *mgmt; - unsigned int hdrlen; -@@ -1252,7 +1253,7 @@ void ieee80211_send_auth(struct ieee8021 - memcpy(skb_put(skb, extra_len), extra, extra_len); - - if (auth_alg == WLAN_AUTH_SHARED_KEY && transaction == 3) { -- hdrlen = ieee80211_hdrlen(mgmt->frame_control); -+ hdrlen = ieee80211_padded_hdrlen(hw, mgmt->frame_control); - mgmt->frame_control |= cpu_to_le16(IEEE80211_FCTL_PROTECTED); - err = ieee80211_wep_encrypt(local, skb, hdrlen, key, - key_len, key_idx); diff --git a/package/kernel/mac80211/patches/306-Revert-ath9k-interpret-requested-txpower-in-EIRP-dom.patch b/package/kernel/mac80211/patches/306-Revert-ath9k-interpret-requested-txpower-in-EIRP-dom.patch new file mode 100644 index 0000000000..956ab83903 --- /dev/null +++ b/package/kernel/mac80211/patches/306-Revert-ath9k-interpret-requested-txpower-in-EIRP-dom.patch @@ -0,0 +1,37 @@ +From: Felix Fietkau +Date: Sat, 14 May 2016 14:51:02 +0200 +Subject: [PATCH] Revert "ath9k: interpret requested txpower in EIRP + domain" + +This reverts commit 71f5137bf010c6faffab50c0ec15374c59c4a411. +--- + +--- a/drivers/net/wireless/ath/ath9k/hw.c ++++ b/drivers/net/wireless/ath/ath9k/hw.c +@@ -2931,7 +2931,8 @@ void ath9k_hw_apply_txpower(struct ath_h + { + struct ath_regulatory *reg = ath9k_hw_regulatory(ah); + struct ieee80211_channel *channel; +- int chan_pwr, new_pwr; ++ int chan_pwr, new_pwr, max_gain; ++ int ant_gain, ant_reduction = 0; + + if (!chan) + return; +@@ -2939,10 +2940,15 @@ void ath9k_hw_apply_txpower(struct ath_h + channel = chan->chan; + chan_pwr = min_t(int, channel->max_power * 2, MAX_RATE_POWER); + new_pwr = min_t(int, chan_pwr, reg->power_limit); ++ max_gain = chan_pwr - new_pwr + channel->max_antenna_gain * 2; ++ ++ ant_gain = get_antenna_gain(ah, chan); ++ if (ant_gain > max_gain) ++ ant_reduction = ant_gain - max_gain; + + ah->eep_ops->set_txpower(ah, chan, + ath9k_regd_get_ctl(reg, chan), +- get_antenna_gain(ah, chan), new_pwr, test); ++ ant_reduction, new_pwr, test); + } + + void ath9k_hw_set_txpowerlimit(struct ath_hw *ah, u32 limit, bool test) diff --git a/package/kernel/mac80211/patches/306-mac80211-minstrel-Enable-STBC-and-LDPC-for-VHT-Rates.patch b/package/kernel/mac80211/patches/306-mac80211-minstrel-Enable-STBC-and-LDPC-for-VHT-Rates.patch deleted file mode 100644 index 6e7ecb9c4d..0000000000 --- a/package/kernel/mac80211/patches/306-mac80211-minstrel-Enable-STBC-and-LDPC-for-VHT-Rates.patch +++ /dev/null @@ -1,81 +0,0 @@ -From: Chaitanya T K -Date: Mon, 27 Jun 2016 15:23:26 +0530 -Subject: [PATCH] mac80211: minstrel: Enable STBC and LDPC for VHT Rates - -If peer support reception of STBC and LDPC, enable them for better -performance. - -Signed-off-by: Chaitanya TK ---- - ---- a/include/linux/ieee80211.h -+++ b/include/linux/ieee80211.h -@@ -1551,6 +1551,7 @@ struct ieee80211_vht_operation { - #define IEEE80211_VHT_CAP_RXSTBC_3 0x00000300 - #define IEEE80211_VHT_CAP_RXSTBC_4 0x00000400 - #define IEEE80211_VHT_CAP_RXSTBC_MASK 0x00000700 -+#define IEEE80211_VHT_CAP_RXSTBC_SHIFT 8 - #define IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE 0x00000800 - #define IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE 0x00001000 - #define IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT 13 ---- a/net/mac80211/rc80211_minstrel_ht.c -+++ b/net/mac80211/rc80211_minstrel_ht.c -@@ -1166,13 +1166,14 @@ minstrel_ht_update_caps(void *priv, stru - struct minstrel_ht_sta_priv *msp = priv_sta; - struct minstrel_ht_sta *mi = &msp->ht; - struct ieee80211_mcs_info *mcs = &sta->ht_cap.mcs; -- u16 sta_cap = sta->ht_cap.cap; -+ u16 ht_cap = sta->ht_cap.cap; - struct ieee80211_sta_vht_cap *vht_cap = &sta->vht_cap; - int use_vht; - int n_supported = 0; - int ack_dur; - int stbc; - int i; -+ bool ldpc = false; - - /* fall back to the old minstrel for legacy stations */ - if (!sta->ht_cap.ht_supported) -@@ -1210,16 +1211,24 @@ minstrel_ht_update_caps(void *priv, stru - } - mi->sample_tries = 4; - -- /* TODO tx_flags for vht - ATM the RC API is not fine-grained enough */ - if (!use_vht) { -- stbc = (sta_cap & IEEE80211_HT_CAP_RX_STBC) >> -+ stbc = (ht_cap & IEEE80211_HT_CAP_RX_STBC) >> - IEEE80211_HT_CAP_RX_STBC_SHIFT; -- mi->tx_flags |= stbc << IEEE80211_TX_CTL_STBC_SHIFT; - -- if (sta_cap & IEEE80211_HT_CAP_LDPC_CODING) -- mi->tx_flags |= IEEE80211_TX_CTL_LDPC; -+ if (ht_cap & IEEE80211_HT_CAP_LDPC_CODING) -+ ldpc = true; -+ } else { -+ stbc = (vht_cap->cap & IEEE80211_VHT_CAP_RXSTBC_MASK) >> -+ IEEE80211_VHT_CAP_RXSTBC_SHIFT; -+ -+ if (vht_cap->cap & IEEE80211_VHT_CAP_RXLDPC) -+ ldpc = true; - } - -+ mi->tx_flags |= stbc << IEEE80211_TX_CTL_STBC_SHIFT; -+ if (ldpc) -+ mi->tx_flags |= IEEE80211_TX_CTL_LDPC; -+ - for (i = 0; i < ARRAY_SIZE(mi->groups); i++) { - u32 gflags = minstrel_mcs_groups[i].flags; - int bw, nss; -@@ -1232,10 +1241,10 @@ minstrel_ht_update_caps(void *priv, stru - - if (gflags & IEEE80211_TX_RC_SHORT_GI) { - if (gflags & IEEE80211_TX_RC_40_MHZ_WIDTH) { -- if (!(sta_cap & IEEE80211_HT_CAP_SGI_40)) -+ if (!(ht_cap & IEEE80211_HT_CAP_SGI_40)) - continue; - } else { -- if (!(sta_cap & IEEE80211_HT_CAP_SGI_20)) -+ if (!(ht_cap & IEEE80211_HT_CAP_SGI_20)) - continue; - } - } diff --git a/package/kernel/mac80211/patches/307-ath9k-fix-moredata-bit-in-PS-buffered-frame-release.patch b/package/kernel/mac80211/patches/307-ath9k-fix-moredata-bit-in-PS-buffered-frame-release.patch deleted file mode 100644 index 4fc6dc1ec3..0000000000 --- a/package/kernel/mac80211/patches/307-ath9k-fix-moredata-bit-in-PS-buffered-frame-release.patch +++ /dev/null @@ -1,50 +0,0 @@ -From: Felix Fietkau -Date: Sun, 28 Aug 2016 13:13:01 +0200 -Subject: [PATCH] ath9k: fix moredata bit in PS buffered frame release - -Signed-off-by: Felix Fietkau ---- - ---- a/drivers/net/wireless/ath/ath9k/xmit.c -+++ b/drivers/net/wireless/ath/ath9k/xmit.c -@@ -1635,6 +1635,22 @@ void ath_tx_aggr_wakeup(struct ath_softc - } - } - -+ -+static void -+ath9k_set_moredata(struct ath_softc *sc, struct ath_buf *bf, bool val) -+{ -+ struct ieee80211_hdr *hdr; -+ u16 mask = cpu_to_le16(IEEE80211_FCTL_MOREDATA); -+ u16 mask_val = mask * val; -+ -+ hdr = (struct ieee80211_hdr *) bf->bf_mpdu->data; -+ if ((hdr->frame_control & mask) != mask_val) { -+ hdr->frame_control = (hdr->frame_control & ~mask) | mask_val; -+ dma_sync_single_for_device(sc->dev, bf->bf_buf_addr, -+ sizeof(*hdr), DMA_TO_DEVICE); -+ } -+} -+ - void ath9k_release_buffered_frames(struct ieee80211_hw *hw, - struct ieee80211_sta *sta, - u16 tids, int nframes, -@@ -1665,6 +1681,7 @@ void ath9k_release_buffered_frames(struc - if (!bf) - break; - -+ ath9k_set_moredata(sc, bf, true); - list_add_tail(&bf->list, &bf_q); - ath_set_rates(tid->an->vif, tid->an->sta, bf, true); - if (bf_isampdu(bf)) { -@@ -1688,6 +1705,9 @@ void ath9k_release_buffered_frames(struc - if (list_empty(&bf_q)) - return; - -+ if (!more_data) -+ ath9k_set_moredata(sc, bf_tail, false); -+ - info = IEEE80211_SKB_CB(bf_tail->bf_mpdu); - info->flags |= IEEE80211_TX_STATUS_EOSP; - diff --git a/package/kernel/mac80211/patches/307-mac80211-add-hdrlen-to-ieee80211_tx_data.patch b/package/kernel/mac80211/patches/307-mac80211-add-hdrlen-to-ieee80211_tx_data.patch new file mode 100644 index 0000000000..1a6fd8471c --- /dev/null +++ b/package/kernel/mac80211/patches/307-mac80211-add-hdrlen-to-ieee80211_tx_data.patch @@ -0,0 +1,219 @@ +From: Janusz Dziedzic +Date: Fri, 19 Feb 2016 11:01:49 +0100 +Subject: [PATCH] mac80211: add hdrlen to ieee80211_tx_data + +Add hdrlen to ieee80211_tx_data and use this +when wep/ccmd/tkip. This is preparation for +aligned4 code. + +Signed-off-by: Janusz Dziedzic +--- + +--- a/net/mac80211/ieee80211_i.h ++++ b/net/mac80211/ieee80211_i.h +@@ -177,6 +177,7 @@ struct ieee80211_tx_data { + struct ieee80211_tx_rate rate; + + unsigned int flags; ++ unsigned int hdrlen; + }; + + +--- a/net/mac80211/tx.c ++++ b/net/mac80211/tx.c +@@ -925,7 +925,7 @@ ieee80211_tx_h_fragment(struct ieee80211 + struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); + struct ieee80211_hdr *hdr = (void *)skb->data; + int frag_threshold = tx->local->hw.wiphy->frag_threshold; +- int hdrlen; ++ int hdrlen = tx->hdrlen; + int fragnum; + + /* no matter what happens, tx->skb moves to tx->skbs */ +@@ -946,8 +946,6 @@ ieee80211_tx_h_fragment(struct ieee80211 + if (WARN_ON(info->flags & IEEE80211_TX_CTL_AMPDU)) + return TX_DROP; + +- hdrlen = ieee80211_hdrlen(hdr->frame_control); +- + /* internal error, why isn't DONTFRAG set? */ + if (WARN_ON(skb->len + FCS_LEN <= frag_threshold)) + return TX_DROP; +@@ -1179,6 +1177,8 @@ ieee80211_tx_prepare(struct ieee80211_su + + hdr = (struct ieee80211_hdr *) skb->data; + ++ tx->hdrlen = ieee80211_hdrlen(hdr->frame_control); ++ + if (likely(sta)) { + if (!IS_ERR(sta)) + tx->sta = sta; +@@ -3437,6 +3437,7 @@ begin: + tx.local = local; + tx.skb = skb; + tx.sdata = vif_to_sdata(info->control.vif); ++ tx.hdrlen = ieee80211_padded_hdrlen(hw, hdr->frame_control); + + if (txq->sta) + tx.sta = container_of(txq->sta, struct sta_info, sta); +@@ -3731,6 +3732,7 @@ ieee80211_build_data_template(struct iee + hdr = (void *)skb->data; + tx.sta = sta_info_get(sdata, hdr->addr1); + tx.skb = skb; ++ tx.hdrlen = ieee80211_padded_hdrlen(&tx.local->hw, hdr->frame_control); + + if (ieee80211_tx_h_select_key(&tx) != TX_CONTINUE) { + rcu_read_unlock(); +--- a/net/mac80211/util.c ++++ b/net/mac80211/util.c +@@ -1227,6 +1227,7 @@ void ieee80211_send_auth(struct ieee8021 + struct ieee80211_local *local = sdata->local; + struct sk_buff *skb; + struct ieee80211_mgmt *mgmt; ++ unsigned int hdrlen; + int err; + + /* 24 + 6 = header + auth_algo + auth_transaction + status_code */ +@@ -1251,8 +1252,10 @@ void ieee80211_send_auth(struct ieee8021 + memcpy(skb_put(skb, extra_len), extra, extra_len); + + if (auth_alg == WLAN_AUTH_SHARED_KEY && transaction == 3) { ++ hdrlen = ieee80211_hdrlen(mgmt->frame_control); + mgmt->frame_control |= cpu_to_le16(IEEE80211_FCTL_PROTECTED); +- err = ieee80211_wep_encrypt(local, skb, key, key_len, key_idx); ++ err = ieee80211_wep_encrypt(local, skb, hdrlen, key, ++ key_len, key_idx); + WARN_ON(err); + } + +--- a/net/mac80211/wep.c ++++ b/net/mac80211/wep.c +@@ -89,11 +89,11 @@ static void ieee80211_wep_get_iv(struct + + static u8 *ieee80211_wep_add_iv(struct ieee80211_local *local, + struct sk_buff *skb, ++ unsigned int hdrlen, + int keylen, int keyidx) + { + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; + struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); +- unsigned int hdrlen; + u8 *newhdr; + + hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_PROTECTED); +@@ -101,7 +101,6 @@ static u8 *ieee80211_wep_add_iv(struct i + if (WARN_ON(skb_headroom(skb) < IEEE80211_WEP_IV_LEN)) + return NULL; + +- hdrlen = ieee80211_hdrlen(hdr->frame_control); + newhdr = skb_push(skb, IEEE80211_WEP_IV_LEN); + memmove(newhdr, newhdr + IEEE80211_WEP_IV_LEN, hdrlen); + +@@ -160,6 +159,7 @@ int ieee80211_wep_encrypt_data(struct cr + */ + int ieee80211_wep_encrypt(struct ieee80211_local *local, + struct sk_buff *skb, ++ unsigned int hdrlen, + const u8 *key, int keylen, int keyidx) + { + u8 *iv; +@@ -169,7 +169,7 @@ int ieee80211_wep_encrypt(struct ieee802 + if (WARN_ON(skb_tailroom(skb) < IEEE80211_WEP_ICV_LEN)) + return -1; + +- iv = ieee80211_wep_add_iv(local, skb, keylen, keyidx); ++ iv = ieee80211_wep_add_iv(local, skb, hdrlen, keylen, keyidx); + if (!iv) + return -1; + +@@ -307,13 +307,14 @@ static int wep_encrypt_skb(struct ieee80 + struct ieee80211_key_conf *hw_key = info->control.hw_key; + + if (!hw_key) { +- if (ieee80211_wep_encrypt(tx->local, skb, tx->key->conf.key, ++ if (ieee80211_wep_encrypt(tx->local, skb, tx->hdrlen, ++ tx->key->conf.key, + tx->key->conf.keylen, + tx->key->conf.keyidx)) + return -1; + } else if ((hw_key->flags & IEEE80211_KEY_FLAG_GENERATE_IV) || + (hw_key->flags & IEEE80211_KEY_FLAG_PUT_IV_SPACE)) { +- if (!ieee80211_wep_add_iv(tx->local, skb, ++ if (!ieee80211_wep_add_iv(tx->local, skb, tx->hdrlen, + tx->key->conf.keylen, + tx->key->conf.keyidx)) + return -1; +--- a/net/mac80211/wep.h ++++ b/net/mac80211/wep.h +@@ -22,6 +22,7 @@ int ieee80211_wep_encrypt_data(struct cr + size_t klen, u8 *data, size_t data_len); + int ieee80211_wep_encrypt(struct ieee80211_local *local, + struct sk_buff *skb, ++ unsigned int hdrlen, + const u8 *key, int keylen, int keyidx); + int ieee80211_wep_decrypt_data(struct crypto_cipher *tfm, u8 *rc4key, + size_t klen, u8 *data, size_t data_len); +--- a/net/mac80211/wpa.c ++++ b/net/mac80211/wpa.c +@@ -43,7 +43,7 @@ ieee80211_tx_h_michael_mic_add(struct ie + skb->len < 24 || !ieee80211_is_data_present(hdr->frame_control)) + return TX_CONTINUE; + +- hdrlen = ieee80211_hdrlen(hdr->frame_control); ++ hdrlen = tx->hdrlen; + if (skb->len < hdrlen) + return TX_DROP; + +@@ -186,7 +186,6 @@ mic_fail_no_key: + + static int tkip_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb) + { +- struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; + struct ieee80211_key *key = tx->key; + struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); + unsigned int hdrlen; +@@ -201,7 +200,7 @@ static int tkip_encrypt_skb(struct ieee8 + return 0; + } + +- hdrlen = ieee80211_hdrlen(hdr->frame_control); ++ hdrlen = tx->hdrlen; + len = skb->len - hdrlen; + + if (info->control.hw_key) +@@ -419,7 +418,7 @@ static int ccmp_encrypt_skb(struct ieee8 + return 0; + } + +- hdrlen = ieee80211_hdrlen(hdr->frame_control); ++ hdrlen = tx->hdrlen; + len = skb->len - hdrlen; + + if (info->control.hw_key) +@@ -652,7 +651,7 @@ static int gcmp_encrypt_skb(struct ieee8 + return 0; + } + +- hdrlen = ieee80211_hdrlen(hdr->frame_control); ++ hdrlen = tx->hdrlen; + len = skb->len - hdrlen; + + if (info->control.hw_key) +@@ -792,7 +791,6 @@ static ieee80211_tx_result + ieee80211_crypto_cs_encrypt(struct ieee80211_tx_data *tx, + struct sk_buff *skb) + { +- struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; + struct ieee80211_key *key = tx->key; + struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); + int hdrlen; +@@ -808,8 +806,7 @@ ieee80211_crypto_cs_encrypt(struct ieee8 + pskb_expand_head(skb, iv_len, 0, GFP_ATOMIC))) + return TX_DROP; + +- hdrlen = ieee80211_hdrlen(hdr->frame_control); +- ++ hdrlen = tx->hdrlen; + pos = skb_push(skb, iv_len); + memmove(pos, pos + iv_len, hdrlen); + diff --git a/package/kernel/mac80211/patches/308-ath9k-clear-potentially-stale-EOSP-status-bit-in-int.patch b/package/kernel/mac80211/patches/308-ath9k-clear-potentially-stale-EOSP-status-bit-in-int.patch deleted file mode 100644 index 929da25d75..0000000000 --- a/package/kernel/mac80211/patches/308-ath9k-clear-potentially-stale-EOSP-status-bit-in-int.patch +++ /dev/null @@ -1,22 +0,0 @@ -From: Felix Fietkau -Date: Sun, 28 Aug 2016 13:13:42 +0200 -Subject: [PATCH] ath9k: clear potentially stale EOSP status bit in - intermediate queues - -Prevents spurious ieee80211_sta_eosp calls. - -Signed-off-by: Felix Fietkau ---- - ---- a/drivers/net/wireless/ath/ath9k/xmit.c -+++ b/drivers/net/wireless/ath/ath9k/xmit.c -@@ -945,7 +945,8 @@ ath_tx_get_tid_subframe(struct ath_softc - bf->bf_lastbf = bf; - - tx_info = IEEE80211_SKB_CB(skb); -- tx_info->flags &= ~IEEE80211_TX_CTL_CLEAR_PS_FILT; -+ tx_info->flags &= ~(IEEE80211_TX_CTL_CLEAR_PS_FILT | -+ IEEE80211_TX_STATUS_EOSP); - - /* - * No aggregation session is running, but there may be frames diff --git a/package/kernel/mac80211/patches/308-mac80211-add-NEED_ALIGNED4_SKBS-hw-flag.patch b/package/kernel/mac80211/patches/308-mac80211-add-NEED_ALIGNED4_SKBS-hw-flag.patch new file mode 100644 index 0000000000..43455773f1 --- /dev/null +++ b/package/kernel/mac80211/patches/308-mac80211-add-NEED_ALIGNED4_SKBS-hw-flag.patch @@ -0,0 +1,233 @@ +From: Janusz Dziedzic +Date: Fri, 19 Feb 2016 11:01:50 +0100 +Subject: [PATCH] mac80211: add NEED_ALIGNED4_SKBS hw flag + +HW/driver should set NEED_ALIGNED4_SKBS flag in case +require aligned skbs to four-byte boundaries. +This affect only TX direction. + +Padding is added after ieee80211_hdr, before IV/LLC. + +Before we have to do memmove(hdrlen) twice in the +dirver. Once before we pass this to HW and next +in tx completion (to be sure monitor will report +this tx frame correctly). + +With this patch we can skip this memmove() and save CPU. + +Currently this was tested with ath9k, both hw/sw crypt for +wep/tkip/ccmp. + +Signed-off-by: Janusz Dziedzic +--- + +--- a/include/net/mac80211.h ++++ b/include/net/mac80211.h +@@ -2043,6 +2043,9 @@ struct ieee80211_txq { + * The stack will not do fragmentation. + * The callback for @set_frag_threshold should be set as well. + * ++ * @IEEE80211_HW_NEEDS_ALIGNED4_SKBS: Driver need aligned skbs to four-byte. ++ * Padding will be added after ieee80211_hdr, before IV/LLC. ++ * + * @NUM_IEEE80211_HW_FLAGS: number of hardware flags, used for sizing arrays + */ + enum ieee80211_hw_flags { +@@ -2085,6 +2088,7 @@ enum ieee80211_hw_flags { + IEEE80211_HW_TX_FRAG_LIST, + IEEE80211_HW_REPORTS_LOW_ACK, + IEEE80211_HW_SUPPORTS_TX_FRAG, ++ IEEE80211_HW_NEEDS_ALIGNED4_SKBS, + + /* keep last, obviously */ + NUM_IEEE80211_HW_FLAGS +--- a/net/mac80211/debugfs.c ++++ b/net/mac80211/debugfs.c +@@ -211,6 +211,7 @@ static const char *hw_flag_names[] = { + FLAG(TX_FRAG_LIST), + FLAG(REPORTS_LOW_ACK), + FLAG(SUPPORTS_TX_FRAG), ++ FLAG(NEEDS_ALIGNED4_SKBS), + #undef FLAG + }; + +--- a/net/mac80211/ieee80211_i.h ++++ b/net/mac80211/ieee80211_i.h +@@ -1553,6 +1553,29 @@ ieee80211_vif_get_num_mcast_if(struct ie + return -1; + } + ++static inline unsigned int ++ieee80211_hdr_padsize(struct ieee80211_hw *hw, unsigned int hdrlen) ++{ ++ /* ++ * While hdrlen is already aligned to two-byte boundaries, ++ * simple check with & 2 will return correct padsize. ++ */ ++ if (ieee80211_hw_check(hw, NEEDS_ALIGNED4_SKBS)) ++ return hdrlen & 2; ++ return 0; ++} ++ ++static inline unsigned int ++ieee80211_padded_hdrlen(struct ieee80211_hw *hw, __le16 fc) ++{ ++ unsigned int hdrlen; ++ ++ hdrlen = ieee80211_hdrlen(fc); ++ hdrlen += ieee80211_hdr_padsize(hw, hdrlen); ++ ++ return hdrlen; ++} ++ + u64 ieee80211_calculate_rx_timestamp(struct ieee80211_local *local, + struct ieee80211_rx_status *status, + unsigned int mpdu_len, +--- a/net/mac80211/sta_info.h ++++ b/net/mac80211/sta_info.h +@@ -282,7 +282,7 @@ struct ieee80211_fast_tx { + u8 hdr_len; + u8 sa_offs, da_offs, pn_offs; + u8 band; +- u8 hdr[30 + 2 + IEEE80211_FAST_XMIT_MAX_IV + ++ u8 hdr[30 + 2 + 2 + IEEE80211_FAST_XMIT_MAX_IV + + sizeof(rfc1042_header)] __aligned(2); + + struct rcu_head rcu_head; +--- a/net/mac80211/status.c ++++ b/net/mac80211/status.c +@@ -693,9 +693,22 @@ void ieee80211_tx_monitor(struct ieee802 + struct sk_buff *skb2; + struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); + struct ieee80211_sub_if_data *sdata; ++ struct ieee80211_hdr *hdr = (void *)skb->data; + struct net_device *prev_dev = NULL; ++ unsigned int hdrlen, padsize; + int rtap_len; + ++ /* Remove padding if was added */ ++ if (ieee80211_hw_check(&local->hw, NEEDS_ALIGNED4_SKBS)) { ++ hdrlen = ieee80211_hdrlen(hdr->frame_control); ++ padsize = ieee80211_hdr_padsize(&local->hw, hdrlen); ++ ++ if (padsize && skb->len > hdrlen + padsize) { ++ memmove(skb->data + padsize, skb->data, hdrlen); ++ skb_pull(skb, padsize); ++ } ++ } ++ + /* send frame to monitor interfaces now */ + rtap_len = ieee80211_tx_radiotap_len(info); + if (WARN_ON_ONCE(skb_headroom(skb) < rtap_len)) { +--- a/net/mac80211/tkip.c ++++ b/net/mac80211/tkip.c +@@ -201,10 +201,12 @@ void ieee80211_get_tkip_p2k(struct ieee8 + { + struct ieee80211_key *key = (struct ieee80211_key *) + container_of(keyconf, struct ieee80211_key, conf); ++ struct ieee80211_hw *hw = &key->local->hw; + const u8 *tk = &key->conf.key[NL80211_TKIP_DATA_OFFSET_ENCR_KEY]; + struct tkip_ctx *ctx = &key->u.tkip.tx; + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; +- const u8 *data = (u8 *)hdr + ieee80211_hdrlen(hdr->frame_control); ++ const u8 *data = (u8 *)hdr + ieee80211_padded_hdrlen(hw, ++ hdr->frame_control); + u32 iv32 = get_unaligned_le32(&data[4]); + u16 iv16 = data[2] | (data[0] << 8); + +--- a/net/mac80211/tx.c ++++ b/net/mac80211/tx.c +@@ -1176,8 +1176,7 @@ ieee80211_tx_prepare(struct ieee80211_su + info->flags &= ~IEEE80211_TX_INTFL_NEED_TXPROCESSING; + + hdr = (struct ieee80211_hdr *) skb->data; +- +- tx->hdrlen = ieee80211_hdrlen(hdr->frame_control); ++ tx->hdrlen = ieee80211_padded_hdrlen(&local->hw, hdr->frame_control); + + if (likely(sta)) { + if (!IS_ERR(sta)) +@@ -2152,7 +2151,7 @@ netdev_tx_t ieee80211_monitor_start_xmit + goto fail; + + hdr = (struct ieee80211_hdr *)(skb->data + len_rthdr); +- hdrlen = ieee80211_hdrlen(hdr->frame_control); ++ hdrlen = ieee80211_padded_hdrlen(&local->hw, hdr->frame_control); + + if (skb->len < len_rthdr + hdrlen) + goto fail; +@@ -2370,7 +2369,7 @@ static struct sk_buff *ieee80211_build_h + struct ieee80211_chanctx_conf *chanctx_conf; + struct ieee80211_sub_if_data *ap_sdata; + enum nl80211_band band; +- int ret; ++ int padsize, ret; + + if (IS_ERR(sta)) + sta = NULL; +@@ -2590,6 +2589,9 @@ static struct sk_buff *ieee80211_build_h + hdrlen += 2; + } + ++ /* Check aligned4 skb required */ ++ padsize = ieee80211_hdr_padsize(&sdata->local->hw, hdrlen); ++ + /* + * Drop unicast frames to unauthorised stations unless they are + * EAPOL frames from the local station. +@@ -2670,6 +2672,7 @@ static struct sk_buff *ieee80211_build_h + + skb_pull(skb, skip_header_bytes); + head_need = hdrlen + encaps_len + meshhdrlen - skb_headroom(skb); ++ head_need += padsize; + + /* + * So we need to modify the skb header and hence need a copy of +@@ -2702,6 +2705,9 @@ static struct sk_buff *ieee80211_build_h + memcpy(skb_push(skb, meshhdrlen), &mesh_hdr, meshhdrlen); + #endif + ++ if (padsize) ++ memset(skb_push(skb, padsize), 0, padsize); ++ + if (ieee80211_is_data_qos(fc)) { + __le16 *qos_control; + +@@ -2877,6 +2883,9 @@ void ieee80211_check_fast_xmit(struct st + fc |= cpu_to_le16(IEEE80211_STYPE_QOS_DATA); + } + ++ /* Check aligned4 skb required */ ++ build.hdr_len += ieee80211_hdr_padsize(&local->hw, build.hdr_len); ++ + /* We store the key here so there's no point in using rcu_dereference() + * but that's fine because the code that changes the pointers will call + * this function after doing so. For a single CPU that would be enough, +@@ -3464,7 +3473,7 @@ begin: + + if (tx.key && + (tx.key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV)) +- pn_offs = ieee80211_hdrlen(hdr->frame_control); ++ pn_offs = tx.hdrlen; + + ieee80211_xmit_fast_finish(sta->sdata, sta, pn_offs, + tx.key, skb); +--- a/net/mac80211/util.c ++++ b/net/mac80211/util.c +@@ -1225,6 +1225,7 @@ void ieee80211_send_auth(struct ieee8021 + u32 tx_flags) + { + struct ieee80211_local *local = sdata->local; ++ struct ieee80211_hw *hw = &local->hw; + struct sk_buff *skb; + struct ieee80211_mgmt *mgmt; + unsigned int hdrlen; +@@ -1252,7 +1253,7 @@ void ieee80211_send_auth(struct ieee8021 + memcpy(skb_put(skb, extra_len), extra, extra_len); + + if (auth_alg == WLAN_AUTH_SHARED_KEY && transaction == 3) { +- hdrlen = ieee80211_hdrlen(mgmt->frame_control); ++ hdrlen = ieee80211_padded_hdrlen(hw, mgmt->frame_control); + mgmt->frame_control |= cpu_to_le16(IEEE80211_FCTL_PROTECTED); + err = ieee80211_wep_encrypt(local, skb, hdrlen, key, + key_len, key_idx); diff --git a/package/kernel/mac80211/patches/309-ath9k-report-tx-status-on-EOSP.patch b/package/kernel/mac80211/patches/309-ath9k-report-tx-status-on-EOSP.patch deleted file mode 100644 index 80a3074a4d..0000000000 --- a/package/kernel/mac80211/patches/309-ath9k-report-tx-status-on-EOSP.patch +++ /dev/null @@ -1,19 +0,0 @@ -From: Felix Fietkau -Date: Sun, 28 Aug 2016 13:23:27 +0200 -Subject: [PATCH] ath9k: report tx status on EOSP - -Signed-off-by: Felix Fietkau ---- - ---- a/drivers/net/wireless/ath/ath9k/xmit.c -+++ b/drivers/net/wireless/ath/ath9k/xmit.c -@@ -86,7 +86,8 @@ static void ath_tx_status(struct ieee802 - struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); - struct ieee80211_sta *sta = info->status.status_driver_data[0]; - -- if (info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS) { -+ if (info->flags & (IEEE80211_TX_CTL_REQ_TX_STATUS | -+ IEEE80211_TX_STATUS_EOSP)) { - ieee80211_tx_status(hw, skb); - return; - } diff --git a/package/kernel/mac80211/patches/309-mac80211-minstrel-Enable-STBC-and-LDPC-for-VHT-Rates.patch b/package/kernel/mac80211/patches/309-mac80211-minstrel-Enable-STBC-and-LDPC-for-VHT-Rates.patch new file mode 100644 index 0000000000..a62b1bb28e --- /dev/null +++ b/package/kernel/mac80211/patches/309-mac80211-minstrel-Enable-STBC-and-LDPC-for-VHT-Rates.patch @@ -0,0 +1,82 @@ +From: Chaitanya T K +Date: Mon, 27 Jun 2016 15:23:26 +0530 +Subject: [PATCH] mac80211: minstrel: Enable STBC and LDPC for VHT Rates + +If peer support reception of STBC and LDPC, enable them for better +performance. + +Signed-off-by: Chaitanya TK +--- + +--- a/include/linux/ieee80211.h ++++ b/include/linux/ieee80211.h +@@ -1553,6 +1553,7 @@ struct ieee80211_vht_operation { + #define IEEE80211_VHT_CAP_RXSTBC_3 0x00000300 + #define IEEE80211_VHT_CAP_RXSTBC_4 0x00000400 + #define IEEE80211_VHT_CAP_RXSTBC_MASK 0x00000700 ++#define IEEE80211_VHT_CAP_RXSTBC_SHIFT 8 + #define IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE 0x00000800 + #define IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE 0x00001000 + #define IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT 13 +--- a/net/mac80211/rc80211_minstrel_ht.c ++++ b/net/mac80211/rc80211_minstrel_ht.c +@@ -1130,7 +1130,7 @@ minstrel_ht_update_caps(void *priv, stru + struct minstrel_ht_sta_priv *msp = priv_sta; + struct minstrel_ht_sta *mi = &msp->ht; + struct ieee80211_mcs_info *mcs = &sta->ht_cap.mcs; +- u16 sta_cap = sta->ht_cap.cap; ++ u16 ht_cap = sta->ht_cap.cap; + struct ieee80211_sta_vht_cap *vht_cap = &sta->vht_cap; + struct sta_info *sinfo = container_of(sta, struct sta_info, sta); + int use_vht; +@@ -1138,6 +1138,7 @@ minstrel_ht_update_caps(void *priv, stru + int ack_dur; + int stbc; + int i; ++ bool ldpc = false; + + /* fall back to the old minstrel for legacy stations */ + if (!sta->ht_cap.ht_supported) +@@ -1175,16 +1176,24 @@ minstrel_ht_update_caps(void *priv, stru + } + mi->sample_tries = 4; + +- /* TODO tx_flags for vht - ATM the RC API is not fine-grained enough */ + if (!use_vht) { +- stbc = (sta_cap & IEEE80211_HT_CAP_RX_STBC) >> ++ stbc = (ht_cap & IEEE80211_HT_CAP_RX_STBC) >> + IEEE80211_HT_CAP_RX_STBC_SHIFT; +- mi->tx_flags |= stbc << IEEE80211_TX_CTL_STBC_SHIFT; + +- if (sta_cap & IEEE80211_HT_CAP_LDPC_CODING) +- mi->tx_flags |= IEEE80211_TX_CTL_LDPC; ++ if (ht_cap & IEEE80211_HT_CAP_LDPC_CODING) ++ ldpc = true; ++ } else { ++ stbc = (vht_cap->cap & IEEE80211_VHT_CAP_RXSTBC_MASK) >> ++ IEEE80211_VHT_CAP_RXSTBC_SHIFT; ++ ++ if (vht_cap->cap & IEEE80211_VHT_CAP_RXLDPC) ++ ldpc = true; + } + ++ mi->tx_flags |= stbc << IEEE80211_TX_CTL_STBC_SHIFT; ++ if (ldpc) ++ mi->tx_flags |= IEEE80211_TX_CTL_LDPC; ++ + for (i = 0; i < ARRAY_SIZE(mi->groups); i++) { + u32 gflags = minstrel_mcs_groups[i].flags; + int bw, nss; +@@ -1197,10 +1206,10 @@ minstrel_ht_update_caps(void *priv, stru + + if (gflags & IEEE80211_TX_RC_SHORT_GI) { + if (gflags & IEEE80211_TX_RC_40_MHZ_WIDTH) { +- if (!(sta_cap & IEEE80211_HT_CAP_SGI_40)) ++ if (!(ht_cap & IEEE80211_HT_CAP_SGI_40)) + continue; + } else { +- if (!(sta_cap & IEEE80211_HT_CAP_SGI_20)) ++ if (!(ht_cap & IEEE80211_HT_CAP_SGI_20)) + continue; + } + } diff --git a/package/kernel/mac80211/patches/310-ath9k-fix-block-ack-window-tracking-issues.patch b/package/kernel/mac80211/patches/310-ath9k-fix-block-ack-window-tracking-issues.patch deleted file mode 100644 index 2993cbab74..0000000000 --- a/package/kernel/mac80211/patches/310-ath9k-fix-block-ack-window-tracking-issues.patch +++ /dev/null @@ -1,114 +0,0 @@ -From: Felix Fietkau -Date: Tue, 30 Aug 2016 12:44:08 +0200 -Subject: [PATCH] ath9k: fix block-ack window tracking issues - -Ensure that a buffer gets tracked as part of the block-ack window as -soon as it's dequeued from the tid for the first time. Ensure that -double calls to ath_tx_addto_baw (e.g. on retransmission) don't cause -any issues. - -Signed-off-by: Felix Fietkau ---- - ---- a/drivers/net/wireless/ath/ath9k/xmit.c -+++ b/drivers/net/wireless/ath/ath9k/xmit.c -@@ -62,7 +62,7 @@ static void ath_tx_rc_status(struct ath_ - struct ath_tx_status *ts, int nframes, int nbad, - int txok); - static void ath_tx_update_baw(struct ath_softc *sc, struct ath_atx_tid *tid, -- int seqno); -+ struct ath_buf *bf); - static struct ath_buf *ath_tx_setup_buffer(struct ath_softc *sc, - struct ath_txq *txq, - struct ath_atx_tid *tid, -@@ -300,7 +300,7 @@ static void ath_tx_flush_tid(struct ath_ - } - - if (fi->baw_tracked) { -- ath_tx_update_baw(sc, tid, bf->bf_state.seqno); -+ ath_tx_update_baw(sc, tid, bf); - sendbar = true; - } - -@@ -316,10 +316,15 @@ static void ath_tx_flush_tid(struct ath_ - } - - static void ath_tx_update_baw(struct ath_softc *sc, struct ath_atx_tid *tid, -- int seqno) -+ struct ath_buf *bf) - { -+ struct ath_frame_info *fi = get_frame_info(bf->bf_mpdu); -+ u16 seqno = bf->bf_state.seqno; - int index, cindex; - -+ if (!fi->baw_tracked) -+ return; -+ - index = ATH_BA_INDEX(tid->seq_start, seqno); - cindex = (tid->baw_head + index) & (ATH_TID_MAX_BUFS - 1); - -@@ -340,6 +345,9 @@ static void ath_tx_addto_baw(struct ath_ - u16 seqno = bf->bf_state.seqno; - int index, cindex; - -+ if (fi->baw_tracked) -+ return; -+ - index = ATH_BA_INDEX(tid->seq_start, seqno); - cindex = (tid->baw_head + index) & (ATH_TID_MAX_BUFS - 1); - __set_bit(cindex, tid->tx_buf); -@@ -616,7 +624,7 @@ static void ath_tx_complete_aggr(struct - * complete the acked-ones/xretried ones; update - * block-ack window - */ -- ath_tx_update_baw(sc, tid, seqno); -+ ath_tx_update_baw(sc, tid, bf); - - if (rc_update && (acked_cnt == 1 || txfail_cnt == 1)) { - memcpy(tx_info->control.rates, rates, sizeof(rates)); -@@ -646,7 +654,7 @@ static void ath_tx_complete_aggr(struct - * run out of tx buf. - */ - if (!tbf) { -- ath_tx_update_baw(sc, tid, seqno); -+ ath_tx_update_baw(sc, tid, bf); - - ath_tx_complete_buf(sc, bf, txq, - &bf_head, NULL, ts, -@@ -987,11 +995,14 @@ ath_tx_get_tid_subframe(struct ath_softc - - INIT_LIST_HEAD(&bf_head); - list_add(&bf->list, &bf_head); -- ath_tx_update_baw(sc, tid, seqno); -+ ath_tx_update_baw(sc, tid, bf); - ath_tx_complete_buf(sc, bf, txq, &bf_head, NULL, &ts, 0); - continue; - } - -+ if (bf_isampdu(bf)) -+ ath_tx_addto_baw(sc, tid, bf); -+ - return bf; - } - -@@ -1049,8 +1060,6 @@ ath_tx_form_aggr(struct ath_softc *sc, s - bf->bf_next = NULL; - - /* link buffers of this frame to the aggregate */ -- if (!fi->baw_tracked) -- ath_tx_addto_baw(sc, tid, bf); - bf->bf_state.ndelim = ndelim; - - list_add_tail(&bf->list, bf_q); -@@ -1686,10 +1695,8 @@ void ath9k_release_buffered_frames(struc - ath9k_set_moredata(sc, bf, true); - list_add_tail(&bf->list, &bf_q); - ath_set_rates(tid->an->vif, tid->an->sta, bf, true); -- if (bf_isampdu(bf)) { -- ath_tx_addto_baw(sc, tid, bf); -+ if (bf_isampdu(bf)) - bf->bf_state.bf_type &= ~BUF_AGGR; -- } - if (bf_tail) - bf_tail->bf_next = bf; - diff --git a/package/kernel/mac80211/patches/310-ath9k-fix-moredata-bit-in-PS-buffered-frame-release.patch b/package/kernel/mac80211/patches/310-ath9k-fix-moredata-bit-in-PS-buffered-frame-release.patch new file mode 100644 index 0000000000..b2a74ccbac --- /dev/null +++ b/package/kernel/mac80211/patches/310-ath9k-fix-moredata-bit-in-PS-buffered-frame-release.patch @@ -0,0 +1,50 @@ +From: Felix Fietkau +Date: Sun, 28 Aug 2016 13:13:01 +0200 +Subject: [PATCH] ath9k: fix moredata bit in PS buffered frame release + +Signed-off-by: Felix Fietkau +--- + +--- a/drivers/net/wireless/ath/ath9k/xmit.c ++++ b/drivers/net/wireless/ath/ath9k/xmit.c +@@ -1694,6 +1694,22 @@ void ath_tx_aggr_wakeup(struct ath_softc + } + } + ++ ++static void ++ath9k_set_moredata(struct ath_softc *sc, struct ath_buf *bf, bool val) ++{ ++ struct ieee80211_hdr *hdr; ++ u16 mask = cpu_to_le16(IEEE80211_FCTL_MOREDATA); ++ u16 mask_val = mask * val; ++ ++ hdr = (struct ieee80211_hdr *) bf->bf_mpdu->data; ++ if ((hdr->frame_control & mask) != mask_val) { ++ hdr->frame_control = (hdr->frame_control & ~mask) | mask_val; ++ dma_sync_single_for_device(sc->dev, bf->bf_buf_addr, ++ sizeof(*hdr), DMA_TO_DEVICE); ++ } ++} ++ + void ath9k_release_buffered_frames(struct ieee80211_hw *hw, + struct ieee80211_sta *sta, + u16 tids, int nframes, +@@ -1724,6 +1740,7 @@ void ath9k_release_buffered_frames(struc + if (!bf) + break; + ++ ath9k_set_moredata(sc, bf, true); + list_add_tail(&bf->list, &bf_q); + ath_set_rates(tid->an->vif, tid->an->sta, bf, true); + if (bf_isampdu(bf)) { +@@ -1747,6 +1764,9 @@ void ath9k_release_buffered_frames(struc + if (list_empty(&bf_q)) + return; + ++ if (!more_data) ++ ath9k_set_moredata(sc, bf_tail, false); ++ + info = IEEE80211_SKB_CB(bf_tail->bf_mpdu); + info->flags |= IEEE80211_TX_STATUS_EOSP; + diff --git a/package/kernel/mac80211/patches/311-ath10k-Add-support-for-160Mhz.patch b/package/kernel/mac80211/patches/311-ath10k-Add-support-for-160Mhz.patch deleted file mode 100644 index 372ce58772..0000000000 --- a/package/kernel/mac80211/patches/311-ath10k-Add-support-for-160Mhz.patch +++ /dev/null @@ -1,285 +0,0 @@ -From: Ben Greear -Date: Thu, 6 Oct 2016 17:34:14 -0700 -Subject: [PATCH] ath10k: Add support for 160Mhz. - -This patch was written by Sebastian Gottschall. - -Signed-off-by: Ben Greear -Signed-off-by: Sebastian Gottschall ---- - ---- a/drivers/net/wireless/ath/ath10k/htt_rx.c -+++ b/drivers/net/wireless/ath/ath10k/htt_rx.c -@@ -702,6 +702,10 @@ static void ath10k_htt_rx_h_rates(struct - /* 80MHZ */ - case 2: - status->vht_flag |= RX_VHT_FLAG_80MHZ; -+ break; -+ case 3: -+ status->vht_flag |= RX_VHT_FLAG_160MHZ; -+ break; - } - - status->flag |= RX_FLAG_VHT; -@@ -926,7 +930,7 @@ static void ath10k_process_rx(struct ath - *status = *rx_status; - - ath10k_dbg(ar, ATH10K_DBG_DATA, -- "rx skb %pK len %u peer %pM %s %s sn %u %s%s%s%s%s %srate_idx %u vht_nss %u freq %u band %u flag 0x%llx fcs-err %i mic-err %i amsdu-more %i\n", -+ "rx skb %pK len %u peer %pM %s %s sn %u %s%s%s%s%s%s %srate_idx %u vht_nss %u freq %u band %u flag 0x%llx fcs-err %i mic-err %i amsdu-more %i\n", - skb, - skb->len, - ieee80211_get_SA(hdr), -@@ -940,6 +944,7 @@ static void ath10k_process_rx(struct ath - status->flag & RX_FLAG_VHT ? "vht" : "", - status->flag & RX_FLAG_40MHZ ? "40" : "", - status->vht_flag & RX_VHT_FLAG_80MHZ ? "80" : "", -+ status->vht_flag & RX_VHT_FLAG_160MHZ ? "160" : "", - status->flag & RX_FLAG_SHORT_GI ? "sgi " : "", - status->rate_idx, - status->vht_nss, ---- a/drivers/net/wireless/ath/ath10k/mac.c -+++ b/drivers/net/wireless/ath/ath10k/mac.c -@@ -568,10 +568,14 @@ chan_to_phymode(const struct cfg80211_ch - case NL80211_CHAN_WIDTH_80: - phymode = MODE_11AC_VHT80; - break; -+ case NL80211_CHAN_WIDTH_160: -+ phymode = MODE_11AC_VHT160; -+ break; -+ case NL80211_CHAN_WIDTH_80P80: -+ phymode = MODE_11AC_VHT80_80; -+ break; - case NL80211_CHAN_WIDTH_5: - case NL80211_CHAN_WIDTH_10: -- case NL80211_CHAN_WIDTH_80P80: -- case NL80211_CHAN_WIDTH_160: - phymode = MODE_UNKNOWN; - break; - } -@@ -970,6 +974,7 @@ static int ath10k_monitor_vdev_start(str - arg.vdev_id = vdev_id; - arg.channel.freq = channel->center_freq; - arg.channel.band_center_freq1 = chandef->center_freq1; -+ arg.channel.band_center_freq2 = chandef->center_freq2; - - /* TODO setup this dynamically, what in case we - don't have any vifs? */ -@@ -1381,6 +1386,7 @@ static int ath10k_vdev_start_restart(str - - arg.channel.freq = chandef->chan->center_freq; - arg.channel.band_center_freq1 = chandef->center_freq1; -+ arg.channel.band_center_freq2 = chandef->center_freq2; - arg.channel.mode = chan_to_phymode(chandef); - - arg.channel.min_power = 0; -@@ -2444,6 +2450,9 @@ static void ath10k_peer_assoc_h_vht(stru - if (sta->bandwidth == IEEE80211_STA_RX_BW_80) - arg->peer_flags |= ar->wmi.peer_flags->bw80; - -+ if (sta->bandwidth == IEEE80211_STA_RX_BW_160) -+ arg->peer_flags |= ar->wmi.peer_flags->bw160; -+ - arg->peer_vht_rates.rx_max_rate = - __le16_to_cpu(vht_cap->vht_mcs.rx_highest); - arg->peer_vht_rates.rx_mcs_set = -@@ -2545,7 +2554,17 @@ static void ath10k_peer_assoc_h_phymode( - !ath10k_peer_assoc_h_vht_masked(vht_mcs_mask)) { - if (sta->bandwidth == IEEE80211_STA_RX_BW_80) - phymode = MODE_11AC_VHT80; -- else if (sta->bandwidth == IEEE80211_STA_RX_BW_40) -+ else if (sta->bandwidth == IEEE80211_STA_RX_BW_160) { -+ phymode = MODE_11AC_VHT160; -+ switch (sta->vht_cap.cap & IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_MASK) { -+ case IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ: -+ phymode = MODE_11AC_VHT160; -+ break; -+ case IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ: -+ phymode = MODE_11AC_VHT80_80; -+ break; -+ } -+ } else if (sta->bandwidth == IEEE80211_STA_RX_BW_40) - phymode = MODE_11AC_VHT40; - else if (sta->bandwidth == IEEE80211_STA_RX_BW_20) - phymode = MODE_11AC_VHT20; -@@ -4277,6 +4296,10 @@ static struct ieee80211_sta_vht_cap ath1 - vht_cap.cap |= val; - } - -+ if ((ar->vht_cap_info & IEEE80211_VHT_CAP_SHORT_GI_160) && !(ar->vht_cap_info & IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ)) { -+ vht_cap.cap |= IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ; -+ } -+ - mcs_map = 0; - for (i = 0; i < 8; i++) { - if ((i < ar->num_rf_chains) && (ar->cfg_tx_chainmask & BIT(i))) -@@ -6913,6 +6936,9 @@ static void ath10k_sta_rc_update(struct - bw = WMI_PEER_CHWIDTH_80MHZ; - break; - case IEEE80211_STA_RX_BW_160: -+ bw = WMI_PEER_CHWIDTH_160MHZ; -+ break; -+ default: - ath10k_warn(ar, "Invalid bandwidth %d in rc update for %pM\n", - sta->bandwidth, sta->addr); - bw = WMI_PEER_CHWIDTH_20MHZ; ---- a/drivers/net/wireless/ath/ath10k/wmi-tlv.c -+++ b/drivers/net/wireless/ath/ath10k/wmi-tlv.c -@@ -3560,6 +3560,7 @@ static const struct wmi_peer_flags_map w - .vht = WMI_TLV_PEER_VHT, - .bw80 = WMI_TLV_PEER_80MHZ, - .pmf = WMI_TLV_PEER_PMF, -+ .bw160 = WMI_TLV_PEER_160MHZ, - }; - - /************/ ---- a/drivers/net/wireless/ath/ath10k/wmi-tlv.h -+++ b/drivers/net/wireless/ath/ath10k/wmi-tlv.h -@@ -543,6 +543,7 @@ enum wmi_tlv_peer_flags { - WMI_TLV_PEER_VHT = 0x02000000, - WMI_TLV_PEER_80MHZ = 0x04000000, - WMI_TLV_PEER_PMF = 0x08000000, -+ WMI_TLV_PEER_160MHZ = 0x20000000, - }; - - enum wmi_tlv_tag { ---- a/drivers/net/wireless/ath/ath10k/wmi.c -+++ b/drivers/net/wireless/ath/ath10k/wmi.c -@@ -1576,6 +1576,7 @@ static const struct wmi_peer_flags_map w - .bw80 = WMI_PEER_80MHZ, - .vht_2g = WMI_PEER_VHT_2G, - .pmf = WMI_PEER_PMF, -+ .bw160 = WMI_PEER_160MHZ, - }; - - static const struct wmi_peer_flags_map wmi_10x_peer_flags_map = { -@@ -1593,6 +1594,7 @@ static const struct wmi_peer_flags_map w - .spatial_mux = WMI_10X_PEER_SPATIAL_MUX, - .vht = WMI_10X_PEER_VHT, - .bw80 = WMI_10X_PEER_80MHZ, -+ .bw160 = WMI_10X_PEER_160MHZ, - }; - - static const struct wmi_peer_flags_map wmi_10_2_peer_flags_map = { -@@ -1612,6 +1614,7 @@ static const struct wmi_peer_flags_map w - .bw80 = WMI_10_2_PEER_80MHZ, - .vht_2g = WMI_10_2_PEER_VHT_2G, - .pmf = WMI_10_2_PEER_PMF, -+ .bw160 = WMI_10_2_PEER_160MHZ, - }; - - void ath10k_wmi_put_wmi_channel(struct wmi_channel *ch, -@@ -1636,7 +1639,10 @@ void ath10k_wmi_put_wmi_channel(struct w - - ch->mhz = __cpu_to_le32(arg->freq); - ch->band_center_freq1 = __cpu_to_le32(arg->band_center_freq1); -- ch->band_center_freq2 = 0; -+ if (arg->mode == MODE_11AC_VHT80_80) -+ ch->band_center_freq2 = __cpu_to_le32(arg->band_center_freq2); -+ else -+ ch->band_center_freq2 = 0; - ch->min_power = arg->min_power; - ch->max_power = arg->max_power; - ch->reg_power = arg->max_reg_power; ---- a/drivers/net/wireless/ath/ath10k/wmi.h -+++ b/drivers/net/wireless/ath/ath10k/wmi.h -@@ -1728,8 +1728,10 @@ enum wmi_phy_mode { - MODE_11AC_VHT20_2G = 11, - MODE_11AC_VHT40_2G = 12, - MODE_11AC_VHT80_2G = 13, -- MODE_UNKNOWN = 14, -- MODE_MAX = 14 -+ MODE_11AC_VHT80_80 = 14, -+ MODE_11AC_VHT160 = 15, -+ MODE_UNKNOWN = 16, -+ MODE_MAX = 16 - }; - - static inline const char *ath10k_wmi_phymode_str(enum wmi_phy_mode mode) -@@ -1757,6 +1759,10 @@ static inline const char *ath10k_wmi_phy - return "11ac-vht40"; - case MODE_11AC_VHT80: - return "11ac-vht80"; -+ case MODE_11AC_VHT160: -+ return "11ac-vht160"; -+ case MODE_11AC_VHT80_80: -+ return "11ac-vht80+80"; - case MODE_11AC_VHT20_2G: - return "11ac-vht20-2g"; - case MODE_11AC_VHT40_2G: -@@ -1811,6 +1817,7 @@ struct wmi_channel { - struct wmi_channel_arg { - u32 freq; - u32 band_center_freq1; -+ u32 band_center_freq2; - bool passive; - bool allow_ibss; - bool allow_ht; -@@ -1875,9 +1882,18 @@ enum wmi_channel_change_cause { - #define WMI_VHT_CAP_MAX_MPDU_LEN_MASK 0x00000003 - #define WMI_VHT_CAP_RX_LDPC 0x00000010 - #define WMI_VHT_CAP_SGI_80MHZ 0x00000020 -+#define WMI_VHT_CAP_SGI_160MHZ 0x00000040 - #define WMI_VHT_CAP_TX_STBC 0x00000080 - #define WMI_VHT_CAP_RX_STBC_MASK 0x00000300 - #define WMI_VHT_CAP_RX_STBC_MASK_SHIFT 8 -+#define WMI_VHT_CAP_SU_BFER 0x00000800 -+#define WMI_VHT_CAP_SU_BFEE 0x00001000 -+#define WMI_VHT_CAP_MAX_CS_ANT_MASK 0x0000E000 -+#define WMI_VHT_CAP_MAX_CS_ANT_MASK_SHIFT 13 -+#define WMI_VHT_CAP_MAX_SND_DIM_MASK 0x00070000 -+#define WMI_VHT_CAP_MAX_SND_DIM_MASK_SHIFT 16 -+#define WMI_VHT_CAP_MU_BFER 0x00080000 -+#define WMI_VHT_CAP_MU_BFEE 0x00100000 - #define WMI_VHT_CAP_MAX_AMPDU_LEN_EXP 0x03800000 - #define WMI_VHT_CAP_MAX_AMPDU_LEN_EXP_SHIFT 23 - #define WMI_VHT_CAP_RX_FIXED_ANT 0x10000000 -@@ -1926,6 +1942,8 @@ enum { - REGDMN_MODE_11AC_VHT40PLUS = 0x40000, /* 5Ghz, VHT40 + channels */ - REGDMN_MODE_11AC_VHT40MINUS = 0x80000, /* 5Ghz VHT40 - channels */ - REGDMN_MODE_11AC_VHT80 = 0x100000, /* 5Ghz, VHT80 channels */ -+ REGDMN_MODE_11AC_VHT160 = 0x200000, /* 5Ghz, VHT160 channels */ -+ REGDMN_MODE_11AC_VHT80_80 = 0x400000, /* 5Ghz, VHT80+80 channels */ - REGDMN_MODE_ALL = 0xffffffff - }; - -@@ -5769,6 +5787,7 @@ enum wmi_peer_chwidth { - WMI_PEER_CHWIDTH_20MHZ = 0, - WMI_PEER_CHWIDTH_40MHZ = 1, - WMI_PEER_CHWIDTH_80MHZ = 2, -+ WMI_PEER_CHWIDTH_160MHZ = 3, - }; - - enum wmi_peer_param { -@@ -5859,6 +5878,7 @@ struct wmi_peer_flags_map { - u32 bw80; - u32 vht_2g; - u32 pmf; -+ u32 bw160; - }; - - enum wmi_peer_flags { -@@ -5878,6 +5898,7 @@ enum wmi_peer_flags { - WMI_PEER_80MHZ = 0x04000000, - WMI_PEER_VHT_2G = 0x08000000, - WMI_PEER_PMF = 0x10000000, -+ WMI_PEER_160MHZ = 0x20000000 - }; - - enum wmi_10x_peer_flags { -@@ -5895,6 +5916,7 @@ enum wmi_10x_peer_flags { - WMI_10X_PEER_SPATIAL_MUX = 0x00200000, - WMI_10X_PEER_VHT = 0x02000000, - WMI_10X_PEER_80MHZ = 0x04000000, -+ WMI_10X_PEER_160MHZ = 0x20000000 - }; - - enum wmi_10_2_peer_flags { -@@ -5914,6 +5936,7 @@ enum wmi_10_2_peer_flags { - WMI_10_2_PEER_80MHZ = 0x04000000, - WMI_10_2_PEER_VHT_2G = 0x08000000, - WMI_10_2_PEER_PMF = 0x10000000, -+ WMI_10_2_PEER_160MHZ = 0x20000000 - }; - - /* diff --git a/package/kernel/mac80211/patches/311-ath9k-clear-potentially-stale-EOSP-status-bit-in-int.patch b/package/kernel/mac80211/patches/311-ath9k-clear-potentially-stale-EOSP-status-bit-in-int.patch new file mode 100644 index 0000000000..9863dffc90 --- /dev/null +++ b/package/kernel/mac80211/patches/311-ath9k-clear-potentially-stale-EOSP-status-bit-in-int.patch @@ -0,0 +1,22 @@ +From: Felix Fietkau +Date: Sun, 28 Aug 2016 13:13:42 +0200 +Subject: [PATCH] ath9k: clear potentially stale EOSP status bit in + intermediate queues + +Prevents spurious ieee80211_sta_eosp calls. + +Signed-off-by: Felix Fietkau +--- + +--- a/drivers/net/wireless/ath/ath9k/xmit.c ++++ b/drivers/net/wireless/ath/ath9k/xmit.c +@@ -1004,7 +1004,8 @@ ath_tx_get_tid_subframe(struct ath_softc + bf->bf_lastbf = bf; + + tx_info = IEEE80211_SKB_CB(skb); +- tx_info->flags &= ~IEEE80211_TX_CTL_CLEAR_PS_FILT; ++ tx_info->flags &= ~(IEEE80211_TX_CTL_CLEAR_PS_FILT | ++ IEEE80211_TX_STATUS_EOSP); + + /* + * No aggregation session is running, but there may be frames diff --git a/package/kernel/mac80211/patches/312-ath9k-report-tx-status-on-EOSP.patch b/package/kernel/mac80211/patches/312-ath9k-report-tx-status-on-EOSP.patch new file mode 100644 index 0000000000..80a3074a4d --- /dev/null +++ b/package/kernel/mac80211/patches/312-ath9k-report-tx-status-on-EOSP.patch @@ -0,0 +1,19 @@ +From: Felix Fietkau +Date: Sun, 28 Aug 2016 13:23:27 +0200 +Subject: [PATCH] ath9k: report tx status on EOSP + +Signed-off-by: Felix Fietkau +--- + +--- a/drivers/net/wireless/ath/ath9k/xmit.c ++++ b/drivers/net/wireless/ath/ath9k/xmit.c +@@ -86,7 +86,8 @@ static void ath_tx_status(struct ieee802 + struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); + struct ieee80211_sta *sta = info->status.status_driver_data[0]; + +- if (info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS) { ++ if (info->flags & (IEEE80211_TX_CTL_REQ_TX_STATUS | ++ IEEE80211_TX_STATUS_EOSP)) { + ieee80211_tx_status(hw, skb); + return; + } diff --git a/package/kernel/mac80211/patches/312-mac80211-Use-rhltable-instead-of-rhashtable.patch b/package/kernel/mac80211/patches/312-mac80211-Use-rhltable-instead-of-rhashtable.patch deleted file mode 100644 index 4c5fff1274..0000000000 --- a/package/kernel/mac80211/patches/312-mac80211-Use-rhltable-instead-of-rhashtable.patch +++ /dev/null @@ -1,275 +0,0 @@ -From: Herbert Xu -Date: Mon, 19 Sep 2016 19:00:10 +0800 -Subject: [PATCH] mac80211: Use rhltable instead of rhashtable - -mac80211 currently uses rhashtable with insecure_elasticity set -to true. The latter is because of duplicate objects. What's -more, mac80211 walks the rhashtable chains by hand which is broken -as rhashtable may contain multiple tables due to resizing or -rehashing. - -This patch fixes it by converting it to the newly added rhltable -interface which is designed for use with duplicate objects. - -With rhltable a lookup returns a list of objects instead of a -single one. This is then fed into the existing for_each_sta_info -macro. - -This patch also deletes the sta_addr_hash function since rhashtable -defaults to jhash. - -Signed-off-by: Herbert Xu ---- - ---- a/net/mac80211/ieee80211_i.h -+++ b/net/mac80211/ieee80211_i.h -@@ -1233,7 +1233,7 @@ struct ieee80211_local { - spinlock_t tim_lock; - unsigned long num_sta; - struct list_head sta_list; -- struct rhashtable sta_hash; -+ struct rhltable sta_hash; - struct timer_list sta_cleanup; - int sta_generation; - ---- a/net/mac80211/rx.c -+++ b/net/mac80211/rx.c -@@ -4004,7 +4004,7 @@ static void __ieee80211_rx_handle_packet - __le16 fc; - struct ieee80211_rx_data rx; - struct ieee80211_sub_if_data *prev; -- struct rhash_head *tmp; -+ struct rhlist_head *tmp; - int err = 0; - - fc = ((struct ieee80211_hdr *)skb->data)->frame_control; -@@ -4047,13 +4047,10 @@ static void __ieee80211_rx_handle_packet - goto out; - } else if (ieee80211_is_data(fc)) { - struct sta_info *sta, *prev_sta; -- const struct bucket_table *tbl; - - prev_sta = NULL; - -- tbl = rht_dereference_rcu(local->sta_hash.tbl, &local->sta_hash); -- -- for_each_sta_info(local, tbl, hdr->addr2, sta, tmp) { -+ for_each_sta_info(local, hdr->addr2, sta, tmp) { - if (!prev_sta) { - prev_sta = sta; - continue; ---- a/net/mac80211/sta_info.c -+++ b/net/mac80211/sta_info.c -@@ -67,12 +67,10 @@ - - static const struct rhashtable_params sta_rht_params = { - .nelem_hint = 3, /* start small */ -- .insecure_elasticity = true, /* Disable chain-length checks. */ - .automatic_shrinking = true, - .head_offset = offsetof(struct sta_info, hash_node), - .key_offset = offsetof(struct sta_info, addr), - .key_len = ETH_ALEN, -- .hashfn = sta_addr_hash, - .max_size = CPTCFG_MAC80211_STA_HASH_MAX_SIZE, - }; - -@@ -80,8 +78,8 @@ static const struct rhashtable_params st - static int sta_info_hash_del(struct ieee80211_local *local, - struct sta_info *sta) - { -- return rhashtable_remove_fast(&local->sta_hash, &sta->hash_node, -- sta_rht_params); -+ return rhltable_remove(&local->sta_hash, &sta->hash_node, -+ sta_rht_params); - } - - static void __cleanup_single_sta(struct sta_info *sta) -@@ -157,19 +155,22 @@ static void cleanup_single_sta(struct st - sta_info_free(local, sta); - } - -+struct rhlist_head *sta_info_hash_lookup(struct ieee80211_local *local, -+ const u8 *addr) -+{ -+ return rhltable_lookup(&local->sta_hash, addr, sta_rht_params); -+} -+ - /* protected by RCU */ - struct sta_info *sta_info_get(struct ieee80211_sub_if_data *sdata, - const u8 *addr) - { - struct ieee80211_local *local = sdata->local; -+ struct rhlist_head *tmp; - struct sta_info *sta; -- struct rhash_head *tmp; -- const struct bucket_table *tbl; - - rcu_read_lock(); -- tbl = rht_dereference_rcu(local->sta_hash.tbl, &local->sta_hash); -- -- for_each_sta_info(local, tbl, addr, sta, tmp) { -+ for_each_sta_info(local, addr, sta, tmp) { - if (sta->sdata == sdata) { - rcu_read_unlock(); - /* this is safe as the caller must already hold -@@ -190,14 +191,11 @@ struct sta_info *sta_info_get_bss(struct - const u8 *addr) - { - struct ieee80211_local *local = sdata->local; -+ struct rhlist_head *tmp; - struct sta_info *sta; -- struct rhash_head *tmp; -- const struct bucket_table *tbl; - - rcu_read_lock(); -- tbl = rht_dereference_rcu(local->sta_hash.tbl, &local->sta_hash); -- -- for_each_sta_info(local, tbl, addr, sta, tmp) { -+ for_each_sta_info(local, addr, sta, tmp) { - if (sta->sdata == sdata || - (sta->sdata->bss && sta->sdata->bss == sdata->bss)) { - rcu_read_unlock(); -@@ -263,8 +261,8 @@ void sta_info_free(struct ieee80211_loca - static int sta_info_hash_add(struct ieee80211_local *local, - struct sta_info *sta) - { -- return rhashtable_insert_fast(&local->sta_hash, &sta->hash_node, -- sta_rht_params); -+ return rhltable_insert(&local->sta_hash, &sta->hash_node, -+ sta_rht_params); - } - - static void sta_deliver_ps_frames(struct work_struct *wk) -@@ -453,9 +451,9 @@ static int sta_info_insert_check(struct - is_multicast_ether_addr(sta->sta.addr))) - return -EINVAL; - -- /* Strictly speaking this isn't necessary as we hold the mutex, but -- * the rhashtable code can't really deal with that distinction. We -- * do require the mutex for correctness though. -+ /* The RCU read lock is required by rhashtable due to -+ * asynchronous resize/rehash. We also require the mutex -+ * for correctness. - */ - rcu_read_lock(); - lockdep_assert_held(&sdata->local->sta_mtx); -@@ -1043,16 +1041,11 @@ static void sta_info_cleanup(unsigned lo - round_jiffies(jiffies + STA_INFO_CLEANUP_INTERVAL)); - } - --u32 sta_addr_hash(const void *key, u32 length, u32 seed) --{ -- return jhash(key, ETH_ALEN, seed); --} -- - int sta_info_init(struct ieee80211_local *local) - { - int err; - -- err = rhashtable_init(&local->sta_hash, &sta_rht_params); -+ err = rhltable_init(&local->sta_hash, &sta_rht_params); - if (err) - return err; - -@@ -1068,7 +1061,7 @@ int sta_info_init(struct ieee80211_local - void sta_info_stop(struct ieee80211_local *local) - { - del_timer_sync(&local->sta_cleanup); -- rhashtable_destroy(&local->sta_hash); -+ rhltable_destroy(&local->sta_hash); - } - - -@@ -1138,17 +1131,14 @@ struct ieee80211_sta *ieee80211_find_sta - const u8 *localaddr) - { - struct ieee80211_local *local = hw_to_local(hw); -+ struct rhlist_head *tmp; - struct sta_info *sta; -- struct rhash_head *tmp; -- const struct bucket_table *tbl; -- -- tbl = rht_dereference_rcu(local->sta_hash.tbl, &local->sta_hash); - - /* - * Just return a random station if localaddr is NULL - * ... first in list. - */ -- for_each_sta_info(local, tbl, addr, sta, tmp) { -+ for_each_sta_info(local, addr, sta, tmp) { - if (localaddr && - !ether_addr_equal(sta->sdata->vif.addr, localaddr)) - continue; ---- a/net/mac80211/sta_info.h -+++ b/net/mac80211/sta_info.h -@@ -455,7 +455,7 @@ struct sta_info { - /* General information, mostly static */ - struct list_head list, free_list; - struct rcu_head rcu_head; -- struct rhash_head hash_node; -+ struct rhlist_head hash_node; - u8 addr[ETH_ALEN]; - struct ieee80211_local *local; - struct ieee80211_sub_if_data *sdata; -@@ -638,6 +638,9 @@ rcu_dereference_protected_tid_tx(struct - */ - #define STA_INFO_CLEANUP_INTERVAL (10 * HZ) - -+struct rhlist_head *sta_info_hash_lookup(struct ieee80211_local *local, -+ const u8 *addr); -+ - /* - * Get a STA info, must be under RCU read lock. - */ -@@ -647,17 +650,9 @@ struct sta_info *sta_info_get(struct iee - struct sta_info *sta_info_get_bss(struct ieee80211_sub_if_data *sdata, - const u8 *addr); - --u32 sta_addr_hash(const void *key, u32 length, u32 seed); -- --#define _sta_bucket_idx(_tbl, _a) \ -- rht_bucket_index(_tbl, sta_addr_hash(_a, ETH_ALEN, (_tbl)->hash_rnd)) -- --#define for_each_sta_info(local, tbl, _addr, _sta, _tmp) \ -- rht_for_each_entry_rcu(_sta, _tmp, tbl, \ -- _sta_bucket_idx(tbl, _addr), \ -- hash_node) \ -- /* compare address and run code only if it matches */ \ -- if (ether_addr_equal(_sta->addr, (_addr))) -+#define for_each_sta_info(local, _addr, _sta, _tmp) \ -+ rhl_for_each_entry_rcu(_sta, _tmp, \ -+ sta_info_hash_lookup(local, _addr), hash_node) - - /* - * Get STA info by index, BROKEN! ---- a/net/mac80211/status.c -+++ b/net/mac80211/status.c -@@ -759,8 +759,8 @@ void ieee80211_tx_status(struct ieee8021 - struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); - __le16 fc; - struct ieee80211_supported_band *sband; -+ struct rhlist_head *tmp; - struct sta_info *sta; -- struct rhash_head *tmp; - int retry_count; - int rates_idx; - bool send_to_cooked; -@@ -768,7 +768,6 @@ void ieee80211_tx_status(struct ieee8021 - struct ieee80211_bar *bar; - int shift = 0; - int tid = IEEE80211_NUM_TIDS; -- const struct bucket_table *tbl; - - rates_idx = ieee80211_tx_get_rates(hw, info, &retry_count); - -@@ -777,9 +776,7 @@ void ieee80211_tx_status(struct ieee8021 - sband = local->hw.wiphy->bands[info->band]; - fc = hdr->frame_control; - -- tbl = rht_dereference_rcu(local->sta_hash.tbl, &local->sta_hash); -- -- for_each_sta_info(local, tbl, hdr->addr1, sta, tmp) { -+ for_each_sta_info(local, hdr->addr1, sta, tmp) { - /* skip wrong virtual interface */ - if (!ether_addr_equal(hdr->addr2, sta->sdata->vif.addr)) - continue; diff --git a/package/kernel/mac80211/patches/313-ath9k-fix-block-ack-window-tracking-issues.patch b/package/kernel/mac80211/patches/313-ath9k-fix-block-ack-window-tracking-issues.patch new file mode 100644 index 0000000000..fb8df08afe --- /dev/null +++ b/package/kernel/mac80211/patches/313-ath9k-fix-block-ack-window-tracking-issues.patch @@ -0,0 +1,114 @@ +From: Felix Fietkau +Date: Tue, 30 Aug 2016 12:44:08 +0200 +Subject: [PATCH] ath9k: fix block-ack window tracking issues + +Ensure that a buffer gets tracked as part of the block-ack window as +soon as it's dequeued from the tid for the first time. Ensure that +double calls to ath_tx_addto_baw (e.g. on retransmission) don't cause +any issues. + +Signed-off-by: Felix Fietkau +--- + +--- a/drivers/net/wireless/ath/ath9k/xmit.c ++++ b/drivers/net/wireless/ath/ath9k/xmit.c +@@ -62,7 +62,7 @@ static void ath_tx_rc_status(struct ath_ + struct ath_tx_status *ts, int nframes, int nbad, + int txok); + static void ath_tx_update_baw(struct ath_softc *sc, struct ath_atx_tid *tid, +- int seqno); ++ struct ath_buf *bf); + static struct ath_buf *ath_tx_setup_buffer(struct ath_softc *sc, + struct ath_txq *txq, + struct ath_atx_tid *tid, +@@ -311,7 +311,7 @@ static void ath_tx_flush_tid(struct ath_ + } + + if (fi->baw_tracked) { +- ath_tx_update_baw(sc, tid, bf->bf_state.seqno); ++ ath_tx_update_baw(sc, tid, bf); + sendbar = true; + } + +@@ -327,10 +327,15 @@ static void ath_tx_flush_tid(struct ath_ + } + + static void ath_tx_update_baw(struct ath_softc *sc, struct ath_atx_tid *tid, +- int seqno) ++ struct ath_buf *bf) + { ++ struct ath_frame_info *fi = get_frame_info(bf->bf_mpdu); ++ u16 seqno = bf->bf_state.seqno; + int index, cindex; + ++ if (!fi->baw_tracked) ++ return; ++ + index = ATH_BA_INDEX(tid->seq_start, seqno); + cindex = (tid->baw_head + index) & (ATH_TID_MAX_BUFS - 1); + +@@ -351,6 +356,9 @@ static void ath_tx_addto_baw(struct ath_ + u16 seqno = bf->bf_state.seqno; + int index, cindex; + ++ if (fi->baw_tracked) ++ return; ++ + index = ATH_BA_INDEX(tid->seq_start, seqno); + cindex = (tid->baw_head + index) & (ATH_TID_MAX_BUFS - 1); + __set_bit(cindex, tid->tx_buf); +@@ -627,7 +635,7 @@ static void ath_tx_complete_aggr(struct + * complete the acked-ones/xretried ones; update + * block-ack window + */ +- ath_tx_update_baw(sc, tid, seqno); ++ ath_tx_update_baw(sc, tid, bf); + + if (rc_update && (acked_cnt == 1 || txfail_cnt == 1)) { + memcpy(tx_info->control.rates, rates, sizeof(rates)); +@@ -657,7 +665,7 @@ static void ath_tx_complete_aggr(struct + * run out of tx buf. + */ + if (!tbf) { +- ath_tx_update_baw(sc, tid, seqno); ++ ath_tx_update_baw(sc, tid, bf); + + ath_tx_complete_buf(sc, bf, txq, + &bf_head, NULL, ts, +@@ -1046,11 +1054,14 @@ ath_tx_get_tid_subframe(struct ath_softc + + INIT_LIST_HEAD(&bf_head); + list_add(&bf->list, &bf_head); +- ath_tx_update_baw(sc, tid, seqno); ++ ath_tx_update_baw(sc, tid, bf); + ath_tx_complete_buf(sc, bf, txq, &bf_head, NULL, &ts, 0); + continue; + } + ++ if (bf_isampdu(bf)) ++ ath_tx_addto_baw(sc, tid, bf); ++ + return bf; + } + +@@ -1108,8 +1119,6 @@ ath_tx_form_aggr(struct ath_softc *sc, s + bf->bf_next = NULL; + + /* link buffers of this frame to the aggregate */ +- if (!fi->baw_tracked) +- ath_tx_addto_baw(sc, tid, bf); + bf->bf_state.ndelim = ndelim; + + list_add_tail(&bf->list, bf_q); +@@ -1745,10 +1754,8 @@ void ath9k_release_buffered_frames(struc + ath9k_set_moredata(sc, bf, true); + list_add_tail(&bf->list, &bf_q); + ath_set_rates(tid->an->vif, tid->an->sta, bf, true); +- if (bf_isampdu(bf)) { +- ath_tx_addto_baw(sc, tid, bf); ++ if (bf_isampdu(bf)) + bf->bf_state.bf_type &= ~BUF_AGGR; +- } + if (bf_tail) + bf_tail->bf_next = bf; + diff --git a/package/kernel/mac80211/patches/313-mac80211-fix-sequence-number-allocation-regression.patch b/package/kernel/mac80211/patches/313-mac80211-fix-sequence-number-allocation-regression.patch deleted file mode 100644 index c1548be0d2..0000000000 --- a/package/kernel/mac80211/patches/313-mac80211-fix-sequence-number-allocation-regression.patch +++ /dev/null @@ -1,37 +0,0 @@ -From: Felix Fietkau -Date: Tue, 11 Oct 2016 11:24:07 +0200 -Subject: [PATCH] mac80211: fix sequence number allocation regression - -The recent commit that moved around TX handlers dropped the sequence -number allocation at the end of ieee80211_tx_dequeue and calls -ieee80211_tx_h_sequence instead (for the non-fast-xmit case). -However, it did not change the fast-xmit sequence allocation condition -in ieee80211_xmit_fast_finish, which skipped seqno alloc if intermediate -tx queues are being used. - -Drop the now obsolete condition. - -Fixes: bb42f2d13ffc ("mac80211: Move reorder-sensitive TX handlers to after TXQ dequeue") -Signed-off-by: Felix Fietkau ---- - ---- a/net/mac80211/tx.c -+++ b/net/mac80211/tx.c -@@ -3212,7 +3212,6 @@ static void ieee80211_xmit_fast_finish(s - struct sk_buff *skb) - { - struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); -- struct ieee80211_local *local = sdata->local; - struct ieee80211_hdr *hdr = (void *)skb->data; - u8 tid = IEEE80211_NUM_TIDS; - -@@ -3224,8 +3223,7 @@ static void ieee80211_xmit_fast_finish(s - if (hdr->frame_control & cpu_to_le16(IEEE80211_STYPE_QOS_DATA)) { - tid = skb->priority & IEEE80211_QOS_CTL_TAG1D_MASK; - *ieee80211_get_qos_ctl(hdr) = tid; -- if (!ieee80211_get_txq(local, &sdata->vif, &sta->sta, skb)) -- hdr->seq_ctrl = ieee80211_tx_next_seq(sta, tid); -+ hdr->seq_ctrl = ieee80211_tx_next_seq(sta, tid); - } else { - info->flags |= IEEE80211_TX_CTL_ASSIGN_SEQ; - hdr->seq_ctrl = cpu_to_le16(sdata->sequence_number); diff --git a/package/kernel/mac80211/patches/314-ath9k-rename-tx_complete_work-to-hw_check_work.patch b/package/kernel/mac80211/patches/314-ath9k-rename-tx_complete_work-to-hw_check_work.patch new file mode 100644 index 0000000000..5465df3ccf --- /dev/null +++ b/package/kernel/mac80211/patches/314-ath9k-rename-tx_complete_work-to-hw_check_work.patch @@ -0,0 +1,175 @@ +From: Felix Fietkau +Date: Wed, 25 Jan 2017 12:57:05 +0100 +Subject: [PATCH] ath9k: rename tx_complete_work to hw_check_work + +Also include common MAC alive check. This should make the hang checks +more reliable for modes where beacons are not sent and is used as a +starting point for further hang check improvements + +Signed-off-by: Felix Fietkau +--- + +--- a/drivers/net/wireless/ath/ath9k/ath9k.h ++++ b/drivers/net/wireless/ath/ath9k/ath9k.h +@@ -108,7 +108,7 @@ int ath_descdma_setup(struct ath_softc * + #define ATH_AGGR_MIN_QDEPTH 2 + /* minimum h/w qdepth for non-aggregated traffic */ + #define ATH_NON_AGGR_MIN_QDEPTH 8 +-#define ATH_TX_COMPLETE_POLL_INT 1000 ++#define ATH_HW_CHECK_POLL_INT 1000 + #define ATH_TXFIFO_DEPTH 8 + #define ATH_TX_ERROR 0x01 + +@@ -745,7 +745,7 @@ void ath9k_csa_update(struct ath_softc * + #define ATH_PAPRD_TIMEOUT 100 /* msecs */ + #define ATH_PLL_WORK_INTERVAL 100 + +-void ath_tx_complete_poll_work(struct work_struct *work); ++void ath_hw_check_work(struct work_struct *work); + void ath_reset_work(struct work_struct *work); + bool ath_hw_check(struct ath_softc *sc); + void ath_hw_pll_work(struct work_struct *work); +@@ -1053,7 +1053,7 @@ struct ath_softc { + #ifdef CPTCFG_ATH9K_DEBUGFS + struct ath9k_debug debug; + #endif +- struct delayed_work tx_complete_work; ++ struct delayed_work hw_check_work; + struct delayed_work hw_pll_work; + struct timer_list sleep_timer; + +--- a/drivers/net/wireless/ath/ath9k/init.c ++++ b/drivers/net/wireless/ath/ath9k/init.c +@@ -681,6 +681,7 @@ static int ath9k_init_softc(u16 devid, s + INIT_WORK(&sc->hw_reset_work, ath_reset_work); + INIT_WORK(&sc->paprd_work, ath_paprd_calibrate); + INIT_DELAYED_WORK(&sc->hw_pll_work, ath_hw_pll_work); ++ INIT_DELAYED_WORK(&sc->hw_check_work, ath_hw_check_work); + + ath9k_init_channel_context(sc); + +--- a/drivers/net/wireless/ath/ath9k/link.c ++++ b/drivers/net/wireless/ath/ath9k/link.c +@@ -20,20 +20,13 @@ + * TX polling - checks if the TX engine is stuck somewhere + * and issues a chip reset if so. + */ +-void ath_tx_complete_poll_work(struct work_struct *work) ++static bool ath_tx_complete_check(struct ath_softc *sc) + { +- struct ath_softc *sc = container_of(work, struct ath_softc, +- tx_complete_work.work); + struct ath_txq *txq; + int i; +- bool needreset = false; +- + +- if (sc->tx99_state) { +- ath_dbg(ath9k_hw_common(sc->sc_ah), RESET, +- "skip tx hung detection on tx99\n"); +- return; +- } ++ if (sc->tx99_state) ++ return true; + + for (i = 0; i < IEEE80211_NUM_ACS; i++) { + txq = sc->tx.txq_map[i]; +@@ -41,25 +34,36 @@ void ath_tx_complete_poll_work(struct wo + ath_txq_lock(sc, txq); + if (txq->axq_depth) { + if (txq->axq_tx_inprogress) { +- needreset = true; + ath_txq_unlock(sc, txq); +- break; +- } else { +- txq->axq_tx_inprogress = true; ++ goto reset; + } ++ ++ txq->axq_tx_inprogress = true; + } + ath_txq_unlock(sc, txq); + } + +- if (needreset) { +- ath_dbg(ath9k_hw_common(sc->sc_ah), RESET, +- "tx hung, resetting the chip\n"); +- ath9k_queue_reset(sc, RESET_TYPE_TX_HANG); ++ return true; ++ ++reset: ++ ath_dbg(ath9k_hw_common(sc->sc_ah), RESET, ++ "tx hung, resetting the chip\n"); ++ ath9k_queue_reset(sc, RESET_TYPE_TX_HANG); ++ return false; ++ ++} ++ ++void ath_hw_check_work(struct work_struct *work) ++{ ++ struct ath_softc *sc = container_of(work, struct ath_softc, ++ hw_check_work.work); ++ ++ if (!ath_hw_check(sc) || ++ !ath_tx_complete_check(sc)) + return; +- } + +- ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work, +- msecs_to_jiffies(ATH_TX_COMPLETE_POLL_INT)); ++ ieee80211_queue_delayed_work(sc->hw, &sc->hw_check_work, ++ msecs_to_jiffies(ATH_HW_CHECK_POLL_INT)); + } + + /* +--- a/drivers/net/wireless/ath/ath9k/main.c ++++ b/drivers/net/wireless/ath/ath9k/main.c +@@ -181,7 +181,7 @@ void ath9k_ps_restore(struct ath_softc * + static void __ath_cancel_work(struct ath_softc *sc) + { + cancel_work_sync(&sc->paprd_work); +- cancel_delayed_work_sync(&sc->tx_complete_work); ++ cancel_delayed_work_sync(&sc->hw_check_work); + cancel_delayed_work_sync(&sc->hw_pll_work); + + #ifdef CPTCFG_ATH9K_BTCOEX_SUPPORT +@@ -198,7 +198,8 @@ void ath_cancel_work(struct ath_softc *s + + void ath_restart_work(struct ath_softc *sc) + { +- ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work, 0); ++ ieee80211_queue_delayed_work(sc->hw, &sc->hw_check_work, ++ ATH_HW_CHECK_POLL_INT); + + if (AR_SREV_9340(sc->sc_ah) || AR_SREV_9330(sc->sc_ah)) + ieee80211_queue_delayed_work(sc->hw, &sc->hw_pll_work, +@@ -2091,7 +2092,7 @@ void __ath9k_flush(struct ieee80211_hw * + int timeout; + bool drain_txq; + +- cancel_delayed_work_sync(&sc->tx_complete_work); ++ cancel_delayed_work_sync(&sc->hw_check_work); + + if (ah->ah_flags & AH_UNPLUGGED) { + ath_dbg(common, ANY, "Device has been unplugged!\n"); +@@ -2129,7 +2130,8 @@ void __ath9k_flush(struct ieee80211_hw * + ath9k_ps_restore(sc); + } + +- ieee80211_queue_delayed_work(hw, &sc->tx_complete_work, 0); ++ ieee80211_queue_delayed_work(hw, &sc->hw_check_work, ++ ATH_HW_CHECK_POLL_INT); + } + + static bool ath9k_tx_frames_pending(struct ieee80211_hw *hw) +--- a/drivers/net/wireless/ath/ath9k/xmit.c ++++ b/drivers/net/wireless/ath/ath9k/xmit.c +@@ -2916,8 +2916,6 @@ int ath_tx_init(struct ath_softc *sc, in + return error; + } + +- INIT_DELAYED_WORK(&sc->tx_complete_work, ath_tx_complete_poll_work); +- + if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) + error = ath_tx_edma_init(sc); + diff --git a/package/kernel/mac80211/patches/314-ath9k_hw-reset-AHB-WMAC-interface-on-AR91xx.patch b/package/kernel/mac80211/patches/314-ath9k_hw-reset-AHB-WMAC-interface-on-AR91xx.patch deleted file mode 100644 index a7bcfa549b..0000000000 --- a/package/kernel/mac80211/patches/314-ath9k_hw-reset-AHB-WMAC-interface-on-AR91xx.patch +++ /dev/null @@ -1,25 +0,0 @@ -From: Felix Fietkau -Date: Sat, 9 Jul 2016 15:25:24 +0200 -Subject: [PATCH] ath9k_hw: reset AHB-WMAC interface on AR91xx - -Should fix a few stability issues - -Signed-off-by: Felix Fietkau ---- - ---- a/drivers/net/wireless/ath/ath9k/hw.c -+++ b/drivers/net/wireless/ath/ath9k/hw.c -@@ -1394,8 +1394,12 @@ static bool ath9k_hw_set_reset(struct at - if (!AR_SREV_9100(ah)) - REG_WRITE(ah, AR_RC, 0); - -- if (AR_SREV_9100(ah)) -+ if (AR_SREV_9100(ah)) { -+ /* Reset the AHB-WMAC interface */ -+ if (ah->external_reset) -+ ah->external_reset(); - udelay(50); -+ } - - return true; - } diff --git a/package/kernel/mac80211/patches/315-ath9k_hw-check-if-the-chip-failed-to-wake-up.patch b/package/kernel/mac80211/patches/315-ath9k_hw-check-if-the-chip-failed-to-wake-up.patch new file mode 100644 index 0000000000..b0cb74ad05 --- /dev/null +++ b/package/kernel/mac80211/patches/315-ath9k_hw-check-if-the-chip-failed-to-wake-up.patch @@ -0,0 +1,30 @@ +From: Felix Fietkau +Date: Wed, 25 Jan 2017 12:58:17 +0100 +Subject: [PATCH] ath9k_hw: check if the chip failed to wake up + +In an RFC patch, Sven Eckelmann and Simon Wunderlich reported: + +"QCA 802.11n chips (especially AR9330/AR9340) sometimes end up in a +state in which a read of AR_CFG always returns 0xdeadbeef. +This should not happen when when the power_mode of the device is +ATH9K_PM_AWAKE." + +Include the check for the default register state in the existing MAC +hang check. + +Signed-off-by: Felix Fietkau +--- + +--- a/drivers/net/wireless/ath/ath9k/hw.c ++++ b/drivers/net/wireless/ath/ath9k/hw.c +@@ -1624,6 +1624,10 @@ bool ath9k_hw_check_alive(struct ath_hw + int count = 50; + u32 reg, last_val; + ++ /* Check if chip failed to wake up */ ++ if (REG_READ(ah, AR_CFG) == 0xdeadbeef) ++ return false; ++ + if (AR_SREV_9300(ah)) + return !ath9k_hw_detect_mac_hang(ah); + diff --git a/package/kernel/mac80211/patches/315-ath9k_hw-issue-external-reset-for-QCA955x.patch b/package/kernel/mac80211/patches/315-ath9k_hw-issue-external-reset-for-QCA955x.patch deleted file mode 100644 index 5eb69b898d..0000000000 --- a/package/kernel/mac80211/patches/315-ath9k_hw-issue-external-reset-for-QCA955x.patch +++ /dev/null @@ -1,129 +0,0 @@ -From: Felix Fietkau -Date: Sat, 9 Jul 2016 15:26:44 +0200 -Subject: [PATCH] ath9k_hw: issue external reset for QCA955x - -The RTC interface on the SoC needs to be reset along with the rest of -the WMAC. - -Signed-off-by: Felix Fietkau ---- - ---- a/drivers/net/wireless/ath/ath9k/hw.c -+++ b/drivers/net/wireless/ath/ath9k/hw.c -@@ -1271,39 +1271,56 @@ void ath9k_hw_get_delta_slope_vals(struc - *coef_exponent = coef_exp - 16; - } - --/* AR9330 WAR: -- * call external reset function to reset WMAC if: -- * - doing a cold reset -- * - we have pending frames in the TX queues. -- */ --static bool ath9k_hw_ar9330_reset_war(struct ath_hw *ah, int type) -+static bool ath9k_hw_need_external_reset(struct ath_hw *ah, int type) - { -- int i, npend = 0; -+ int i; - -- for (i = 0; i < AR_NUM_QCU; i++) { -- npend = ath9k_hw_numtxpending(ah, i); -- if (npend) -- break; -- } -- -- if (ah->external_reset && -- (npend || type == ATH9K_RESET_COLD)) { -- int reset_err = 0; -- -- ath_dbg(ath9k_hw_common(ah), RESET, -- "reset MAC via external reset\n"); -- -- reset_err = ah->external_reset(); -- if (reset_err) { -- ath_err(ath9k_hw_common(ah), -- "External reset failed, err=%d\n", -- reset_err); -- return false; -+ if (type == ATH9K_RESET_COLD) -+ return true; -+ -+ if (AR_SREV_9550(ah)) -+ return true; -+ -+ /* AR9330 WAR: -+ * call external reset function to reset WMAC if: -+ * - doing a cold reset -+ * - we have pending frames in the TX queues. -+ */ -+ if (AR_SREV_9330(ah)) { -+ for (i = 0; i < AR_NUM_QCU; i++) { -+ if (ath9k_hw_numtxpending(ah, i)) -+ return true; - } -+ } -+ -+ return false; -+} -+ -+static bool ath9k_hw_external_reset(struct ath_hw *ah, int type) -+{ -+ int err; -+ -+ if (!ah->external_reset || !ath9k_hw_need_external_reset(ah, type)) -+ return true; -+ -+ ath_dbg(ath9k_hw_common(ah), RESET, -+ "reset MAC via external reset\n"); - -- REG_WRITE(ah, AR_RTC_RESET, 1); -+ err = ah->external_reset(); -+ if (err) { -+ ath_err(ath9k_hw_common(ah), -+ "External reset failed, err=%d\n", err); -+ return false; - } - -+ if (AR_SREV_9550(ah)) { -+ REG_WRITE(ah, AR_RTC_RESET, 0); -+ udelay(10); -+ } -+ -+ REG_WRITE(ah, AR_RTC_RESET, 1); -+ udelay(10); -+ - return true; - } - -@@ -1356,24 +1373,24 @@ static bool ath9k_hw_set_reset(struct at - rst_flags |= AR_RTC_RC_MAC_COLD; - } - -- if (AR_SREV_9330(ah)) { -- if (!ath9k_hw_ar9330_reset_war(ah, type)) -- return false; -- } -- - if (ath9k_hw_mci_is_enabled(ah)) - ar9003_mci_check_gpm_offset(ah); - - /* DMA HALT added to resolve ar9300 and ar9580 bus error during -- * RTC_RC reg read -+ * RTC_RC reg read. Also needed for AR9550 external reset - */ -- if (AR_SREV_9300(ah) || AR_SREV_9580(ah)) { -+ if (AR_SREV_9300(ah) || AR_SREV_9580(ah) || AR_SREV_9550(ah)) { - REG_SET_BIT(ah, AR_CFG, AR_CFG_HALT_REQ); - ath9k_hw_wait(ah, AR_CFG, AR_CFG_HALT_ACK, AR_CFG_HALT_ACK, - 20 * AH_WAIT_TIMEOUT); -- REG_CLR_BIT(ah, AR_CFG, AR_CFG_HALT_REQ); - } - -+ if (!AR_SREV_9100(ah)) -+ ath9k_hw_external_reset(ah, type); -+ -+ if (AR_SREV_9300(ah) || AR_SREV_9580(ah)) -+ REG_CLR_BIT(ah, AR_CFG, AR_CFG_HALT_REQ); -+ - REG_WRITE(ah, AR_RTC_RC, rst_flags); - - REGWRITE_BUFFER_FLUSH(ah); diff --git a/package/kernel/mac80211/patches/316-ath9k-fix-race-condition-in-enabling-disabling-IRQs.patch b/package/kernel/mac80211/patches/316-ath9k-fix-race-condition-in-enabling-disabling-IRQs.patch new file mode 100644 index 0000000000..7a41206132 --- /dev/null +++ b/package/kernel/mac80211/patches/316-ath9k-fix-race-condition-in-enabling-disabling-IRQs.patch @@ -0,0 +1,197 @@ +From: Felix Fietkau +Date: Wed, 25 Jan 2017 15:10:37 +0100 +Subject: [PATCH] ath9k: fix race condition in enabling/disabling IRQs + +The code currently relies on refcounting to disable IRQs from within the +IRQ handler and re-enabling them again after the tasklet has run. + +However, due to race conditions sometimes the IRQ handler might be +called twice, or the tasklet may not run at all (if interrupted in the +middle of a reset). + +This can cause nasty imbalances in the irq-disable refcount which will +get the driver permanently stuck until the entire radio has been stopped +and started again (ath_reset will not recover from this). + +Instead of using this fragile logic, change the code to ensure that +running the irq handler during tasklet processing is safe, and leave the +refcount untouched. + +Cc: stable@vger.kernel.org +Signed-off-by: Felix Fietkau +--- + +--- a/drivers/net/wireless/ath/ath9k/ath9k.h ++++ b/drivers/net/wireless/ath/ath9k/ath9k.h +@@ -998,6 +998,7 @@ struct ath_softc { + struct survey_info *cur_survey; + struct survey_info survey[ATH9K_NUM_CHANNELS]; + ++ spinlock_t intr_lock; + struct tasklet_struct intr_tq; + struct tasklet_struct bcon_tasklet; + struct ath_hw *sc_ah; +--- a/drivers/net/wireless/ath/ath9k/init.c ++++ b/drivers/net/wireless/ath/ath9k/init.c +@@ -669,6 +669,7 @@ static int ath9k_init_softc(u16 devid, s + common->bt_ant_diversity = 1; + + spin_lock_init(&common->cc_lock); ++ spin_lock_init(&sc->intr_lock); + spin_lock_init(&sc->sc_serial_rw); + spin_lock_init(&sc->sc_pm_lock); + spin_lock_init(&sc->chan_lock); +--- a/drivers/net/wireless/ath/ath9k/mac.c ++++ b/drivers/net/wireless/ath/ath9k/mac.c +@@ -810,21 +810,12 @@ void ath9k_hw_disable_interrupts(struct + } + EXPORT_SYMBOL(ath9k_hw_disable_interrupts); + +-void ath9k_hw_enable_interrupts(struct ath_hw *ah) ++static void __ath9k_hw_enable_interrupts(struct ath_hw *ah) + { + struct ath_common *common = ath9k_hw_common(ah); + u32 sync_default = AR_INTR_SYNC_DEFAULT; + u32 async_mask; + +- if (!(ah->imask & ATH9K_INT_GLOBAL)) +- return; +- +- if (!atomic_inc_and_test(&ah->intr_ref_cnt)) { +- ath_dbg(common, INTERRUPT, "Do not enable IER ref count %d\n", +- atomic_read(&ah->intr_ref_cnt)); +- return; +- } +- + if (AR_SREV_9340(ah) || AR_SREV_9550(ah) || AR_SREV_9531(ah) || + AR_SREV_9561(ah)) + sync_default &= ~AR_INTR_SYNC_HOST1_FATAL; +@@ -846,6 +837,39 @@ void ath9k_hw_enable_interrupts(struct a + ath_dbg(common, INTERRUPT, "AR_IMR 0x%x IER 0x%x\n", + REG_READ(ah, AR_IMR), REG_READ(ah, AR_IER)); + } ++ ++void ath9k_hw_resume_interrupts(struct ath_hw *ah) ++{ ++ struct ath_common *common = ath9k_hw_common(ah); ++ ++ if (!(ah->imask & ATH9K_INT_GLOBAL)) ++ return; ++ ++ if (atomic_read(&ah->intr_ref_cnt) != 0) { ++ ath_dbg(common, INTERRUPT, "Do not enable IER ref count %d\n", ++ atomic_read(&ah->intr_ref_cnt)); ++ return; ++ } ++ ++ __ath9k_hw_enable_interrupts(ah); ++} ++EXPORT_SYMBOL(ath9k_hw_resume_interrupts); ++ ++void ath9k_hw_enable_interrupts(struct ath_hw *ah) ++{ ++ struct ath_common *common = ath9k_hw_common(ah); ++ ++ if (!(ah->imask & ATH9K_INT_GLOBAL)) ++ return; ++ ++ if (!atomic_inc_and_test(&ah->intr_ref_cnt)) { ++ ath_dbg(common, INTERRUPT, "Do not enable IER ref count %d\n", ++ atomic_read(&ah->intr_ref_cnt)); ++ return; ++ } ++ ++ __ath9k_hw_enable_interrupts(ah); ++} + EXPORT_SYMBOL(ath9k_hw_enable_interrupts); + + void ath9k_hw_set_interrupts(struct ath_hw *ah) +--- a/drivers/net/wireless/ath/ath9k/mac.h ++++ b/drivers/net/wireless/ath/ath9k/mac.h +@@ -744,6 +744,7 @@ void ath9k_hw_set_interrupts(struct ath_ + void ath9k_hw_enable_interrupts(struct ath_hw *ah); + void ath9k_hw_disable_interrupts(struct ath_hw *ah); + void ath9k_hw_kill_interrupts(struct ath_hw *ah); ++void ath9k_hw_resume_interrupts(struct ath_hw *ah); + + void ar9002_hw_attach_mac_ops(struct ath_hw *ah); + +--- a/drivers/net/wireless/ath/ath9k/main.c ++++ b/drivers/net/wireless/ath/ath9k/main.c +@@ -374,21 +374,20 @@ void ath9k_tasklet(unsigned long data) + struct ath_common *common = ath9k_hw_common(ah); + enum ath_reset_type type; + unsigned long flags; +- u32 status = sc->intrstatus; ++ u32 status; + u32 rxmask; + ++ spin_lock_irqsave(&sc->intr_lock, flags); ++ status = sc->intrstatus; ++ sc->intrstatus = 0; ++ spin_unlock_irqrestore(&sc->intr_lock, flags); ++ + ath9k_ps_wakeup(sc); + spin_lock(&sc->sc_pcu_lock); + + if (status & ATH9K_INT_FATAL) { + type = RESET_TYPE_FATAL_INT; + ath9k_queue_reset(sc, type); +- +- /* +- * Increment the ref. counter here so that +- * interrupts are enabled in the reset routine. +- */ +- atomic_inc(&ah->intr_ref_cnt); + ath_dbg(common, RESET, "FATAL: Skipping interrupts\n"); + goto out; + } +@@ -404,11 +403,6 @@ void ath9k_tasklet(unsigned long data) + type = RESET_TYPE_BB_WATCHDOG; + ath9k_queue_reset(sc, type); + +- /* +- * Increment the ref. counter here so that +- * interrupts are enabled in the reset routine. +- */ +- atomic_inc(&ah->intr_ref_cnt); + ath_dbg(common, RESET, + "BB_WATCHDOG: Skipping interrupts\n"); + goto out; +@@ -421,7 +415,6 @@ void ath9k_tasklet(unsigned long data) + if ((sc->gtt_cnt >= MAX_GTT_CNT) && !ath9k_hw_check_alive(ah)) { + type = RESET_TYPE_TX_GTT; + ath9k_queue_reset(sc, type); +- atomic_inc(&ah->intr_ref_cnt); + ath_dbg(common, RESET, + "GTT: Skipping interrupts\n"); + goto out; +@@ -478,7 +471,7 @@ void ath9k_tasklet(unsigned long data) + ath9k_btcoex_handle_interrupt(sc, status); + + /* re-enable hardware interrupt */ +- ath9k_hw_enable_interrupts(ah); ++ ath9k_hw_resume_interrupts(ah); + out: + spin_unlock(&sc->sc_pcu_lock); + ath9k_ps_restore(sc); +@@ -542,7 +535,9 @@ irqreturn_t ath_isr(int irq, void *dev) + return IRQ_NONE; + + /* Cache the status */ +- sc->intrstatus = status; ++ spin_lock(&sc->intr_lock); ++ sc->intrstatus |= status; ++ spin_unlock(&sc->intr_lock); + + if (status & SCHED_INTR) + sched = true; +@@ -588,7 +583,7 @@ chip_reset: + + if (sched) { + /* turn off every interrupt */ +- ath9k_hw_disable_interrupts(ah); ++ ath9k_hw_kill_interrupts(ah); + tasklet_schedule(&sc->intr_tq); + } + diff --git a/package/kernel/mac80211/patches/316-ath9k_hw-set-spectral-scan-enable-bit-on-trigger-for.patch b/package/kernel/mac80211/patches/316-ath9k_hw-set-spectral-scan-enable-bit-on-trigger-for.patch deleted file mode 100644 index dfe9aae268..0000000000 --- a/package/kernel/mac80211/patches/316-ath9k_hw-set-spectral-scan-enable-bit-on-trigger-for.patch +++ /dev/null @@ -1,21 +0,0 @@ -From: Felix Fietkau -Date: Mon, 11 Jul 2016 12:07:40 +0200 -Subject: [PATCH] ath9k_hw: set spectral scan enable bit on trigger for - AR9003+ - -AR9002 code and QCA AR9003+ code do the same. - -Signed-off-by: Felix Fietkau ---- - ---- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c -+++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c -@@ -1800,6 +1800,8 @@ static void ar9003_hw_spectral_scan_conf - - static void ar9003_hw_spectral_scan_trigger(struct ath_hw *ah) - { -+ REG_SET_BIT(ah, AR_PHY_SPECTRAL_SCAN, -+ AR_PHY_SPECTRAL_SCAN_ENABLE); - /* Activate spectral scan */ - REG_SET_BIT(ah, AR_PHY_SPECTRAL_SCAN, - AR_PHY_SPECTRAL_SCAN_ACTIVE); diff --git a/package/kernel/mac80211/patches/317-Revert-ath9k_hw-implement-temperature-compensation-s.patch b/package/kernel/mac80211/patches/317-Revert-ath9k_hw-implement-temperature-compensation-s.patch deleted file mode 100644 index 687df35a9e..0000000000 --- a/package/kernel/mac80211/patches/317-Revert-ath9k_hw-implement-temperature-compensation-s.patch +++ /dev/null @@ -1,101 +0,0 @@ -From: Felix Fietkau -Date: Tue, 11 Oct 2016 19:45:41 +0200 -Subject: [PATCH] Revert "ath9k_hw: implement temperature compensation support - for AR9003+" - -This reverts commit 171f6402e4aa5cd3b8407f82501f7ea21fa54ccc. -Some users report that this commit causes a regression in performance -under some conditions. - -Signed-off-by: Felix Fietkau ---- - ---- a/drivers/net/wireless/ath/ath9k/ar9003_calib.c -+++ b/drivers/net/wireless/ath/ath9k/ar9003_calib.c -@@ -33,7 +33,6 @@ struct coeff { - - enum ar9003_cal_types { - IQ_MISMATCH_CAL = BIT(0), -- TEMP_COMP_CAL = BIT(1), - }; - - static void ar9003_hw_setup_calibration(struct ath_hw *ah, -@@ -59,12 +58,6 @@ static void ar9003_hw_setup_calibration( - /* Kick-off cal */ - REG_SET_BIT(ah, AR_PHY_TIMING4, AR_PHY_TIMING4_DO_CAL); - break; -- case TEMP_COMP_CAL: -- ath_dbg(common, CALIBRATE, -- "starting Temperature Compensation Calibration\n"); -- REG_SET_BIT(ah, AR_CH0_THERM, AR_CH0_THERM_LOCAL); -- REG_SET_BIT(ah, AR_CH0_THERM, AR_CH0_THERM_START); -- break; - default: - ath_err(common, "Invalid calibration type\n"); - break; -@@ -93,8 +86,7 @@ static bool ar9003_hw_per_calibration(st - /* - * Accumulate cal measures for active chains - */ -- if (cur_caldata->calCollect) -- cur_caldata->calCollect(ah); -+ cur_caldata->calCollect(ah); - ah->cal_samples++; - - if (ah->cal_samples >= cur_caldata->calNumSamples) { -@@ -107,8 +99,7 @@ static bool ar9003_hw_per_calibration(st - /* - * Process accumulated data - */ -- if (cur_caldata->calPostProc) -- cur_caldata->calPostProc(ah, numChains); -+ cur_caldata->calPostProc(ah, numChains); - - /* Calibration has finished. */ - caldata->CalValid |= cur_caldata->calType; -@@ -323,16 +314,9 @@ static const struct ath9k_percal_data iq - ar9003_hw_iqcalibrate - }; - --static const struct ath9k_percal_data temp_cal_single_sample = { -- TEMP_COMP_CAL, -- MIN_CAL_SAMPLES, -- PER_MAX_LOG_COUNT, --}; -- - static void ar9003_hw_init_cal_settings(struct ath_hw *ah) - { - ah->iq_caldata.calData = &iq_cal_single_sample; -- ah->temp_caldata.calData = &temp_cal_single_sample; - - if (AR_SREV_9300_20_OR_LATER(ah)) { - ah->enabled_cals |= TX_IQ_CAL; -@@ -340,7 +324,7 @@ static void ar9003_hw_init_cal_settings( - ah->enabled_cals |= TX_IQ_ON_AGC_CAL; - } - -- ah->supp_cals = IQ_MISMATCH_CAL | TEMP_COMP_CAL; -+ ah->supp_cals = IQ_MISMATCH_CAL; - } - - #define OFF_UPPER_LT 24 -@@ -1399,9 +1383,6 @@ static void ar9003_hw_init_cal_common(st - INIT_CAL(&ah->iq_caldata); - INSERT_CAL(ah, &ah->iq_caldata); - -- INIT_CAL(&ah->temp_caldata); -- INSERT_CAL(ah, &ah->temp_caldata); -- - /* Initialize current pointer to first element in list */ - ah->cal_list_curr = ah->cal_list; - ---- a/drivers/net/wireless/ath/ath9k/hw.h -+++ b/drivers/net/wireless/ath/ath9k/hw.h -@@ -830,7 +830,6 @@ struct ath_hw { - /* Calibration */ - u32 supp_cals; - struct ath9k_cal_list iq_caldata; -- struct ath9k_cal_list temp_caldata; - struct ath9k_cal_list adcgain_caldata; - struct ath9k_cal_list adcdc_caldata; - struct ath9k_cal_list *cal_list; diff --git a/package/kernel/mac80211/patches/317-rt2x00-avoid-introducing-a-USB-dependency-in-the-rt2.patch b/package/kernel/mac80211/patches/317-rt2x00-avoid-introducing-a-USB-dependency-in-the-rt2.patch new file mode 100644 index 0000000000..c0274ddde9 --- /dev/null +++ b/package/kernel/mac80211/patches/317-rt2x00-avoid-introducing-a-USB-dependency-in-the-rt2.patch @@ -0,0 +1,73 @@ +From: Stanislaw Gruszka +Date: Thu, 2 Feb 2017 10:57:40 +0100 +Subject: [PATCH] rt2x00: avoid introducing a USB dependency in the + rt2x00lib module + +As reported by Felix: + +Though protected by an ifdef, introducing an usb symbol dependency in +the rt2x00lib module is a major inconvenience for distributions that +package kernel modules split into individual packages. + +Get rid of this unnecessary dependency by calling the usb related +function from a more suitable place. + +Cc: Vishal Thanki +Reported-by: Felix Fietkau +Fixes: 8b4c0009313f ("rt2x00usb: Use usb anchor to manage URB") +Signed-off-by: Stanislaw Gruszka +--- + +--- a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c +@@ -1436,21 +1436,6 @@ void rt2x00lib_remove_dev(struct rt2x00_ + cancel_work_sync(&rt2x00dev->intf_work); + cancel_delayed_work_sync(&rt2x00dev->autowakeup_work); + cancel_work_sync(&rt2x00dev->sleep_work); +-#if IS_ENABLED(CPTCFG_RT2X00_LIB_USB) +- if (rt2x00_is_usb(rt2x00dev)) { +- usb_kill_anchored_urbs(rt2x00dev->anchor); +- hrtimer_cancel(&rt2x00dev->txstatus_timer); +- cancel_work_sync(&rt2x00dev->rxdone_work); +- cancel_work_sync(&rt2x00dev->txdone_work); +- } +-#endif +- if (rt2x00dev->workqueue) +- destroy_workqueue(rt2x00dev->workqueue); +- +- /* +- * Free the tx status fifo. +- */ +- kfifo_free(&rt2x00dev->txstatus_fifo); + + /* + * Kill the tx status tasklet. +@@ -1466,6 +1451,14 @@ void rt2x00lib_remove_dev(struct rt2x00_ + */ + rt2x00lib_uninitialize(rt2x00dev); + ++ if (rt2x00dev->workqueue) ++ destroy_workqueue(rt2x00dev->workqueue); ++ ++ /* ++ * Free the tx status fifo. ++ */ ++ kfifo_free(&rt2x00dev->txstatus_fifo); ++ + /* + * Free extra components + */ +--- a/drivers/net/wireless/ralink/rt2x00/rt2x00usb.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2x00usb.c +@@ -744,6 +744,11 @@ void rt2x00usb_uninitialize(struct rt2x0 + { + struct data_queue *queue; + ++ usb_kill_anchored_urbs(rt2x00dev->anchor); ++ hrtimer_cancel(&rt2x00dev->txstatus_timer); ++ cancel_work_sync(&rt2x00dev->rxdone_work); ++ cancel_work_sync(&rt2x00dev->txdone_work); ++ + queue_for_each(rt2x00dev, queue) + rt2x00usb_free_entries(queue); + } diff --git a/package/kernel/mac80211/patches/318-brcmfmac-check-brcmf_bus_get_memdump-result-for-erro.patch b/package/kernel/mac80211/patches/318-brcmfmac-check-brcmf_bus_get_memdump-result-for-erro.patch new file mode 100644 index 0000000000..4ae4c606c5 --- /dev/null +++ b/package/kernel/mac80211/patches/318-brcmfmac-check-brcmf_bus_get_memdump-result-for-erro.patch @@ -0,0 +1,52 @@ +From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= +Date: Mon, 30 Jan 2017 16:09:51 +0100 +Subject: [PATCH] brcmfmac: check brcmf_bus_get_memdump result for error +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This method may be unsupported (see: USB bus) or may just fail (see: +SDIO bus). +While at it rework logic in brcmf_sdio_bus_get_memdump function to avoid +too many conditional code nesting levels. + +Signed-off-by: Rafał Miłecki +Acked-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/debug.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/debug.c +@@ -32,16 +32,25 @@ static int brcmf_debug_create_memdump(st + { + void *dump; + size_t ramsize; ++ int err; + + ramsize = brcmf_bus_get_ramsize(bus); +- if (ramsize) { +- dump = vzalloc(len + ramsize); +- if (!dump) +- return -ENOMEM; +- memcpy(dump, data, len); +- brcmf_bus_get_memdump(bus, dump + len, ramsize); +- dev_coredumpv(bus->dev, dump, len + ramsize, GFP_KERNEL); ++ if (!ramsize) ++ return -ENOTSUPP; ++ ++ dump = vzalloc(len + ramsize); ++ if (!dump) ++ return -ENOMEM; ++ ++ memcpy(dump, data, len); ++ err = brcmf_bus_get_memdump(bus, dump + len, ramsize); ++ if (err) { ++ vfree(dump); ++ return err; + } ++ ++ dev_coredumpv(bus->dev, dump, len + ramsize, GFP_KERNEL); ++ + return 0; + } + diff --git a/package/kernel/mac80211/patches/318-mac80211-fix-up-mismerge-of-ieee80211_tx_dequeue.patch b/package/kernel/mac80211/patches/318-mac80211-fix-up-mismerge-of-ieee80211_tx_dequeue.patch deleted file mode 100644 index 2e742e4484..0000000000 --- a/package/kernel/mac80211/patches/318-mac80211-fix-up-mismerge-of-ieee80211_tx_dequeue.patch +++ /dev/null @@ -1,35 +0,0 @@ -From: Bob Copeland -Date: Wed, 12 Oct 2016 08:24:54 -0400 -Subject: [PATCH] mac80211: fix up mismerge of ieee80211_tx_dequeue - -Looks like this spinlock wound up on the wrong side of the -linearize, and I also lost the part that re-enters the loop. -Fix up to match mac80211-next. - -Signed-off-by: Bob Copeland ---- - ---- a/net/mac80211/tx.c -+++ b/net/mac80211/tx.c -@@ -3457,17 +3457,17 @@ begin: - skb_queue_splice_tail(&tx.skbs, &txqi->frags); - } - --out: -- spin_unlock_bh(&fq->lock); -- - if (skb && skb_has_frag_list(skb) && - !ieee80211_hw_check(&local->hw, TX_FRAG_LIST)) { - if (skb_linearize(skb)) { - ieee80211_free_txskb(&local->hw, skb); -- return NULL; -+ goto begin; - } - } - -+out: -+ spin_unlock_bh(&fq->lock); -+ - return skb; - } - EXPORT_SYMBOL(ieee80211_tx_dequeue); diff --git a/package/kernel/mac80211/patches/319-brcmfmac-be-more-verbose-when-PSM-s-watchdog-fires.patch b/package/kernel/mac80211/patches/319-brcmfmac-be-more-verbose-when-PSM-s-watchdog-fires.patch new file mode 100644 index 0000000000..2a3b83864e --- /dev/null +++ b/package/kernel/mac80211/patches/319-brcmfmac-be-more-verbose-when-PSM-s-watchdog-fires.patch @@ -0,0 +1,38 @@ +From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= +Date: Mon, 30 Jan 2017 16:09:52 +0100 +Subject: [PATCH] brcmfmac: be more verbose when PSM's watchdog fires +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +It's important to inform user so he knows things went wrong. He may also +want to get memory dump for further debugging purposes. + +Signed-off-by: Rafał Miłecki +Acked-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/debug.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/debug.c +@@ -58,10 +58,18 @@ static int brcmf_debug_psm_watchdog_noti + const struct brcmf_event_msg *evtmsg, + void *data) + { ++ int err; ++ + brcmf_dbg(TRACE, "enter: bsscfgidx=%d\n", ifp->bsscfgidx); + +- return brcmf_debug_create_memdump(ifp->drvr->bus_if, data, +- evtmsg->datalen); ++ brcmf_err("PSM's watchdog has fired!\n"); ++ ++ err = brcmf_debug_create_memdump(ifp->drvr->bus_if, data, ++ evtmsg->datalen); ++ if (err) ++ brcmf_err("Failed to get memory dump, %d\n", err); ++ ++ return err; + } + + void brcmf_debugfs_init(void) diff --git a/package/kernel/mac80211/patches/319-mac80211-avoid-extra-memcpy-in-A-MSDU-head-creation.patch b/package/kernel/mac80211/patches/319-mac80211-avoid-extra-memcpy-in-A-MSDU-head-creation.patch deleted file mode 100644 index 4668226530..0000000000 --- a/package/kernel/mac80211/patches/319-mac80211-avoid-extra-memcpy-in-A-MSDU-head-creation.patch +++ /dev/null @@ -1,56 +0,0 @@ -From: Michael Braun -Date: Sat, 15 Oct 2016 13:28:18 +0200 -Subject: [PATCH] mac80211: avoid extra memcpy in A-MSDU head creation - -Signed-off-by: Michael Braun -Signed-off-by: Johannes Berg ---- - ---- a/net/mac80211/tx.c -+++ b/net/mac80211/tx.c -@@ -3069,11 +3069,11 @@ static bool ieee80211_amsdu_prepare_head - struct ieee80211_local *local = sdata->local; - struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); - struct ieee80211_hdr *hdr; -- struct ethhdr amsdu_hdr; -+ struct ethhdr *amsdu_hdr; - int hdr_len = fast_tx->hdr_len - sizeof(rfc1042_header); - int subframe_len = skb->len - hdr_len; - void *data; -- u8 *qc; -+ u8 *qc, *h_80211_src, *h_80211_dst; - - if (info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE) - return false; -@@ -3081,19 +3081,22 @@ static bool ieee80211_amsdu_prepare_head - if (info->control.flags & IEEE80211_TX_CTRL_AMSDU) - return true; - -- if (!ieee80211_amsdu_realloc_pad(local, skb, sizeof(amsdu_hdr), -+ if (!ieee80211_amsdu_realloc_pad(local, skb, sizeof(*amsdu_hdr), - &subframe_len)) - return false; - -- amsdu_hdr.h_proto = cpu_to_be16(subframe_len); -- memcpy(amsdu_hdr.h_source, skb->data + fast_tx->sa_offs, ETH_ALEN); -- memcpy(amsdu_hdr.h_dest, skb->data + fast_tx->da_offs, ETH_ALEN); -- -- data = skb_push(skb, sizeof(amsdu_hdr)); -- memmove(data, data + sizeof(amsdu_hdr), hdr_len); -- memcpy(data + hdr_len, &amsdu_hdr, sizeof(amsdu_hdr)); -- -+ data = skb_push(skb, sizeof(*amsdu_hdr)); -+ memmove(data, data + sizeof(*amsdu_hdr), hdr_len); - hdr = data; -+ amsdu_hdr = data + hdr_len; -+ /* h_80211_src/dst is addr* field within hdr */ -+ h_80211_src = data + fast_tx->sa_offs; -+ h_80211_dst = data + fast_tx->da_offs; -+ -+ amsdu_hdr->h_proto = cpu_to_be16(subframe_len); -+ ether_addr_copy(amsdu_hdr->h_source, h_80211_src); -+ ether_addr_copy(amsdu_hdr->h_dest, h_80211_dst); -+ - qc = ieee80211_get_qos_ctl(hdr); - *qc |= IEEE80211_QOS_CTL_A_MSDU_PRESENT; - diff --git a/package/kernel/mac80211/patches/320-mac80211-fix-A-MSDU-outer-SA-DA.patch b/package/kernel/mac80211/patches/320-mac80211-fix-A-MSDU-outer-SA-DA.patch deleted file mode 100644 index 7700254cd1..0000000000 --- a/package/kernel/mac80211/patches/320-mac80211-fix-A-MSDU-outer-SA-DA.patch +++ /dev/null @@ -1,73 +0,0 @@ -From: Michael Braun -Date: Sat, 15 Oct 2016 13:28:19 +0200 -Subject: [PATCH] mac80211: fix A-MSDU outer SA/DA - -According to IEEE 802.11-2012 section 8.3.2 table 8-19, the outer SA/DA -of A-MSDU frames need to be changed depending on FromDS/ToDS values. - -Signed-off-by: Michael Braun -[use ether_addr_copy and add alignment annotations] -Signed-off-by: Johannes Berg ---- - ---- a/include/net/mac80211.h -+++ b/include/net/mac80211.h -@@ -1438,7 +1438,7 @@ enum ieee80211_vif_flags { - struct ieee80211_vif { - enum nl80211_iftype type; - struct ieee80211_bss_conf bss_conf; -- u8 addr[ETH_ALEN]; -+ u8 addr[ETH_ALEN] __aligned(2); - bool p2p; - bool csa_active; - bool mu_mimo_owner; ---- a/net/mac80211/ieee80211_i.h -+++ b/net/mac80211/ieee80211_i.h -@@ -443,7 +443,7 @@ struct ieee80211_if_managed { - struct ieee80211_mgd_auth_data *auth_data; - struct ieee80211_mgd_assoc_data *assoc_data; - -- u8 bssid[ETH_ALEN]; -+ u8 bssid[ETH_ALEN] __aligned(2); - - u16 aid; - ---- a/net/mac80211/tx.c -+++ b/net/mac80211/tx.c -@@ -3074,6 +3074,7 @@ static bool ieee80211_amsdu_prepare_head - int subframe_len = skb->len - hdr_len; - void *data; - u8 *qc, *h_80211_src, *h_80211_dst; -+ const u8 *bssid; - - if (info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE) - return false; -@@ -3097,6 +3098,28 @@ static bool ieee80211_amsdu_prepare_head - ether_addr_copy(amsdu_hdr->h_source, h_80211_src); - ether_addr_copy(amsdu_hdr->h_dest, h_80211_dst); - -+ /* according to IEEE 802.11-2012 8.3.2 table 8-19, the outer SA/DA -+ * fields needs to be changed to BSSID for A-MSDU frames depending -+ * on FromDS/ToDS values. -+ */ -+ switch (sdata->vif.type) { -+ case NL80211_IFTYPE_STATION: -+ bssid = sdata->u.mgd.bssid; -+ break; -+ case NL80211_IFTYPE_AP: -+ case NL80211_IFTYPE_AP_VLAN: -+ bssid = sdata->vif.addr; -+ break; -+ default: -+ bssid = NULL; -+ } -+ -+ if (bssid && ieee80211_has_fromds(hdr->frame_control)) -+ ether_addr_copy(h_80211_src, bssid); -+ -+ if (bssid && ieee80211_has_tods(hdr->frame_control)) -+ ether_addr_copy(h_80211_dst, bssid); -+ - qc = ieee80211_get_qos_ctl(hdr); - *qc |= IEEE80211_QOS_CTL_A_MSDU_PRESENT; - diff --git a/package/kernel/mac80211/patches/321-Revert-mac80211-allow-using-AP_LINK_PS-with-mac80211.patch b/package/kernel/mac80211/patches/321-Revert-mac80211-allow-using-AP_LINK_PS-with-mac80211.patch deleted file mode 100644 index ace20e706b..0000000000 --- a/package/kernel/mac80211/patches/321-Revert-mac80211-allow-using-AP_LINK_PS-with-mac80211.patch +++ /dev/null @@ -1,28 +0,0 @@ -From: Felix Fietkau -Date: Thu, 3 Nov 2016 12:10:34 +0100 -Subject: [PATCH] Revert "mac80211: allow using AP_LINK_PS with - mac80211-generated TIM IE" - -This reverts commit c68df2e7be0c1238ea3c281fd744a204ef3b15a0. - -__sta_info_recalc_tim turns into a no-op if local->ops->set_tim is not -set. This prevents the beacon TIM bit from being set for all drivers -that do not implement this op (almost all of them), thus thoroughly -essential AP mode powersave functionality. - -Cc: Emmanuel Grumbach -Fixes: c68df2e7be0c ("mac80211: allow using AP_LINK_PS with mac80211-generated TIM IE") -Signed-off-by: Felix Fietkau ---- - ---- a/net/mac80211/sta_info.c -+++ b/net/mac80211/sta_info.c -@@ -688,7 +688,7 @@ static void __sta_info_recalc_tim(struct - } - - /* No need to do anything if the driver does all */ -- if (!local->ops->set_tim) -+ if (ieee80211_hw_check(&local->hw, AP_LINK_PS)) - return; - - if (sta->dead) diff --git a/package/kernel/mac80211/patches/322-mac80211-update-A-MPDU-flag-on-tx-dequeue.patch b/package/kernel/mac80211/patches/322-mac80211-update-A-MPDU-flag-on-tx-dequeue.patch deleted file mode 100644 index 1898d23584..0000000000 --- a/package/kernel/mac80211/patches/322-mac80211-update-A-MPDU-flag-on-tx-dequeue.patch +++ /dev/null @@ -1,30 +0,0 @@ -From: Felix Fietkau -Date: Fri, 4 Nov 2016 10:13:34 +0100 -Subject: [PATCH] mac80211: update A-MPDU flag on tx dequeue - -The sequence number counter is used to derive the starting sequence -number. Since that counter is updated on tx dequeue, the A-MPDU flag -needs to be up to date at the tme of dequeue as well. - -This patch prevents sending more A-MPDU frames after the session has -been terminated and also ensures that aggregation starts right after the -session has been established - -Fixes: bb42f2d13ffc ("mac80211: Move reorder-sensitive TX handlers to after TXQ dequeue") -Signed-off-by: Felix Fietkau ---- - ---- a/net/mac80211/tx.c -+++ b/net/mac80211/tx.c -@@ -3462,6 +3462,11 @@ begin: - goto begin; - } - -+ if (test_bit(IEEE80211_TXQ_AMPDU, &txqi->flags)) -+ info->flags |= IEEE80211_TX_CTL_AMPDU; -+ else -+ info->flags &= ~IEEE80211_TX_CTL_AMPDU; -+ - if (info->control.flags & IEEE80211_TX_CTRL_FAST_XMIT) { - struct sta_info *sta = container_of(txq->sta, struct sta_info, - sta); diff --git a/package/kernel/mac80211/patches/323-mac80211-remove-bogus-skb-vif-assignment.patch b/package/kernel/mac80211/patches/323-mac80211-remove-bogus-skb-vif-assignment.patch deleted file mode 100644 index 66449aca2b..0000000000 --- a/package/kernel/mac80211/patches/323-mac80211-remove-bogus-skb-vif-assignment.patch +++ /dev/null @@ -1,29 +0,0 @@ -From: Felix Fietkau -Date: Fri, 4 Nov 2016 10:17:38 +0100 -Subject: [PATCH] mac80211: remove bogus skb vif assignment - -The call to ieee80211_txq_enqueue overwrites the vif pointer with the -codel enqueue time, so setting it just before that call makes no sense. - -Signed-off-by: Felix Fietkau ---- - ---- a/net/mac80211/tx.c -+++ b/net/mac80211/tx.c -@@ -1500,7 +1500,6 @@ static bool ieee80211_queue_skb(struct i - struct sta_info *sta, - struct sk_buff *skb) - { -- struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); - struct fq *fq = &local->fq; - struct ieee80211_vif *vif; - struct txq_info *txqi; -@@ -1525,8 +1524,6 @@ static bool ieee80211_queue_skb(struct i - if (!txqi) - return false; - -- info->control.vif = vif; -- - spin_lock_bh(&fq->lock); - ieee80211_txq_enqueue(local, txqi, skb); - spin_unlock_bh(&fq->lock); diff --git a/package/kernel/mac80211/patches/324-mac80211-fix-A-MSDU-aggregation-with-fast-xmit-txq.patch b/package/kernel/mac80211/patches/324-mac80211-fix-A-MSDU-aggregation-with-fast-xmit-txq.patch deleted file mode 100644 index 579f112f71..0000000000 --- a/package/kernel/mac80211/patches/324-mac80211-fix-A-MSDU-aggregation-with-fast-xmit-txq.patch +++ /dev/null @@ -1,34 +0,0 @@ -From: Felix Fietkau -Date: Fri, 4 Nov 2016 10:18:51 +0100 -Subject: [PATCH] mac80211: fix A-MSDU aggregation with fast-xmit + txq - -A-MSDU aggregation alters the QoS header after a frame has been -enqueued, so it needs to be ready before enqueue and not overwritten -again afterwards - -Fixes: bb42f2d13ffc ("mac80211: Move reorder-sensitive TX handlers to after TXQ dequeue") -Signed-off-by: Felix Fietkau ---- - ---- a/net/mac80211/tx.c -+++ b/net/mac80211/tx.c -@@ -3245,7 +3245,6 @@ static void ieee80211_xmit_fast_finish(s - - if (hdr->frame_control & cpu_to_le16(IEEE80211_STYPE_QOS_DATA)) { - tid = skb->priority & IEEE80211_QOS_CTL_TAG1D_MASK; -- *ieee80211_get_qos_ctl(hdr) = tid; - hdr->seq_ctrl = ieee80211_tx_next_seq(sta, tid); - } else { - info->flags |= IEEE80211_TX_CTL_ASSIGN_SEQ; -@@ -3370,6 +3369,11 @@ static bool ieee80211_xmit_fast(struct i - (tid_tx ? IEEE80211_TX_CTL_AMPDU : 0); - info->control.flags = IEEE80211_TX_CTRL_FAST_XMIT; - -+ if (hdr->frame_control & cpu_to_le16(IEEE80211_STYPE_QOS_DATA)) { -+ tid = skb->priority & IEEE80211_QOS_CTL_TAG1D_MASK; -+ *ieee80211_get_qos_ctl(hdr) = tid; -+ } -+ - __skb_queue_head_init(&tx.skbs); - - tx.flags = IEEE80211_TX_UNICAST; diff --git a/package/kernel/mac80211/patches/325-ath9k-fix-ath9k_hw_gpio_get-to-return-0-or-1-on-succ.patch b/package/kernel/mac80211/patches/325-ath9k-fix-ath9k_hw_gpio_get-to-return-0-or-1-on-succ.patch deleted file mode 100644 index 012a49de9b..0000000000 --- a/package/kernel/mac80211/patches/325-ath9k-fix-ath9k_hw_gpio_get-to-return-0-or-1-on-succ.patch +++ /dev/null @@ -1,29 +0,0 @@ -From: Matthias Schiffer -Date: Tue, 15 Nov 2016 16:08:29 +0100 -Subject: [PATCH] ath9k: fix ath9k_hw_gpio_get() to return 0 or 1 on success - -Commit b2d70d4944c1 ("ath9k: make GPIO API to support both of WMAC and -SOC") refactored ath9k_hw_gpio_get() to support both WMAC and SOC GPIOs, -changing the return on success from 1 to BIT(gpio). This broke some callers -like ath_is_rfkill_set(). - -Instead of fixing all callers, change ath9k_hw_gpio_get() back to only -return 0 or 1. - -Fixes: b2d70d4944c1 ("ath9k: make GPIO API to support both of WMAC and SOC") -Signed-off-by: Matthias Schiffer ---- - drivers/net/wireless/ath/ath9k/hw.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/net/wireless/ath/ath9k/hw.c -+++ b/drivers/net/wireless/ath/ath9k/hw.c -@@ -2813,7 +2813,7 @@ u32 ath9k_hw_gpio_get(struct ath_hw *ah, - WARN_ON(1); - } - -- return val; -+ return !!val; - } - EXPORT_SYMBOL(ath9k_hw_gpio_get); - diff --git a/package/kernel/mac80211/patches/326-Documentation-dt-net-add-ath9k-wireless-device-bindi.patch b/package/kernel/mac80211/patches/326-Documentation-dt-net-add-ath9k-wireless-device-bindi.patch deleted file mode 100644 index 72a459c9e6..0000000000 --- a/package/kernel/mac80211/patches/326-Documentation-dt-net-add-ath9k-wireless-device-bindi.patch +++ /dev/null @@ -1,67 +0,0 @@ -From b263e0bb9d4585ca3ec04d7257ca5308d21333bb Mon Sep 17 00:00:00 2001 -From: Martin Blumenstingl -Date: Sun, 16 Oct 2016 22:59:05 +0200 -Subject: [PATCH 1/3] Documentation: dt: net: add ath9k wireless device binding - -Add documentation how devicetree can be used to configure ath9k based -devices. - -Signed-off-by: Martin Blumenstingl -Acked-by: Rob Herring -Signed-off-by: Kalle Valo ---- - .../devicetree/bindings/net/wireless/qca,ath9k.txt | 48 ++++++++++++++++++++++ - 1 file changed, 48 insertions(+) - create mode 100644 Documentation/devicetree/bindings/net/wireless/qca,ath9k.txt - ---- /dev/null -+++ b/Documentation/devicetree/bindings/net/wireless/qca,ath9k.txt -@@ -0,0 +1,48 @@ -+* Qualcomm Atheros ath9k wireless devices -+ -+This node provides properties for configuring the ath9k wireless device. The -+node is expected to be specified as a child node of the PCI controller to -+which the wireless chip is connected. -+ -+Required properties: -+- compatible: For PCI and PCIe devices this should be an identifier following -+ the format as defined in "PCI Bus Binding to Open Firmware" -+ Revision 2.1. One of the possible formats is "pciVVVV,DDDD" -+ where VVVV is the PCI vendor ID and DDDD is PCI device ID. -+ Typically QCA's PCI vendor ID 168c is used while the PCI device -+ ID depends on the chipset - see the following (possibly -+ incomplete) list: -+ - 0023 for AR5416 -+ - 0024 for AR5418 -+ - 0027 for AR9160 -+ - 0029 for AR9220 and AR9223 -+ - 002a for AR9280 and AR9283 -+ - 002b for AR9285 -+ - 002c for AR2427 -+ - 002d for AR9227 -+ - 002e for AR9287 -+ - 0030 for AR9380, AR9381 and AR9382 -+ - 0032 for AR9485 -+ - 0033 for AR9580 and AR9590 -+ - 0034 for AR9462 -+ - 0036 for AR9565 -+ - 0037 for AR9485 -+- reg: Address and length of the register set for the device. -+ -+Optional properties: -+- qca,no-eeprom: Indicates that there is no physical EEPROM connected to the -+ ath9k wireless chip (in this case the calibration / -+ EEPROM data will be loaded from userspace using the -+ kernel firmware loader). -+- mac-address: See ethernet.txt in the parent directory -+- local-mac-address: See ethernet.txt in the parent directory -+ -+ -+In this example, the node is defined as child node of the PCI controller: -+&pci0 { -+ wifi@168c,002d { -+ compatible = "pci168c,002d"; -+ reg = <0x7000 0 0 0 0x1000>; -+ qca,no-eeprom; -+ }; -+}; diff --git a/package/kernel/mac80211/patches/327-ath9k-add-a-helper-to-get-the-string-representation-.patch b/package/kernel/mac80211/patches/327-ath9k-add-a-helper-to-get-the-string-representation-.patch deleted file mode 100644 index c191495b84..0000000000 --- a/package/kernel/mac80211/patches/327-ath9k-add-a-helper-to-get-the-string-representation-.patch +++ /dev/null @@ -1,42 +0,0 @@ -From 25b8b2d57def4854558c135228a52326a7d346ad Mon Sep 17 00:00:00 2001 -From: Martin Blumenstingl -Date: Sun, 16 Oct 2016 22:59:06 +0200 -Subject: [PATCH 2/3] ath9k: add a helper to get the string representation of - ath_bus_type - -This can be used when the ath_bus_type has to be presented in a log -message or firmware filename. - -Signed-off-by: Martin Blumenstingl -Signed-off-by: Kalle Valo ---- - drivers/net/wireless/ath/ath.h | 6 ++++++ - drivers/net/wireless/ath/main.c | 7 +++++++ - 2 files changed, 13 insertions(+) - ---- a/drivers/net/wireless/ath/ath.h -+++ b/drivers/net/wireless/ath/ath.h -@@ -327,4 +327,10 @@ static inline const char *ath_opmode_to_ - } - #endif - -+extern const char *ath_bus_type_strings[]; -+static inline const char *ath_bus_type_to_string(enum ath_bus_type bustype) -+{ -+ return ath_bus_type_strings[bustype]; -+} -+ - #endif /* ATH_H */ ---- a/drivers/net/wireless/ath/main.c -+++ b/drivers/net/wireless/ath/main.c -@@ -90,3 +90,10 @@ void ath_printk(const char *level, const - va_end(args); - } - EXPORT_SYMBOL(ath_printk); -+ -+const char *ath_bus_type_strings[] = { -+ [ATH_PCI] = "pci", -+ [ATH_AHB] = "ahb", -+ [ATH_USB] = "usb", -+}; -+EXPORT_SYMBOL(ath_bus_type_strings); diff --git a/package/kernel/mac80211/patches/328-ath9k-parse-the-device-configuration-from-an-OF-node.patch b/package/kernel/mac80211/patches/328-ath9k-parse-the-device-configuration-from-an-OF-node.patch deleted file mode 100644 index b260858d45..0000000000 --- a/package/kernel/mac80211/patches/328-ath9k-parse-the-device-configuration-from-an-OF-node.patch +++ /dev/null @@ -1,85 +0,0 @@ -From cea03be5a848823cb8052e2e7b93cb2249d5f60c Mon Sep 17 00:00:00 2001 -From: Martin Blumenstingl -Date: Sun, 16 Oct 2016 22:59:07 +0200 -Subject: [PATCH 3/3] ath9k: parse the device configuration from an OF node - -This allows setting the MAC address and specifying that the firmware -will be requested from userspace (because there might not be a hardware -EEPROM connected to the chip) for ath9k based PCI devices using -the device tree. - -There is some out-of-tree code to "convert devicetree to -ath9k_platform_data" (for example in OpenWrt and LEDE) which becomes -obsolete with this patch. - -Signed-off-by: Martin Blumenstingl -Signed-off-by: Kalle Valo ---- - drivers/net/wireless/ath/ath9k/init.c | 42 +++++++++++++++++++++++++++++++++++ - 1 file changed, 42 insertions(+) - ---- a/drivers/net/wireless/ath/ath9k/init.c -+++ b/drivers/net/wireless/ath/ath9k/init.c -@@ -20,6 +20,8 @@ - #include - #include - #include -+#include -+#include - #include - #include - -@@ -554,6 +556,42 @@ static int ath9k_init_platform(struct at - return 0; - } - -+static int ath9k_of_init(struct ath_softc *sc) -+{ -+ struct device_node *np = sc->dev->of_node; -+ struct ath_hw *ah = sc->sc_ah; -+ struct ath_common *common = ath9k_hw_common(ah); -+ enum ath_bus_type bus_type = common->bus_ops->ath_bus_type; -+ const char *mac; -+ char eeprom_name[100]; -+ int ret; -+ -+ if (!of_device_is_available(np)) -+ return 0; -+ -+ ath_dbg(common, CONFIG, "parsing configuration from OF node\n"); -+ -+ if (of_property_read_bool(np, "qca,no-eeprom")) { -+ /* ath9k-eeprom--.bin */ -+ scnprintf(eeprom_name, sizeof(eeprom_name), -+ "ath9k-eeprom-%s-%s.bin", -+ ath_bus_type_to_string(bus_type), dev_name(ah->dev)); -+ -+ ret = ath9k_eeprom_request(sc, eeprom_name); -+ if (ret) -+ return ret; -+ } -+ -+ mac = of_get_mac_address(np); -+ if (mac) -+ ether_addr_copy(common->macaddr, mac); -+ -+ ah->ah_flags &= ~AH_USE_EEPROM; -+ ah->ah_flags |= AH_NO_EEP_SWAP; -+ -+ return 0; -+} -+ - static int ath9k_init_softc(u16 devid, struct ath_softc *sc, - const struct ath_bus_ops *bus_ops) - { -@@ -610,6 +648,10 @@ static int ath9k_init_softc(u16 devid, s - if (ret) - return ret; - -+ ret = ath9k_of_init(sc); -+ if (ret) -+ return ret; -+ - if (ath9k_led_active_high != -1) - ah->config.led_active_high = ath9k_led_active_high == 1; - diff --git a/package/kernel/mac80211/patches/329-ath9k-unlock-rcu-read-when-returning-early.patch b/package/kernel/mac80211/patches/329-ath9k-unlock-rcu-read-when-returning-early.patch deleted file mode 100644 index b8ba355899..0000000000 --- a/package/kernel/mac80211/patches/329-ath9k-unlock-rcu-read-when-returning-early.patch +++ /dev/null @@ -1,65 +0,0 @@ -From: Tobias Klausmann -Date: Mon, 12 Dec 2016 19:50:01 +0100 -Subject: [PATCH] ath9k: unlock rcu read when returning early - -Starting with ath9k: use ieee80211_tx_status_noskb where possible -[d94a461d7a7df68991fb9663531173f60ef89c68] the driver uses rcu_read_lock() && -rcu_read_unlock() yet on returning early in ath_tx_edma_tasklet() the unlock is -missing leading to stalls and suspicious RCU usage: - - =============================== - [ INFO: suspicious RCU usage. ] - 4.9.0-rc8 #11 Not tainted - ------------------------------- - kernel/rcu/tree.c:705 Illegal idle entry in RCU read-side critical section.! - - other info that might help us debug this: - - RCU used illegally from idle CPU! - rcu_scheduler_active = 1, debug_locks = 0 - RCU used illegally from extended quiescent state! - 1 lock held by swapper/7/0: - #0: - ( - rcu_read_lock - ){......} - , at: - [] ath_tx_edma_tasklet+0x0/0x450 [ath9k] - - stack backtrace: - CPU: 7 PID: 0 Comm: swapper/7 Not tainted 4.9.0-rc8 #11 - Hardware name: Acer Aspire V3-571G/VA50_HC_CR, BIOS V2.21 12/16/2013 - ffff88025efc3f38 ffffffff8132b1e5 ffff88017ede4540 0000000000000001 - ffff88025efc3f68 ffffffff810a25f7 ffff88025efcee60 ffff88017edebdd8 - ffff88025eeb5400 0000000000000091 ffff88025efc3f88 ffffffff810c3cd4 - Call Trace: - - [] dump_stack+0x68/0x93 - [] lockdep_rcu_suspicious+0xd7/0x110 - [] rcu_eqs_enter_common.constprop.85+0x154/0x200 - [] rcu_irq_exit+0x44/0xa0 - [] irq_exit+0x61/0xd0 - [] do_IRQ+0x65/0x110 - [] common_interrupt+0x89/0x89 - - [] ? cpuidle_enter_state+0x151/0x200 - [] cpuidle_enter+0x12/0x20 - [] call_cpuidle+0x1e/0x40 - [] cpu_startup_entry+0x146/0x220 - [] start_secondary+0x148/0x170 - -Signed-off-by: Tobias Klausmann -Signed-off-by: Felix Fietkau ---- - ---- a/drivers/net/wireless/ath/ath9k/xmit.c -+++ b/drivers/net/wireless/ath/ath9k/xmit.c -@@ -2757,7 +2757,7 @@ void ath_tx_edma_tasklet(struct ath_soft - fifo_list = &txq->txq_fifo[txq->txq_tailidx]; - if (list_empty(fifo_list)) { - ath_txq_unlock(sc, txq); -- return; -+ break; - } - - bf = list_first_entry(fifo_list, struct ath_buf, list); diff --git a/package/kernel/mac80211/patches/330-ath10k-wmi-alloc-chunk-should-use-DMA_BIDIRECTIONAL.patch b/package/kernel/mac80211/patches/330-ath10k-wmi-alloc-chunk-should-use-DMA_BIDIRECTIONAL.patch deleted file mode 100644 index 4ac9bcd7d4..0000000000 --- a/package/kernel/mac80211/patches/330-ath10k-wmi-alloc-chunk-should-use-DMA_BIDIRECTIONAL.patch +++ /dev/null @@ -1,27 +0,0 @@ -From: Ben Greear -Date: Tue, 29 Nov 2016 14:00:28 -0800 -Subject: [PATCH] ath10k: wmi-alloc-chunk should use DMA_BIDIRECTIONAL. - -These memory chunks are often used as 'swap' by the NIC, -so it will be both reading and writing to these areas. - -This seems to fix errors like this on my x86-64 machine: - -kernel: DMAR: DMAR:[DMA Write] Request device [05:00.0] fault addr ff5de000 - DMAR:[fault reason 05] PTE Write access is not set - -Tested-by: Marek Behun -Signed-off-by: Ben Greear ---- - ---- a/drivers/net/wireless/ath/ath10k/wmi.c -+++ b/drivers/net/wireless/ath/ath10k/wmi.c -@@ -4495,7 +4495,7 @@ static int ath10k_wmi_alloc_chunk(struct - if (!num_units) - return -ENOMEM; - -- paddr = dma_map_single(ar->dev, vaddr, pool_size, DMA_TO_DEVICE); -+ paddr = dma_map_single(ar->dev, vaddr, pool_size, DMA_BIDIRECTIONAL); - if (dma_mapping_error(ar->dev, paddr)) { - kfree(vaddr); - return -ENOMEM; diff --git a/package/kernel/mac80211/patches/331-ath10k-free-host-mem-with-DMA_BIRECTIONAL-flag.patch b/package/kernel/mac80211/patches/331-ath10k-free-host-mem-with-DMA_BIRECTIONAL-flag.patch deleted file mode 100644 index e203be0582..0000000000 --- a/package/kernel/mac80211/patches/331-ath10k-free-host-mem-with-DMA_BIRECTIONAL-flag.patch +++ /dev/null @@ -1,81 +0,0 @@ -From: Ben Greear -Date: Mon, 5 Dec 2016 10:28:39 -0800 -Subject: [PATCH] ath10k: free host-mem with DMA_BIRECTIONAL flag. - -Hopefully this fixes the problem reported by Kalle: - -Noticed this in my log, but I don't have time to investigate this in -detail right now: - -[ 413.795346] IPv6: ADDRCONF(NETDEV_UP): wlan0: link is not ready -[ 414.158755] IPv6: ADDRCONF(NETDEV_CHANGE): wlan0: link becomes ready -[ 477.439659] ath10k_pci 0000:02:00.0: could not get mac80211 beacon -[ 481.666630] ------------[ cut here ]------------ -[ 481.666669] WARNING: CPU: 0 PID: 1978 at lib/dma-debug.c:1155 check_unmap+0x320/0x8e0 -[ 481.666688] ath10k_pci 0000:02:00.0: DMA-API: device driver frees DMA memory with different direction [device address=0x000000002d130000] [size=63800 bytes] [mapped with DMA_BIDIRECTIONAL] [unmapped with DMA_TO_DEVICE] -[ 481.666703] Modules linked in: ctr ccm ath10k_pci(E-) ath10k_core(E) ath(E) mac80211(E) cfg80211(E) snd_hda_codec_hdmi snd_hda_codec_idt snd_hda_codec_generic snd_hda_intel snd_hda_codec snd_hda_core snd_hwdep snd_pcm snd_seq_midi arc4 snd_rawmidi snd_seq_midi_event snd_seq btusb btintel snd_seq_device joydev coret -[ 481.671468] CPU: 0 PID: 1978 Comm: rmmod Tainted: G E 4.9.0-rc7-wt+ #54 -[ 481.671478] Hardware name: Hewlett-Packard HP ProBook 6540b/1722, BIOS 68CDD Ver. F.04 01/27/2010 -[ 481.671489] ef49dcec c842ee92 c8b5830e ef49dd34 ef49dd20 c80850f5 c8b5a13c ef49dd50 -[ 481.671560] 000007ba c8b5830e 00000483 c8461830 c8461830 00000483 ef49ddcc f34e64b8 -[ 481.671641] c8b58360 ef49dd3c c80851bb 00000009 00000000 ef49dd34 c8b5a13c ef49dd50 -[ 481.671716] Call Trace: -[ 481.671731] [] dump_stack+0x76/0xb4 -[ 481.671745] [] __warn+0xe5/0x100 -[ 481.671757] [] ? check_unmap+0x320/0x8e0 -[ 481.671769] [] ? check_unmap+0x320/0x8e0 -[ 481.671780] [] warn_slowpath_fmt+0x3b/0x40 -[ 481.671791] [] check_unmap+0x320/0x8e0 -[ 481.671804] [] debug_dma_unmap_page+0x84/0xa0 -[ 481.671835] [] ath10k_wmi_free_host_mem+0x9a/0xe0 [ath10k_core] -[ 481.671861] [] ath10k_core_destroy+0x50/0x60 [ath10k_core] -[ 481.671875] [] ath10k_pci_remove+0x79/0xa0 [ath10k_pci] -[ 481.671889] [] pci_device_remove+0x38/0xb0 -[ 481.671901] [] __device_release_driver+0x7b/0x110 -[ 481.671913] [] driver_detach+0x97/0xa0 -[ 481.671923] [] bus_remove_driver+0x4b/0xb0 -[ 481.671934] [] driver_unregister+0x2a/0x60 -[ 481.671949] [] pci_unregister_driver+0x18/0x70 -[ 481.671965] [] ath10k_pci_exit+0xd/0x25f [ath10k_pci] -[ 481.671979] [] SyS_delete_module+0xf4/0x180 -[ 481.671995] [] ? __might_fault+0x8b/0xa0 -[ 481.672009] [] do_fast_syscall_32+0xa0/0x1e0 -[ 481.672025] [] sysenter_past_esp+0x45/0x74 -[ 481.672037] ---[ end trace 3fd23759e17e1622 ]--- -[ 481.672049] Mapped at: -[ 481.672060] [ 481.672072] [] debug_dma_map_page.part.25+0x1c/0xf0 -[ 481.672083] [ 481.672095] [] debug_dma_map_page+0x99/0xc0 -[ 481.672106] [ 481.672132] [] ath10k_wmi_alloc_chunk+0x12c/0x1f0 [ath10k_core] -[ 481.672142] [ 481.672168] [] ath10k_wmi_event_service_ready_work+0x304/0x540 [ath10k_core] -[ 481.672178] [ 481.672190] [] process_one_work+0x1c3/0x670 -[ 482.137134] ath10k_pci 0000:02:00.0: pci irq msi oper_irq_mode 2 irq_mode 0 reset_mode 0 -[ 482.313144] ath10k_pci 0000:02:00.0: Direct firmware load for ath10k/pre-cal-pci-0000:02:00.0.bin failed with error -2 -[ 482.313274] ath10k_pci 0000:02:00.0: Direct firmware load for ath10k/cal-pci-0000:02:00.0.bin failed with error -2 -[ 482.313768] ath10k_pci 0000:02:00.0: qca988x hw2.0 target 0x4100016c chip_id 0x043202ff sub 0000:0000 -[ 482.313777] ath10k_pci 0000:02:00.0: kconfig debug 1 debugfs 1 tracing 1 dfs 0 testmode 1 -[ 482.313974] ath10k_pci 0000:02:00.0: firmware ver 10.2.4.70.59-2 api 5 features no-p2p,raw-mode,mfp,allows-mesh-bcast crc32 4159f498 -[ 482.369858] ath10k_pci 0000:02:00.0: Direct firmware load for ath10k/QCA988X/hw2.0/board-2.bin failed with error -2 -[ 482.370011] ath10k_pci 0000:02:00.0: board_file api 1 bmi_id N/A crc32 bebc7c08 -[ 483.596770] ath10k_pci 0000:02:00.0: htt-ver 2.1 wmi-op 5 htt-op 2 cal otp max-sta 128 raw 0 hwcrypto 1 -[ 483.701686] ath: EEPROM regdomain: 0x0 -[ 483.701706] ath: EEPROM indicates default country code should be used -[ 483.701713] ath: doing EEPROM country->regdmn map search -[ 483.701721] ath: country maps to regdmn code: 0x3a -[ 483.701730] ath: Country alpha2 being used: US -[ 483.701737] ath: Regpair used: 0x3a - -Reported-by: Kalle Valo -Signed-off-by: Ben Greear ---- - ---- a/drivers/net/wireless/ath/ath10k/wmi.c -+++ b/drivers/net/wireless/ath/ath10k/wmi.c -@@ -8227,7 +8227,7 @@ void ath10k_wmi_free_host_mem(struct ath - dma_unmap_single(ar->dev, - ar->wmi.mem_chunks[i].paddr, - ar->wmi.mem_chunks[i].len, -- DMA_TO_DEVICE); -+ DMA_BIDIRECTIONAL); - kfree(ar->wmi.mem_chunks[i].vaddr); - } - diff --git a/package/kernel/mac80211/patches/332-ath10k-Fix-failure-to-send-NULL-func-frame-for-10.4.patch b/package/kernel/mac80211/patches/332-ath10k-Fix-failure-to-send-NULL-func-frame-for-10.4.patch deleted file mode 100644 index 76e6ccab72..0000000000 --- a/package/kernel/mac80211/patches/332-ath10k-Fix-failure-to-send-NULL-func-frame-for-10.4.patch +++ /dev/null @@ -1,42 +0,0 @@ -From: Mohammed Shafi Shajakhan -Date: Wed, 12 Oct 2016 12:59:02 +0530 -Subject: [PATCH] ath10k: Fix failure to send NULL func frame for 10.4 - -This partially reverts 'commit 2cdce425aa33 -("ath10k: Fix broken NULL func data frame status for 10.4")' -Unfortunately this breaks sending NULL func and the existing -issue of obtaining proper tx status for NULL function will be -fixed. Also update the comments for feature flag added to be -useless and not working - -Fixes: 2cdce425aa33 "ath10k: Fix broken NULL func data frame status for -10.4" -Signed-off-by: Mohammed Shafi Shajakhan ---- - ---- a/drivers/net/wireless/ath/ath10k/core.h -+++ b/drivers/net/wireless/ath/ath10k/core.h -@@ -556,10 +556,8 @@ enum ath10k_fw_features { - */ - ATH10K_FW_FEATURE_BTCOEX_PARAM = 14, - -- /* Older firmware with HTT delivers incorrect tx status for null func -- * frames to driver, but this fixed in 10.2 and 10.4 firmware versions. -- * Also this workaround results in reporting of incorrect null func -- * status for 10.4. This flag is used to skip the workaround. -+ /* Unused flag and proven to be not working, enable this if you want -+ * to experiment sending NULL func data frames in HTT TX - */ - ATH10K_FW_FEATURE_SKIP_NULL_FUNC_WAR = 15, - ---- a/drivers/net/wireless/ath/ath10k/mac.c -+++ b/drivers/net/wireless/ath/ath10k/mac.c -@@ -3274,8 +3274,6 @@ ath10k_mac_tx_h_get_txmode(struct ath10k - if (ar->htt.target_version_major < 3 && - (ieee80211_is_nullfunc(fc) || ieee80211_is_qos_nullfunc(fc)) && - !test_bit(ATH10K_FW_FEATURE_HAS_WMI_MGMT_TX, -- ar->running_fw->fw_file.fw_features) && -- !test_bit(ATH10K_FW_FEATURE_SKIP_NULL_FUNC_WAR, - ar->running_fw->fw_file.fw_features)) - return ATH10K_HW_TXRX_MGMT; - diff --git a/package/kernel/mac80211/patches/333-ath10k-Fix-soft-lockup-during-firmware-crash-hw-rest.patch b/package/kernel/mac80211/patches/333-ath10k-Fix-soft-lockup-during-firmware-crash-hw-rest.patch deleted file mode 100644 index 89ff1fcfd8..0000000000 --- a/package/kernel/mac80211/patches/333-ath10k-Fix-soft-lockup-during-firmware-crash-hw-rest.patch +++ /dev/null @@ -1,49 +0,0 @@ -From: Mohammed Shafi Shajakhan -Date: Wed, 30 Nov 2016 10:59:29 +0530 -Subject: [PATCH] ath10k: Fix soft lockup during firmware crash/hw-restart - -During firmware crash (or) user requested manual restart -the system gets into a soft lock up state because of the -below root cause. - -During user requested hardware restart / firmware crash -the system goes into a soft lockup state as 'napi_synchronize' -is called after 'napi_disable' (which sets 'NAPI_STATE_SCHED' -bit) and it sleeps into infinite loop as it waits for -'NAPI_STATE_SCHED' to be cleared. This condition is hit because -'ath10k_hif_stop' is called twice as below (resulting in calling -'napi_synchronize' after 'napi_disable') - -'ath10k_core_restart' -> 'ath10k_hif_stop' (ATH10K_STATE_ON) -> --> 'ieee80211_restart_hw' -> 'ath10k_start' -> 'ath10k_halt' -> -'ath10k_core_stop' -> 'ath10k_hif_stop' (ATH10K_STATE_RESTARTING) - -Fix this by calling 'ath10k_halt' in ath10k_core_restart itself -as it makes more sense before informing mac80211 to restart h/w -Also remove 'ath10k_halt' in ath10k_start for the state of 'restarting' - -Fixes: 3c97f5de1f28 ("ath10k: implement NAPI support") -Signed-off-by: Mohammed Shafi Shajakhan ---- - ---- a/drivers/net/wireless/ath/ath10k/core.c -+++ b/drivers/net/wireless/ath/ath10k/core.c -@@ -1534,7 +1534,7 @@ static void ath10k_core_restart(struct w - switch (ar->state) { - case ATH10K_STATE_ON: - ar->state = ATH10K_STATE_RESTARTING; -- ath10k_hif_stop(ar); -+ ath10k_halt(ar); - ath10k_scan_finish(ar); - ieee80211_restart_hw(ar->hw); - break; ---- a/drivers/net/wireless/ath/ath10k/mac.c -+++ b/drivers/net/wireless/ath/ath10k/mac.c -@@ -4470,7 +4470,6 @@ static int ath10k_start(struct ieee80211 - ar->state = ATH10K_STATE_ON; - break; - case ATH10K_STATE_RESTARTING: -- ath10k_halt(ar); - ar->state = ATH10K_STATE_RESTARTED; - break; - case ATH10K_STATE_ON: diff --git a/package/kernel/mac80211/patches/334-mac80211-minstrel_ht-move-supported-bitrate-mask-out.patch b/package/kernel/mac80211/patches/334-mac80211-minstrel_ht-move-supported-bitrate-mask-out.patch deleted file mode 100644 index 5e5992e6b4..0000000000 --- a/package/kernel/mac80211/patches/334-mac80211-minstrel_ht-move-supported-bitrate-mask-out.patch +++ /dev/null @@ -1,196 +0,0 @@ -From: Felix Fietkau -Date: Wed, 14 Dec 2016 19:33:23 +0100 -Subject: [PATCH] mac80211: minstrel_ht: move supported bitrate mask out of - group data - -Improves dcache footprint by ensuring that fewer cache lines need to be -touched. - -Signed-off-by: Felix Fietkau ---- - ---- a/net/mac80211/rc80211_minstrel_ht.c -+++ b/net/mac80211/rc80211_minstrel_ht.c -@@ -301,7 +301,7 @@ minstrel_ht_get_stats(struct minstrel_pr - break; - - /* short preamble */ -- if (!(mi->groups[group].supported & BIT(idx))) -+ if (!(mi->supported[group] & BIT(idx))) - idx += 4; - } - return &mi->groups[group].rates[idx]; -@@ -486,7 +486,7 @@ minstrel_ht_prob_rate_reduce_streams(str - MCS_GROUP_RATES].streams; - for (group = 0; group < ARRAY_SIZE(minstrel_mcs_groups); group++) { - mg = &mi->groups[group]; -- if (!mg->supported || group == MINSTREL_CCK_GROUP) -+ if (!mi->supported[group] || group == MINSTREL_CCK_GROUP) - continue; - - tmp_idx = mg->max_group_prob_rate % MCS_GROUP_RATES; -@@ -540,7 +540,7 @@ minstrel_ht_update_stats(struct minstrel - for (group = 0; group < ARRAY_SIZE(minstrel_mcs_groups); group++) { - - mg = &mi->groups[group]; -- if (!mg->supported) -+ if (!mi->supported[group]) - continue; - - mi->sample_count++; -@@ -550,7 +550,7 @@ minstrel_ht_update_stats(struct minstrel - tmp_group_tp_rate[j] = group; - - for (i = 0; i < MCS_GROUP_RATES; i++) { -- if (!(mg->supported & BIT(i))) -+ if (!(mi->supported[group] & BIT(i))) - continue; - - index = MCS_GROUP_RATES * group + i; -@@ -636,7 +636,7 @@ minstrel_set_next_sample_idx(struct mins - mi->sample_group %= ARRAY_SIZE(minstrel_mcs_groups); - mg = &mi->groups[mi->sample_group]; - -- if (!mg->supported) -+ if (!mi->supported[mi->sample_group]) - continue; - - if (++mg->index >= MCS_GROUP_RATES) { -@@ -657,7 +657,7 @@ minstrel_downgrade_rate(struct minstrel_ - while (group > 0) { - group--; - -- if (!mi->groups[group].supported) -+ if (!mi->supported[group]) - continue; - - if (minstrel_mcs_groups[group].streams > -@@ -994,7 +994,7 @@ minstrel_get_sample_rate(struct minstrel - sample_idx = sample_table[mg->column][mg->index]; - minstrel_set_next_sample_idx(mi); - -- if (!(mg->supported & BIT(sample_idx))) -+ if (!(mi->supported[sample_group] & BIT(sample_idx))) - return -1; - - mrs = &mg->rates[sample_idx]; -@@ -1052,7 +1052,7 @@ static void - minstrel_ht_check_cck_shortpreamble(struct minstrel_priv *mp, - struct minstrel_ht_sta *mi, bool val) - { -- u8 supported = mi->groups[MINSTREL_CCK_GROUP].supported; -+ u8 supported = mi->supported[MINSTREL_CCK_GROUP]; - - if (!supported || !mi->cck_supported_short) - return; -@@ -1061,7 +1061,7 @@ minstrel_ht_check_cck_shortpreamble(stru - return; - - supported ^= mi->cck_supported_short | (mi->cck_supported_short << 4); -- mi->groups[MINSTREL_CCK_GROUP].supported = supported; -+ mi->supported[MINSTREL_CCK_GROUP] = supported; - } - - static void -@@ -1154,7 +1154,7 @@ minstrel_ht_update_cck(struct minstrel_p - mi->cck_supported_short |= BIT(i); - } - -- mi->groups[MINSTREL_CCK_GROUP].supported = mi->cck_supported; -+ mi->supported[MINSTREL_CCK_GROUP] = mi->cck_supported; - } - - static void -@@ -1233,7 +1233,7 @@ minstrel_ht_update_caps(void *priv, stru - u32 gflags = minstrel_mcs_groups[i].flags; - int bw, nss; - -- mi->groups[i].supported = 0; -+ mi->supported[i] = 0; - if (i == MINSTREL_CCK_GROUP) { - minstrel_ht_update_cck(mp, mi, sband, sta); - continue; -@@ -1265,8 +1265,8 @@ minstrel_ht_update_caps(void *priv, stru - if (use_vht && minstrel_vht_only) - continue; - #endif -- mi->groups[i].supported = mcs->rx_mask[nss - 1]; -- if (mi->groups[i].supported) -+ mi->supported[i] = mcs->rx_mask[nss - 1]; -+ if (mi->supported[i]) - n_supported++; - continue; - } -@@ -1292,10 +1292,10 @@ minstrel_ht_update_caps(void *priv, stru - else - bw = BW_20; - -- mi->groups[i].supported = minstrel_get_valid_vht_rates(bw, nss, -+ mi->supported[i] = minstrel_get_valid_vht_rates(bw, nss, - vht_cap->vht_mcs.tx_mcs_map); - -- if (mi->groups[i].supported) -+ if (mi->supported[i]) - n_supported++; - } - ---- a/net/mac80211/rc80211_minstrel_ht.h -+++ b/net/mac80211/rc80211_minstrel_ht.h -@@ -52,9 +52,6 @@ struct minstrel_mcs_group_data { - u8 index; - u8 column; - -- /* bitfield of supported MCS rates of this group */ -- u16 supported; -- - /* sorted rate set within a MCS group*/ - u16 max_group_tp_rate[MAX_THR_RATES]; - u16 max_group_prob_rate; -@@ -101,6 +98,9 @@ struct minstrel_ht_sta { - u8 cck_supported; - u8 cck_supported_short; - -+ /* Bitfield of supported MCS rates of all groups */ -+ u16 supported[MINSTREL_GROUPS_NB]; -+ - /* MCS rate group info and statistics */ - struct minstrel_mcs_group_data groups[MINSTREL_GROUPS_NB]; - }; ---- a/net/mac80211/rc80211_minstrel_ht_debugfs.c -+++ b/net/mac80211/rc80211_minstrel_ht_debugfs.c -@@ -24,7 +24,7 @@ minstrel_ht_stats_dump(struct minstrel_h - char gimode = 'L'; - u32 gflags; - -- if (!mi->groups[i].supported) -+ if (!mi->supported[i]) - return p; - - mg = &minstrel_mcs_groups[i]; -@@ -42,7 +42,7 @@ minstrel_ht_stats_dump(struct minstrel_h - static const int bitrates[4] = { 10, 20, 55, 110 }; - int idx = i * MCS_GROUP_RATES + j; - -- if (!(mi->groups[i].supported & BIT(j))) -+ if (!(mi->supported[i] & BIT(j))) - continue; - - if (gflags & IEEE80211_TX_RC_MCS) { -@@ -170,7 +170,7 @@ minstrel_ht_stats_csv_dump(struct minstr - char gimode = 'L'; - u32 gflags; - -- if (!mi->groups[i].supported) -+ if (!mi->supported[i]) - return p; - - mg = &minstrel_mcs_groups[i]; -@@ -188,7 +188,7 @@ minstrel_ht_stats_csv_dump(struct minstr - static const int bitrates[4] = { 10, 20, 55, 110 }; - int idx = i * MCS_GROUP_RATES + j; - -- if (!(mi->groups[i].supported & BIT(j))) -+ if (!(mi->supported[i] & BIT(j))) - continue; - - if (gflags & IEEE80211_TX_RC_MCS) { diff --git a/package/kernel/mac80211/patches/335-mac80211-minstrel_ht-move-short-preamble-check-out-o.patch b/package/kernel/mac80211/patches/335-mac80211-minstrel_ht-move-short-preamble-check-out-o.patch deleted file mode 100644 index 7a6e8cdb91..0000000000 --- a/package/kernel/mac80211/patches/335-mac80211-minstrel_ht-move-short-preamble-check-out-o.patch +++ /dev/null @@ -1,70 +0,0 @@ -From: Felix Fietkau -Date: Wed, 14 Dec 2016 20:06:08 +0100 -Subject: [PATCH] mac80211: minstrel_ht: move short preamble check out of - get_rate - -Test short preamble support in minstrel_ht_update_caps instead of -looking at the per-packet flag. Makes the code more efficient. - -Signed-off-by: Felix Fietkau ---- - ---- a/net/mac80211/rc80211_minstrel_ht.c -+++ b/net/mac80211/rc80211_minstrel_ht.c -@@ -14,6 +14,7 @@ - #include - #include - #include "rate.h" -+#include "sta_info.h" - #include "rc80211_minstrel.h" - #include "rc80211_minstrel_ht.h" - -@@ -1049,22 +1050,6 @@ minstrel_get_sample_rate(struct minstrel - } - - static void --minstrel_ht_check_cck_shortpreamble(struct minstrel_priv *mp, -- struct minstrel_ht_sta *mi, bool val) --{ -- u8 supported = mi->supported[MINSTREL_CCK_GROUP]; -- -- if (!supported || !mi->cck_supported_short) -- return; -- -- if (supported & (mi->cck_supported_short << (val * 4))) -- return; -- -- supported ^= mi->cck_supported_short | (mi->cck_supported_short << 4); -- mi->supported[MINSTREL_CCK_GROUP] = supported; --} -- --static void - minstrel_ht_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta, - struct ieee80211_tx_rate_control *txrc) - { -@@ -1087,7 +1072,6 @@ minstrel_ht_get_rate(void *priv, struct - minstrel_aggr_check(sta, txrc->skb); - - info->flags |= mi->tx_flags; -- minstrel_ht_check_cck_shortpreamble(mp, mi, txrc->short_preamble); - - #ifdef CPTCFG_MAC80211_DEBUGFS - if (mp->fixed_rate_idx != -1) -@@ -1168,6 +1152,7 @@ minstrel_ht_update_caps(void *priv, stru - struct ieee80211_mcs_info *mcs = &sta->ht_cap.mcs; - u16 ht_cap = sta->ht_cap.cap; - struct ieee80211_sta_vht_cap *vht_cap = &sta->vht_cap; -+ struct sta_info *sinfo = container_of(sta, struct sta_info, sta); - int use_vht; - int n_supported = 0; - int ack_dur; -@@ -1302,6 +1287,9 @@ minstrel_ht_update_caps(void *priv, stru - if (!n_supported) - goto use_legacy; - -+ if (test_sta_flag(sinfo, WLAN_STA_SHORT_PREAMBLE)) -+ mi->cck_supported_short |= mi->cck_supported_short << 4; -+ - /* create an initial rate table with the lowest supported rates */ - minstrel_ht_update_stats(mp, mi); - minstrel_ht_update_rates(mp, mi); diff --git a/package/kernel/mac80211/patches/336-mac80211-minstrel_ht-make-att_hist-and-succ_hist-u32.patch b/package/kernel/mac80211/patches/336-mac80211-minstrel_ht-make-att_hist-and-succ_hist-u32.patch deleted file mode 100644 index 40d03001c6..0000000000 --- a/package/kernel/mac80211/patches/336-mac80211-minstrel_ht-make-att_hist-and-succ_hist-u32.patch +++ /dev/null @@ -1,22 +0,0 @@ -From: Felix Fietkau -Date: Wed, 14 Dec 2016 20:09:14 +0100 -Subject: [PATCH] mac80211: minstrel_ht: make att_hist and succ_hist u32 - instead of u64 - -They are only used for debugging purposes and take a very long time to -overflow. Visibly reduces the size of the per-sta rate control data. - -Signed-off-by: Felix Fietkau ---- - ---- a/net/mac80211/rc80211_minstrel.h -+++ b/net/mac80211/rc80211_minstrel.h -@@ -59,7 +59,7 @@ struct minstrel_rate_stats { - u16 success, last_success; - - /* total attempts/success counters */ -- u64 att_hist, succ_hist; -+ u32 att_hist, succ_hist; - - /* statistis of packet delivery probability - * cur_prob - current prob within last update intervall diff --git a/package/kernel/mac80211/patches/337-mac80211-check-for-MCS-in-ieee80211_duration-before-.patch b/package/kernel/mac80211/patches/337-mac80211-check-for-MCS-in-ieee80211_duration-before-.patch deleted file mode 100644 index 066e1d1445..0000000000 --- a/package/kernel/mac80211/patches/337-mac80211-check-for-MCS-in-ieee80211_duration-before-.patch +++ /dev/null @@ -1,34 +0,0 @@ -From: Felix Fietkau -Date: Wed, 14 Dec 2016 20:12:25 +0100 -Subject: [PATCH] mac80211: check for MCS in ieee80211_duration before fetching - chanctx - -Makes the code a bit more efficient - -Signed-off-by: Felix Fietkau ---- - ---- a/net/mac80211/tx.c -+++ b/net/mac80211/tx.c -@@ -63,6 +63,10 @@ static __le16 ieee80211_duration(struct - struct ieee80211_chanctx_conf *chanctx_conf; - u32 rate_flags = 0; - -+ /* assume HW handles this */ -+ if (tx->rate.flags & (IEEE80211_TX_RC_MCS | IEEE80211_TX_RC_VHT_MCS)) -+ return 0; -+ - rcu_read_lock(); - chanctx_conf = rcu_dereference(tx->sdata->vif.chanctx_conf); - if (chanctx_conf) { -@@ -71,10 +75,6 @@ static __le16 ieee80211_duration(struct - } - rcu_read_unlock(); - -- /* assume HW handles this */ -- if (tx->rate.flags & (IEEE80211_TX_RC_MCS | IEEE80211_TX_RC_VHT_MCS)) -- return 0; -- - /* uh huh? */ - if (WARN_ON_ONCE(tx->rate.idx < 0)) - return 0; diff --git a/package/kernel/mac80211/patches/338-mac80211-minstrel-remove-cur_prob-from-debugfs.patch b/package/kernel/mac80211/patches/338-mac80211-minstrel-remove-cur_prob-from-debugfs.patch deleted file mode 100644 index f25b0a8a8c..0000000000 --- a/package/kernel/mac80211/patches/338-mac80211-minstrel-remove-cur_prob-from-debugfs.patch +++ /dev/null @@ -1,192 +0,0 @@ -From: Felix Fietkau -Date: Wed, 14 Dec 2016 20:13:58 +0100 -Subject: [PATCH] mac80211: minstrel: remove cur_prob from debugfs - -This field is redundant, because it is simply last success divided by -last attempt count. Removing it from the rate stats struct saves about -1.2 KiB per HT station. - -Signed-off-by: Felix Fietkau ---- - ---- a/net/mac80211/rc80211_minstrel.c -+++ b/net/mac80211/rc80211_minstrel.c -@@ -159,21 +159,23 @@ minstrel_update_rates(struct minstrel_pr - void - minstrel_calc_rate_stats(struct minstrel_rate_stats *mrs) - { -+ unsigned int cur_prob; -+ - if (unlikely(mrs->attempts > 0)) { - mrs->sample_skipped = 0; -- mrs->cur_prob = MINSTREL_FRAC(mrs->success, mrs->attempts); -+ cur_prob = MINSTREL_FRAC(mrs->success, mrs->attempts); - if (unlikely(!mrs->att_hist)) { -- mrs->prob_ewma = mrs->cur_prob; -+ mrs->prob_ewma = cur_prob; - } else { - /* update exponential weighted moving variance */ - mrs->prob_ewmsd = minstrel_ewmsd(mrs->prob_ewmsd, -- mrs->cur_prob, -+ cur_prob, - mrs->prob_ewma, - EWMA_LEVEL); - - /*update exponential weighted moving avarage */ - mrs->prob_ewma = minstrel_ewma(mrs->prob_ewma, -- mrs->cur_prob, -+ cur_prob, - EWMA_LEVEL); - } - mrs->att_hist += mrs->attempts; ---- a/net/mac80211/rc80211_minstrel.h -+++ b/net/mac80211/rc80211_minstrel.h -@@ -62,10 +62,8 @@ struct minstrel_rate_stats { - u32 att_hist, succ_hist; - - /* statistis of packet delivery probability -- * cur_prob - current prob within last update intervall - * prob_ewma - exponential weighted moving average of prob - * prob_ewmsd - exp. weighted moving standard deviation of prob */ -- unsigned int cur_prob; - unsigned int prob_ewma; - u16 prob_ewmsd; - ---- a/net/mac80211/rc80211_minstrel_debugfs.c -+++ b/net/mac80211/rc80211_minstrel_debugfs.c -@@ -75,7 +75,7 @@ minstrel_stats_open(struct inode *inode, - { - struct minstrel_sta_info *mi = inode->i_private; - struct minstrel_debugfs_info *ms; -- unsigned int i, tp_max, tp_avg, prob, eprob; -+ unsigned int i, tp_max, tp_avg, eprob; - char *p; - - ms = kmalloc(2048, GFP_KERNEL); -@@ -86,9 +86,9 @@ minstrel_stats_open(struct inode *inode, - p = ms->buf; - p += sprintf(p, "\n"); - p += sprintf(p, -- "best __________rate_________ ________statistics________ ________last_______ ______sum-of________\n"); -+ "best __________rate_________ ________statistics________ ____last_____ ______sum-of________\n"); - p += sprintf(p, -- "rate [name idx airtime max_tp] [avg(tp) avg(prob) sd(prob)] [prob.|retry|suc|att] [#success | #attempts]\n"); -+ "rate [name idx airtime max_tp] [avg(tp) avg(prob) sd(prob)] [retry|suc|att] [#success | #attempts]\n"); - - for (i = 0; i < mi->n_rates; i++) { - struct minstrel_rate *mr = &mi->r[i]; -@@ -107,17 +107,15 @@ minstrel_stats_open(struct inode *inode, - - tp_max = minstrel_get_tp_avg(mr, MINSTREL_FRAC(100,100)); - tp_avg = minstrel_get_tp_avg(mr, mrs->prob_ewma); -- prob = MINSTREL_TRUNC(mrs->cur_prob * 1000); - eprob = MINSTREL_TRUNC(mrs->prob_ewma * 1000); - - p += sprintf(p, "%4u.%1u %4u.%1u %3u.%1u %3u.%1u" -- " %3u.%1u %3u %3u %-3u " -+ " %3u %3u %-3u " - "%9llu %-9llu\n", - tp_max / 10, tp_max % 10, - tp_avg / 10, tp_avg % 10, - eprob / 10, eprob % 10, - mrs->prob_ewmsd / 10, mrs->prob_ewmsd % 10, -- prob / 10, prob % 10, - mrs->retry_count, - mrs->last_success, - mrs->last_attempts, -@@ -148,7 +146,7 @@ minstrel_stats_csv_open(struct inode *in - { - struct minstrel_sta_info *mi = inode->i_private; - struct minstrel_debugfs_info *ms; -- unsigned int i, tp_max, tp_avg, prob, eprob; -+ unsigned int i, tp_max, tp_avg, eprob; - char *p; - - ms = kmalloc(2048, GFP_KERNEL); -@@ -175,16 +173,14 @@ minstrel_stats_csv_open(struct inode *in - - tp_max = minstrel_get_tp_avg(mr, MINSTREL_FRAC(100,100)); - tp_avg = minstrel_get_tp_avg(mr, mrs->prob_ewma); -- prob = MINSTREL_TRUNC(mrs->cur_prob * 1000); - eprob = MINSTREL_TRUNC(mrs->prob_ewma * 1000); - -- p += sprintf(p, "%u.%u,%u.%u,%u.%u,%u.%u,%u.%u,%u,%u,%u," -+ p += sprintf(p, "%u.%u,%u.%u,%u.%u,%u.%u,%u,%u,%u," - "%llu,%llu,%d,%d\n", - tp_max / 10, tp_max % 10, - tp_avg / 10, tp_avg % 10, - eprob / 10, eprob % 10, - mrs->prob_ewmsd / 10, mrs->prob_ewmsd % 10, -- prob / 10, prob % 10, - mrs->retry_count, - mrs->last_success, - mrs->last_attempts, ---- a/net/mac80211/rc80211_minstrel_ht_debugfs.c -+++ b/net/mac80211/rc80211_minstrel_ht_debugfs.c -@@ -19,7 +19,7 @@ static char * - minstrel_ht_stats_dump(struct minstrel_ht_sta *mi, int i, char *p) - { - const struct mcs_group *mg; -- unsigned int j, tp_max, tp_avg, prob, eprob, tx_time; -+ unsigned int j, tp_max, tp_avg, eprob, tx_time; - char htmode = '2'; - char gimode = 'L'; - u32 gflags; -@@ -83,17 +83,15 @@ minstrel_ht_stats_dump(struct minstrel_h - - tp_max = minstrel_ht_get_tp_avg(mi, i, j, MINSTREL_FRAC(100, 100)); - tp_avg = minstrel_ht_get_tp_avg(mi, i, j, mrs->prob_ewma); -- prob = MINSTREL_TRUNC(mrs->cur_prob * 1000); - eprob = MINSTREL_TRUNC(mrs->prob_ewma * 1000); - - p += sprintf(p, "%4u.%1u %4u.%1u %3u.%1u %3u.%1u" -- " %3u.%1u %3u %3u %-3u " -+ " %3u %3u %-3u " - "%9llu %-9llu\n", - tp_max / 10, tp_max % 10, - tp_avg / 10, tp_avg % 10, - eprob / 10, eprob % 10, - mrs->prob_ewmsd / 10, mrs->prob_ewmsd % 10, -- prob / 10, prob % 10, - mrs->retry_count, - mrs->last_success, - mrs->last_attempts, -@@ -130,9 +128,9 @@ minstrel_ht_stats_open(struct inode *ino - - p += sprintf(p, "\n"); - p += sprintf(p, -- " best ____________rate__________ ________statistics________ ________last_______ ______sum-of________\n"); -+ " best ____________rate__________ ________statistics________ _____last____ ______sum-of________\n"); - p += sprintf(p, -- "mode guard # rate [name idx airtime max_tp] [avg(tp) avg(prob) sd(prob)] [prob.|retry|suc|att] [#success | #attempts]\n"); -+ "mode guard # rate [name idx airtime max_tp] [avg(tp) avg(prob) sd(prob)] [retry|suc|att] [#success | #attempts]\n"); - - p = minstrel_ht_stats_dump(mi, MINSTREL_CCK_GROUP, p); - for (i = 0; i < MINSTREL_CCK_GROUP; i++) -@@ -165,7 +163,7 @@ static char * - minstrel_ht_stats_csv_dump(struct minstrel_ht_sta *mi, int i, char *p) - { - const struct mcs_group *mg; -- unsigned int j, tp_max, tp_avg, prob, eprob, tx_time; -+ unsigned int j, tp_max, tp_avg, eprob, tx_time; - char htmode = '2'; - char gimode = 'L'; - u32 gflags; -@@ -226,16 +224,14 @@ minstrel_ht_stats_csv_dump(struct minstr - - tp_max = minstrel_ht_get_tp_avg(mi, i, j, MINSTREL_FRAC(100, 100)); - tp_avg = minstrel_ht_get_tp_avg(mi, i, j, mrs->prob_ewma); -- prob = MINSTREL_TRUNC(mrs->cur_prob * 1000); - eprob = MINSTREL_TRUNC(mrs->prob_ewma * 1000); - -- p += sprintf(p, "%u.%u,%u.%u,%u.%u,%u.%u,%u.%u,%u,%u," -+ p += sprintf(p, "%u.%u,%u.%u,%u.%u,%u.%u,%u,%u," - "%u,%llu,%llu,", - tp_max / 10, tp_max % 10, - tp_avg / 10, tp_avg % 10, - eprob / 10, eprob % 10, - mrs->prob_ewmsd / 10, mrs->prob_ewmsd % 10, -- prob / 10, prob % 10, - mrs->retry_count, - mrs->last_success, - mrs->last_attempts, diff --git a/package/kernel/mac80211/patches/339-mac80211-minstrel-reduce-MINSTREL_SCALE.patch b/package/kernel/mac80211/patches/339-mac80211-minstrel-reduce-MINSTREL_SCALE.patch deleted file mode 100644 index 0416cf5900..0000000000 --- a/package/kernel/mac80211/patches/339-mac80211-minstrel-reduce-MINSTREL_SCALE.patch +++ /dev/null @@ -1,22 +0,0 @@ -From: Felix Fietkau -Date: Wed, 14 Dec 2016 20:15:33 +0100 -Subject: [PATCH] mac80211: minstrel: reduce MINSTREL_SCALE - -The loss of a bit of extra precision does not hurt the calculation, 12 -bits is still enough to calculate probabilities well. Reducing the scale -makes it easier to avoid overflows - -Signed-off-by: Felix Fietkau ---- - ---- a/net/mac80211/rc80211_minstrel.h -+++ b/net/mac80211/rc80211_minstrel.h -@@ -14,7 +14,7 @@ - #define SAMPLE_COLUMNS 10 /* number of columns in sample table */ - - /* scaled fraction values */ --#define MINSTREL_SCALE 16 -+#define MINSTREL_SCALE 12 - #define MINSTREL_FRAC(val, div) (((val) << MINSTREL_SCALE) / div) - #define MINSTREL_TRUNC(val) ((val) >> MINSTREL_SCALE) - diff --git a/package/kernel/mac80211/patches/340-mac80211-minstrel-store-probability-variance-instead.patch b/package/kernel/mac80211/patches/340-mac80211-minstrel-store-probability-variance-instead.patch deleted file mode 100644 index f679a43224..0000000000 --- a/package/kernel/mac80211/patches/340-mac80211-minstrel-store-probability-variance-instead.patch +++ /dev/null @@ -1,186 +0,0 @@ -From: Felix Fietkau -Date: Wed, 14 Dec 2016 20:17:06 +0100 -Subject: [PATCH] mac80211: minstrel: store probability variance instead of - standard deviation - -This avoids the costly int_sqrt calls in the statistics update and moves -it to the debugfs code instead. -This also fixes an overflow in the previous standard deviation -calculation. - -Signed-off-by: Thomas Huehn -Signed-off-by: Felix Fietkau ---- - ---- a/net/mac80211/rc80211_minstrel.c -+++ b/net/mac80211/rc80211_minstrel.c -@@ -168,10 +168,10 @@ minstrel_calc_rate_stats(struct minstrel - mrs->prob_ewma = cur_prob; - } else { - /* update exponential weighted moving variance */ -- mrs->prob_ewmsd = minstrel_ewmsd(mrs->prob_ewmsd, -- cur_prob, -- mrs->prob_ewma, -- EWMA_LEVEL); -+ mrs->prob_ewmv = minstrel_ewmv(mrs->prob_ewmv, -+ cur_prob, -+ mrs->prob_ewma, -+ EWMA_LEVEL); - - /*update exponential weighted moving avarage */ - mrs->prob_ewma = minstrel_ewma(mrs->prob_ewma, ---- a/net/mac80211/rc80211_minstrel.h -+++ b/net/mac80211/rc80211_minstrel.h -@@ -36,21 +36,16 @@ minstrel_ewma(int old, int new, int weig - } - - /* -- * Perform EWMSD (Exponentially Weighted Moving Standard Deviation) calculation -+ * Perform EWMV (Exponentially Weighted Moving Variance) calculation - */ - static inline int --minstrel_ewmsd(int old_ewmsd, int cur_prob, int prob_ewma, int weight) -+minstrel_ewmv(int old_ewmv, int cur_prob, int prob_ewma, int weight) - { -- int diff, incr, tmp_var; -+ int diff, incr; - -- /* calculate exponential weighted moving variance */ -- diff = MINSTREL_TRUNC((cur_prob - prob_ewma) * 1000000); -+ diff = cur_prob - prob_ewma; - incr = (EWMA_DIV - weight) * diff / EWMA_DIV; -- tmp_var = old_ewmsd * old_ewmsd; -- tmp_var = weight * (tmp_var + diff * incr / 1000000) / EWMA_DIV; -- -- /* return standard deviation */ -- return (u16) int_sqrt(tmp_var); -+ return weight * (old_ewmv + MINSTREL_TRUNC(diff * incr)) / EWMA_DIV; - } - - struct minstrel_rate_stats { -@@ -65,7 +60,7 @@ struct minstrel_rate_stats { - * prob_ewma - exponential weighted moving average of prob - * prob_ewmsd - exp. weighted moving standard deviation of prob */ - unsigned int prob_ewma; -- u16 prob_ewmsd; -+ u16 prob_ewmv; - - /* maximum retry counts */ - u8 retry_count; -@@ -151,6 +146,14 @@ struct minstrel_debugfs_info { - char buf[]; - }; - -+/* Get EWMSD (Exponentially Weighted Moving Standard Deviation) * 10 */ -+static inline int -+minstrel_get_ewmsd10(struct minstrel_rate_stats *mrs) -+{ -+ unsigned int ewmv = mrs->prob_ewmv; -+ return int_sqrt(MINSTREL_TRUNC(ewmv * 1000 * 1000)); -+} -+ - extern const struct rate_control_ops mac80211_minstrel; - void minstrel_add_sta_debugfs(void *priv, void *priv_sta, struct dentry *dir); - void minstrel_remove_sta_debugfs(void *priv, void *priv_sta); ---- a/net/mac80211/rc80211_minstrel_debugfs.c -+++ b/net/mac80211/rc80211_minstrel_debugfs.c -@@ -93,6 +93,7 @@ minstrel_stats_open(struct inode *inode, - for (i = 0; i < mi->n_rates; i++) { - struct minstrel_rate *mr = &mi->r[i]; - struct minstrel_rate_stats *mrs = &mi->r[i].stats; -+ unsigned int prob_ewmsd; - - *(p++) = (i == mi->max_tp_rate[0]) ? 'A' : ' '; - *(p++) = (i == mi->max_tp_rate[1]) ? 'B' : ' '; -@@ -108,6 +109,7 @@ minstrel_stats_open(struct inode *inode, - tp_max = minstrel_get_tp_avg(mr, MINSTREL_FRAC(100,100)); - tp_avg = minstrel_get_tp_avg(mr, mrs->prob_ewma); - eprob = MINSTREL_TRUNC(mrs->prob_ewma * 1000); -+ prob_ewmsd = minstrel_get_ewmsd10(mrs); - - p += sprintf(p, "%4u.%1u %4u.%1u %3u.%1u %3u.%1u" - " %3u %3u %-3u " -@@ -115,7 +117,7 @@ minstrel_stats_open(struct inode *inode, - tp_max / 10, tp_max % 10, - tp_avg / 10, tp_avg % 10, - eprob / 10, eprob % 10, -- mrs->prob_ewmsd / 10, mrs->prob_ewmsd % 10, -+ prob_ewmsd / 10, prob_ewmsd % 10, - mrs->retry_count, - mrs->last_success, - mrs->last_attempts, -@@ -159,6 +161,7 @@ minstrel_stats_csv_open(struct inode *in - for (i = 0; i < mi->n_rates; i++) { - struct minstrel_rate *mr = &mi->r[i]; - struct minstrel_rate_stats *mrs = &mi->r[i].stats; -+ unsigned int prob_ewmsd; - - p += sprintf(p, "%s" ,((i == mi->max_tp_rate[0]) ? "A" : "")); - p += sprintf(p, "%s" ,((i == mi->max_tp_rate[1]) ? "B" : "")); -@@ -174,13 +177,14 @@ minstrel_stats_csv_open(struct inode *in - tp_max = minstrel_get_tp_avg(mr, MINSTREL_FRAC(100,100)); - tp_avg = minstrel_get_tp_avg(mr, mrs->prob_ewma); - eprob = MINSTREL_TRUNC(mrs->prob_ewma * 1000); -+ prob_ewmsd = minstrel_get_ewmsd10(mrs); - - p += sprintf(p, "%u.%u,%u.%u,%u.%u,%u.%u,%u,%u,%u," - "%llu,%llu,%d,%d\n", - tp_max / 10, tp_max % 10, - tp_avg / 10, tp_avg % 10, - eprob / 10, eprob % 10, -- mrs->prob_ewmsd / 10, mrs->prob_ewmsd % 10, -+ prob_ewmsd / 10, prob_ewmsd % 10, - mrs->retry_count, - mrs->last_success, - mrs->last_attempts, ---- a/net/mac80211/rc80211_minstrel_ht_debugfs.c -+++ b/net/mac80211/rc80211_minstrel_ht_debugfs.c -@@ -41,6 +41,7 @@ minstrel_ht_stats_dump(struct minstrel_h - struct minstrel_rate_stats *mrs = &mi->groups[i].rates[j]; - static const int bitrates[4] = { 10, 20, 55, 110 }; - int idx = i * MCS_GROUP_RATES + j; -+ unsigned int prob_ewmsd; - - if (!(mi->supported[i] & BIT(j))) - continue; -@@ -84,6 +85,7 @@ minstrel_ht_stats_dump(struct minstrel_h - tp_max = minstrel_ht_get_tp_avg(mi, i, j, MINSTREL_FRAC(100, 100)); - tp_avg = minstrel_ht_get_tp_avg(mi, i, j, mrs->prob_ewma); - eprob = MINSTREL_TRUNC(mrs->prob_ewma * 1000); -+ prob_ewmsd = minstrel_get_ewmsd10(mrs); - - p += sprintf(p, "%4u.%1u %4u.%1u %3u.%1u %3u.%1u" - " %3u %3u %-3u " -@@ -91,7 +93,7 @@ minstrel_ht_stats_dump(struct minstrel_h - tp_max / 10, tp_max % 10, - tp_avg / 10, tp_avg % 10, - eprob / 10, eprob % 10, -- mrs->prob_ewmsd / 10, mrs->prob_ewmsd % 10, -+ prob_ewmsd / 10, prob_ewmsd % 10, - mrs->retry_count, - mrs->last_success, - mrs->last_attempts, -@@ -185,6 +187,7 @@ minstrel_ht_stats_csv_dump(struct minstr - struct minstrel_rate_stats *mrs = &mi->groups[i].rates[j]; - static const int bitrates[4] = { 10, 20, 55, 110 }; - int idx = i * MCS_GROUP_RATES + j; -+ unsigned int prob_ewmsd; - - if (!(mi->supported[i] & BIT(j))) - continue; -@@ -225,13 +228,14 @@ minstrel_ht_stats_csv_dump(struct minstr - tp_max = minstrel_ht_get_tp_avg(mi, i, j, MINSTREL_FRAC(100, 100)); - tp_avg = minstrel_ht_get_tp_avg(mi, i, j, mrs->prob_ewma); - eprob = MINSTREL_TRUNC(mrs->prob_ewma * 1000); -+ prob_ewmsd = minstrel_get_ewmsd10(mrs); - - p += sprintf(p, "%u.%u,%u.%u,%u.%u,%u.%u,%u,%u," - "%u,%llu,%llu,", - tp_max / 10, tp_max % 10, - tp_avg / 10, tp_avg % 10, - eprob / 10, eprob % 10, -- mrs->prob_ewmsd / 10, mrs->prob_ewmsd % 10, -+ prob_ewmsd / 10, prob_ewmsd % 10, - mrs->retry_count, - mrs->last_success, - mrs->last_attempts, diff --git a/package/kernel/mac80211/patches/341-mac80211-minstrel-make-prob_ewma-u16-instead-of-u32.patch b/package/kernel/mac80211/patches/341-mac80211-minstrel-make-prob_ewma-u16-instead-of-u32.patch deleted file mode 100644 index 570cd19ee4..0000000000 --- a/package/kernel/mac80211/patches/341-mac80211-minstrel-make-prob_ewma-u16-instead-of-u32.patch +++ /dev/null @@ -1,20 +0,0 @@ -From: Felix Fietkau -Date: Wed, 14 Dec 2016 20:19:56 +0100 -Subject: [PATCH] mac80211: minstrel: make prob_ewma u16 instead of u32 - -Saves about 1.2 KiB memory per station - -Signed-off-by: Felix Fietkau ---- - ---- a/net/mac80211/rc80211_minstrel.h -+++ b/net/mac80211/rc80211_minstrel.h -@@ -59,7 +59,7 @@ struct minstrel_rate_stats { - /* statistis of packet delivery probability - * prob_ewma - exponential weighted moving average of prob - * prob_ewmsd - exp. weighted moving standard deviation of prob */ -- unsigned int prob_ewma; -+ u16 prob_ewma; - u16 prob_ewmv; - - /* maximum retry counts */ diff --git a/package/kernel/mac80211/patches/342-mac80211-minstrel_ht-remove-obsolete-if-for-3-stream.patch b/package/kernel/mac80211/patches/342-mac80211-minstrel_ht-remove-obsolete-if-for-3-stream.patch deleted file mode 100644 index 39d3c99e74..0000000000 --- a/package/kernel/mac80211/patches/342-mac80211-minstrel_ht-remove-obsolete-if-for-3-stream.patch +++ /dev/null @@ -1,80 +0,0 @@ -From: Felix Fietkau -Date: Wed, 14 Dec 2016 20:23:29 +0100 -Subject: [PATCH] mac80211: minstrel_ht: remove obsolete #if for >= 3 streams - -This was added during early development when 3x3 hardware was not very -common yet. This is completely unnecessary now. - -Signed-off-by: Felix Fietkau ---- - ---- a/net/mac80211/rc80211_minstrel_ht.c -+++ b/net/mac80211/rc80211_minstrel_ht.c -@@ -155,67 +155,47 @@ MODULE_PARM_DESC(minstrel_vht_only, - const struct mcs_group minstrel_mcs_groups[] = { - MCS_GROUP(1, 0, BW_20), - MCS_GROUP(2, 0, BW_20), --#if MINSTREL_MAX_STREAMS >= 3 - MCS_GROUP(3, 0, BW_20), --#endif - - MCS_GROUP(1, 1, BW_20), - MCS_GROUP(2, 1, BW_20), --#if MINSTREL_MAX_STREAMS >= 3 - MCS_GROUP(3, 1, BW_20), --#endif - - MCS_GROUP(1, 0, BW_40), - MCS_GROUP(2, 0, BW_40), --#if MINSTREL_MAX_STREAMS >= 3 - MCS_GROUP(3, 0, BW_40), --#endif - - MCS_GROUP(1, 1, BW_40), - MCS_GROUP(2, 1, BW_40), --#if MINSTREL_MAX_STREAMS >= 3 - MCS_GROUP(3, 1, BW_40), --#endif - - CCK_GROUP, - - #ifdef CPTCFG_MAC80211_RC_MINSTREL_VHT - VHT_GROUP(1, 0, BW_20), - VHT_GROUP(2, 0, BW_20), --#if MINSTREL_MAX_STREAMS >= 3 - VHT_GROUP(3, 0, BW_20), --#endif - - VHT_GROUP(1, 1, BW_20), - VHT_GROUP(2, 1, BW_20), --#if MINSTREL_MAX_STREAMS >= 3 - VHT_GROUP(3, 1, BW_20), --#endif - - VHT_GROUP(1, 0, BW_40), - VHT_GROUP(2, 0, BW_40), --#if MINSTREL_MAX_STREAMS >= 3 - VHT_GROUP(3, 0, BW_40), --#endif - - VHT_GROUP(1, 1, BW_40), - VHT_GROUP(2, 1, BW_40), --#if MINSTREL_MAX_STREAMS >= 3 - VHT_GROUP(3, 1, BW_40), --#endif - - VHT_GROUP(1, 0, BW_80), - VHT_GROUP(2, 0, BW_80), --#if MINSTREL_MAX_STREAMS >= 3 - VHT_GROUP(3, 0, BW_80), --#endif - - VHT_GROUP(1, 1, BW_80), - VHT_GROUP(2, 1, BW_80), --#if MINSTREL_MAX_STREAMS >= 3 - VHT_GROUP(3, 1, BW_80), - #endif --#endif - }; - - static u8 sample_table[SAMPLE_COLUMNS][MCS_GROUP_RATES] __read_mostly; diff --git a/package/kernel/mac80211/patches/343-cfg80211-limit-scan-results-cache-size.patch b/package/kernel/mac80211/patches/343-cfg80211-limit-scan-results-cache-size.patch deleted file mode 100644 index f26548a3df..0000000000 --- a/package/kernel/mac80211/patches/343-cfg80211-limit-scan-results-cache-size.patch +++ /dev/null @@ -1,150 +0,0 @@ -From: Johannes Berg -Date: Tue, 15 Nov 2016 12:05:11 +0100 -Subject: [PATCH] cfg80211: limit scan results cache size - -It's possible to make scanning consume almost arbitrary amounts -of memory, e.g. by sending beacon frames with random BSSIDs at -high rates while somebody is scanning. - -Limit the number of BSS table entries we're willing to cache to -1000, limiting maximum memory usage to maybe 4-5MB, but lower -in practice - that would be the case for having both full-sized -beacon and probe response frames for each entry; this seems not -possible in practice, so a limit of 1000 entries will likely be -closer to 0.5 MB. - -Cc: stable@vger.kernel.org -Signed-off-by: Johannes Berg ---- - ---- a/net/wireless/core.h -+++ b/net/wireless/core.h -@@ -71,6 +71,7 @@ struct cfg80211_registered_device { - struct list_head bss_list; - struct rb_root bss_tree; - u32 bss_generation; -+ u32 bss_entries; - struct cfg80211_scan_request *scan_req; /* protected by RTNL */ - struct sk_buff *scan_msg; - struct cfg80211_sched_scan_request __rcu *sched_scan_req; ---- a/net/wireless/scan.c -+++ b/net/wireless/scan.c -@@ -57,6 +57,19 @@ - * also linked into the probe response struct. - */ - -+/* -+ * Limit the number of BSS entries stored in mac80211. Each one is -+ * a bit over 4k at most, so this limits to roughly 4-5M of memory. -+ * If somebody wants to really attack this though, they'd likely -+ * use small beacons, and only one type of frame, limiting each of -+ * the entries to a much smaller size (in order to generate more -+ * entries in total, so overhead is bigger.) -+ */ -+static int bss_entries_limit = 1000; -+module_param(bss_entries_limit, int, 0644); -+MODULE_PARM_DESC(bss_entries_limit, -+ "limit to number of scan BSS entries (per wiphy, default 1000)"); -+ - #define IEEE80211_SCAN_RESULT_EXPIRE (30 * HZ) - - static void bss_free(struct cfg80211_internal_bss *bss) -@@ -137,6 +150,10 @@ static bool __cfg80211_unlink_bss(struct - - list_del_init(&bss->list); - rb_erase(&bss->rbn, &rdev->bss_tree); -+ rdev->bss_entries--; -+ WARN_ONCE((rdev->bss_entries == 0) ^ list_empty(&rdev->bss_list), -+ "rdev bss entries[%d]/list[empty:%d] corruption\n", -+ rdev->bss_entries, list_empty(&rdev->bss_list)); - bss_ref_put(rdev, bss); - return true; - } -@@ -163,6 +180,40 @@ static void __cfg80211_bss_expire(struct - rdev->bss_generation++; - } - -+static bool cfg80211_bss_expire_oldest(struct cfg80211_registered_device *rdev) -+{ -+ struct cfg80211_internal_bss *bss, *oldest = NULL; -+ bool ret; -+ -+ lockdep_assert_held(&rdev->bss_lock); -+ -+ list_for_each_entry(bss, &rdev->bss_list, list) { -+ if (atomic_read(&bss->hold)) -+ continue; -+ -+ if (!list_empty(&bss->hidden_list) && -+ !bss->pub.hidden_beacon_bss) -+ continue; -+ -+ if (oldest && time_before(oldest->ts, bss->ts)) -+ continue; -+ oldest = bss; -+ } -+ -+ if (WARN_ON(!oldest)) -+ return false; -+ -+ /* -+ * The callers make sure to increase rdev->bss_generation if anything -+ * gets removed (and a new entry added), so there's no need to also do -+ * it here. -+ */ -+ -+ ret = __cfg80211_unlink_bss(rdev, oldest); -+ WARN_ON(!ret); -+ return ret; -+} -+ - void ___cfg80211_scan_done(struct cfg80211_registered_device *rdev, - bool send_message) - { -@@ -689,6 +740,7 @@ static bool cfg80211_combine_bsses(struc - const u8 *ie; - int i, ssidlen; - u8 fold = 0; -+ u32 n_entries = 0; - - ies = rcu_access_pointer(new->pub.beacon_ies); - if (WARN_ON(!ies)) -@@ -712,6 +764,12 @@ static bool cfg80211_combine_bsses(struc - /* This is the bad part ... */ - - list_for_each_entry(bss, &rdev->bss_list, list) { -+ /* -+ * we're iterating all the entries anyway, so take the -+ * opportunity to validate the list length accounting -+ */ -+ n_entries++; -+ - if (!ether_addr_equal(bss->pub.bssid, new->pub.bssid)) - continue; - if (bss->pub.channel != new->pub.channel) -@@ -740,6 +798,10 @@ static bool cfg80211_combine_bsses(struc - new->pub.beacon_ies); - } - -+ WARN_ONCE(n_entries != rdev->bss_entries, -+ "rdev bss entries[%d]/list[len:%d] corruption\n", -+ rdev->bss_entries, n_entries); -+ - return true; - } - -@@ -894,7 +956,14 @@ cfg80211_bss_update(struct cfg80211_regi - } - } - -+ if (rdev->bss_entries >= bss_entries_limit && -+ !cfg80211_bss_expire_oldest(rdev)) { -+ kfree(new); -+ goto drop; -+ } -+ - list_add_tail(&new->list, &rdev->bss_list); -+ rdev->bss_entries++; - rb_insert_bss(rdev, new); - found = new; - } diff --git a/package/kernel/mac80211/patches/344-ath9k-Introduce-airtime-fairness-scheduling-between-.patch b/package/kernel/mac80211/patches/344-ath9k-Introduce-airtime-fairness-scheduling-between-.patch deleted file mode 100644 index 10c6573b8c..0000000000 --- a/package/kernel/mac80211/patches/344-ath9k-Introduce-airtime-fairness-scheduling-between-.patch +++ /dev/null @@ -1,651 +0,0 @@ -From: =?UTF-8?q?Toke=20H=C3=B8iland-J=C3=B8rgensen?= -Date: Mon, 5 Dec 2016 13:27:37 +0200 -Subject: [PATCH] ath9k: Introduce airtime fairness scheduling between stations -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -This reworks the ath9k driver to schedule transmissions to connected -stations in a way that enforces airtime fairness between them. It -accomplishes this by measuring the time spent transmitting to or -receiving from a station at TX and RX completion, and accounting this to -a per-station, per-QoS level airtime deficit. Then, an FQ-CoDel based -deficit scheduler is employed at packet dequeue time, to control which -station gets the next transmission opportunity. - -Airtime fairness can significantly improve the efficiency of the network -when station rates vary. The following throughput values are from a -simple three-station test scenario, where two stations operate at the -highest HT20 rate, and one station at the lowest, and the scheduler is -employed at the access point: - - Before / After -Fast station 1: 19.17 / 25.09 Mbps -Fast station 2: 19.83 / 25.21 Mbps -Slow station: 2.58 / 1.77 Mbps -Total: 41.58 / 52.07 Mbps - -The benefit of airtime fairness goes up the more stations are present. -In a 30-station test with one station artificially limited to 1 Mbps, -we have seen aggregate throughput go from 2.14 to 17.76 Mbps. - -Signed-off-by: Toke Høiland-Jørgensen -Signed-off-by: Kalle Valo ---- - ---- a/drivers/net/wireless/ath/ath9k/ath9k.h -+++ b/drivers/net/wireless/ath/ath9k/ath9k.h -@@ -112,6 +112,8 @@ int ath_descdma_setup(struct ath_softc * - #define ATH_TXFIFO_DEPTH 8 - #define ATH_TX_ERROR 0x01 - -+#define ATH_AIRTIME_QUANTUM 300 /* usec */ -+ - /* Stop tx traffic 1ms before the GO goes away */ - #define ATH_P2P_PS_STOP_TIME 1000 - -@@ -247,6 +249,9 @@ struct ath_atx_tid { - bool has_queued; - }; - -+void __ath_tx_queue_tid(struct ath_softc *sc, struct ath_atx_tid *tid); -+void ath_tx_queue_tid(struct ath_softc *sc, struct ath_atx_tid *tid); -+ - struct ath_node { - struct ath_softc *sc; - struct ieee80211_sta *sta; /* station struct we're part of */ -@@ -258,9 +263,12 @@ struct ath_node { - - bool sleeping; - bool no_ps_filter; -+ s64 airtime_deficit[IEEE80211_NUM_ACS]; -+ u32 airtime_rx_start; - - #ifdef CPTCFG_ATH9K_STATION_STATISTICS - struct ath_rx_rate_stats rx_rate_stats; -+ struct ath_airtime_stats airtime_stats; - #endif - u8 key_idx[4]; - -@@ -317,10 +325,16 @@ struct ath_rx { - /* Channel Context */ - /*******************/ - -+struct ath_acq { -+ struct list_head acq_new; -+ struct list_head acq_old; -+ spinlock_t lock; -+}; -+ - struct ath_chanctx { - struct cfg80211_chan_def chandef; - struct list_head vifs; -- struct list_head acq[IEEE80211_NUM_ACS]; -+ struct ath_acq acq[IEEE80211_NUM_ACS]; - int hw_queue_base; - - /* do not dereference, use for comparison only */ -@@ -575,6 +589,8 @@ void ath_txq_schedule_all(struct ath_sof - int ath_tx_init(struct ath_softc *sc, int nbufs); - int ath_txq_update(struct ath_softc *sc, int qnum, - struct ath9k_tx_queue_info *q); -+u32 ath_pkt_duration(struct ath_softc *sc, u8 rix, int pktlen, -+ int width, int half_gi, bool shortPreamble); - void ath_update_max_aggr_framelen(struct ath_softc *sc, int queue, int txop); - void ath_assign_seq(struct ath_common *common, struct sk_buff *skb); - int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb, -@@ -963,6 +979,11 @@ void ath_ant_comb_scan(struct ath_softc - - #define ATH9K_NUM_CHANCTX 2 /* supports 2 operating channels */ - -+#define AIRTIME_USE_TX BIT(0) -+#define AIRTIME_USE_RX BIT(1) -+#define AIRTIME_USE_NEW_QUEUES BIT(2) -+#define AIRTIME_ACTIVE(flags) (!!(flags & (AIRTIME_USE_TX|AIRTIME_USE_RX))) -+ - struct ath_softc { - struct ieee80211_hw *hw; - struct device *dev; -@@ -1005,6 +1026,8 @@ struct ath_softc { - short nbcnvifs; - unsigned long ps_usecount; - -+ u16 airtime_flags; /* AIRTIME_* */ -+ - struct ath_rx rx; - struct ath_tx tx; - struct ath_beacon beacon; ---- a/drivers/net/wireless/ath/ath9k/channel.c -+++ b/drivers/net/wireless/ath/ath9k/channel.c -@@ -118,8 +118,11 @@ void ath_chanctx_init(struct ath_softc * - INIT_LIST_HEAD(&ctx->vifs); - ctx->txpower = ATH_TXPOWER_MAX; - ctx->flush_timeout = HZ / 5; /* 200ms */ -- for (j = 0; j < ARRAY_SIZE(ctx->acq); j++) -- INIT_LIST_HEAD(&ctx->acq[j]); -+ for (j = 0; j < ARRAY_SIZE(ctx->acq); j++) { -+ INIT_LIST_HEAD(&ctx->acq[j].acq_new); -+ INIT_LIST_HEAD(&ctx->acq[j].acq_old); -+ spin_lock_init(&ctx->acq[j].lock); -+ } - } - } - -@@ -1345,8 +1348,11 @@ void ath9k_offchannel_init(struct ath_so - ctx->txpower = ATH_TXPOWER_MAX; - cfg80211_chandef_create(&ctx->chandef, chan, NL80211_CHAN_HT20); - -- for (i = 0; i < ARRAY_SIZE(ctx->acq); i++) -- INIT_LIST_HEAD(&ctx->acq[i]); -+ for (i = 0; i < ARRAY_SIZE(ctx->acq); i++) { -+ INIT_LIST_HEAD(&ctx->acq[i].acq_new); -+ INIT_LIST_HEAD(&ctx->acq[i].acq_old); -+ spin_lock_init(&ctx->acq[i].lock); -+ } - - sc->offchannel.chan.offchannel = true; - } ---- a/drivers/net/wireless/ath/ath9k/debug.c -+++ b/drivers/net/wireless/ath/ath9k/debug.c -@@ -1399,5 +1399,8 @@ int ath9k_init_debug(struct ath_hw *ah) - debugfs_create_file("tpc", S_IRUSR | S_IWUSR, - sc->debug.debugfs_phy, sc, &fops_tpc); - -+ debugfs_create_u16("airtime_flags", S_IRUSR | S_IWUSR, -+ sc->debug.debugfs_phy, &sc->airtime_flags); -+ - return 0; - } ---- a/drivers/net/wireless/ath/ath9k/debug.h -+++ b/drivers/net/wireless/ath/ath9k/debug.h -@@ -221,6 +221,11 @@ struct ath_rx_rate_stats { - } cck_stats[4]; - }; - -+struct ath_airtime_stats { -+ u32 rx_airtime; -+ u32 tx_airtime; -+}; -+ - #define ANT_MAIN 0 - #define ANT_ALT 1 - -@@ -314,12 +319,20 @@ ath9k_debug_sync_cause(struct ath_softc - void ath_debug_rate_stats(struct ath_softc *sc, - struct ath_rx_status *rs, - struct sk_buff *skb); -+void ath_debug_airtime(struct ath_softc *sc, -+ struct ath_node *an, -+ u32 rx, u32 tx); - #else - static inline void ath_debug_rate_stats(struct ath_softc *sc, - struct ath_rx_status *rs, - struct sk_buff *skb) - { - } -+static inline void ath_debug_airtime(struct ath_softc *sc, -+ struct ath_node *an, -+ u32 rx, u32 tx) -+{ -+} - #endif /* CPTCFG_ATH9K_STATION_STATISTICS */ - - #endif /* DEBUG_H */ ---- a/drivers/net/wireless/ath/ath9k/debug_sta.c -+++ b/drivers/net/wireless/ath/ath9k/debug_sta.c -@@ -242,6 +242,59 @@ static const struct file_operations fops - .llseek = default_llseek, - }; - -+void ath_debug_airtime(struct ath_softc *sc, -+ struct ath_node *an, -+ u32 rx, -+ u32 tx) -+{ -+ struct ath_airtime_stats *astats = &an->airtime_stats; -+ -+ astats->rx_airtime += rx; -+ astats->tx_airtime += tx; -+} -+ -+static ssize_t read_airtime(struct file *file, char __user *user_buf, -+ size_t count, loff_t *ppos) -+{ -+ struct ath_node *an = file->private_data; -+ struct ath_airtime_stats *astats; -+ static const char *qname[4] = { -+ "VO", "VI", "BE", "BK" -+ }; -+ u32 len = 0, size = 256; -+ char *buf; -+ size_t retval; -+ int i; -+ -+ buf = kzalloc(size, GFP_KERNEL); -+ if (buf == NULL) -+ return -ENOMEM; -+ -+ astats = &an->airtime_stats; -+ -+ len += scnprintf(buf + len, size - len, "RX: %u us\n", astats->rx_airtime); -+ len += scnprintf(buf + len, size - len, "TX: %u us\n", astats->tx_airtime); -+ len += scnprintf(buf + len, size - len, "Deficit: "); -+ for (i = 0; i < 4; i++) -+ len += scnprintf(buf+len, size - len, "%s: %lld us ", qname[i], an->airtime_deficit[i]); -+ if (len < size) -+ buf[len++] = '\n'; -+ -+ retval = simple_read_from_buffer(user_buf, count, ppos, buf, len); -+ kfree(buf); -+ -+ return retval; -+} -+ -+ -+static const struct file_operations fops_airtime = { -+ .read = read_airtime, -+ .open = simple_open, -+ .owner = THIS_MODULE, -+ .llseek = default_llseek, -+}; -+ -+ - void ath9k_sta_add_debugfs(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, - struct ieee80211_sta *sta, -@@ -251,4 +304,5 @@ void ath9k_sta_add_debugfs(struct ieee80 - - debugfs_create_file("node_aggr", S_IRUGO, dir, an, &fops_node_aggr); - debugfs_create_file("node_recv", S_IRUGO, dir, an, &fops_node_recv); -+ debugfs_create_file("airtime", S_IRUGO, dir, an, &fops_airtime); - } ---- a/drivers/net/wireless/ath/ath9k/init.c -+++ b/drivers/net/wireless/ath/ath9k/init.c -@@ -620,6 +620,8 @@ static int ath9k_init_softc(u16 devid, s - - /* Will be cleared in ath9k_start() */ - set_bit(ATH_OP_INVALID, &common->op_flags); -+ sc->airtime_flags = (AIRTIME_USE_TX | AIRTIME_USE_RX | -+ AIRTIME_USE_NEW_QUEUES); - - sc->sc_ah = ah; - sc->dfs_detector = dfs_pattern_detector_init(common, NL80211_DFS_UNSET); ---- a/drivers/net/wireless/ath/ath9k/main.c -+++ b/drivers/net/wireless/ath/ath9k/main.c -@@ -70,10 +70,10 @@ static bool ath9k_has_pending_frames(str - goto out; - - if (txq->mac80211_qnum >= 0) { -- struct list_head *list; -+ struct ath_acq *acq; - -- list = &sc->cur_chan->acq[txq->mac80211_qnum]; -- if (!list_empty(list)) -+ acq = &sc->cur_chan->acq[txq->mac80211_qnum]; -+ if (!list_empty(&acq->acq_new) || !list_empty(&acq->acq_old)) - pending = true; - } - out: ---- a/drivers/net/wireless/ath/ath9k/recv.c -+++ b/drivers/net/wireless/ath/ath9k/recv.c -@@ -991,6 +991,70 @@ static void ath9k_apply_ampdu_details(st - } - } - -+static void ath_rx_count_airtime(struct ath_softc *sc, -+ struct ath_rx_status *rs, -+ struct sk_buff *skb) -+{ -+ struct ath_node *an; -+ struct ath_acq *acq; -+ struct ath_vif *avp; -+ struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; -+ struct ath_hw *ah = sc->sc_ah; -+ struct ath_common *common = ath9k_hw_common(ah); -+ struct ieee80211_sta *sta; -+ struct ieee80211_rx_status *rxs; -+ const struct ieee80211_rate *rate; -+ bool is_sgi, is_40, is_sp; -+ int phy; -+ u16 len = rs->rs_datalen; -+ u32 airtime = 0; -+ u8 tidno, acno; -+ -+ if (!ieee80211_is_data(hdr->frame_control)) -+ return; -+ -+ rcu_read_lock(); -+ -+ sta = ieee80211_find_sta_by_ifaddr(sc->hw, hdr->addr2, NULL); -+ if (!sta) -+ goto exit; -+ an = (struct ath_node *) sta->drv_priv; -+ avp = (struct ath_vif *) an->vif->drv_priv; -+ tidno = skb->priority & IEEE80211_QOS_CTL_TID_MASK; -+ acno = TID_TO_WME_AC(tidno); -+ acq = &avp->chanctx->acq[acno]; -+ -+ rxs = IEEE80211_SKB_RXCB(skb); -+ -+ is_sgi = !!(rxs->flag & RX_FLAG_SHORT_GI); -+ is_40 = !!(rxs->flag & RX_FLAG_40MHZ); -+ is_sp = !!(rxs->flag & RX_FLAG_SHORTPRE); -+ -+ if (!!(rxs->flag & RX_FLAG_HT)) { -+ /* MCS rates */ -+ -+ airtime += ath_pkt_duration(sc, rxs->rate_idx, len, -+ is_40, is_sgi, is_sp); -+ } else { -+ -+ phy = IS_CCK_RATE(rs->rs_rate) ? WLAN_RC_PHY_CCK : WLAN_RC_PHY_OFDM; -+ rate = &common->sbands[rxs->band].bitrates[rxs->rate_idx]; -+ airtime += ath9k_hw_computetxtime(ah, phy, rate->bitrate * 100, -+ len, rxs->rate_idx, is_sp); -+ } -+ -+ if (!!(sc->airtime_flags & AIRTIME_USE_RX)) { -+ spin_lock_bh(&acq->lock); -+ an->airtime_deficit[acno] -= airtime; -+ if (an->airtime_deficit[acno] <= 0) -+ __ath_tx_queue_tid(sc, ATH_AN_2_TID(an, tidno)); -+ spin_unlock_bh(&acq->lock); -+ } -+ ath_debug_airtime(sc, an, airtime, 0); -+exit: -+ rcu_read_unlock(); -+} -+ - int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp) - { - struct ath_rxbuf *bf; -@@ -1137,6 +1201,7 @@ int ath_rx_tasklet(struct ath_softc *sc, - ath9k_antenna_check(sc, &rs); - ath9k_apply_ampdu_details(sc, &rs, rxs); - ath_debug_rate_stats(sc, &rs, skb); -+ ath_rx_count_airtime(sc, &rs, skb); - - hdr = (struct ieee80211_hdr *)skb->data; - if (ieee80211_is_ack(hdr->frame_control)) ---- a/drivers/net/wireless/ath/ath9k/xmit.c -+++ b/drivers/net/wireless/ath/ath9k/xmit.c -@@ -125,21 +125,44 @@ void ath_txq_unlock_complete(struct ath_ - ath_tx_status(hw, skb); - } - --static void ath_tx_queue_tid(struct ath_softc *sc, struct ath_txq *txq, -- struct ath_atx_tid *tid) -+void __ath_tx_queue_tid(struct ath_softc *sc, struct ath_atx_tid *tid) - { -- struct list_head *list; - struct ath_vif *avp = (struct ath_vif *) tid->an->vif->drv_priv; - struct ath_chanctx *ctx = avp->chanctx; -+ struct ath_acq *acq; -+ struct list_head *tid_list; -+ u8 acno = TID_TO_WME_AC(tid->tidno); - -- if (!ctx) -+ if (!ctx || !list_empty(&tid->list)) - return; - -- list = &ctx->acq[TID_TO_WME_AC(tid->tidno)]; -- if (list_empty(&tid->list)) -- list_add_tail(&tid->list, list); -+ -+ acq = &ctx->acq[acno]; -+ if ((sc->airtime_flags & AIRTIME_USE_NEW_QUEUES) && -+ tid->an->airtime_deficit[acno] > 0) -+ tid_list = &acq->acq_new; -+ else -+ tid_list = &acq->acq_old; -+ -+ list_add_tail(&tid->list, tid_list); - } - -+void ath_tx_queue_tid(struct ath_softc *sc, struct ath_atx_tid *tid) -+{ -+ struct ath_vif *avp = (struct ath_vif *) tid->an->vif->drv_priv; -+ struct ath_chanctx *ctx = avp->chanctx; -+ struct ath_acq *acq; -+ -+ if (!ctx || !list_empty(&tid->list)) -+ return; -+ -+ acq = &ctx->acq[TID_TO_WME_AC(tid->tidno)]; -+ spin_lock_bh(&acq->lock); -+ __ath_tx_queue_tid(sc, tid); -+ spin_unlock_bh(&acq->lock); -+} -+ -+ - void ath9k_wake_tx_queue(struct ieee80211_hw *hw, struct ieee80211_txq *queue) - { - struct ath_softc *sc = hw->priv; -@@ -154,7 +177,7 @@ void ath9k_wake_tx_queue(struct ieee8021 - ath_txq_lock(sc, txq); - - tid->has_queued = true; -- ath_tx_queue_tid(sc, txq, tid); -+ ath_tx_queue_tid(sc, tid); - ath_txq_schedule(sc, txq); - - ath_txq_unlock(sc, txq); -@@ -684,7 +707,7 @@ static void ath_tx_complete_aggr(struct - - skb_queue_splice_tail(&bf_pending, &tid->retry_q); - if (!an->sleeping) { -- ath_tx_queue_tid(sc, txq, tid); -+ ath_tx_queue_tid(sc, tid); - - if (ts->ts_status & (ATH9K_TXERR_FILT | ATH9K_TXERR_XRETRY)) - tid->clear_ps_filter = true; -@@ -712,6 +735,53 @@ static bool bf_is_ampdu_not_probing(stru - return bf_isampdu(bf) && !(info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE); - } - -+static void ath_tx_count_airtime(struct ath_softc *sc, struct ath_txq *txq, -+ struct ath_buf *bf, struct ath_tx_status *ts) -+{ -+ struct ath_node *an; -+ struct ath_acq *acq = &sc->cur_chan->acq[txq->mac80211_qnum]; -+ struct sk_buff *skb; -+ struct ieee80211_hdr *hdr; -+ struct ieee80211_hw *hw = sc->hw; -+ struct ieee80211_tx_rate rates[4]; -+ struct ieee80211_sta *sta; -+ int i; -+ u32 airtime = 0; -+ -+ skb = bf->bf_mpdu; -+ if(!skb) -+ return; -+ -+ hdr = (struct ieee80211_hdr *)skb->data; -+ memcpy(rates, bf->rates, sizeof(rates)); -+ -+ rcu_read_lock(); -+ -+ sta = ieee80211_find_sta_by_ifaddr(hw, hdr->addr1, hdr->addr2); -+ if(!sta) -+ goto exit; -+ -+ -+ an = (struct ath_node *) sta->drv_priv; -+ -+ airtime += ts->duration * (ts->ts_longretry + 1); -+ -+ for(i=0; i < ts->ts_rateindex; i++) -+ airtime += ath9k_hw_get_duration(sc->sc_ah, bf->bf_desc, i) * rates[i].count; -+ -+ if (!!(sc->airtime_flags & AIRTIME_USE_TX)) { -+ spin_lock_bh(&acq->lock); -+ an->airtime_deficit[txq->mac80211_qnum] -= airtime; -+ if (an->airtime_deficit[txq->mac80211_qnum] <= 0) -+ __ath_tx_queue_tid(sc, ath_get_skb_tid(sc, an, skb)); -+ spin_unlock_bh(&acq->lock); -+ } -+ ath_debug_airtime(sc, an, 0, airtime); -+ -+exit: -+ rcu_read_unlock(); -+} -+ - static void ath_tx_process_buffer(struct ath_softc *sc, struct ath_txq *txq, - struct ath_tx_status *ts, struct ath_buf *bf, - struct list_head *bf_head) -@@ -733,6 +803,7 @@ static void ath_tx_process_buffer(struct - - ts->duration = ath9k_hw_get_duration(sc->sc_ah, bf->bf_desc, - ts->ts_rateindex); -+ ath_tx_count_airtime(sc, txq, bf, ts); - - hdr = (struct ieee80211_hdr *) bf->bf_mpdu->data; - sta = ieee80211_find_sta_by_ifaddr(hw, hdr->addr1, hdr->addr2); -@@ -1094,8 +1165,8 @@ finish: - * width - 0 for 20 MHz, 1 for 40 MHz - * half_gi - to use 4us v/s 3.6 us for symbol time - */ --static u32 ath_pkt_duration(struct ath_softc *sc, u8 rix, int pktlen, -- int width, int half_gi, bool shortPreamble) -+u32 ath_pkt_duration(struct ath_softc *sc, u8 rix, int pktlen, -+ int width, int half_gi, bool shortPreamble) - { - u32 nbits, nsymbits, duration, nsymbols; - int streams; -@@ -1493,7 +1564,7 @@ ath_tx_form_burst(struct ath_softc *sc, - } - - static bool ath_tx_sched_aggr(struct ath_softc *sc, struct ath_txq *txq, -- struct ath_atx_tid *tid, bool *stop) -+ struct ath_atx_tid *tid) - { - struct ath_buf *bf; - struct ieee80211_tx_info *tx_info; -@@ -1515,7 +1586,6 @@ static bool ath_tx_sched_aggr(struct ath - if ((aggr && txq->axq_ampdu_depth >= ATH_AGGR_MIN_QDEPTH) || - (!aggr && txq->axq_depth >= ATH_NON_AGGR_MIN_QDEPTH)) { - __skb_queue_tail(&tid->retry_q, bf->bf_mpdu); -- *stop = true; - return false; - } - -@@ -1639,7 +1709,7 @@ void ath_tx_aggr_wakeup(struct ath_softc - ath_txq_lock(sc, txq); - tid->clear_ps_filter = true; - if (ath_tid_has_buffered(tid)) { -- ath_tx_queue_tid(sc, txq, tid); -+ ath_tx_queue_tid(sc, tid); - ath_txq_schedule(sc, txq); - } - ath_txq_unlock_complete(sc, txq); -@@ -1956,9 +2026,10 @@ void ath_tx_cleanupq(struct ath_softc *s - void ath_txq_schedule(struct ath_softc *sc, struct ath_txq *txq) - { - struct ath_common *common = ath9k_hw_common(sc->sc_ah); -- struct ath_atx_tid *tid, *last_tid; -+ struct ath_atx_tid *tid; - struct list_head *tid_list; -- bool sent = false; -+ struct ath_acq *acq; -+ bool active = AIRTIME_ACTIVE(sc->airtime_flags); - - if (txq->mac80211_qnum < 0) - return; -@@ -1967,48 +2038,55 @@ void ath_txq_schedule(struct ath_softc * - return; - - spin_lock_bh(&sc->chan_lock); -- tid_list = &sc->cur_chan->acq[txq->mac80211_qnum]; -- -- if (list_empty(tid_list)) { -- spin_unlock_bh(&sc->chan_lock); -- return; -- } -- - rcu_read_lock(); -+ acq = &sc->cur_chan->acq[txq->mac80211_qnum]; - -- last_tid = list_entry(tid_list->prev, struct ath_atx_tid, list); -- while (!list_empty(tid_list)) { -- bool stop = false; -- -- if (sc->cur_chan->stopped) -- break; -- -- tid = list_first_entry(tid_list, struct ath_atx_tid, list); -- list_del_init(&tid->list); -+ if (sc->cur_chan->stopped) -+ goto out; - -- if (ath_tx_sched_aggr(sc, txq, tid, &stop)) -- sent = true; -+begin: -+ tid_list = &acq->acq_new; -+ if (list_empty(tid_list)) { -+ tid_list = &acq->acq_old; -+ if (list_empty(tid_list)) -+ goto out; -+ } -+ tid = list_first_entry(tid_list, struct ath_atx_tid, list); - -- /* -- * add tid to round-robin queue if more frames -- * are pending for the tid -- */ -- if (ath_tid_has_buffered(tid)) -- ath_tx_queue_tid(sc, txq, tid); -+ if (active && tid->an->airtime_deficit[txq->mac80211_qnum] <= 0) { -+ spin_lock_bh(&acq->lock); -+ tid->an->airtime_deficit[txq->mac80211_qnum] += ATH_AIRTIME_QUANTUM; -+ list_move_tail(&tid->list, &acq->acq_old); -+ spin_unlock_bh(&acq->lock); -+ goto begin; -+ } - -- if (stop) -- break; -+ if (!ath_tid_has_buffered(tid)) { -+ spin_lock_bh(&acq->lock); -+ if ((tid_list == &acq->acq_new) && !list_empty(&acq->acq_old)) -+ list_move_tail(&tid->list, &acq->acq_old); -+ else { -+ list_del_init(&tid->list); -+ } -+ spin_unlock_bh(&acq->lock); -+ goto begin; -+ } - -- if (tid == last_tid) { -- if (!sent) -- break; - -- sent = false; -- last_tid = list_entry(tid_list->prev, -- struct ath_atx_tid, list); -+ /* -+ * If we succeed in scheduling something, immediately restart to make -+ * sure we keep the HW busy. -+ */ -+ if(ath_tx_sched_aggr(sc, txq, tid)) { -+ if (!active) { -+ spin_lock_bh(&acq->lock); -+ list_move_tail(&tid->list, &acq->acq_old); -+ spin_unlock_bh(&acq->lock); - } -+ goto begin; - } - -+out: - rcu_read_unlock(); - spin_unlock_bh(&sc->chan_lock); - } -@@ -2862,6 +2940,9 @@ void ath_tx_node_init(struct ath_softc * - struct ath_atx_tid *tid; - int tidno, acno; - -+ for (acno = 0; acno < IEEE80211_NUM_ACS; acno++) -+ an->airtime_deficit[acno] = ATH_AIRTIME_QUANTUM; -+ - for (tidno = 0; tidno < IEEE80211_NUM_TIDS; tidno++) { - tid = ath_node_to_tid(an, tidno); - tid->an = an; diff --git a/package/kernel/mac80211/patches/345-ath9k-Turn-ath_txq_lock-unlock-into-static-inlines.patch b/package/kernel/mac80211/patches/345-ath9k-Turn-ath_txq_lock-unlock-into-static-inlines.patch deleted file mode 100644 index 734ba22af1..0000000000 --- a/package/kernel/mac80211/patches/345-ath9k-Turn-ath_txq_lock-unlock-into-static-inlines.patch +++ /dev/null @@ -1,62 +0,0 @@ -From: =?UTF-8?q?Toke=20H=C3=B8iland-J=C3=B8rgensen?= -Date: Mon, 5 Dec 2016 13:27:38 +0200 -Subject: [PATCH] ath9k: Turn ath_txq_lock/unlock() into static inlines. -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -These are one-line functions that just call spin_lock/unlock_bh(); turn -them into static inlines to avoid the function call overhead. - -Signed-off-by: Toke Høiland-Jørgensen -Signed-off-by: Kalle Valo ---- - ---- a/drivers/net/wireless/ath/ath9k/ath9k.h -+++ b/drivers/net/wireless/ath/ath9k/ath9k.h -@@ -569,6 +569,15 @@ static inline void ath_chanctx_check_act - - #endif /* CPTCFG_ATH9K_CHANNEL_CONTEXT */ - -+static inline void ath_txq_lock(struct ath_softc *sc, struct ath_txq *txq) -+{ -+ spin_lock_bh(&txq->axq_lock); -+} -+static inline void ath_txq_unlock(struct ath_softc *sc, struct ath_txq *txq) -+{ -+ spin_unlock_bh(&txq->axq_lock); -+} -+ - void ath_startrecv(struct ath_softc *sc); - bool ath_stoprecv(struct ath_softc *sc); - u32 ath_calcrxfilter(struct ath_softc *sc); -@@ -576,8 +585,6 @@ int ath_rx_init(struct ath_softc *sc, in - void ath_rx_cleanup(struct ath_softc *sc); - int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp); - struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype); --void ath_txq_lock(struct ath_softc *sc, struct ath_txq *txq); --void ath_txq_unlock(struct ath_softc *sc, struct ath_txq *txq); - void ath_txq_unlock_complete(struct ath_softc *sc, struct ath_txq *txq); - void ath_tx_cleanupq(struct ath_softc *sc, struct ath_txq *txq); - bool ath_drain_all_txq(struct ath_softc *sc); ---- a/drivers/net/wireless/ath/ath9k/xmit.c -+++ b/drivers/net/wireless/ath/ath9k/xmit.c -@@ -98,18 +98,6 @@ static void ath_tx_status(struct ieee802 - dev_kfree_skb(skb); - } - --void ath_txq_lock(struct ath_softc *sc, struct ath_txq *txq) -- __acquires(&txq->axq_lock) --{ -- spin_lock_bh(&txq->axq_lock); --} -- --void ath_txq_unlock(struct ath_softc *sc, struct ath_txq *txq) -- __releases(&txq->axq_lock) --{ -- spin_unlock_bh(&txq->axq_lock); --} -- - void ath_txq_unlock_complete(struct ath_softc *sc, struct ath_txq *txq) - __releases(&txq->axq_lock) - { diff --git a/package/kernel/mac80211/patches/346-ath5k-drop-bogus-warning-on-drv_set_key-with-unsuppo.patch b/package/kernel/mac80211/patches/346-ath5k-drop-bogus-warning-on-drv_set_key-with-unsuppo.patch deleted file mode 100644 index 243907cb26..0000000000 --- a/package/kernel/mac80211/patches/346-ath5k-drop-bogus-warning-on-drv_set_key-with-unsuppo.patch +++ /dev/null @@ -1,23 +0,0 @@ -From: Felix Fietkau -Date: Tue, 27 Dec 2016 12:15:14 +0100 -Subject: [PATCH] ath5k: drop bogus warning on drv_set_key with unsupported - cipher - -Simply return -EOPNOTSUPP instead. - -Cc: stable@vger.kernel.org -Signed-off-by: Felix Fietkau ---- - ---- a/drivers/net/wireless/ath/ath5k/mac80211-ops.c -+++ b/drivers/net/wireless/ath/ath5k/mac80211-ops.c -@@ -502,8 +502,7 @@ ath5k_set_key(struct ieee80211_hw *hw, e - break; - return -EOPNOTSUPP; - default: -- WARN_ON(1); -- return -EINVAL; -+ return -EOPNOTSUPP; - } - - mutex_lock(&ah->lock); diff --git a/package/kernel/mac80211/patches/347-0001-cfg80211-move-function-checking-range-fit-to-util.c.patch b/package/kernel/mac80211/patches/347-0001-cfg80211-move-function-checking-range-fit-to-util.c.patch deleted file mode 100644 index 4a50d37b2e..0000000000 --- a/package/kernel/mac80211/patches/347-0001-cfg80211-move-function-checking-range-fit-to-util.c.patch +++ /dev/null @@ -1,101 +0,0 @@ -From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= -Date: Wed, 4 Jan 2017 18:58:30 +0100 -Subject: [PATCH] cfg80211: move function checking range fit to util.c -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -It is needed for another cfg80211 helper that will be out of reg.c so -move it to common util.c file and make it non-static. - -Signed-off-by: Rafał Miłecki -Signed-off-by: Johannes Berg ---- - ---- a/net/wireless/core.h -+++ b/net/wireless/core.h -@@ -429,6 +429,9 @@ int cfg80211_change_iface(struct cfg8021 - void cfg80211_process_rdev_events(struct cfg80211_registered_device *rdev); - void cfg80211_process_wdev_events(struct wireless_dev *wdev); - -+bool cfg80211_does_bw_fit_range(const struct ieee80211_freq_range *freq_range, -+ u32 center_freq_khz, u32 bw_khz); -+ - /** - * cfg80211_chandef_dfs_usable - checks if chandef is DFS usable - * @wiphy: the wiphy to validate against ---- a/net/wireless/reg.c -+++ b/net/wireless/reg.c -@@ -748,21 +748,6 @@ static bool is_valid_rd(const struct iee - return true; - } - --static bool reg_does_bw_fit(const struct ieee80211_freq_range *freq_range, -- u32 center_freq_khz, u32 bw_khz) --{ -- u32 start_freq_khz, end_freq_khz; -- -- start_freq_khz = center_freq_khz - (bw_khz/2); -- end_freq_khz = center_freq_khz + (bw_khz/2); -- -- if (start_freq_khz >= freq_range->start_freq_khz && -- end_freq_khz <= freq_range->end_freq_khz) -- return true; -- -- return false; --} -- - /** - * freq_in_rule_band - tells us if a frequency is in a frequency band - * @freq_range: frequency rule we want to query -@@ -1070,7 +1055,7 @@ freq_reg_info_regd(u32 center_freq, - if (!band_rule_found) - band_rule_found = freq_in_rule_band(fr, center_freq); - -- bw_fits = reg_does_bw_fit(fr, center_freq, bw); -+ bw_fits = cfg80211_does_bw_fit_range(fr, center_freq, bw); - - if (band_rule_found && bw_fits) - return rr; -@@ -1138,11 +1123,13 @@ static uint32_t reg_rule_to_chan_bw_flag - max_bandwidth_khz = reg_get_max_bandwidth(regd, reg_rule); - - /* If we get a reg_rule we can assume that at least 5Mhz fit */ -- if (!reg_does_bw_fit(freq_range, MHZ_TO_KHZ(chan->center_freq), -- MHZ_TO_KHZ(10))) -+ if (!cfg80211_does_bw_fit_range(freq_range, -+ MHZ_TO_KHZ(chan->center_freq), -+ MHZ_TO_KHZ(10))) - bw_flags |= IEEE80211_CHAN_NO_10MHZ; -- if (!reg_does_bw_fit(freq_range, MHZ_TO_KHZ(chan->center_freq), -- MHZ_TO_KHZ(20))) -+ if (!cfg80211_does_bw_fit_range(freq_range, -+ MHZ_TO_KHZ(chan->center_freq), -+ MHZ_TO_KHZ(20))) - bw_flags |= IEEE80211_CHAN_NO_20MHZ; - - if (max_bandwidth_khz < MHZ_TO_KHZ(10)) ---- a/net/wireless/util.c -+++ b/net/wireless/util.c -@@ -1788,6 +1788,21 @@ void cfg80211_free_nan_func(struct cfg80 - } - EXPORT_SYMBOL(cfg80211_free_nan_func); - -+bool cfg80211_does_bw_fit_range(const struct ieee80211_freq_range *freq_range, -+ u32 center_freq_khz, u32 bw_khz) -+{ -+ u32 start_freq_khz, end_freq_khz; -+ -+ start_freq_khz = center_freq_khz - (bw_khz / 2); -+ end_freq_khz = center_freq_khz + (bw_khz / 2); -+ -+ if (start_freq_khz >= freq_range->start_freq_khz && -+ end_freq_khz <= freq_range->end_freq_khz) -+ return true; -+ -+ return false; -+} -+ - /* See IEEE 802.1H for LLC/SNAP encapsulation/decapsulation */ - /* Ethernet-II snap header (RFC1042 for most EtherTypes) */ - const unsigned char rfc1042_header[] __aligned(2) = diff --git a/package/kernel/mac80211/patches/347-0002-cfg80211-support-ieee80211-freq-limit-DT-property.patch b/package/kernel/mac80211/patches/347-0002-cfg80211-support-ieee80211-freq-limit-DT-property.patch deleted file mode 100644 index 3e1aae72db..0000000000 --- a/package/kernel/mac80211/patches/347-0002-cfg80211-support-ieee80211-freq-limit-DT-property.patch +++ /dev/null @@ -1,211 +0,0 @@ -From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= -Date: Wed, 4 Jan 2017 18:58:31 +0100 -Subject: [PATCH] cfg80211: support ieee80211-freq-limit DT property -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -This patch adds a helper for reading that new property and applying -limitations of supported channels specified this way. -It is used with devices that normally support a wide wireless band but -in a given config are limited to some part of it (usually due to board -design). For example a dual-band chipset may be able to support one band -only because of used antennas. -It's also common that tri-band routers have separated radios for lower -and higher part of 5 GHz band and it may be impossible to say which is -which without a DT info. - -Signed-off-by: Rafał Miłecki -[add new function to documentation, fix link] -Signed-off-by: Johannes Berg ---- - create mode 100644 net/wireless/of.c - ---- a/include/net/cfg80211.h -+++ b/include/net/cfg80211.h -@@ -311,6 +311,34 @@ struct ieee80211_supported_band { - struct ieee80211_sta_vht_cap vht_cap; - }; - -+/** -+ * wiphy_read_of_freq_limits - read frequency limits from device tree -+ * -+ * @wiphy: the wireless device to get extra limits for -+ * -+ * Some devices may have extra limitations specified in DT. This may be useful -+ * for chipsets that normally support more bands but are limited due to board -+ * design (e.g. by antennas or external power amplifier). -+ * -+ * This function reads info from DT and uses it to *modify* channels (disable -+ * unavailable ones). It's usually a *bad* idea to use it in drivers with -+ * shared channel data as DT limitations are device specific. You should make -+ * sure to call it only if channels in wiphy are copied and can be modified -+ * without affecting other devices. -+ * -+ * As this function access device node it has to be called after set_wiphy_dev. -+ * It also modifies channels so they have to be set first. -+ * If using this helper, call it before wiphy_register(). -+ */ -+#ifdef CONFIG_OF -+void wiphy_read_of_freq_limits(struct wiphy *wiphy); -+#else /* CONFIG_OF */ -+static inline void wiphy_read_of_freq_limits(struct wiphy *wiphy) -+{ -+} -+#endif /* !CONFIG_OF */ -+ -+ - /* - * Wireless hardware/device configuration structures and methods - */ ---- a/net/wireless/Makefile -+++ b/net/wireless/Makefile -@@ -11,6 +11,7 @@ obj-$(CONFIG_WEXT_PRIV) += wext-priv.o - - cfg80211-y += core.o sysfs.o radiotap.o util.o reg.o scan.o nl80211.o - cfg80211-y += mlme.o ibss.o sme.o chan.o ethtool.o mesh.o ap.o trace.o ocb.o -+cfg80211-$(CONFIG_OF) += of.o - cfg80211-$(CPTCFG_CFG80211_DEBUGFS) += debugfs.o - cfg80211-$(CPTCFG_CFG80211_WEXT) += wext-compat.o wext-sme.o - cfg80211-$(CPTCFG_CFG80211_INTERNAL_REGDB) += regdb.o ---- /dev/null -+++ b/net/wireless/of.c -@@ -0,0 +1,138 @@ -+/* -+ * Copyright (C) 2017 Rafał Miłecki -+ * -+ * Permission to use, copy, modify, and/or distribute this software for any -+ * purpose with or without fee is hereby granted, provided that the above -+ * copyright notice and this permission notice appear in all copies. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -+ */ -+ -+#include -+#include -+#include "core.h" -+ -+static bool wiphy_freq_limits_valid_chan(struct wiphy *wiphy, -+ struct ieee80211_freq_range *freq_limits, -+ unsigned int n_freq_limits, -+ struct ieee80211_channel *chan) -+{ -+ u32 bw = MHZ_TO_KHZ(20); -+ int i; -+ -+ for (i = 0; i < n_freq_limits; i++) { -+ struct ieee80211_freq_range *limit = &freq_limits[i]; -+ -+ if (cfg80211_does_bw_fit_range(limit, -+ MHZ_TO_KHZ(chan->center_freq), -+ bw)) -+ return true; -+ } -+ -+ return false; -+} -+ -+static void wiphy_freq_limits_apply(struct wiphy *wiphy, -+ struct ieee80211_freq_range *freq_limits, -+ unsigned int n_freq_limits) -+{ -+ enum nl80211_band band; -+ int i; -+ -+ if (WARN_ON(!n_freq_limits)) -+ return; -+ -+ for (band = 0; band < NUM_NL80211_BANDS; band++) { -+ struct ieee80211_supported_band *sband = wiphy->bands[band]; -+ -+ if (!sband) -+ continue; -+ -+ for (i = 0; i < sband->n_channels; i++) { -+ struct ieee80211_channel *chan = &sband->channels[i]; -+ -+ if (chan->flags & IEEE80211_CHAN_DISABLED) -+ continue; -+ -+ if (!wiphy_freq_limits_valid_chan(wiphy, freq_limits, -+ n_freq_limits, -+ chan)) { -+ pr_debug("Disabling freq %d MHz as it's out of OF limits\n", -+ chan->center_freq); -+ chan->flags |= IEEE80211_CHAN_DISABLED; -+ } -+ } -+ } -+} -+ -+void wiphy_read_of_freq_limits(struct wiphy *wiphy) -+{ -+ struct device *dev = wiphy_dev(wiphy); -+ struct device_node *np; -+ struct property *prop; -+ struct ieee80211_freq_range *freq_limits; -+ unsigned int n_freq_limits; -+ const __be32 *p; -+ int len, i; -+ int err = 0; -+ -+ if (!dev) -+ return; -+ np = dev_of_node(dev); -+ if (!np) -+ return; -+ -+ prop = of_find_property(np, "ieee80211-freq-limit", &len); -+ if (!prop) -+ return; -+ -+ if (!len || len % sizeof(u32) || len / sizeof(u32) % 2) { -+ dev_err(dev, "ieee80211-freq-limit wrong format"); -+ return; -+ } -+ n_freq_limits = len / sizeof(u32) / 2; -+ -+ freq_limits = kcalloc(n_freq_limits, sizeof(*freq_limits), GFP_KERNEL); -+ if (!freq_limits) { -+ err = -ENOMEM; -+ goto out_kfree; -+ } -+ -+ p = NULL; -+ for (i = 0; i < n_freq_limits; i++) { -+ struct ieee80211_freq_range *limit = &freq_limits[i]; -+ -+ p = of_prop_next_u32(prop, p, &limit->start_freq_khz); -+ if (!p) { -+ err = -EINVAL; -+ goto out_kfree; -+ } -+ -+ p = of_prop_next_u32(prop, p, &limit->end_freq_khz); -+ if (!p) { -+ err = -EINVAL; -+ goto out_kfree; -+ } -+ -+ if (!limit->start_freq_khz || -+ !limit->end_freq_khz || -+ limit->start_freq_khz >= limit->end_freq_khz) { -+ err = -EINVAL; -+ goto out_kfree; -+ } -+ } -+ -+ wiphy_freq_limits_apply(wiphy, freq_limits, n_freq_limits); -+ -+out_kfree: -+ kfree(freq_limits); -+ if (err) -+ dev_err(dev, "Failed to get limits: %d\n", err); -+} -+EXPORT_SYMBOL(wiphy_read_of_freq_limits); diff --git a/package/kernel/mac80211/patches/347-ath9k-don-t-run-periodic-and-nf-calibation-at-the-sa.patch b/package/kernel/mac80211/patches/347-ath9k-don-t-run-periodic-and-nf-calibation-at-the-sa.patch deleted file mode 100644 index 529e1098b3..0000000000 --- a/package/kernel/mac80211/patches/347-ath9k-don-t-run-periodic-and-nf-calibation-at-the-sa.patch +++ /dev/null @@ -1,26 +0,0 @@ -From: Felix Fietkau -Date: Tue, 27 Dec 2016 23:16:23 +0100 -Subject: [PATCH] ath9k: don't run periodic and nf calibation at the same time - -The checks already prevents periodic cal from being started while noise -floor calibration runs. It is missing checks for the other way around. - -Signed-off-by: Felix Fietkau ---- - ---- a/drivers/net/wireless/ath/ath9k/ar9002_calib.c -+++ b/drivers/net/wireless/ath/ath9k/ar9002_calib.c -@@ -676,10 +676,10 @@ static int ar9002_hw_calibrate(struct at - return 0; - - ah->cal_list_curr = currCal = currCal->calNext; -- if (currCal->calState == CAL_WAITING) { -+ if (currCal->calState == CAL_WAITING) - ath9k_hw_reset_calibration(ah, currCal); -- return 0; -- } -+ -+ return 0; - } - - /* Do NF cal only at longer intervals */ diff --git a/package/kernel/mac80211/patches/348-mac80211-initialize-SMPS-field-in-HT-capabilities.patch b/package/kernel/mac80211/patches/348-mac80211-initialize-SMPS-field-in-HT-capabilities.patch deleted file mode 100644 index 118f535716..0000000000 --- a/package/kernel/mac80211/patches/348-mac80211-initialize-SMPS-field-in-HT-capabilities.patch +++ /dev/null @@ -1,41 +0,0 @@ -From: Felix Fietkau -Date: Wed, 11 Jan 2017 23:30:20 +0100 -Subject: [PATCH] mac80211: initialize SMPS field in HT capabilities - -ibss and mesh modes copy the ht capabilites from the band without -overriding the SMPS state. Unfortunately the default value 0 for the -SMPS field means static SMPS instead of disabled. - -This results in HT ibss and mesh setups using only single-stream rates, -even though SMPS is not supposed to be active. - -Initialize SMPS to disabled for all bands on ieee80211_hw_register to -ensure that the value is sane where it is not overriden with the real -SMPS state. - -Reported-by: Elektra Wagenrad -Signed-off-by: Felix Fietkau ---- - ---- a/net/mac80211/main.c -+++ b/net/mac80211/main.c -@@ -908,10 +908,15 @@ int ieee80211_register_hw(struct ieee802 - supp_ht = supp_ht || sband->ht_cap.ht_supported; - supp_vht = supp_vht || sband->vht_cap.vht_supported; - -- if (sband->ht_cap.ht_supported) -- local->rx_chains = -- max(ieee80211_mcs_to_chains(&sband->ht_cap.mcs), -- local->rx_chains); -+ if (!sband->ht_cap.ht_supported) -+ continue; -+ -+ local->rx_chains = -+ max(ieee80211_mcs_to_chains(&sband->ht_cap.mcs), -+ local->rx_chains); -+ -+ sband->ht_cap.cap |= WLAN_HT_CAP_SM_PS_DISABLED << -+ IEEE80211_HT_CAP_SM_PS_SHIFT; - - /* TODO: consider VHT for RX chains, hopefully it's the same */ - } diff --git a/package/kernel/mac80211/patches/349-mac80211-fix-legacy-invalid-rxrate.patch b/package/kernel/mac80211/patches/349-mac80211-fix-legacy-invalid-rxrate.patch deleted file mode 100644 index c160515892..0000000000 --- a/package/kernel/mac80211/patches/349-mac80211-fix-legacy-invalid-rxrate.patch +++ /dev/null @@ -1,60 +0,0 @@ -From a17d93ff3a950fefaea40e4a4bf3669b9137c533 Mon Sep 17 00:00:00 2001 -From: Ben Greear -Date: Wed, 14 Dec 2016 11:30:38 -0800 -Subject: [PATCH] mac80211: fix legacy and invalid rx-rate report - -This fixes obtaining the rate info via sta_set_sinfo -when the rx rate is invalid (for instance, on IBSS -interface that has received no frames from one of its -peers). - -Also initialize rinfo->flags for legacy rates, to not -rely on the whole sinfo being initialized to zero. - -Signed-off-by: Ben Greear -Signed-off-by: Johannes Berg ---- - net/mac80211/sta_info.c | 14 ++++++++------ - 1 file changed, 8 insertions(+), 6 deletions(-) - ---- a/net/mac80211/sta_info.c -+++ b/net/mac80211/sta_info.c -@@ -1975,6 +1975,7 @@ static void sta_stats_decode_rate(struct - u16 brate; - unsigned int shift; - -+ rinfo->flags = 0; - sband = local->hw.wiphy->bands[(rate >> 4) & 0xf]; - brate = sband->bitrates[rate & 0xf].bitrate; - if (rinfo->bw == RATE_INFO_BW_5) -@@ -1990,14 +1991,15 @@ static void sta_stats_decode_rate(struct - rinfo->flags |= RATE_INFO_FLAGS_SHORT_GI; - } - --static void sta_set_rate_info_rx(struct sta_info *sta, struct rate_info *rinfo) -+static int sta_set_rate_info_rx(struct sta_info *sta, struct rate_info *rinfo) - { - u16 rate = ACCESS_ONCE(sta_get_last_rx_stats(sta)->last_rate); - - if (rate == STA_STATS_RATE_INVALID) -- rinfo->flags = 0; -- else -- sta_stats_decode_rate(sta->local, rate, rinfo); -+ return -EINVAL; -+ -+ sta_stats_decode_rate(sta->local, rate, rinfo); -+ return 0; - } - - static void sta_set_tidstats(struct sta_info *sta, -@@ -2202,8 +2204,8 @@ void sta_set_sinfo(struct sta_info *sta, - } - - if (!(sinfo->filled & BIT(NL80211_STA_INFO_RX_BITRATE))) { -- sta_set_rate_info_rx(sta, &sinfo->rxrate); -- sinfo->filled |= BIT(NL80211_STA_INFO_RX_BITRATE); -+ if (sta_set_rate_info_rx(sta, &sinfo->rxrate) == 0) -+ sinfo->filled |= BIT(NL80211_STA_INFO_RX_BITRATE); - } - - sinfo->filled |= BIT(NL80211_STA_INFO_TID_STATS); diff --git a/package/kernel/mac80211/patches/350-mac80211-init-fastxmit-later.patch b/package/kernel/mac80211/patches/350-mac80211-init-fastxmit-later.patch deleted file mode 100644 index 0b640efea9..0000000000 --- a/package/kernel/mac80211/patches/350-mac80211-init-fastxmit-later.patch +++ /dev/null @@ -1,41 +0,0 @@ -From 35f432a03e41d3bf08c51ede917f94e2288fbe8c Mon Sep 17 00:00:00 2001 -From: Johannes Berg -Date: Mon, 2 Jan 2017 11:19:29 +0100 -Subject: [PATCH] mac80211: initialize fast-xmit 'info' later - -In ieee80211_xmit_fast(), 'info' is initialized to point to the skb -that's passed in, but that skb may later be replaced by a clone (if -it was shared), leading to an invalid pointer. - -This can lead to use-after-free and also later crashes since the -real SKB's info->hw_queue doesn't get initialized properly. - -Fix this by assigning info only later, when it's needed, after the -skb replacement (may have) happened. - -Cc: stable@vger.kernel.org -Reported-by: Ben Greear -Signed-off-by: Johannes Berg ---- - net/mac80211/tx.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - ---- a/net/mac80211/tx.c -+++ b/net/mac80211/tx.c -@@ -3297,7 +3297,7 @@ static bool ieee80211_xmit_fast(struct i - int extra_head = fast_tx->hdr_len - (ETH_HLEN - 2); - int hw_headroom = sdata->local->hw.extra_tx_headroom; - struct ethhdr eth; -- struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); -+ struct ieee80211_tx_info *info; - struct ieee80211_hdr *hdr = (void *)fast_tx->hdr; - struct ieee80211_tx_data tx; - ieee80211_tx_result r; -@@ -3361,6 +3361,7 @@ static bool ieee80211_xmit_fast(struct i - memcpy(skb->data + fast_tx->da_offs, eth.h_dest, ETH_ALEN); - memcpy(skb->data + fast_tx->sa_offs, eth.h_source, ETH_ALEN); - -+ info = IEEE80211_SKB_CB(skb); - memset(info, 0, sizeof(*info)); - info->band = fast_tx->band; - info->control.vif = &sdata->vif; diff --git a/package/kernel/mac80211/patches/351-mac80211-fix-tid-agg-null.patch b/package/kernel/mac80211/patches/351-mac80211-fix-tid-agg-null.patch deleted file mode 100644 index 9148cfa426..0000000000 --- a/package/kernel/mac80211/patches/351-mac80211-fix-tid-agg-null.patch +++ /dev/null @@ -1,99 +0,0 @@ -From 1c3d185a9a0b136a58e73b02912d593d0303d1da Mon Sep 17 00:00:00 2001 -From: Johannes Berg -Date: Tue, 18 Oct 2016 23:12:08 +0300 -Subject: [PATCH] mac80211: fix tid_agg_rx NULL dereference - -On drivers setting the SUPPORTS_REORDERING_BUFFER hardware flag, -we crash when the peer sends an AddBA request while we already -have a session open on the seame TID; this is because on those -drivers, the tid_agg_rx is left NULL even though the session is -valid, and the agg_session_valid bit is set. - -To fix this, store the dialog tokens outside the tid_agg_rx to -be able to compare them to the received AddBA request. - -Fixes: f89e07d4cf26 ("mac80211: agg-rx: refuse ADDBA Request with timeout update") -Reported-by: Emmanuel Grumbach -Signed-off-by: Johannes Berg ---- - net/mac80211/agg-rx.c | 8 ++------ - net/mac80211/debugfs_sta.c | 2 +- - net/mac80211/sta_info.h | 4 ++-- - 3 files changed, 5 insertions(+), 9 deletions(-) - ---- a/net/mac80211/agg-rx.c -+++ b/net/mac80211/agg-rx.c -@@ -315,11 +315,7 @@ void __ieee80211_start_rx_ba_session(str - mutex_lock(&sta->ampdu_mlme.mtx); - - if (test_bit(tid, sta->ampdu_mlme.agg_session_valid)) { -- tid_agg_rx = rcu_dereference_protected( -- sta->ampdu_mlme.tid_rx[tid], -- lockdep_is_held(&sta->ampdu_mlme.mtx)); -- -- if (tid_agg_rx->dialog_token == dialog_token) { -+ if (sta->ampdu_mlme.tid_rx_token[tid] == dialog_token) { - ht_dbg_ratelimited(sta->sdata, - "updated AddBA Req from %pM on tid %u\n", - sta->sta.addr, tid); -@@ -396,7 +392,6 @@ void __ieee80211_start_rx_ba_session(str - } - - /* update data */ -- tid_agg_rx->dialog_token = dialog_token; - tid_agg_rx->ssn = start_seq_num; - tid_agg_rx->head_seq_num = start_seq_num; - tid_agg_rx->buf_size = buf_size; -@@ -418,6 +413,7 @@ end: - if (status == WLAN_STATUS_SUCCESS) { - __set_bit(tid, sta->ampdu_mlme.agg_session_valid); - __clear_bit(tid, sta->ampdu_mlme.unexpected_agg); -+ sta->ampdu_mlme.tid_rx_token[tid] = dialog_token; - } - mutex_unlock(&sta->ampdu_mlme.mtx); - ---- a/net/mac80211/debugfs_sta.c -+++ b/net/mac80211/debugfs_sta.c -@@ -205,7 +205,7 @@ static ssize_t sta_agg_status_read(struc - p += scnprintf(p, sizeof(buf) + buf - p, "%02d", i); - p += scnprintf(p, sizeof(buf) + buf - p, "\t\t%x", !!tid_rx); - p += scnprintf(p, sizeof(buf) + buf - p, "\t%#.2x", -- tid_rx ? tid_rx->dialog_token : 0); -+ tid_rx ? sta->ampdu_mlme.tid_rx_token[i] : 0); - p += scnprintf(p, sizeof(buf) + buf - p, "\t%#.3x", - tid_rx ? tid_rx->ssn : 0); - ---- a/net/mac80211/sta_info.h -+++ b/net/mac80211/sta_info.h -@@ -184,7 +184,6 @@ struct tid_ampdu_tx { - * @ssn: Starting Sequence Number expected to be aggregated. - * @buf_size: buffer size for incoming A-MPDUs - * @timeout: reset timer value (in TUs). -- * @dialog_token: dialog token for aggregation session - * @rcu_head: RCU head used for freeing this struct - * @reorder_lock: serializes access to reorder buffer, see below. - * @auto_seq: used for offloaded BA sessions to automatically pick head_seq_and -@@ -213,7 +212,6 @@ struct tid_ampdu_rx { - u16 ssn; - u16 buf_size; - u16 timeout; -- u8 dialog_token; - bool auto_seq; - bool removed; - }; -@@ -225,6 +223,7 @@ struct tid_ampdu_rx { - * to tid_tx[idx], which are protected by the sta spinlock) - * tid_start_tx is also protected by sta->lock. - * @tid_rx: aggregation info for Rx per TID -- RCU protected -+ * @tid_rx_token: dialog tokens for valid aggregation sessions - * @tid_rx_timer_expired: bitmap indicating on which TIDs the - * RX timer expired until the work for it runs - * @tid_rx_stop_requested: bitmap indicating which BA sessions per TID the -@@ -243,6 +242,7 @@ struct sta_ampdu_mlme { - struct mutex mtx; - /* rx */ - struct tid_ampdu_rx __rcu *tid_rx[IEEE80211_NUM_TIDS]; -+ u8 tid_rx_token[IEEE80211_NUM_TIDS]; - unsigned long tid_rx_timer_expired[BITS_TO_LONGS(IEEE80211_NUM_TIDS)]; - unsigned long tid_rx_stop_requested[BITS_TO_LONGS(IEEE80211_NUM_TIDS)]; - unsigned long agg_session_valid[BITS_TO_LONGS(IEEE80211_NUM_TIDS)]; diff --git a/package/kernel/mac80211/patches/352-mac80211-prevent-skb-txq-mismatch.patch b/package/kernel/mac80211/patches/352-mac80211-prevent-skb-txq-mismatch.patch deleted file mode 100644 index 3822026352..0000000000 --- a/package/kernel/mac80211/patches/352-mac80211-prevent-skb-txq-mismatch.patch +++ /dev/null @@ -1,107 +0,0 @@ -From: Michal Kazior -Date: Fri, 13 Jan 2017 13:32:51 +0100 -Subject: [PATCH] mac80211: prevent skb/txq mismatch - -Station structure is considered as not uploaded -(to driver) until drv_sta_state() finishes. This -call is however done after the structure is -attached to mac80211 internal lists and hashes. -This means mac80211 can lookup (and use) station -structure before it is uploaded to a driver. - -If this happens (structure exists, but -sta->uploaded is false) fast_tx path can still be -taken. Deep in the fastpath call the sta->uploaded -is checked against to derive "pubsta" argument for -ieee80211_get_txq(). If sta->uploaded is false -(and sta is actually non-NULL) ieee80211_get_txq() -effectively downgraded to vif->txq. - -At first glance this may look innocent but coerces -mac80211 into a state that is almost guaranteed -(codel may drop offending skb) to crash because a -station-oriented skb gets queued up on -vif-oriented txq. The ieee80211_tx_dequeue() ends -up looking at info->control.flags and tries to use -txq->sta which in the fail case is NULL. - -It's probably pointless to pretend one can -downgrade skb from sta-txq to vif-txq. - -Since downgrading unicast traffic to vif->txq must -not be done there's no txq to put a frame on if -sta->uploaded is false. Therefore the code is made -to fall back to regular tx() op path if the -described condition is hit. - -Only drivers using wake_tx_queue were affected. - -Example crash dump before fix: - - Unable to handle kernel paging request at virtual address ffffe26c - PC is at ieee80211_tx_dequeue+0x204/0x690 [mac80211] - [] (ieee80211_tx_dequeue [mac80211]) from - [] (ath10k_mac_tx_push_txq+0x54/0x1c0 [ath10k_core]) - [] (ath10k_mac_tx_push_txq [ath10k_core]) from - [] (ath10k_htt_txrx_compl_task+0xd78/0x11d0 [ath10k_core]) - [] (ath10k_htt_txrx_compl_task [ath10k_core]) - [] (ath10k_pci_napi_poll+0x54/0xe8 [ath10k_pci]) - [] (ath10k_pci_napi_poll [ath10k_pci]) from - [] (net_rx_action+0xac/0x160) - -Reported-by: Mohammed Shafi Shajakhan -Signed-off-by: Michal Kazior ---- - ---- a/net/mac80211/tx.c -+++ b/net/mac80211/tx.c -@@ -798,7 +798,7 @@ static __le16 ieee80211_tx_next_seq(stru - - static struct txq_info *ieee80211_get_txq(struct ieee80211_local *local, - struct ieee80211_vif *vif, -- struct ieee80211_sta *pubsta, -+ struct sta_info *sta, - struct sk_buff *skb) - { - struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; -@@ -812,10 +812,13 @@ static struct txq_info *ieee80211_get_tx - if (!ieee80211_is_data(hdr->frame_control)) - return NULL; - -- if (pubsta) { -+ if (sta) { - u8 tid = skb->priority & IEEE80211_QOS_CTL_TID_MASK; - -- txq = pubsta->txq[tid]; -+ if (!sta->uploaded) -+ return NULL; -+ -+ txq = sta->sta.txq[tid]; - } else if (vif) { - txq = vif->txq; - } -@@ -1503,23 +1506,17 @@ static bool ieee80211_queue_skb(struct i - struct fq *fq = &local->fq; - struct ieee80211_vif *vif; - struct txq_info *txqi; -- struct ieee80211_sta *pubsta; - - if (!local->ops->wake_tx_queue || - sdata->vif.type == NL80211_IFTYPE_MONITOR) - return false; - -- if (sta && sta->uploaded) -- pubsta = &sta->sta; -- else -- pubsta = NULL; -- - if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) - sdata = container_of(sdata->bss, - struct ieee80211_sub_if_data, u.ap); - - vif = &sdata->vif; -- txqi = ieee80211_get_txq(local, vif, pubsta, skb); -+ txqi = ieee80211_get_txq(local, vif, sta, skb); - - if (!txqi) - return false; diff --git a/package/kernel/mac80211/patches/354-ath9k-rename-tx_complete_work-to-hw_check_work.patch b/package/kernel/mac80211/patches/354-ath9k-rename-tx_complete_work-to-hw_check_work.patch deleted file mode 100644 index 31a0277e1c..0000000000 --- a/package/kernel/mac80211/patches/354-ath9k-rename-tx_complete_work-to-hw_check_work.patch +++ /dev/null @@ -1,175 +0,0 @@ -From: Felix Fietkau -Date: Wed, 25 Jan 2017 12:57:05 +0100 -Subject: [PATCH] ath9k: rename tx_complete_work to hw_check_work - -Also include common MAC alive check. This should make the hang checks -more reliable for modes where beacons are not sent and is used as a -starting point for further hang check improvements - -Signed-off-by: Felix Fietkau ---- - ---- a/drivers/net/wireless/ath/ath9k/ath9k.h -+++ b/drivers/net/wireless/ath/ath9k/ath9k.h -@@ -108,7 +108,7 @@ int ath_descdma_setup(struct ath_softc * - #define ATH_AGGR_MIN_QDEPTH 2 - /* minimum h/w qdepth for non-aggregated traffic */ - #define ATH_NON_AGGR_MIN_QDEPTH 8 --#define ATH_TX_COMPLETE_POLL_INT 1000 -+#define ATH_HW_CHECK_POLL_INT 1000 - #define ATH_TXFIFO_DEPTH 8 - #define ATH_TX_ERROR 0x01 - -@@ -745,7 +745,7 @@ void ath9k_csa_update(struct ath_softc * - #define ATH_PAPRD_TIMEOUT 100 /* msecs */ - #define ATH_PLL_WORK_INTERVAL 100 - --void ath_tx_complete_poll_work(struct work_struct *work); -+void ath_hw_check_work(struct work_struct *work); - void ath_reset_work(struct work_struct *work); - bool ath_hw_check(struct ath_softc *sc); - void ath_hw_pll_work(struct work_struct *work); -@@ -1053,7 +1053,7 @@ struct ath_softc { - #ifdef CPTCFG_ATH9K_DEBUGFS - struct ath9k_debug debug; - #endif -- struct delayed_work tx_complete_work; -+ struct delayed_work hw_check_work; - struct delayed_work hw_pll_work; - struct timer_list sleep_timer; - ---- a/drivers/net/wireless/ath/ath9k/init.c -+++ b/drivers/net/wireless/ath/ath9k/init.c -@@ -681,6 +681,7 @@ static int ath9k_init_softc(u16 devid, s - INIT_WORK(&sc->hw_reset_work, ath_reset_work); - INIT_WORK(&sc->paprd_work, ath_paprd_calibrate); - INIT_DELAYED_WORK(&sc->hw_pll_work, ath_hw_pll_work); -+ INIT_DELAYED_WORK(&sc->hw_check_work, ath_hw_check_work); - - ath9k_init_channel_context(sc); - ---- a/drivers/net/wireless/ath/ath9k/link.c -+++ b/drivers/net/wireless/ath/ath9k/link.c -@@ -20,20 +20,13 @@ - * TX polling - checks if the TX engine is stuck somewhere - * and issues a chip reset if so. - */ --void ath_tx_complete_poll_work(struct work_struct *work) -+static bool ath_tx_complete_check(struct ath_softc *sc) - { -- struct ath_softc *sc = container_of(work, struct ath_softc, -- tx_complete_work.work); - struct ath_txq *txq; - int i; -- bool needreset = false; -- - -- if (sc->tx99_state) { -- ath_dbg(ath9k_hw_common(sc->sc_ah), RESET, -- "skip tx hung detection on tx99\n"); -- return; -- } -+ if (sc->tx99_state) -+ return true; - - for (i = 0; i < IEEE80211_NUM_ACS; i++) { - txq = sc->tx.txq_map[i]; -@@ -41,25 +34,36 @@ void ath_tx_complete_poll_work(struct wo - ath_txq_lock(sc, txq); - if (txq->axq_depth) { - if (txq->axq_tx_inprogress) { -- needreset = true; - ath_txq_unlock(sc, txq); -- break; -- } else { -- txq->axq_tx_inprogress = true; -+ goto reset; - } -+ -+ txq->axq_tx_inprogress = true; - } - ath_txq_unlock(sc, txq); - } - -- if (needreset) { -- ath_dbg(ath9k_hw_common(sc->sc_ah), RESET, -- "tx hung, resetting the chip\n"); -- ath9k_queue_reset(sc, RESET_TYPE_TX_HANG); -+ return true; -+ -+reset: -+ ath_dbg(ath9k_hw_common(sc->sc_ah), RESET, -+ "tx hung, resetting the chip\n"); -+ ath9k_queue_reset(sc, RESET_TYPE_TX_HANG); -+ return false; -+ -+} -+ -+void ath_hw_check_work(struct work_struct *work) -+{ -+ struct ath_softc *sc = container_of(work, struct ath_softc, -+ hw_check_work.work); -+ -+ if (!ath_hw_check(sc) || -+ !ath_tx_complete_check(sc)) - return; -- } - -- ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work, -- msecs_to_jiffies(ATH_TX_COMPLETE_POLL_INT)); -+ ieee80211_queue_delayed_work(sc->hw, &sc->hw_check_work, -+ msecs_to_jiffies(ATH_HW_CHECK_POLL_INT)); - } - - /* ---- a/drivers/net/wireless/ath/ath9k/main.c -+++ b/drivers/net/wireless/ath/ath9k/main.c -@@ -181,7 +181,7 @@ void ath9k_ps_restore(struct ath_softc * - static void __ath_cancel_work(struct ath_softc *sc) - { - cancel_work_sync(&sc->paprd_work); -- cancel_delayed_work_sync(&sc->tx_complete_work); -+ cancel_delayed_work_sync(&sc->hw_check_work); - cancel_delayed_work_sync(&sc->hw_pll_work); - - #ifdef CPTCFG_ATH9K_BTCOEX_SUPPORT -@@ -198,7 +198,8 @@ void ath_cancel_work(struct ath_softc *s - - void ath_restart_work(struct ath_softc *sc) - { -- ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work, 0); -+ ieee80211_queue_delayed_work(sc->hw, &sc->hw_check_work, -+ ATH_HW_CHECK_POLL_INT); - - if (AR_SREV_9340(sc->sc_ah) || AR_SREV_9330(sc->sc_ah)) - ieee80211_queue_delayed_work(sc->hw, &sc->hw_pll_work, -@@ -2091,7 +2092,7 @@ void __ath9k_flush(struct ieee80211_hw * - int timeout; - bool drain_txq; - -- cancel_delayed_work_sync(&sc->tx_complete_work); -+ cancel_delayed_work_sync(&sc->hw_check_work); - - if (ah->ah_flags & AH_UNPLUGGED) { - ath_dbg(common, ANY, "Device has been unplugged!\n"); -@@ -2129,7 +2130,8 @@ void __ath9k_flush(struct ieee80211_hw * - ath9k_ps_restore(sc); - } - -- ieee80211_queue_delayed_work(hw, &sc->tx_complete_work, 0); -+ ieee80211_queue_delayed_work(hw, &sc->hw_check_work, -+ ATH_HW_CHECK_POLL_INT); - } - - static bool ath9k_tx_frames_pending(struct ieee80211_hw *hw) ---- a/drivers/net/wireless/ath/ath9k/xmit.c -+++ b/drivers/net/wireless/ath/ath9k/xmit.c -@@ -2915,8 +2915,6 @@ int ath_tx_init(struct ath_softc *sc, in - return error; - } - -- INIT_DELAYED_WORK(&sc->tx_complete_work, ath_tx_complete_poll_work); -- - if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) - error = ath_tx_edma_init(sc); - diff --git a/package/kernel/mac80211/patches/355-ath9k_hw-check-if-the-chip-failed-to-wake-up.patch b/package/kernel/mac80211/patches/355-ath9k_hw-check-if-the-chip-failed-to-wake-up.patch deleted file mode 100644 index b0cb74ad05..0000000000 --- a/package/kernel/mac80211/patches/355-ath9k_hw-check-if-the-chip-failed-to-wake-up.patch +++ /dev/null @@ -1,30 +0,0 @@ -From: Felix Fietkau -Date: Wed, 25 Jan 2017 12:58:17 +0100 -Subject: [PATCH] ath9k_hw: check if the chip failed to wake up - -In an RFC patch, Sven Eckelmann and Simon Wunderlich reported: - -"QCA 802.11n chips (especially AR9330/AR9340) sometimes end up in a -state in which a read of AR_CFG always returns 0xdeadbeef. -This should not happen when when the power_mode of the device is -ATH9K_PM_AWAKE." - -Include the check for the default register state in the existing MAC -hang check. - -Signed-off-by: Felix Fietkau ---- - ---- a/drivers/net/wireless/ath/ath9k/hw.c -+++ b/drivers/net/wireless/ath/ath9k/hw.c -@@ -1624,6 +1624,10 @@ bool ath9k_hw_check_alive(struct ath_hw - int count = 50; - u32 reg, last_val; - -+ /* Check if chip failed to wake up */ -+ if (REG_READ(ah, AR_CFG) == 0xdeadbeef) -+ return false; -+ - if (AR_SREV_9300(ah)) - return !ath9k_hw_detect_mac_hang(ah); - diff --git a/package/kernel/mac80211/patches/356-0001-brcmfmac-avoid-maybe-uninitialized-warning-in-brcmf_.patch b/package/kernel/mac80211/patches/356-0001-brcmfmac-avoid-maybe-uninitialized-warning-in-brcmf_.patch deleted file mode 100644 index e7ca4be526..0000000000 --- a/package/kernel/mac80211/patches/356-0001-brcmfmac-avoid-maybe-uninitialized-warning-in-brcmf_.patch +++ /dev/null @@ -1,43 +0,0 @@ -From d3532ea6ce4ea501e421d130555e59edc2945f99 Mon Sep 17 00:00:00 2001 -From: Arnd Bergmann -Date: Tue, 18 Oct 2016 00:13:40 +0200 -Subject: [PATCH] brcmfmac: avoid maybe-uninitialized warning in - brcmf_cfg80211_start_ap -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -A bugfix added a sanity check around the assignment and use of the -'is_11d' variable, which looks correct to me, but as the function is -rather complex already, this confuses the compiler to the point where -it can no longer figure out if the variable is always initialized -correctly: - -brcm80211/brcmfmac/cfg80211.c: In function ‘brcmf_cfg80211_start_ap’: -brcm80211/brcmfmac/cfg80211.c:4586:10: error: ‘is_11d’ may be used uninitialized in this function [-Werror=maybe-uninitialized] - -This adds an initialization for the newly introduced case in which -the variable should not really be used, in order to make the warning -go away. - -Fixes: b3589dfe0212 ("brcmfmac: ignore 11d configuration errors") -Cc: Hante Meuleman -Cc: Arend van Spriel -Cc: Kalle Valo -Signed-off-by: Arnd Bergmann -Signed-off-by: Kalle Valo ---- - drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c -+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c -@@ -4516,7 +4516,7 @@ brcmf_cfg80211_start_ap(struct wiphy *wi - /* store current 11d setting */ - if (brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_REGULATORY, - &ifp->vif->is_11d)) { -- supports_11d = false; -+ is_11d = supports_11d = false; - } else { - country_ie = brcmf_parse_tlvs((u8 *)settings->beacon.tail, - settings->beacon.tail_len, diff --git a/package/kernel/mac80211/patches/356-0002-brcmfmac-proto-add-callback-for-queuing-TX-data.patch b/package/kernel/mac80211/patches/356-0002-brcmfmac-proto-add-callback-for-queuing-TX-data.patch deleted file mode 100644 index 1662eb5dbb..0000000000 --- a/package/kernel/mac80211/patches/356-0002-brcmfmac-proto-add-callback-for-queuing-TX-data.patch +++ /dev/null @@ -1,174 +0,0 @@ -From b073ac1fcf42376018f6db6acc885dfd2cc9ff02 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= -Date: Mon, 26 Sep 2016 23:51:44 +0200 -Subject: [PATCH] brcmfmac: proto: add callback for queuing TX data -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -So far our core code was calling brcmf_fws_process_skb which wasn't -a proper thing to do. If case of devices using msgbuf protocol fwsignal -shouldn't be used. It was an unnecessary extra layer simply calling -a protocol specifix txdata function. - -Please note we already have txdata callback, but it's used for calls -between bcdc and fwsignal so it couldn't be simply used there. - -This makes core code more generic (instead of bcdc/fwsignal specific). - -Signed-off-by: Rafał Miłecki -Signed-off-by: Kalle Valo ---- - drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcdc.c | 12 ++++++++++++ - drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c | 8 +++++++- - .../net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c | 15 +++++---------- - .../net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.h | 1 + - drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c | 6 +++--- - drivers/net/wireless/broadcom/brcm80211/brcmfmac/proto.c | 2 +- - drivers/net/wireless/broadcom/brcm80211/brcmfmac/proto.h | 9 +++++++++ - 7 files changed, 38 insertions(+), 15 deletions(-) - ---- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcdc.c -+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcdc.c -@@ -326,6 +326,17 @@ brcmf_proto_bcdc_hdrpull(struct brcmf_pu - return 0; - } - -+static int brcmf_proto_bcdc_tx_queue_data(struct brcmf_pub *drvr, int ifidx, -+ struct sk_buff *skb) -+{ -+ struct brcmf_if *ifp = brcmf_get_ifp(drvr, ifidx); -+ -+ if (!brcmf_fws_queue_skbs(drvr->fws)) -+ return brcmf_proto_txdata(drvr, ifidx, 0, skb); -+ -+ return brcmf_fws_process_skb(ifp, skb); -+} -+ - static int - brcmf_proto_bcdc_txdata(struct brcmf_pub *drvr, int ifidx, u8 offset, - struct sk_buff *pktbuf) -@@ -375,6 +386,7 @@ int brcmf_proto_bcdc_attach(struct brcmf - drvr->proto->hdrpull = brcmf_proto_bcdc_hdrpull; - drvr->proto->query_dcmd = brcmf_proto_bcdc_query_dcmd; - drvr->proto->set_dcmd = brcmf_proto_bcdc_set_dcmd; -+ drvr->proto->tx_queue_data = brcmf_proto_bcdc_tx_queue_data; - drvr->proto->txdata = brcmf_proto_bcdc_txdata; - drvr->proto->configure_addr_mode = brcmf_proto_bcdc_configure_addr_mode; - drvr->proto->delete_peer = brcmf_proto_bcdc_delete_peer; ---- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c -+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c -@@ -239,7 +239,13 @@ static netdev_tx_t brcmf_netdev_start_xm - if (eh->h_proto == htons(ETH_P_PAE)) - atomic_inc(&ifp->pend_8021x_cnt); - -- ret = brcmf_fws_process_skb(ifp, skb); -+ /* determine the priority */ -+ if ((skb->priority == 0) || (skb->priority > 7)) -+ skb->priority = cfg80211_classify8021d(skb, NULL); -+ -+ ret = brcmf_proto_tx_queue_data(drvr, ifp->ifidx, skb); -+ if (ret < 0) -+ brcmf_txfinalize(ifp, skb, false); - - done: - if (ret) { ---- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c -+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c -@@ -2100,16 +2100,6 @@ int brcmf_fws_process_skb(struct brcmf_i - int rc = 0; - - brcmf_dbg(DATA, "tx proto=0x%X\n", ntohs(eh->h_proto)); -- /* determine the priority */ -- if ((skb->priority == 0) || (skb->priority > 7)) -- skb->priority = cfg80211_classify8021d(skb, NULL); -- -- if (fws->avoid_queueing) { -- rc = brcmf_proto_txdata(drvr, ifp->ifidx, 0, skb); -- if (rc < 0) -- brcmf_txfinalize(ifp, skb, false); -- return rc; -- } - - /* set control buffer information */ - skcb->if_flags = 0; -@@ -2442,6 +2432,11 @@ void brcmf_fws_deinit(struct brcmf_pub * - kfree(fws); - } - -+bool brcmf_fws_queue_skbs(struct brcmf_fws_info *fws) -+{ -+ return !fws->avoid_queueing; -+} -+ - bool brcmf_fws_fc_active(struct brcmf_fws_info *fws) - { - if (!fws->creditmap_received) ---- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.h -+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.h -@@ -20,6 +20,7 @@ - - int brcmf_fws_init(struct brcmf_pub *drvr); - void brcmf_fws_deinit(struct brcmf_pub *drvr); -+bool brcmf_fws_queue_skbs(struct brcmf_fws_info *fws); - bool brcmf_fws_fc_active(struct brcmf_fws_info *fws); - void brcmf_fws_hdrpull(struct brcmf_if *ifp, s16 siglen, struct sk_buff *skb); - int brcmf_fws_process_skb(struct brcmf_if *ifp, struct sk_buff *skb); ---- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c -+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c -@@ -782,8 +782,8 @@ static int brcmf_msgbuf_schedule_txdata( - } - - --static int brcmf_msgbuf_txdata(struct brcmf_pub *drvr, int ifidx, -- u8 offset, struct sk_buff *skb) -+static int brcmf_msgbuf_tx_queue_data(struct brcmf_pub *drvr, int ifidx, -+ struct sk_buff *skb) - { - struct brcmf_msgbuf *msgbuf = (struct brcmf_msgbuf *)drvr->proto->pd; - struct brcmf_flowring *flow = msgbuf->flow; -@@ -1467,7 +1467,7 @@ int brcmf_proto_msgbuf_attach(struct brc - drvr->proto->hdrpull = brcmf_msgbuf_hdrpull; - drvr->proto->query_dcmd = brcmf_msgbuf_query_dcmd; - drvr->proto->set_dcmd = brcmf_msgbuf_set_dcmd; -- drvr->proto->txdata = brcmf_msgbuf_txdata; -+ drvr->proto->tx_queue_data = brcmf_msgbuf_tx_queue_data; - drvr->proto->configure_addr_mode = brcmf_msgbuf_configure_addr_mode; - drvr->proto->delete_peer = brcmf_msgbuf_delete_peer; - drvr->proto->add_tdls_peer = brcmf_msgbuf_add_tdls_peer; ---- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/proto.c -+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/proto.c -@@ -51,7 +51,7 @@ int brcmf_proto_attach(struct brcmf_pub - drvr->bus_if->proto_type); - goto fail; - } -- if ((proto->txdata == NULL) || (proto->hdrpull == NULL) || -+ if (!proto->tx_queue_data || (proto->hdrpull == NULL) || - (proto->query_dcmd == NULL) || (proto->set_dcmd == NULL) || - (proto->configure_addr_mode == NULL) || - (proto->delete_peer == NULL) || (proto->add_tdls_peer == NULL)) { ---- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/proto.h -+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/proto.h -@@ -33,6 +33,8 @@ struct brcmf_proto { - void *buf, uint len); - int (*set_dcmd)(struct brcmf_pub *drvr, int ifidx, uint cmd, void *buf, - uint len); -+ int (*tx_queue_data)(struct brcmf_pub *drvr, int ifidx, -+ struct sk_buff *skb); - int (*txdata)(struct brcmf_pub *drvr, int ifidx, u8 offset, - struct sk_buff *skb); - void (*configure_addr_mode)(struct brcmf_pub *drvr, int ifidx, -@@ -74,6 +76,13 @@ static inline int brcmf_proto_set_dcmd(s - { - return drvr->proto->set_dcmd(drvr, ifidx, cmd, buf, len); - } -+ -+static inline int brcmf_proto_tx_queue_data(struct brcmf_pub *drvr, int ifidx, -+ struct sk_buff *skb) -+{ -+ return drvr->proto->tx_queue_data(drvr, ifidx, skb); -+} -+ - static inline int brcmf_proto_txdata(struct brcmf_pub *drvr, int ifidx, - u8 offset, struct sk_buff *skb) - { diff --git a/package/kernel/mac80211/patches/356-0003-brcmfmac-print-name-of-connect-status-event.patch b/package/kernel/mac80211/patches/356-0003-brcmfmac-print-name-of-connect-status-event.patch deleted file mode 100644 index 1b2587ba51..0000000000 --- a/package/kernel/mac80211/patches/356-0003-brcmfmac-print-name-of-connect-status-event.patch +++ /dev/null @@ -1,62 +0,0 @@ -From e1c122d55f9ec5608ca98a9a846fd39cdf3ed7d7 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= -Date: Fri, 14 Oct 2016 09:45:59 +0200 -Subject: [PATCH] brcmfmac: print name of connect status event -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -This simplifies debugging. Format %s (%u) comes from similar debugging -message in brcmf_fweh_event_worker. - -Signed-off-by: Rafał Miłecki -Signed-off-by: Kalle Valo ---- - drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | 3 ++- - drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.c | 4 ++-- - drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.h | 2 ++ - 3 files changed, 6 insertions(+), 3 deletions(-) - ---- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c -+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c -@@ -5506,7 +5506,8 @@ brcmf_notify_connect_status_ap(struct br - u32 reason = e->reason; - struct station_info sinfo; - -- brcmf_dbg(CONN, "event %d, reason %d\n", event, reason); -+ brcmf_dbg(CONN, "event %s (%u), reason %d\n", -+ brcmf_fweh_event_name(event), event, reason); - if (event == BRCMF_E_LINK && reason == BRCMF_E_REASON_LINK_BSSCFG_DIS && - ndev != cfg_to_ndev(cfg)) { - brcmf_dbg(CONN, "AP mode link down\n"); ---- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.c -+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.c -@@ -69,7 +69,7 @@ static struct brcmf_fweh_event_name fweh - * - * @code: code to lookup. - */ --static const char *brcmf_fweh_event_name(enum brcmf_fweh_event_code code) -+const char *brcmf_fweh_event_name(enum brcmf_fweh_event_code code) - { - int i; - for (i = 0; i < ARRAY_SIZE(fweh_event_names); i++) { -@@ -79,7 +79,7 @@ static const char *brcmf_fweh_event_name - return "unknown"; - } - #else --static const char *brcmf_fweh_event_name(enum brcmf_fweh_event_code code) -+const char *brcmf_fweh_event_name(enum brcmf_fweh_event_code code) - { - return "nodebug"; - } ---- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.h -+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.h -@@ -287,6 +287,8 @@ struct brcmf_fweh_info { - void *data); - }; - -+const char *brcmf_fweh_event_name(enum brcmf_fweh_event_code code); -+ - void brcmf_fweh_attach(struct brcmf_pub *drvr); - void brcmf_fweh_detach(struct brcmf_pub *drvr); - int brcmf_fweh_register(struct brcmf_pub *drvr, enum brcmf_fweh_event_code code, diff --git a/package/kernel/mac80211/patches/356-0004-brcmfmac-update-beacon-IE-after-bss-up-and-clear-whe.patch b/package/kernel/mac80211/patches/356-0004-brcmfmac-update-beacon-IE-after-bss-up-and-clear-whe.patch deleted file mode 100644 index 01024f1efb..0000000000 --- a/package/kernel/mac80211/patches/356-0004-brcmfmac-update-beacon-IE-after-bss-up-and-clear-whe.patch +++ /dev/null @@ -1,45 +0,0 @@ -From f25ba69c638b24097840a96bd3caf5599f9a3616 Mon Sep 17 00:00:00 2001 -From: Wright Feng -Date: Fri, 18 Nov 2016 09:59:52 +0800 -Subject: [PATCH] brcmfmac: update beacon IE after bss up and clear when AP - stopped - -Firmware doesn't update beacon/Probe Response vendor IEs correctly when -bss is down, so we move brcmf_config_ap_mgmt_ie after BSS up. And host -driver should clear IEs when AP stopped so that the IEs in host side will -be synced with in firmware side. - -Signed-off-by: Wright Feng -Signed-off-by: Kalle Valo ---- - drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | 5 +++-- - 1 file changed, 3 insertions(+), 2 deletions(-) - ---- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c -+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c -@@ -4578,8 +4578,6 @@ brcmf_cfg80211_start_ap(struct wiphy *wi - brcmf_configure_opensecurity(ifp); - } - -- brcmf_config_ap_mgmt_ie(ifp->vif, &settings->beacon); -- - /* Parameters shared by all radio interfaces */ - if (!mbss) { - if ((supports_11d) && (is_11d != ifp->vif->is_11d)) { -@@ -4708,6 +4706,7 @@ brcmf_cfg80211_start_ap(struct wiphy *wi - WARN_ON(1); - } - -+ brcmf_config_ap_mgmt_ie(ifp->vif, &settings->beacon); - set_bit(BRCMF_VIF_STATUS_AP_CREATED, &ifp->vif->sme_state); - brcmf_net_setcarrier(ifp, true); - -@@ -4764,6 +4763,8 @@ static int brcmf_cfg80211_stop_ap(struct - err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_UP, 1); - if (err < 0) - brcmf_err("BRCMF_C_UP error %d\n", err); -+ -+ brcmf_vif_clear_mgmt_ies(ifp->vif); - } else { - bss_enable.bsscfgidx = cpu_to_le32(ifp->bsscfgidx); - bss_enable.enable = cpu_to_le32(0); diff --git a/package/kernel/mac80211/patches/356-ath9k-fix-race-condition-in-enabling-disabling-IRQs.patch b/package/kernel/mac80211/patches/356-ath9k-fix-race-condition-in-enabling-disabling-IRQs.patch deleted file mode 100644 index 7a41206132..0000000000 --- a/package/kernel/mac80211/patches/356-ath9k-fix-race-condition-in-enabling-disabling-IRQs.patch +++ /dev/null @@ -1,197 +0,0 @@ -From: Felix Fietkau -Date: Wed, 25 Jan 2017 15:10:37 +0100 -Subject: [PATCH] ath9k: fix race condition in enabling/disabling IRQs - -The code currently relies on refcounting to disable IRQs from within the -IRQ handler and re-enabling them again after the tasklet has run. - -However, due to race conditions sometimes the IRQ handler might be -called twice, or the tasklet may not run at all (if interrupted in the -middle of a reset). - -This can cause nasty imbalances in the irq-disable refcount which will -get the driver permanently stuck until the entire radio has been stopped -and started again (ath_reset will not recover from this). - -Instead of using this fragile logic, change the code to ensure that -running the irq handler during tasklet processing is safe, and leave the -refcount untouched. - -Cc: stable@vger.kernel.org -Signed-off-by: Felix Fietkau ---- - ---- a/drivers/net/wireless/ath/ath9k/ath9k.h -+++ b/drivers/net/wireless/ath/ath9k/ath9k.h -@@ -998,6 +998,7 @@ struct ath_softc { - struct survey_info *cur_survey; - struct survey_info survey[ATH9K_NUM_CHANNELS]; - -+ spinlock_t intr_lock; - struct tasklet_struct intr_tq; - struct tasklet_struct bcon_tasklet; - struct ath_hw *sc_ah; ---- a/drivers/net/wireless/ath/ath9k/init.c -+++ b/drivers/net/wireless/ath/ath9k/init.c -@@ -669,6 +669,7 @@ static int ath9k_init_softc(u16 devid, s - common->bt_ant_diversity = 1; - - spin_lock_init(&common->cc_lock); -+ spin_lock_init(&sc->intr_lock); - spin_lock_init(&sc->sc_serial_rw); - spin_lock_init(&sc->sc_pm_lock); - spin_lock_init(&sc->chan_lock); ---- a/drivers/net/wireless/ath/ath9k/mac.c -+++ b/drivers/net/wireless/ath/ath9k/mac.c -@@ -810,21 +810,12 @@ void ath9k_hw_disable_interrupts(struct - } - EXPORT_SYMBOL(ath9k_hw_disable_interrupts); - --void ath9k_hw_enable_interrupts(struct ath_hw *ah) -+static void __ath9k_hw_enable_interrupts(struct ath_hw *ah) - { - struct ath_common *common = ath9k_hw_common(ah); - u32 sync_default = AR_INTR_SYNC_DEFAULT; - u32 async_mask; - -- if (!(ah->imask & ATH9K_INT_GLOBAL)) -- return; -- -- if (!atomic_inc_and_test(&ah->intr_ref_cnt)) { -- ath_dbg(common, INTERRUPT, "Do not enable IER ref count %d\n", -- atomic_read(&ah->intr_ref_cnt)); -- return; -- } -- - if (AR_SREV_9340(ah) || AR_SREV_9550(ah) || AR_SREV_9531(ah) || - AR_SREV_9561(ah)) - sync_default &= ~AR_INTR_SYNC_HOST1_FATAL; -@@ -846,6 +837,39 @@ void ath9k_hw_enable_interrupts(struct a - ath_dbg(common, INTERRUPT, "AR_IMR 0x%x IER 0x%x\n", - REG_READ(ah, AR_IMR), REG_READ(ah, AR_IER)); - } -+ -+void ath9k_hw_resume_interrupts(struct ath_hw *ah) -+{ -+ struct ath_common *common = ath9k_hw_common(ah); -+ -+ if (!(ah->imask & ATH9K_INT_GLOBAL)) -+ return; -+ -+ if (atomic_read(&ah->intr_ref_cnt) != 0) { -+ ath_dbg(common, INTERRUPT, "Do not enable IER ref count %d\n", -+ atomic_read(&ah->intr_ref_cnt)); -+ return; -+ } -+ -+ __ath9k_hw_enable_interrupts(ah); -+} -+EXPORT_SYMBOL(ath9k_hw_resume_interrupts); -+ -+void ath9k_hw_enable_interrupts(struct ath_hw *ah) -+{ -+ struct ath_common *common = ath9k_hw_common(ah); -+ -+ if (!(ah->imask & ATH9K_INT_GLOBAL)) -+ return; -+ -+ if (!atomic_inc_and_test(&ah->intr_ref_cnt)) { -+ ath_dbg(common, INTERRUPT, "Do not enable IER ref count %d\n", -+ atomic_read(&ah->intr_ref_cnt)); -+ return; -+ } -+ -+ __ath9k_hw_enable_interrupts(ah); -+} - EXPORT_SYMBOL(ath9k_hw_enable_interrupts); - - void ath9k_hw_set_interrupts(struct ath_hw *ah) ---- a/drivers/net/wireless/ath/ath9k/mac.h -+++ b/drivers/net/wireless/ath/ath9k/mac.h -@@ -744,6 +744,7 @@ void ath9k_hw_set_interrupts(struct ath_ - void ath9k_hw_enable_interrupts(struct ath_hw *ah); - void ath9k_hw_disable_interrupts(struct ath_hw *ah); - void ath9k_hw_kill_interrupts(struct ath_hw *ah); -+void ath9k_hw_resume_interrupts(struct ath_hw *ah); - - void ar9002_hw_attach_mac_ops(struct ath_hw *ah); - ---- a/drivers/net/wireless/ath/ath9k/main.c -+++ b/drivers/net/wireless/ath/ath9k/main.c -@@ -374,21 +374,20 @@ void ath9k_tasklet(unsigned long data) - struct ath_common *common = ath9k_hw_common(ah); - enum ath_reset_type type; - unsigned long flags; -- u32 status = sc->intrstatus; -+ u32 status; - u32 rxmask; - -+ spin_lock_irqsave(&sc->intr_lock, flags); -+ status = sc->intrstatus; -+ sc->intrstatus = 0; -+ spin_unlock_irqrestore(&sc->intr_lock, flags); -+ - ath9k_ps_wakeup(sc); - spin_lock(&sc->sc_pcu_lock); - - if (status & ATH9K_INT_FATAL) { - type = RESET_TYPE_FATAL_INT; - ath9k_queue_reset(sc, type); -- -- /* -- * Increment the ref. counter here so that -- * interrupts are enabled in the reset routine. -- */ -- atomic_inc(&ah->intr_ref_cnt); - ath_dbg(common, RESET, "FATAL: Skipping interrupts\n"); - goto out; - } -@@ -404,11 +403,6 @@ void ath9k_tasklet(unsigned long data) - type = RESET_TYPE_BB_WATCHDOG; - ath9k_queue_reset(sc, type); - -- /* -- * Increment the ref. counter here so that -- * interrupts are enabled in the reset routine. -- */ -- atomic_inc(&ah->intr_ref_cnt); - ath_dbg(common, RESET, - "BB_WATCHDOG: Skipping interrupts\n"); - goto out; -@@ -421,7 +415,6 @@ void ath9k_tasklet(unsigned long data) - if ((sc->gtt_cnt >= MAX_GTT_CNT) && !ath9k_hw_check_alive(ah)) { - type = RESET_TYPE_TX_GTT; - ath9k_queue_reset(sc, type); -- atomic_inc(&ah->intr_ref_cnt); - ath_dbg(common, RESET, - "GTT: Skipping interrupts\n"); - goto out; -@@ -478,7 +471,7 @@ void ath9k_tasklet(unsigned long data) - ath9k_btcoex_handle_interrupt(sc, status); - - /* re-enable hardware interrupt */ -- ath9k_hw_enable_interrupts(ah); -+ ath9k_hw_resume_interrupts(ah); - out: - spin_unlock(&sc->sc_pcu_lock); - ath9k_ps_restore(sc); -@@ -542,7 +535,9 @@ irqreturn_t ath_isr(int irq, void *dev) - return IRQ_NONE; - - /* Cache the status */ -- sc->intrstatus = status; -+ spin_lock(&sc->intr_lock); -+ sc->intrstatus |= status; -+ spin_unlock(&sc->intr_lock); - - if (status & SCHED_INTR) - sched = true; -@@ -588,7 +583,7 @@ chip_reset: - - if (sched) { - /* turn off every interrupt */ -- ath9k_hw_disable_interrupts(ah); -+ ath9k_hw_kill_interrupts(ah); - tasklet_schedule(&sc->intr_tq); - } - diff --git a/package/kernel/mac80211/patches/357-0001-brcmfmac-add-pcie-host-dongle-interface-rev6-support.patch b/package/kernel/mac80211/patches/357-0001-brcmfmac-add-pcie-host-dongle-interface-rev6-support.patch deleted file mode 100644 index e09391332b..0000000000 --- a/package/kernel/mac80211/patches/357-0001-brcmfmac-add-pcie-host-dongle-interface-rev6-support.patch +++ /dev/null @@ -1,490 +0,0 @@ -From be4b092cab84b2ecc01ee7f4da6a044279430b6f Mon Sep 17 00:00:00 2001 -From: Franky Lin -Date: Wed, 23 Nov 2016 10:25:20 +0000 -Subject: [PATCH] brcmfmac: add pcie host dongle interface rev6 support - -In rev6 of pcie host dongle interface protocol, host needs to maximum -supported ring number from dongle shared memory and set up ring buffer -and ring indices offset accordingly. - -Reviewed-by: Hante Meuleman -Reviewed-by: Pieter-Paul Giesberts -Reviewed-by: Arend van Spriel -Signed-off-by: Franky Lin -Signed-off-by: Arend van Spriel -Signed-off-by: Kalle Valo ---- - .../net/wireless/broadcom/brcm80211/brcmfmac/bus.h | 10 +- - .../wireless/broadcom/brcm80211/brcmfmac/msgbuf.c | 38 +++-- - .../wireless/broadcom/brcm80211/brcmfmac/msgbuf.h | 4 + - .../wireless/broadcom/brcm80211/brcmfmac/pcie.c | 171 ++++++++++++--------- - 4 files changed, 132 insertions(+), 91 deletions(-) - ---- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h -+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h -@@ -22,10 +22,12 @@ - /* IDs of the 6 default common rings of msgbuf protocol */ - #define BRCMF_H2D_MSGRING_CONTROL_SUBMIT 0 - #define BRCMF_H2D_MSGRING_RXPOST_SUBMIT 1 -+#define BRCMF_H2D_MSGRING_FLOWRING_IDSTART 2 - #define BRCMF_D2H_MSGRING_CONTROL_COMPLETE 2 - #define BRCMF_D2H_MSGRING_TX_COMPLETE 3 - #define BRCMF_D2H_MSGRING_RX_COMPLETE 4 - -+ - #define BRCMF_NROF_H2D_COMMON_MSGRINGS 2 - #define BRCMF_NROF_D2H_COMMON_MSGRINGS 3 - #define BRCMF_NROF_COMMON_MSGRINGS (BRCMF_NROF_H2D_COMMON_MSGRINGS + \ -@@ -95,14 +97,18 @@ struct brcmf_bus_ops { - * @flowrings: commonrings which are dynamically created and destroyed for data. - * @rx_dataoffset: if set then all rx data has this this offset. - * @max_rxbufpost: maximum number of buffers to post for rx. -- * @nrof_flowrings: number of flowrings. -+ * @max_flowrings: maximum number of tx flow rings supported. -+ * @max_submissionrings: maximum number of submission rings(h2d) supported. -+ * @max_completionrings: maximum number of completion rings(d2h) supported. - */ - struct brcmf_bus_msgbuf { - struct brcmf_commonring *commonrings[BRCMF_NROF_COMMON_MSGRINGS]; - struct brcmf_commonring **flowrings; - u32 rx_dataoffset; - u32 max_rxbufpost; -- u32 nrof_flowrings; -+ u16 max_flowrings; -+ u16 max_submissionrings; -+ u16 max_completionrings; - }; - - ---- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c -+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c -@@ -87,11 +87,6 @@ struct msgbuf_common_hdr { - __le32 request_id; - }; - --struct msgbuf_buf_addr { -- __le32 low_addr; -- __le32 high_addr; --}; -- - struct msgbuf_ioctl_req_hdr { - struct msgbuf_common_hdr msg; - __le32 cmd; -@@ -227,7 +222,10 @@ struct brcmf_msgbuf { - struct brcmf_commonring **commonrings; - struct brcmf_commonring **flowrings; - dma_addr_t *flowring_dma_handle; -- u16 nrof_flowrings; -+ -+ u16 max_flowrings; -+ u16 max_submissionrings; -+ u16 max_completionrings; - - u16 rx_dataoffset; - u32 max_rxbufpost; -@@ -610,7 +608,7 @@ brcmf_msgbuf_flowring_create_worker(stru - create->msg.request_id = 0; - create->tid = brcmf_flowring_tid(msgbuf->flow, flowid); - create->flow_ring_id = cpu_to_le16(flowid + -- BRCMF_NROF_H2D_COMMON_MSGRINGS); -+ BRCMF_H2D_MSGRING_FLOWRING_IDSTART); - memcpy(create->sa, work->sa, ETH_ALEN); - memcpy(create->da, work->da, ETH_ALEN); - address = (u64)msgbuf->flowring_dma_handle[flowid]; -@@ -760,7 +758,7 @@ static void brcmf_msgbuf_txflow_worker(s - u32 flowid; - - msgbuf = container_of(worker, struct brcmf_msgbuf, txflow_work); -- for_each_set_bit(flowid, msgbuf->flow_map, msgbuf->nrof_flowrings) { -+ for_each_set_bit(flowid, msgbuf->flow_map, msgbuf->max_flowrings) { - clear_bit(flowid, msgbuf->flow_map); - brcmf_msgbuf_txflow(msgbuf, flowid); - } -@@ -866,7 +864,7 @@ brcmf_msgbuf_process_txstatus(struct brc - tx_status = (struct msgbuf_tx_status *)buf; - idx = le32_to_cpu(tx_status->msg.request_id); - flowid = le16_to_cpu(tx_status->compl_hdr.flow_ring_id); -- flowid -= BRCMF_NROF_H2D_COMMON_MSGRINGS; -+ flowid -= BRCMF_H2D_MSGRING_FLOWRING_IDSTART; - skb = brcmf_msgbuf_get_pktid(msgbuf->drvr->bus_if->dev, - msgbuf->tx_pktids, idx); - if (!skb) -@@ -1174,7 +1172,7 @@ brcmf_msgbuf_process_flow_ring_create_re - flowring_create_resp = (struct msgbuf_flowring_create_resp *)buf; - - flowid = le16_to_cpu(flowring_create_resp->compl_hdr.flow_ring_id); -- flowid -= BRCMF_NROF_H2D_COMMON_MSGRINGS; -+ flowid -= BRCMF_H2D_MSGRING_FLOWRING_IDSTART; - status = le16_to_cpu(flowring_create_resp->compl_hdr.status); - - if (status) { -@@ -1202,7 +1200,7 @@ brcmf_msgbuf_process_flow_ring_delete_re - flowring_delete_resp = (struct msgbuf_flowring_delete_resp *)buf; - - flowid = le16_to_cpu(flowring_delete_resp->compl_hdr.flow_ring_id); -- flowid -= BRCMF_NROF_H2D_COMMON_MSGRINGS; -+ flowid -= BRCMF_H2D_MSGRING_FLOWRING_IDSTART; - status = le16_to_cpu(flowring_delete_resp->compl_hdr.status); - - if (status) { -@@ -1307,7 +1305,7 @@ int brcmf_proto_msgbuf_rx_trigger(struct - brcmf_msgbuf_process_rx(msgbuf, buf); - - for_each_set_bit(flowid, msgbuf->txstatus_done_map, -- msgbuf->nrof_flowrings) { -+ msgbuf->max_flowrings) { - clear_bit(flowid, msgbuf->txstatus_done_map); - commonring = msgbuf->flowrings[flowid]; - qlen = brcmf_flowring_qlen(msgbuf->flow, flowid); -@@ -1349,7 +1347,7 @@ void brcmf_msgbuf_delete_flowring(struct - delete->msg.request_id = 0; - - delete->flow_ring_id = cpu_to_le16(flowid + -- BRCMF_NROF_H2D_COMMON_MSGRINGS); -+ BRCMF_H2D_MSGRING_FLOWRING_IDSTART); - delete->reason = 0; - - brcmf_dbg(MSGBUF, "Send Flow Delete Req flow ID %d, ifindex %d\n", -@@ -1427,10 +1425,10 @@ int brcmf_proto_msgbuf_attach(struct brc - - if_msgbuf = drvr->bus_if->msgbuf; - -- if (if_msgbuf->nrof_flowrings >= BRCMF_FLOWRING_HASHSIZE) { -+ if (if_msgbuf->max_flowrings >= BRCMF_FLOWRING_HASHSIZE) { - brcmf_err("driver not configured for this many flowrings %d\n", -- if_msgbuf->nrof_flowrings); -- if_msgbuf->nrof_flowrings = BRCMF_FLOWRING_HASHSIZE - 1; -+ if_msgbuf->max_flowrings); -+ if_msgbuf->max_flowrings = BRCMF_FLOWRING_HASHSIZE - 1; - } - - msgbuf = kzalloc(sizeof(*msgbuf), GFP_KERNEL); -@@ -1443,7 +1441,7 @@ int brcmf_proto_msgbuf_attach(struct brc - goto fail; - } - INIT_WORK(&msgbuf->txflow_work, brcmf_msgbuf_txflow_worker); -- count = BITS_TO_LONGS(if_msgbuf->nrof_flowrings); -+ count = BITS_TO_LONGS(if_msgbuf->max_flowrings); - count = count * sizeof(unsigned long); - msgbuf->flow_map = kzalloc(count, GFP_KERNEL); - if (!msgbuf->flow_map) -@@ -1479,8 +1477,8 @@ int brcmf_proto_msgbuf_attach(struct brc - msgbuf->commonrings = - (struct brcmf_commonring **)if_msgbuf->commonrings; - msgbuf->flowrings = (struct brcmf_commonring **)if_msgbuf->flowrings; -- msgbuf->nrof_flowrings = if_msgbuf->nrof_flowrings; -- msgbuf->flowring_dma_handle = kzalloc(msgbuf->nrof_flowrings * -+ msgbuf->max_flowrings = if_msgbuf->max_flowrings; -+ msgbuf->flowring_dma_handle = kzalloc(msgbuf->max_flowrings * - sizeof(*msgbuf->flowring_dma_handle), GFP_KERNEL); - if (!msgbuf->flowring_dma_handle) - goto fail; -@@ -1501,7 +1499,7 @@ int brcmf_proto_msgbuf_attach(struct brc - goto fail; - - msgbuf->flow = brcmf_flowring_attach(drvr->bus_if->dev, -- if_msgbuf->nrof_flowrings); -+ if_msgbuf->max_flowrings); - if (!msgbuf->flow) - goto fail; - ---- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.h -+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.h -@@ -31,6 +31,10 @@ - #define BRCMF_D2H_MSGRING_RX_COMPLETE_ITEMSIZE 32 - #define BRCMF_H2D_TXFLOWRING_ITEMSIZE 48 - -+struct msgbuf_buf_addr { -+ __le32 low_addr; -+ __le32 high_addr; -+}; - - int brcmf_proto_msgbuf_rx_trigger(struct device *dev); - void brcmf_msgbuf_delete_flowring(struct brcmf_pub *drvr, u16 flowid); ---- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c -+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c -@@ -135,7 +135,7 @@ static struct brcmf_firmware_mapping brc - BRCMF_PCIE_MB_INT_D2H3_DB1) - - #define BRCMF_PCIE_MIN_SHARED_VERSION 5 --#define BRCMF_PCIE_MAX_SHARED_VERSION 5 -+#define BRCMF_PCIE_MAX_SHARED_VERSION 6 - #define BRCMF_PCIE_SHARED_VERSION_MASK 0x00FF - #define BRCMF_PCIE_SHARED_DMA_INDEX 0x10000 - #define BRCMF_PCIE_SHARED_DMA_2B_IDX 0x100000 -@@ -166,17 +166,6 @@ static struct brcmf_firmware_mapping brc - #define BRCMF_RING_MEM_SZ 16 - #define BRCMF_RING_STATE_SZ 8 - --#define BRCMF_SHARED_RING_H2D_W_IDX_PTR_OFFSET 4 --#define BRCMF_SHARED_RING_H2D_R_IDX_PTR_OFFSET 8 --#define BRCMF_SHARED_RING_D2H_W_IDX_PTR_OFFSET 12 --#define BRCMF_SHARED_RING_D2H_R_IDX_PTR_OFFSET 16 --#define BRCMF_SHARED_RING_H2D_WP_HADDR_OFFSET 20 --#define BRCMF_SHARED_RING_H2D_RP_HADDR_OFFSET 28 --#define BRCMF_SHARED_RING_D2H_WP_HADDR_OFFSET 36 --#define BRCMF_SHARED_RING_D2H_RP_HADDR_OFFSET 44 --#define BRCMF_SHARED_RING_TCM_MEMLOC_OFFSET 0 --#define BRCMF_SHARED_RING_MAX_SUB_QUEUES 52 -- - #define BRCMF_DEF_MAX_RXBUFPOST 255 - - #define BRCMF_CONSOLE_BUFADDR_OFFSET 8 -@@ -231,7 +220,9 @@ struct brcmf_pcie_shared_info { - struct brcmf_pcie_ringbuf *commonrings[BRCMF_NROF_COMMON_MSGRINGS]; - struct brcmf_pcie_ringbuf *flowrings; - u16 max_rxbufpost; -- u32 nrof_flowrings; -+ u16 max_flowrings; -+ u16 max_submissionrings; -+ u16 max_completionrings; - u32 rx_dataoffset; - u32 htod_mb_data_addr; - u32 dtoh_mb_data_addr; -@@ -241,6 +232,7 @@ struct brcmf_pcie_shared_info { - dma_addr_t scratch_dmahandle; - void *ringupd; - dma_addr_t ringupd_dmahandle; -+ u8 version; - }; - - struct brcmf_pcie_core_info { -@@ -284,6 +276,36 @@ struct brcmf_pcie_ringbuf { - u8 id; - }; - -+/** -+ * struct brcmf_pcie_dhi_ringinfo - dongle/host interface shared ring info -+ * -+ * @ringmem: dongle memory pointer to ring memory location -+ * @h2d_w_idx_ptr: h2d ring write indices dongle memory pointers -+ * @h2d_r_idx_ptr: h2d ring read indices dongle memory pointers -+ * @d2h_w_idx_ptr: d2h ring write indices dongle memory pointers -+ * @d2h_r_idx_ptr: d2h ring read indices dongle memory pointers -+ * @h2d_w_idx_hostaddr: h2d ring write indices host memory pointers -+ * @h2d_r_idx_hostaddr: h2d ring read indices host memory pointers -+ * @d2h_w_idx_hostaddr: d2h ring write indices host memory pointers -+ * @d2h_r_idx_hostaddr: d2h ring reaD indices host memory pointers -+ * @max_flowrings: maximum number of tx flow rings supported. -+ * @max_submissionrings: maximum number of submission rings(h2d) supported. -+ * @max_completionrings: maximum number of completion rings(d2h) supported. -+ */ -+struct brcmf_pcie_dhi_ringinfo { -+ __le32 ringmem; -+ __le32 h2d_w_idx_ptr; -+ __le32 h2d_r_idx_ptr; -+ __le32 d2h_w_idx_ptr; -+ __le32 d2h_r_idx_ptr; -+ struct msgbuf_buf_addr h2d_w_idx_hostaddr; -+ struct msgbuf_buf_addr h2d_r_idx_hostaddr; -+ struct msgbuf_buf_addr d2h_w_idx_hostaddr; -+ struct msgbuf_buf_addr d2h_r_idx_hostaddr; -+ __le16 max_flowrings; -+ __le16 max_submissionrings; -+ __le16 max_completionrings; -+}; - - static const u32 brcmf_ring_max_item[BRCMF_NROF_COMMON_MSGRINGS] = { - BRCMF_H2D_MSGRING_CONTROL_SUBMIT_MAX_ITEM, -@@ -1054,26 +1076,35 @@ static int brcmf_pcie_init_ringbuffers(s - { - struct brcmf_pcie_ringbuf *ring; - struct brcmf_pcie_ringbuf *rings; -- u32 ring_addr; - u32 d2h_w_idx_ptr; - u32 d2h_r_idx_ptr; - u32 h2d_w_idx_ptr; - u32 h2d_r_idx_ptr; -- u32 addr; - u32 ring_mem_ptr; - u32 i; - u64 address; - u32 bufsz; -- u16 max_sub_queues; - u8 idx_offset; -- -- ring_addr = devinfo->shared.ring_info_addr; -- brcmf_dbg(PCIE, "Base ring addr = 0x%08x\n", ring_addr); -- addr = ring_addr + BRCMF_SHARED_RING_MAX_SUB_QUEUES; -- max_sub_queues = brcmf_pcie_read_tcm16(devinfo, addr); -+ struct brcmf_pcie_dhi_ringinfo ringinfo; -+ u16 max_flowrings; -+ u16 max_submissionrings; -+ u16 max_completionrings; -+ -+ memcpy_fromio(&ringinfo, devinfo->tcm + devinfo->shared.ring_info_addr, -+ sizeof(ringinfo)); -+ if (devinfo->shared.version >= 6) { -+ max_submissionrings = le16_to_cpu(ringinfo.max_submissionrings); -+ max_flowrings = le16_to_cpu(ringinfo.max_flowrings); -+ max_completionrings = le16_to_cpu(ringinfo.max_completionrings); -+ } else { -+ max_submissionrings = le16_to_cpu(ringinfo.max_flowrings); -+ max_flowrings = max_submissionrings - -+ BRCMF_NROF_H2D_COMMON_MSGRINGS; -+ max_completionrings = BRCMF_NROF_D2H_COMMON_MSGRINGS; -+ } - - if (devinfo->dma_idx_sz != 0) { -- bufsz = (BRCMF_NROF_D2H_COMMON_MSGRINGS + max_sub_queues) * -+ bufsz = (max_submissionrings + max_completionrings) * - devinfo->dma_idx_sz * 2; - devinfo->idxbuf = dma_alloc_coherent(&devinfo->pdev->dev, bufsz, - &devinfo->idxbuf_dmahandle, -@@ -1083,14 +1114,10 @@ static int brcmf_pcie_init_ringbuffers(s - } - - if (devinfo->dma_idx_sz == 0) { -- addr = ring_addr + BRCMF_SHARED_RING_D2H_W_IDX_PTR_OFFSET; -- d2h_w_idx_ptr = brcmf_pcie_read_tcm32(devinfo, addr); -- addr = ring_addr + BRCMF_SHARED_RING_D2H_R_IDX_PTR_OFFSET; -- d2h_r_idx_ptr = brcmf_pcie_read_tcm32(devinfo, addr); -- addr = ring_addr + BRCMF_SHARED_RING_H2D_W_IDX_PTR_OFFSET; -- h2d_w_idx_ptr = brcmf_pcie_read_tcm32(devinfo, addr); -- addr = ring_addr + BRCMF_SHARED_RING_H2D_R_IDX_PTR_OFFSET; -- h2d_r_idx_ptr = brcmf_pcie_read_tcm32(devinfo, addr); -+ d2h_w_idx_ptr = le32_to_cpu(ringinfo.d2h_w_idx_ptr); -+ d2h_r_idx_ptr = le32_to_cpu(ringinfo.d2h_r_idx_ptr); -+ h2d_w_idx_ptr = le32_to_cpu(ringinfo.h2d_w_idx_ptr); -+ h2d_r_idx_ptr = le32_to_cpu(ringinfo.h2d_r_idx_ptr); - idx_offset = sizeof(u32); - devinfo->write_ptr = brcmf_pcie_write_tcm16; - devinfo->read_ptr = brcmf_pcie_read_tcm16; -@@ -1103,34 +1130,42 @@ static int brcmf_pcie_init_ringbuffers(s - devinfo->read_ptr = brcmf_pcie_read_idx; - - h2d_w_idx_ptr = 0; -- addr = ring_addr + BRCMF_SHARED_RING_H2D_WP_HADDR_OFFSET; - address = (u64)devinfo->idxbuf_dmahandle; -- brcmf_pcie_write_tcm32(devinfo, addr, address & 0xffffffff); -- brcmf_pcie_write_tcm32(devinfo, addr + 4, address >> 32); -- -- h2d_r_idx_ptr = h2d_w_idx_ptr + max_sub_queues * idx_offset; -- addr = ring_addr + BRCMF_SHARED_RING_H2D_RP_HADDR_OFFSET; -- address += max_sub_queues * idx_offset; -- brcmf_pcie_write_tcm32(devinfo, addr, address & 0xffffffff); -- brcmf_pcie_write_tcm32(devinfo, addr + 4, address >> 32); -- -- d2h_w_idx_ptr = h2d_r_idx_ptr + max_sub_queues * idx_offset; -- addr = ring_addr + BRCMF_SHARED_RING_D2H_WP_HADDR_OFFSET; -- address += max_sub_queues * idx_offset; -- brcmf_pcie_write_tcm32(devinfo, addr, address & 0xffffffff); -- brcmf_pcie_write_tcm32(devinfo, addr + 4, address >> 32); -+ ringinfo.h2d_w_idx_hostaddr.low_addr = -+ cpu_to_le32(address & 0xffffffff); -+ ringinfo.h2d_w_idx_hostaddr.high_addr = -+ cpu_to_le32(address >> 32); -+ -+ h2d_r_idx_ptr = h2d_w_idx_ptr + -+ max_submissionrings * idx_offset; -+ address += max_submissionrings * idx_offset; -+ ringinfo.h2d_r_idx_hostaddr.low_addr = -+ cpu_to_le32(address & 0xffffffff); -+ ringinfo.h2d_r_idx_hostaddr.high_addr = -+ cpu_to_le32(address >> 32); -+ -+ d2h_w_idx_ptr = h2d_r_idx_ptr + -+ max_submissionrings * idx_offset; -+ address += max_submissionrings * idx_offset; -+ ringinfo.d2h_w_idx_hostaddr.low_addr = -+ cpu_to_le32(address & 0xffffffff); -+ ringinfo.d2h_w_idx_hostaddr.high_addr = -+ cpu_to_le32(address >> 32); - - d2h_r_idx_ptr = d2h_w_idx_ptr + -- BRCMF_NROF_D2H_COMMON_MSGRINGS * idx_offset; -- addr = ring_addr + BRCMF_SHARED_RING_D2H_RP_HADDR_OFFSET; -- address += BRCMF_NROF_D2H_COMMON_MSGRINGS * idx_offset; -- brcmf_pcie_write_tcm32(devinfo, addr, address & 0xffffffff); -- brcmf_pcie_write_tcm32(devinfo, addr + 4, address >> 32); -+ max_completionrings * idx_offset; -+ address += max_completionrings * idx_offset; -+ ringinfo.d2h_r_idx_hostaddr.low_addr = -+ cpu_to_le32(address & 0xffffffff); -+ ringinfo.d2h_r_idx_hostaddr.high_addr = -+ cpu_to_le32(address >> 32); -+ -+ memcpy_toio(devinfo->tcm + devinfo->shared.ring_info_addr, -+ &ringinfo, sizeof(ringinfo)); - brcmf_dbg(PCIE, "Using host memory indices\n"); - } - -- addr = ring_addr + BRCMF_SHARED_RING_TCM_MEMLOC_OFFSET; -- ring_mem_ptr = brcmf_pcie_read_tcm32(devinfo, addr); -+ ring_mem_ptr = le32_to_cpu(ringinfo.ringmem); - - for (i = 0; i < BRCMF_NROF_H2D_COMMON_MSGRINGS; i++) { - ring = brcmf_pcie_alloc_dma_and_ring(devinfo, i, ring_mem_ptr); -@@ -1161,20 +1196,19 @@ static int brcmf_pcie_init_ringbuffers(s - ring_mem_ptr += BRCMF_RING_MEM_SZ; - } - -- devinfo->shared.nrof_flowrings = -- max_sub_queues - BRCMF_NROF_H2D_COMMON_MSGRINGS; -- rings = kcalloc(devinfo->shared.nrof_flowrings, sizeof(*ring), -- GFP_KERNEL); -+ devinfo->shared.max_flowrings = max_flowrings; -+ devinfo->shared.max_submissionrings = max_submissionrings; -+ devinfo->shared.max_completionrings = max_completionrings; -+ rings = kcalloc(max_flowrings, sizeof(*ring), GFP_KERNEL); - if (!rings) - goto fail; - -- brcmf_dbg(PCIE, "Nr of flowrings is %d\n", -- devinfo->shared.nrof_flowrings); -+ brcmf_dbg(PCIE, "Nr of flowrings is %d\n", max_flowrings); - -- for (i = 0; i < devinfo->shared.nrof_flowrings; i++) { -+ for (i = 0; i < max_flowrings; i++) { - ring = &rings[i]; - ring->devinfo = devinfo; -- ring->id = i + BRCMF_NROF_COMMON_MSGRINGS; -+ ring->id = i + BRCMF_H2D_MSGRING_FLOWRING_IDSTART; - brcmf_commonring_register_cb(&ring->commonring, - brcmf_pcie_ring_mb_ring_bell, - brcmf_pcie_ring_mb_update_rptr, -@@ -1357,17 +1391,16 @@ brcmf_pcie_init_share_ram_info(struct br - { - struct brcmf_pcie_shared_info *shared; - u32 addr; -- u32 version; - - shared = &devinfo->shared; - shared->tcm_base_address = sharedram_addr; - - shared->flags = brcmf_pcie_read_tcm32(devinfo, sharedram_addr); -- version = shared->flags & BRCMF_PCIE_SHARED_VERSION_MASK; -- brcmf_dbg(PCIE, "PCIe protocol version %d\n", version); -- if ((version > BRCMF_PCIE_MAX_SHARED_VERSION) || -- (version < BRCMF_PCIE_MIN_SHARED_VERSION)) { -- brcmf_err("Unsupported PCIE version %d\n", version); -+ shared->version = (u8)(shared->flags & BRCMF_PCIE_SHARED_VERSION_MASK); -+ brcmf_dbg(PCIE, "PCIe protocol version %d\n", shared->version); -+ if ((shared->version > BRCMF_PCIE_MAX_SHARED_VERSION) || -+ (shared->version < BRCMF_PCIE_MIN_SHARED_VERSION)) { -+ brcmf_err("Unsupported PCIE version %d\n", shared->version); - return -EINVAL; - } - -@@ -1661,18 +1694,18 @@ static void brcmf_pcie_setup(struct devi - bus->msgbuf->commonrings[i] = - &devinfo->shared.commonrings[i]->commonring; - -- flowrings = kcalloc(devinfo->shared.nrof_flowrings, sizeof(*flowrings), -+ flowrings = kcalloc(devinfo->shared.max_flowrings, sizeof(*flowrings), - GFP_KERNEL); - if (!flowrings) - goto fail; - -- for (i = 0; i < devinfo->shared.nrof_flowrings; i++) -+ for (i = 0; i < devinfo->shared.max_flowrings; i++) - flowrings[i] = &devinfo->shared.flowrings[i].commonring; - bus->msgbuf->flowrings = flowrings; - - bus->msgbuf->rx_dataoffset = devinfo->shared.rx_dataoffset; - bus->msgbuf->max_rxbufpost = devinfo->shared.max_rxbufpost; -- bus->msgbuf->nrof_flowrings = devinfo->shared.nrof_flowrings; -+ bus->msgbuf->max_flowrings = devinfo->shared.max_flowrings; - - init_waitqueue_head(&devinfo->mbdata_resp_wait); - diff --git a/package/kernel/mac80211/patches/357-0002-brcmfmac-add-support-for-43341-chip.patch b/package/kernel/mac80211/patches/357-0002-brcmfmac-add-support-for-43341-chip.patch deleted file mode 100644 index edd7de33c7..0000000000 --- a/package/kernel/mac80211/patches/357-0002-brcmfmac-add-support-for-43341-chip.patch +++ /dev/null @@ -1,39 +0,0 @@ -From dc630dc5c753ccba97ce174f9c2894f802f9bd93 Mon Sep 17 00:00:00 2001 -From: Arend Van Spriel -Date: Wed, 23 Nov 2016 10:25:21 +0000 -Subject: [PATCH] brcmfmac: add support for 43341 chip - -This chip was already supported, but seems a device came up giving -a different chip identifier. So adding that effectively mapping to -the same firmware file as for 43340 chip. - -Reviewed-by: Hante Meuleman -Reviewed-by: Pieter-Paul Giesberts -Reviewed-by: Franky Lin -Signed-off-by: Arend van Spriel -Signed-off-by: Kalle Valo ---- - drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c | 1 + - drivers/net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h | 1 + - 2 files changed, 2 insertions(+) - ---- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c -+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c -@@ -621,6 +621,7 @@ static struct brcmf_firmware_mapping brc - BRCMF_FW_NVRAM_ENTRY(BRCM_CC_4330_CHIP_ID, 0xFFFFFFFF, 4330), - BRCMF_FW_NVRAM_ENTRY(BRCM_CC_4334_CHIP_ID, 0xFFFFFFFF, 4334), - BRCMF_FW_NVRAM_ENTRY(BRCM_CC_43340_CHIP_ID, 0xFFFFFFFF, 43340), -+ BRCMF_FW_NVRAM_ENTRY(BRCM_CC_43341_CHIP_ID, 0xFFFFFFFF, 43340), - BRCMF_FW_NVRAM_ENTRY(BRCM_CC_4335_CHIP_ID, 0xFFFFFFFF, 4335), - BRCMF_FW_NVRAM_ENTRY(BRCM_CC_43362_CHIP_ID, 0xFFFFFFFE, 43362), - BRCMF_FW_NVRAM_ENTRY(BRCM_CC_4339_CHIP_ID, 0xFFFFFFFF, 4339), ---- a/drivers/net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h -+++ b/drivers/net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h -@@ -36,6 +36,7 @@ - #define BRCM_CC_4330_CHIP_ID 0x4330 - #define BRCM_CC_4334_CHIP_ID 0x4334 - #define BRCM_CC_43340_CHIP_ID 43340 -+#define BRCM_CC_43341_CHIP_ID 43341 - #define BRCM_CC_43362_CHIP_ID 43362 - #define BRCM_CC_4335_CHIP_ID 0x4335 - #define BRCM_CC_4339_CHIP_ID 0x4339 diff --git a/package/kernel/mac80211/patches/357-0003-brcmfmac-move-pno-helper-functions-in-separate-sourc.patch b/package/kernel/mac80211/patches/357-0003-brcmfmac-move-pno-helper-functions-in-separate-sourc.patch deleted file mode 100644 index 94f2e6b972..0000000000 --- a/package/kernel/mac80211/patches/357-0003-brcmfmac-move-pno-helper-functions-in-separate-sourc.patch +++ /dev/null @@ -1,319 +0,0 @@ -From ac55136f43d3336c7b40238b779c404008229929 Mon Sep 17 00:00:00 2001 -From: Arend Van Spriel -Date: Wed, 23 Nov 2016 10:25:22 +0000 -Subject: [PATCH] brcmfmac: move pno helper functions in separate source file - -Introducing new source file for pno related functionality. Moving -existing pno functions. - -Reviewed-by: Hante Meuleman -Reviewed-by: Pieter-Paul Giesberts -Reviewed-by: Franky Lin -Signed-off-by: Arend van Spriel -Signed-off-by: Kalle Valo ---- - .../wireless/broadcom/brcm80211/brcmfmac/Makefile | 3 +- - .../broadcom/brcm80211/brcmfmac/cfg80211.c | 93 ++----------------- - .../net/wireless/broadcom/brcm80211/brcmfmac/pno.c | 100 +++++++++++++++++++++ - .../net/wireless/broadcom/brcm80211/brcmfmac/pno.h | 40 +++++++++ - 4 files changed, 150 insertions(+), 86 deletions(-) - create mode 100644 drivers/net/wireless/broadcom/brcm80211/brcmfmac/pno.c - create mode 100644 drivers/net/wireless/broadcom/brcm80211/brcmfmac/pno.h - ---- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/Makefile -+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/Makefile -@@ -35,7 +35,8 @@ brcmfmac-objs += \ - firmware.o \ - feature.o \ - btcoex.o \ -- vendor.o -+ vendor.o \ -+ pno.o - brcmfmac-$(CPTCFG_BRCMFMAC_PROTO_BCDC) += \ - bcdc.o - brcmfmac-$(CPTCFG_BRCMFMAC_PROTO_MSGBUF) += \ ---- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c -+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c -@@ -32,6 +32,7 @@ - #include "fwil_types.h" - #include "p2p.h" - #include "btcoex.h" -+#include "pno.h" - #include "cfg80211.h" - #include "feature.h" - #include "fwil.h" -@@ -41,16 +42,6 @@ - #include "common.h" - - #define BRCMF_SCAN_IE_LEN_MAX 2048 --#define BRCMF_PNO_VERSION 2 --#define BRCMF_PNO_TIME 30 --#define BRCMF_PNO_REPEAT 4 --#define BRCMF_PNO_FREQ_EXPO_MAX 3 --#define BRCMF_PNO_MAX_PFN_COUNT 16 --#define BRCMF_PNO_ENABLE_ADAPTSCAN_BIT 6 --#define BRCMF_PNO_HIDDEN_BIT 2 --#define BRCMF_PNO_WPA_AUTH_ANY 0xFFFFFFFF --#define BRCMF_PNO_SCAN_COMPLETE 1 --#define BRCMF_PNO_SCAN_INCOMPLETE 0 - - #define WPA_OUI "\x00\x50\xF2" /* WPA OUI */ - #define WPA_OUI_TYPE 1 -@@ -3323,76 +3314,6 @@ out_err: - return err; - } - --static int brcmf_dev_pno_clean(struct net_device *ndev) --{ -- int ret; -- -- /* Disable pfn */ -- ret = brcmf_fil_iovar_int_set(netdev_priv(ndev), "pfn", 0); -- if (ret == 0) { -- /* clear pfn */ -- ret = brcmf_fil_iovar_data_set(netdev_priv(ndev), "pfnclear", -- NULL, 0); -- } -- if (ret < 0) -- brcmf_err("failed code %d\n", ret); -- -- return ret; --} -- --static int brcmf_dev_pno_config(struct brcmf_if *ifp, -- struct cfg80211_sched_scan_request *request) --{ -- struct brcmf_pno_param_le pfn_param; -- struct brcmf_pno_macaddr_le pfn_mac; -- s32 err; -- u8 *mac_mask; -- int i; -- -- memset(&pfn_param, 0, sizeof(pfn_param)); -- pfn_param.version = cpu_to_le32(BRCMF_PNO_VERSION); -- -- /* set extra pno params */ -- pfn_param.flags = cpu_to_le16(1 << BRCMF_PNO_ENABLE_ADAPTSCAN_BIT); -- pfn_param.repeat = BRCMF_PNO_REPEAT; -- pfn_param.exp = BRCMF_PNO_FREQ_EXPO_MAX; -- -- /* set up pno scan fr */ -- pfn_param.scan_freq = cpu_to_le32(BRCMF_PNO_TIME); -- -- err = brcmf_fil_iovar_data_set(ifp, "pfn_set", &pfn_param, -- sizeof(pfn_param)); -- if (err) { -- brcmf_err("pfn_set failed, err=%d\n", err); -- return err; -- } -- -- /* Find out if mac randomization should be turned on */ -- if (!(request->flags & NL80211_SCAN_FLAG_RANDOM_ADDR)) -- return 0; -- -- pfn_mac.version = BRCMF_PFN_MACADDR_CFG_VER; -- pfn_mac.flags = BRCMF_PFN_MAC_OUI_ONLY | BRCMF_PFN_SET_MAC_UNASSOC; -- -- memcpy(pfn_mac.mac, request->mac_addr, ETH_ALEN); -- mac_mask = request->mac_addr_mask; -- for (i = 0; i < ETH_ALEN; i++) { -- pfn_mac.mac[i] &= mac_mask[i]; -- pfn_mac.mac[i] |= get_random_int() & ~(mac_mask[i]); -- } -- /* Clear multi bit */ -- pfn_mac.mac[0] &= 0xFE; -- /* Set locally administered */ -- pfn_mac.mac[0] |= 0x02; -- -- err = brcmf_fil_iovar_data_set(ifp, "pfn_macaddr", &pfn_mac, -- sizeof(pfn_mac)); -- if (err) -- brcmf_err("pfn_macaddr failed, err=%d\n", err); -- -- return err; --} -- - static int - brcmf_cfg80211_sched_scan_start(struct wiphy *wiphy, - struct net_device *ndev, -@@ -3436,15 +3357,16 @@ brcmf_cfg80211_sched_scan_start(struct w - - if (request->n_match_sets > 0) { - /* clean up everything */ -- ret = brcmf_dev_pno_clean(ndev); -+ ret = brcmf_pno_clean(ifp); - if (ret < 0) { - brcmf_err("failed error=%d\n", ret); - return ret; - } - - /* configure pno */ -- if (brcmf_dev_pno_config(ifp, request)) -- return -EINVAL; -+ ret = brcmf_pno_config(ifp, request); -+ if (ret < 0) -+ return ret; - - /* configure each match set */ - for (i = 0; i < request->n_match_sets; i++) { -@@ -3486,11 +3408,12 @@ static int brcmf_cfg80211_sched_scan_sto - struct net_device *ndev) - { - struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); -+ struct brcmf_if *ifp = netdev_priv(ndev); - - brcmf_dbg(SCAN, "enter\n"); -- brcmf_dev_pno_clean(ndev); -+ brcmf_pno_clean(ifp); - if (cfg->sched_escan) -- brcmf_notify_escan_complete(cfg, netdev_priv(ndev), true, true); -+ brcmf_notify_escan_complete(cfg, ifp, true, true); - return 0; - } - ---- /dev/null -+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pno.c -@@ -0,0 +1,100 @@ -+/* -+ * Copyright (c) 2016 Broadcom -+ * -+ * Permission to use, copy, modify, and/or distribute this software for any -+ * purpose with or without fee is hereby granted, provided that the above -+ * copyright notice and this permission notice appear in all copies. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY -+ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION -+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN -+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -+ */ -+#include -+#include -+ -+#include "core.h" -+#include "debug.h" -+#include "pno.h" -+#include "fwil.h" -+#include "fwil_types.h" -+ -+#define BRCMF_PNO_VERSION 2 -+#define BRCMF_PNO_TIME 30 -+#define BRCMF_PNO_REPEAT 4 -+#define BRCMF_PNO_FREQ_EXPO_MAX 3 -+#define BRCMF_PNO_ENABLE_ADAPTSCAN_BIT 6 -+#define BRCMF_PNO_SCAN_INCOMPLETE 0 -+ -+int brcmf_pno_clean(struct brcmf_if *ifp) -+{ -+ int ret; -+ -+ /* Disable pfn */ -+ ret = brcmf_fil_iovar_int_set(ifp, "pfn", 0); -+ if (ret == 0) { -+ /* clear pfn */ -+ ret = brcmf_fil_iovar_data_set(ifp, "pfnclear", NULL, 0); -+ } -+ if (ret < 0) -+ brcmf_err("failed code %d\n", ret); -+ -+ return ret; -+} -+ -+int brcmf_pno_config(struct brcmf_if *ifp, -+ struct cfg80211_sched_scan_request *request) -+{ -+ struct brcmf_pno_param_le pfn_param; -+ struct brcmf_pno_macaddr_le pfn_mac; -+ s32 err; -+ u8 *mac_mask; -+ int i; -+ -+ memset(&pfn_param, 0, sizeof(pfn_param)); -+ pfn_param.version = cpu_to_le32(BRCMF_PNO_VERSION); -+ -+ /* set extra pno params */ -+ pfn_param.flags = cpu_to_le16(1 << BRCMF_PNO_ENABLE_ADAPTSCAN_BIT); -+ pfn_param.repeat = BRCMF_PNO_REPEAT; -+ pfn_param.exp = BRCMF_PNO_FREQ_EXPO_MAX; -+ -+ /* set up pno scan fr */ -+ pfn_param.scan_freq = cpu_to_le32(BRCMF_PNO_TIME); -+ -+ err = brcmf_fil_iovar_data_set(ifp, "pfn_set", &pfn_param, -+ sizeof(pfn_param)); -+ if (err) { -+ brcmf_err("pfn_set failed, err=%d\n", err); -+ return err; -+ } -+ -+ /* Find out if mac randomization should be turned on */ -+ if (!(request->flags & NL80211_SCAN_FLAG_RANDOM_ADDR)) -+ return 0; -+ -+ pfn_mac.version = BRCMF_PFN_MACADDR_CFG_VER; -+ pfn_mac.flags = BRCMF_PFN_MAC_OUI_ONLY | BRCMF_PFN_SET_MAC_UNASSOC; -+ -+ memcpy(pfn_mac.mac, request->mac_addr, ETH_ALEN); -+ mac_mask = request->mac_addr_mask; -+ for (i = 0; i < ETH_ALEN; i++) { -+ pfn_mac.mac[i] &= mac_mask[i]; -+ pfn_mac.mac[i] |= get_random_int() & ~(mac_mask[i]); -+ } -+ /* Clear multi bit */ -+ pfn_mac.mac[0] &= 0xFE; -+ /* Set locally administered */ -+ pfn_mac.mac[0] |= 0x02; -+ -+ err = brcmf_fil_iovar_data_set(ifp, "pfn_macaddr", &pfn_mac, -+ sizeof(pfn_mac)); -+ if (err) -+ brcmf_err("pfn_macaddr failed, err=%d\n", err); -+ -+ return err; -+} -+ ---- /dev/null -+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pno.h -@@ -0,0 +1,40 @@ -+/* -+ * Copyright (c) 2016 Broadcom -+ * -+ * Permission to use, copy, modify, and/or distribute this software for any -+ * purpose with or without fee is hereby granted, provided that the above -+ * copyright notice and this permission notice appear in all copies. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY -+ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION -+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN -+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -+ */ -+#ifndef _BRCMF_PNO_H -+#define _BRCMF_PNO_H -+ -+#define BRCMF_PNO_SCAN_COMPLETE 1 -+#define BRCMF_PNO_WPA_AUTH_ANY 0xFFFFFFFF -+#define BRCMF_PNO_HIDDEN_BIT 2 -+#define BRCMF_PNO_MAX_PFN_COUNT 16 -+ -+/** -+ * brcmf_pno_clean - disable and clear pno in firmware. -+ * -+ * @ifp: interface object used. -+ */ -+int brcmf_pno_clean(struct brcmf_if *ifp); -+ -+/** -+ * brcmf_pno_config - configure pno parameters. -+ * -+ * @ifp: interface object used. -+ * @request: scheduled scan parameters. -+ */ -+int brcmf_pno_config(struct brcmf_if *ifp, -+ struct cfg80211_sched_scan_request *request); -+ -+#endif /* _BRCMF_PNO_H */ diff --git a/package/kernel/mac80211/patches/357-0004-brcmfmac-fix-handling-ssids-in-.sched_scan_start-cal.patch b/package/kernel/mac80211/patches/357-0004-brcmfmac-fix-handling-ssids-in-.sched_scan_start-cal.patch deleted file mode 100644 index f1934af71c..0000000000 --- a/package/kernel/mac80211/patches/357-0004-brcmfmac-fix-handling-ssids-in-.sched_scan_start-cal.patch +++ /dev/null @@ -1,221 +0,0 @@ -From 3e2e86ab19c2a43953de30089c5411c580ddb5f7 Mon Sep 17 00:00:00 2001 -From: Arend Van Spriel -Date: Wed, 23 Nov 2016 10:25:23 +0000 -Subject: [PATCH] brcmfmac: fix handling ssids in .sched_scan_start() callback - -The ssids list in the scheduled scan request were not properly taken -into account when configuring in firmware. The hidden bit was set for -any ssid resulting in active scanning for all. Only set it for ssids -that are in the ssids list. - -Reviewed-by: Hante Meuleman -Reviewed-by: Pieter-Paul Giesberts -Reviewed-by: Franky Lin -Signed-off-by: Arend van Spriel -Signed-off-by: Kalle Valo ---- - .../broadcom/brcm80211/brcmfmac/cfg80211.c | 103 ++++++++++----------- - .../net/wireless/broadcom/brcm80211/brcmfmac/pno.c | 18 ++++ - .../net/wireless/broadcom/brcm80211/brcmfmac/pno.h | 12 ++- - 3 files changed, 76 insertions(+), 57 deletions(-) - ---- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c -+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c -@@ -3314,19 +3314,37 @@ out_err: - return err; - } - -+static bool brcmf_is_ssid_active(struct cfg80211_ssid *ssid, -+ struct cfg80211_sched_scan_request *req) -+{ -+ int i; -+ -+ if (!ssid || !req->ssids || !req->n_ssids) -+ return false; -+ -+ for (i = 0; i < req->n_ssids; i++) { -+ if (ssid->ssid_len == req->ssids[i].ssid_len) { -+ if (!strncmp(ssid->ssid, req->ssids[i].ssid, -+ ssid->ssid_len)) -+ return true; -+ } -+ } -+ return false; -+} -+ - static int - brcmf_cfg80211_sched_scan_start(struct wiphy *wiphy, - struct net_device *ndev, -- struct cfg80211_sched_scan_request *request) -+ struct cfg80211_sched_scan_request *req) - { - struct brcmf_if *ifp = netdev_priv(ndev); - struct brcmf_cfg80211_info *cfg = wiphy_priv(wiphy); -- struct brcmf_pno_net_param_le pfn; -+ struct cfg80211_ssid *ssid; - int i; - int ret = 0; - - brcmf_dbg(SCAN, "Enter n_match_sets:%d n_ssids:%d\n", -- request->n_match_sets, request->n_ssids); -+ req->n_match_sets, req->n_ssids); - if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) { - brcmf_err("Scanning already: status (%lu)\n", cfg->scan_status); - return -EAGAIN; -@@ -3337,71 +3355,46 @@ brcmf_cfg80211_sched_scan_start(struct w - return -EAGAIN; - } - -- if (!request->n_ssids || !request->n_match_sets) { -- brcmf_dbg(SCAN, "Invalid sched scan req!! n_ssids:%d\n", -- request->n_ssids); -+ if (req->n_match_sets <= 0) { -+ brcmf_dbg(SCAN, "invalid number of matchsets specified: %d\n", -+ req->n_match_sets); - return -EINVAL; - } - -- if (request->n_ssids > 0) { -- for (i = 0; i < request->n_ssids; i++) { -- /* Active scan req for ssids */ -- brcmf_dbg(SCAN, ">>> Active scan req for ssid (%s)\n", -- request->ssids[i].ssid); -- -- /* match_set ssids is a supert set of n_ssid list, -- * so we need not add these set separately. -- */ -- } -+ /* clean up everything */ -+ ret = brcmf_pno_clean(ifp); -+ if (ret < 0) { -+ brcmf_err("failed error=%d\n", ret); -+ return ret; - } - -- if (request->n_match_sets > 0) { -- /* clean up everything */ -- ret = brcmf_pno_clean(ifp); -- if (ret < 0) { -- brcmf_err("failed error=%d\n", ret); -- return ret; -+ /* configure pno */ -+ ret = brcmf_pno_config(ifp, req); -+ if (ret < 0) -+ return ret; -+ -+ /* configure each match set */ -+ for (i = 0; i < req->n_match_sets; i++) { -+ -+ ssid = &req->match_sets[i].ssid; -+ -+ if (!ssid->ssid_len) { -+ brcmf_err("skip broadcast ssid\n"); -+ continue; - } - -- /* configure pno */ -- ret = brcmf_pno_config(ifp, request); -+ ret = brcmf_pno_add_ssid(ifp, ssid, -+ brcmf_is_ssid_active(ssid, req)); - if (ret < 0) -- return ret; -- -- /* configure each match set */ -- for (i = 0; i < request->n_match_sets; i++) { -- struct cfg80211_ssid *ssid; -- u32 ssid_len; -- -- ssid = &request->match_sets[i].ssid; -- ssid_len = ssid->ssid_len; -- -- if (!ssid_len) { -- brcmf_err("skip broadcast ssid\n"); -- continue; -- } -- pfn.auth = cpu_to_le32(WLAN_AUTH_OPEN); -- pfn.wpa_auth = cpu_to_le32(BRCMF_PNO_WPA_AUTH_ANY); -- pfn.wsec = cpu_to_le32(0); -- pfn.infra = cpu_to_le32(1); -- pfn.flags = cpu_to_le32(1 << BRCMF_PNO_HIDDEN_BIT); -- pfn.ssid.SSID_len = cpu_to_le32(ssid_len); -- memcpy(pfn.ssid.SSID, ssid->ssid, ssid_len); -- ret = brcmf_fil_iovar_data_set(ifp, "pfn_add", &pfn, -- sizeof(pfn)); - brcmf_dbg(SCAN, ">>> PNO filter %s for ssid (%s)\n", - ret == 0 ? "set" : "failed", ssid->ssid); -- } -- /* Enable the PNO */ -- if (brcmf_fil_iovar_int_set(ifp, "pfn", 1) < 0) { -- brcmf_err("PNO enable failed!! ret=%d\n", ret); -- return -EINVAL; -- } -- } else { -- return -EINVAL; - } -+ /* Enable the PNO */ -+ ret = brcmf_fil_iovar_int_set(ifp, "pfn", 1); -+ if (ret < 0) -+ brcmf_err("PNO enable failed!! ret=%d\n", ret); - -- return 0; -+ return ret; - } - - static int brcmf_cfg80211_sched_scan_stop(struct wiphy *wiphy, ---- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pno.c -+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pno.c -@@ -28,6 +28,8 @@ - #define BRCMF_PNO_FREQ_EXPO_MAX 3 - #define BRCMF_PNO_ENABLE_ADAPTSCAN_BIT 6 - #define BRCMF_PNO_SCAN_INCOMPLETE 0 -+#define BRCMF_PNO_WPA_AUTH_ANY 0xFFFFFFFF -+#define BRCMF_PNO_HIDDEN_BIT 2 - - int brcmf_pno_clean(struct brcmf_if *ifp) - { -@@ -98,3 +100,19 @@ int brcmf_pno_config(struct brcmf_if *if - return err; - } - -+int brcmf_pno_add_ssid(struct brcmf_if *ifp, struct cfg80211_ssid *ssid, -+ bool active) -+{ -+ struct brcmf_pno_net_param_le pfn; -+ -+ pfn.auth = cpu_to_le32(WLAN_AUTH_OPEN); -+ pfn.wpa_auth = cpu_to_le32(BRCMF_PNO_WPA_AUTH_ANY); -+ pfn.wsec = cpu_to_le32(0); -+ pfn.infra = cpu_to_le32(1); -+ if (active) -+ pfn.flags = cpu_to_le32(1 << BRCMF_PNO_HIDDEN_BIT); -+ pfn.ssid.SSID_len = cpu_to_le32(ssid->ssid_len); -+ memcpy(pfn.ssid.SSID, ssid->ssid, ssid->ssid_len); -+ return brcmf_fil_iovar_data_set(ifp, "pfn_add", &pfn, sizeof(pfn)); -+} -+ ---- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pno.h -+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pno.h -@@ -17,8 +17,6 @@ - #define _BRCMF_PNO_H - - #define BRCMF_PNO_SCAN_COMPLETE 1 --#define BRCMF_PNO_WPA_AUTH_ANY 0xFFFFFFFF --#define BRCMF_PNO_HIDDEN_BIT 2 - #define BRCMF_PNO_MAX_PFN_COUNT 16 - - /** -@@ -37,4 +35,14 @@ int brcmf_pno_clean(struct brcmf_if *ifp - int brcmf_pno_config(struct brcmf_if *ifp, - struct cfg80211_sched_scan_request *request); - -+/** -+ * brcmf_pno_add_ssid - add ssid for pno in firmware. -+ * -+ * @ifp: interface object used. -+ * @ssid: ssid information. -+ * @active: indicate this ssid needs to be actively probed. -+ */ -+int brcmf_pno_add_ssid(struct brcmf_if *ifp, struct cfg80211_ssid *ssid, -+ bool active); -+ - #endif /* _BRCMF_PNO_H */ diff --git a/package/kernel/mac80211/patches/357-0005-brcmfmac-change-prototype-for-brcmf_do_escan.patch b/package/kernel/mac80211/patches/357-0005-brcmfmac-change-prototype-for-brcmf_do_escan.patch deleted file mode 100644 index 07b353ba3b..0000000000 --- a/package/kernel/mac80211/patches/357-0005-brcmfmac-change-prototype-for-brcmf_do_escan.patch +++ /dev/null @@ -1,58 +0,0 @@ -From ab5981c830339b945ddbedc314567a9e5f506d72 Mon Sep 17 00:00:00 2001 -From: Arend Van Spriel -Date: Wed, 23 Nov 2016 10:25:24 +0000 -Subject: [PATCH] brcmfmac: change prototype for brcmf_do_escan() - -Reduce the number of parameters as the removed ones can be obtained -through struct brcmf_if parameter. - -Reviewed-by: Hante Meuleman -Reviewed-by: Pieter-Paul Giesberts -Reviewed-by: Franky Lin -Signed-off-by: Arend van Spriel -Signed-off-by: Kalle Valo ---- - drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | 10 +++++----- - 1 file changed, 5 insertions(+), 5 deletions(-) - ---- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c -+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c -@@ -1080,9 +1080,9 @@ exit: - } - - static s32 --brcmf_do_escan(struct brcmf_cfg80211_info *cfg, struct wiphy *wiphy, -- struct brcmf_if *ifp, struct cfg80211_scan_request *request) -+brcmf_do_escan(struct brcmf_if *ifp, struct cfg80211_scan_request *request) - { -+ struct brcmf_cfg80211_info *cfg = ifp->drvr->config; - s32 err; - u32 passive_scan; - struct brcmf_scan_results *results; -@@ -1090,7 +1090,7 @@ brcmf_do_escan(struct brcmf_cfg80211_inf - - brcmf_dbg(SCAN, "Enter\n"); - escan->ifp = ifp; -- escan->wiphy = wiphy; -+ escan->wiphy = cfg->wiphy; - escan->escan_state = WL_ESCAN_STATE_SCANNING; - passive_scan = cfg->active_scan ? 0 : 1; - err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PASSIVE_SCAN, -@@ -1170,7 +1170,7 @@ brcmf_cfg80211_escan(struct wiphy *wiphy - if (err) - goto scan_out; - -- err = brcmf_do_escan(cfg, wiphy, vif->ifp, request); -+ err = brcmf_do_escan(vif->ifp, request); - if (err) - goto scan_out; - } else { -@@ -3289,7 +3289,7 @@ brcmf_notify_sched_scan_results(struct b - - set_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status); - cfg->escan_info.run = brcmf_run_escan; -- err = brcmf_do_escan(cfg, wiphy, ifp, request); -+ err = brcmf_do_escan(ifp, request); - if (err) { - clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status); - goto out_err; diff --git a/package/kernel/mac80211/patches/357-0006-brcmfmac-make-internal-escan-more-generic.patch b/package/kernel/mac80211/patches/357-0006-brcmfmac-make-internal-escan-more-generic.patch deleted file mode 100644 index 84a69f0739..0000000000 --- a/package/kernel/mac80211/patches/357-0006-brcmfmac-make-internal-escan-more-generic.patch +++ /dev/null @@ -1,306 +0,0 @@ -From fa85b30a908455ff25def3a5f319aad272ef4862 Mon Sep 17 00:00:00 2001 -From: Arend Van Spriel -Date: Wed, 23 Nov 2016 10:25:25 +0000 -Subject: [PATCH] brcmfmac: make internal escan more generic - -For scheduled scan we initiate an escan in firmware to obtain more -info missing from the scheduled scan notification we get from firmware. -For upcoming functionality this is also required so make it a bit -more generic. - -Reviewed-by: Hante Meuleman -Reviewed-by: Pieter-Paul Giesberts -Reviewed-by: Franky Lin -Signed-off-by: Arend van Spriel -Signed-off-by: Kalle Valo ---- - .../broadcom/brcm80211/brcmfmac/cfg80211.c | 187 ++++++++++++--------- - .../broadcom/brcm80211/brcmfmac/cfg80211.h | 4 +- - 2 files changed, 109 insertions(+), 82 deletions(-) - ---- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c -+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c -@@ -757,12 +757,12 @@ s32 brcmf_notify_escan_complete(struct b - brcmf_scan_config_mpc(ifp, 1); - - /* -- * e-scan can be initiated by scheduled scan -+ * e-scan can be initiated internally - * which takes precedence. - */ -- if (cfg->sched_escan) { -+ if (cfg->internal_escan) { - brcmf_dbg(SCAN, "scheduled scan completed\n"); -- cfg->sched_escan = false; -+ cfg->internal_escan = false; - if (!aborted) - cfg80211_sched_scan_results(cfg_to_wiphy(cfg)); - } else if (scan_request) { -@@ -3013,7 +3013,7 @@ void brcmf_abort_scanning(struct brcmf_c - struct escan_info *escan = &cfg->escan_info; - - set_bit(BRCMF_SCAN_STATUS_ABORT, &cfg->scan_status); -- if (cfg->scan_request) { -+ if (cfg->internal_escan || cfg->scan_request) { - escan->escan_state = WL_ESCAN_STATE_IDLE; - brcmf_notify_escan_complete(cfg, escan->ifp, true, true); - } -@@ -3036,7 +3036,7 @@ static void brcmf_escan_timeout(unsigned - struct brcmf_cfg80211_info *cfg = - (struct brcmf_cfg80211_info *)data; - -- if (cfg->scan_request) { -+ if (cfg->internal_escan || cfg->scan_request) { - brcmf_err("timer expired\n"); - schedule_work(&cfg->escan_timeout_work); - } -@@ -3119,7 +3119,7 @@ brcmf_cfg80211_escan_handler(struct brcm - if (brcmf_p2p_scan_finding_common_channel(cfg, bss_info_le)) - goto exit; - -- if (!cfg->scan_request) { -+ if (!cfg->internal_escan && !cfg->scan_request) { - brcmf_dbg(SCAN, "result without cfg80211 request\n"); - goto exit; - } -@@ -3165,7 +3165,7 @@ brcmf_cfg80211_escan_handler(struct brcm - cfg->escan_info.escan_state = WL_ESCAN_STATE_IDLE; - if (brcmf_p2p_scan_finding_common_channel(cfg, NULL)) - goto exit; -- if (cfg->scan_request) { -+ if (cfg->internal_escan || cfg->scan_request) { - brcmf_inform_bss(cfg); - aborted = status != BRCMF_E_STATUS_SUCCESS; - brcmf_notify_escan_complete(cfg, ifp, aborted, false); -@@ -3190,6 +3190,73 @@ static void brcmf_init_escan(struct brcm - brcmf_cfg80211_escan_timeout_worker); - } - -+static struct cfg80211_scan_request * -+brcmf_alloc_internal_escan_request(struct wiphy *wiphy, u32 n_netinfo) { -+ struct cfg80211_scan_request *req; -+ size_t req_size; -+ -+ req_size = sizeof(*req) + -+ n_netinfo * sizeof(req->channels[0]) + -+ n_netinfo * sizeof(*req->ssids); -+ -+ req = kzalloc(req_size, GFP_KERNEL); -+ if (req) { -+ req->wiphy = wiphy; -+ req->ssids = (void *)(&req->channels[0]) + -+ n_netinfo * sizeof(req->channels[0]); -+ } -+ return req; -+} -+ -+static int brcmf_internal_escan_add_info(struct cfg80211_scan_request *req, -+ u8 *ssid, u8 ssid_len, u8 channel) -+{ -+ struct ieee80211_channel *chan; -+ enum nl80211_band band; -+ int freq; -+ -+ if (channel <= CH_MAX_2G_CHANNEL) -+ band = NL80211_BAND_2GHZ; -+ else -+ band = NL80211_BAND_5GHZ; -+ -+ freq = ieee80211_channel_to_frequency(channel, band); -+ if (!freq) -+ return -EINVAL; -+ -+ chan = ieee80211_get_channel(req->wiphy, freq); -+ if (!chan) -+ return -EINVAL; -+ -+ req->channels[req->n_channels++] = chan; -+ memcpy(req->ssids[req->n_ssids].ssid, ssid, ssid_len); -+ req->ssids[req->n_ssids++].ssid_len = ssid_len; -+ -+ return 0; -+} -+ -+static int brcmf_start_internal_escan(struct brcmf_if *ifp, -+ struct cfg80211_scan_request *request) -+{ -+ struct brcmf_cfg80211_info *cfg = ifp->drvr->config; -+ int err; -+ -+ if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) { -+ /* Abort any on-going scan */ -+ brcmf_abort_scanning(cfg); -+ } -+ -+ set_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status); -+ cfg->escan_info.run = brcmf_run_escan; -+ err = brcmf_do_escan(ifp, request); -+ if (err) { -+ clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status); -+ return err; -+ } -+ cfg->internal_escan = true; -+ return 0; -+} -+ - /* PFN result doesn't have all the info which are required by the supplicant - * (For e.g IEs) Do a target Escan so that sched scan results are reported - * via wl_inform_single_bss in the required format. Escan does require the -@@ -3203,12 +3270,8 @@ brcmf_notify_sched_scan_results(struct b - struct brcmf_cfg80211_info *cfg = ifp->drvr->config; - struct brcmf_pno_net_info_le *netinfo, *netinfo_start; - struct cfg80211_scan_request *request = NULL; -- struct cfg80211_ssid *ssid = NULL; -- struct ieee80211_channel *channel = NULL; - struct wiphy *wiphy = cfg_to_wiphy(cfg); -- int err = 0; -- int channel_req = 0; -- int band = 0; -+ int i, err = 0; - struct brcmf_pno_scanresults_le *pfn_result; - u32 result_count; - u32 status; -@@ -3234,83 +3297,47 @@ brcmf_notify_sched_scan_results(struct b - */ - WARN_ON(status != BRCMF_PNO_SCAN_COMPLETE); - brcmf_dbg(SCAN, "PFN NET FOUND event. count: %d\n", result_count); -- if (result_count > 0) { -- int i; -- -- request = kzalloc(sizeof(*request), GFP_KERNEL); -- ssid = kcalloc(result_count, sizeof(*ssid), GFP_KERNEL); -- channel = kcalloc(result_count, sizeof(*channel), GFP_KERNEL); -- if (!request || !ssid || !channel) { -- err = -ENOMEM; -- goto out_err; -- } -+ if (!result_count) { -+ brcmf_err("FALSE PNO Event. (pfn_count == 0)\n"); -+ goto out_err; -+ } -+ request = brcmf_alloc_internal_escan_request(wiphy, -+ result_count); -+ if (!request) { -+ err = -ENOMEM; -+ goto out_err; -+ } - -- request->wiphy = wiphy; -- data += sizeof(struct brcmf_pno_scanresults_le); -- netinfo_start = (struct brcmf_pno_net_info_le *)data; -- -- for (i = 0; i < result_count; i++) { -- netinfo = &netinfo_start[i]; -- if (!netinfo) { -- brcmf_err("Invalid netinfo ptr. index: %d\n", -- i); -- err = -EINVAL; -- goto out_err; -- } -+ data += sizeof(struct brcmf_pno_scanresults_le); -+ netinfo_start = (struct brcmf_pno_net_info_le *)data; - -- brcmf_dbg(SCAN, "SSID:%s Channel:%d\n", -- netinfo->SSID, netinfo->channel); -- memcpy(ssid[i].ssid, netinfo->SSID, netinfo->SSID_len); -- ssid[i].ssid_len = netinfo->SSID_len; -- request->n_ssids++; -- -- channel_req = netinfo->channel; -- if (channel_req <= CH_MAX_2G_CHANNEL) -- band = NL80211_BAND_2GHZ; -- else -- band = NL80211_BAND_5GHZ; -- channel[i].center_freq = -- ieee80211_channel_to_frequency(channel_req, -- band); -- channel[i].band = band; -- channel[i].flags |= IEEE80211_CHAN_NO_HT40; -- request->channels[i] = &channel[i]; -- request->n_channels++; -- } -- -- /* assign parsed ssid array */ -- if (request->n_ssids) -- request->ssids = &ssid[0]; -- -- if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) { -- /* Abort any on-going scan */ -- brcmf_abort_scanning(cfg); -+ for (i = 0; i < result_count; i++) { -+ netinfo = &netinfo_start[i]; -+ if (!netinfo) { -+ brcmf_err("Invalid netinfo ptr. index: %d\n", -+ i); -+ err = -EINVAL; -+ goto out_err; - } - -- set_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status); -- cfg->escan_info.run = brcmf_run_escan; -- err = brcmf_do_escan(ifp, request); -- if (err) { -- clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status); -+ brcmf_dbg(SCAN, "SSID:%.32s Channel:%d\n", -+ netinfo->SSID, netinfo->channel); -+ err = brcmf_internal_escan_add_info(request, -+ netinfo->SSID, -+ netinfo->SSID_len, -+ netinfo->channel); -+ if (err) - goto out_err; -- } -- cfg->sched_escan = true; -- cfg->scan_request = request; -- } else { -- brcmf_err("FALSE PNO Event. (pfn_count == 0)\n"); -- goto out_err; - } - -- kfree(ssid); -- kfree(channel); -- kfree(request); -- return 0; -+ err = brcmf_start_internal_escan(ifp, request); -+ if (!err) -+ goto free_req; - - out_err: -- kfree(ssid); -- kfree(channel); -- kfree(request); - cfg80211_sched_scan_stopped(wiphy); -+free_req: -+ kfree(request); - return err; - } - -@@ -3405,7 +3432,7 @@ static int brcmf_cfg80211_sched_scan_sto - - brcmf_dbg(SCAN, "enter\n"); - brcmf_pno_clean(ifp); -- if (cfg->sched_escan) -+ if (cfg->internal_escan) - brcmf_notify_escan_complete(cfg, ifp, true, true); - return 0; - } ---- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h -+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h -@@ -271,7 +271,7 @@ struct brcmf_cfg80211_wowl { - * @pub: common driver information. - * @channel: current channel. - * @active_scan: current scan mode. -- * @sched_escan: e-scan for scheduled scan support running. -+ * @internal_escan: indicates internally initiated e-scan is running. - * @ibss_starter: indicates this sta is ibss starter. - * @pwr_save: indicate whether dongle to support power save mode. - * @dongle_up: indicate whether dongle up or not. -@@ -303,7 +303,7 @@ struct brcmf_cfg80211_info { - struct brcmf_pub *pub; - u32 channel; - bool active_scan; -- bool sched_escan; -+ bool internal_escan; - bool ibss_starter; - bool pwr_save; - bool dongle_up; diff --git a/package/kernel/mac80211/patches/357-0007-brcmfmac-split-up-brcmf_pno_config-function.patch b/package/kernel/mac80211/patches/357-0007-brcmfmac-split-up-brcmf_pno_config-function.patch deleted file mode 100644 index f81523aa01..0000000000 --- a/package/kernel/mac80211/patches/357-0007-brcmfmac-split-up-brcmf_pno_config-function.patch +++ /dev/null @@ -1,176 +0,0 @@ -From fca6cb2f059e51dec3fcf3589a5abbbcce5b4043 Mon Sep 17 00:00:00 2001 -From: Arend Van Spriel -Date: Wed, 23 Nov 2016 10:25:26 +0000 -Subject: [PATCH] brcmfmac: split up brcmf_pno_config() function - -The brcmf_pno_config() function handles two configurations in -firmware. Split it and have caller sort out what is needed. - -Reviewed-by: Hante Meuleman -Reviewed-by: Pieter-Paul Giesberts -Reviewed-by: Franky Lin -Signed-off-by: Arend van Spriel -Signed-off-by: Kalle Valo ---- - .../broadcom/brcm80211/brcmfmac/cfg80211.c | 11 +++- - .../net/wireless/broadcom/brcm80211/brcmfmac/pno.c | 60 ++++++++++++++++------ - .../net/wireless/broadcom/brcm80211/brcmfmac/pno.h | 17 ++++-- - 3 files changed, 68 insertions(+), 20 deletions(-) - ---- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c -+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c -@@ -42,6 +42,7 @@ - #include "common.h" - - #define BRCMF_SCAN_IE_LEN_MAX 2048 -+#define BRCMF_SCHED_SCAN_PERIOD 30 - - #define WPA_OUI "\x00\x50\xF2" /* WPA OUI */ - #define WPA_OUI_TYPE 1 -@@ -3396,10 +3397,18 @@ brcmf_cfg80211_sched_scan_start(struct w - } - - /* configure pno */ -- ret = brcmf_pno_config(ifp, req); -+ ret = brcmf_pno_config(ifp, BRCMF_SCHED_SCAN_PERIOD, 0, 0); - if (ret < 0) - return ret; - -+ /* configure random mac */ -+ if (req->flags & NL80211_SCAN_FLAG_RANDOM_ADDR) { -+ ret = brcmf_pno_set_random(ifp, req->mac_addr, -+ req->mac_addr_mask); -+ if (ret < 0) -+ return ret; -+ } -+ - /* configure each match set */ - for (i = 0; i < req->n_match_sets; i++) { - ---- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pno.c -+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pno.c -@@ -23,10 +23,12 @@ - #include "fwil_types.h" - - #define BRCMF_PNO_VERSION 2 --#define BRCMF_PNO_TIME 30 - #define BRCMF_PNO_REPEAT 4 - #define BRCMF_PNO_FREQ_EXPO_MAX 3 -+#define BRCMF_PNO_IMMEDIATE_SCAN_BIT 3 -+#define BRCMF_PNO_ENABLE_BD_SCAN_BIT 5 - #define BRCMF_PNO_ENABLE_ADAPTSCAN_BIT 6 -+#define BRCMF_PNO_REPORT_SEPARATELY_BIT 11 - #define BRCMF_PNO_SCAN_INCOMPLETE 0 - #define BRCMF_PNO_WPA_AUTH_ANY 0xFFFFFFFF - #define BRCMF_PNO_HIDDEN_BIT 2 -@@ -47,42 +49,68 @@ int brcmf_pno_clean(struct brcmf_if *ifp - return ret; - } - --int brcmf_pno_config(struct brcmf_if *ifp, -- struct cfg80211_sched_scan_request *request) -+int brcmf_pno_config(struct brcmf_if *ifp, u32 scan_freq, -+ u32 mscan, u32 bestn) - { - struct brcmf_pno_param_le pfn_param; -- struct brcmf_pno_macaddr_le pfn_mac; -+ u16 flags; -+ u32 pfnmem; - s32 err; -- u8 *mac_mask; -- int i; - - memset(&pfn_param, 0, sizeof(pfn_param)); - pfn_param.version = cpu_to_le32(BRCMF_PNO_VERSION); - - /* set extra pno params */ -- pfn_param.flags = cpu_to_le16(1 << BRCMF_PNO_ENABLE_ADAPTSCAN_BIT); -+ flags = BIT(BRCMF_PNO_IMMEDIATE_SCAN_BIT) | -+ BIT(BRCMF_PNO_REPORT_SEPARATELY_BIT) | -+ BIT(BRCMF_PNO_ENABLE_ADAPTSCAN_BIT); - pfn_param.repeat = BRCMF_PNO_REPEAT; - pfn_param.exp = BRCMF_PNO_FREQ_EXPO_MAX; - - /* set up pno scan fr */ -- pfn_param.scan_freq = cpu_to_le32(BRCMF_PNO_TIME); -+ pfn_param.scan_freq = cpu_to_le32(scan_freq); -+ -+ if (mscan) { -+ pfnmem = bestn; - -+ /* set bestn in firmware */ -+ err = brcmf_fil_iovar_int_set(ifp, "pfnmem", pfnmem); -+ if (err < 0) { -+ brcmf_err("failed to set pfnmem\n"); -+ goto exit; -+ } -+ /* get max mscan which the firmware supports */ -+ err = brcmf_fil_iovar_int_get(ifp, "pfnmem", &pfnmem); -+ if (err < 0) { -+ brcmf_err("failed to get pfnmem\n"); -+ goto exit; -+ } -+ mscan = min_t(u32, mscan, pfnmem); -+ pfn_param.mscan = mscan; -+ pfn_param.bestn = bestn; -+ flags |= BIT(BRCMF_PNO_ENABLE_BD_SCAN_BIT); -+ brcmf_dbg(INFO, "mscan=%d, bestn=%d\n", mscan, bestn); -+ } -+ -+ pfn_param.flags = cpu_to_le16(flags); - err = brcmf_fil_iovar_data_set(ifp, "pfn_set", &pfn_param, - sizeof(pfn_param)); -- if (err) { -+ if (err) - brcmf_err("pfn_set failed, err=%d\n", err); -- return err; -- } - -- /* Find out if mac randomization should be turned on */ -- if (!(request->flags & NL80211_SCAN_FLAG_RANDOM_ADDR)) -- return 0; -+exit: -+ return err; -+} -+ -+int brcmf_pno_set_random(struct brcmf_if *ifp, u8 *mac_addr, u8 *mac_mask) -+{ -+ struct brcmf_pno_macaddr_le pfn_mac; -+ int err, i; - - pfn_mac.version = BRCMF_PFN_MACADDR_CFG_VER; - pfn_mac.flags = BRCMF_PFN_MAC_OUI_ONLY | BRCMF_PFN_SET_MAC_UNASSOC; - -- memcpy(pfn_mac.mac, request->mac_addr, ETH_ALEN); -- mac_mask = request->mac_addr_mask; -+ memcpy(pfn_mac.mac, mac_addr, ETH_ALEN); - for (i = 0; i < ETH_ALEN; i++) { - pfn_mac.mac[i] &= mac_mask[i]; - pfn_mac.mac[i] |= get_random_int() & ~(mac_mask[i]); ---- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pno.h -+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pno.h -@@ -30,10 +30,21 @@ int brcmf_pno_clean(struct brcmf_if *ifp - * brcmf_pno_config - configure pno parameters. - * - * @ifp: interface object used. -- * @request: scheduled scan parameters. -+ * @scan_freq: scan frequency period in seconds. -+ * @mscan: maximum number of scans stored in firmware. -+ * @bestn: maximum number of APs per scan stored in firmware. - */ --int brcmf_pno_config(struct brcmf_if *ifp, -- struct cfg80211_sched_scan_request *request); -+int brcmf_pno_config(struct brcmf_if *ifp, u32 scan_freq, -+ u32 mscan, u32 bestn); -+ -+/** -+ * brcmf_pno_set_random - setup randomisation mac address for pno. -+ * -+ * @ifp: interface object used. -+ * @mac_addr: MAC address used with randomisation. -+ * @mac_mask: MAC address mask used for randomisation. -+ */ -+int brcmf_pno_set_random(struct brcmf_if *ifp, u8 *mac_addr, u8 *mac_mask); - - /** - * brcmf_pno_add_ssid - add ssid for pno in firmware. diff --git a/package/kernel/mac80211/patches/357-0008-brcmfmac-move-scheduled-scan-activation-to-pno-sourc.patch b/package/kernel/mac80211/patches/357-0008-brcmfmac-move-scheduled-scan-activation-to-pno-sourc.patch deleted file mode 100644 index 6dcea2832a..0000000000 --- a/package/kernel/mac80211/patches/357-0008-brcmfmac-move-scheduled-scan-activation-to-pno-sourc.patch +++ /dev/null @@ -1,292 +0,0 @@ -From 3e48611d31dd333be01576902f2dc11adefc9a06 Mon Sep 17 00:00:00 2001 -From: Arend Van Spriel -Date: Wed, 23 Nov 2016 10:25:27 +0000 -Subject: [PATCH] brcmfmac: move scheduled scan activation to pno source file - -Rework .sched_scan_start() callback moving actual configuration of -the device in pno source file. - -Reviewed-by: Hante Meuleman -Reviewed-by: Pieter-Paul Giesberts -Reviewed-by: Franky Lin -Signed-off-by: Arend van Spriel -Signed-off-by: Kalle Valo ---- - .../broadcom/brcm80211/brcmfmac/cfg80211.c | 65 +----------- - .../net/wireless/broadcom/brcm80211/brcmfmac/pno.c | 110 +++++++++++++++++---- - .../net/wireless/broadcom/brcm80211/brcmfmac/pno.h | 29 +----- - 3 files changed, 94 insertions(+), 110 deletions(-) - ---- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c -+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c -@@ -42,7 +42,6 @@ - #include "common.h" - - #define BRCMF_SCAN_IE_LEN_MAX 2048 --#define BRCMF_SCHED_SCAN_PERIOD 30 - - #define WPA_OUI "\x00\x50\xF2" /* WPA OUI */ - #define WPA_OUI_TYPE 1 -@@ -3342,24 +3341,6 @@ free_req: - return err; - } - --static bool brcmf_is_ssid_active(struct cfg80211_ssid *ssid, -- struct cfg80211_sched_scan_request *req) --{ -- int i; -- -- if (!ssid || !req->ssids || !req->n_ssids) -- return false; -- -- for (i = 0; i < req->n_ssids; i++) { -- if (ssid->ssid_len == req->ssids[i].ssid_len) { -- if (!strncmp(ssid->ssid, req->ssids[i].ssid, -- ssid->ssid_len)) -- return true; -- } -- } -- return false; --} -- - static int - brcmf_cfg80211_sched_scan_start(struct wiphy *wiphy, - struct net_device *ndev, -@@ -3367,9 +3348,6 @@ brcmf_cfg80211_sched_scan_start(struct w - { - struct brcmf_if *ifp = netdev_priv(ndev); - struct brcmf_cfg80211_info *cfg = wiphy_priv(wiphy); -- struct cfg80211_ssid *ssid; -- int i; -- int ret = 0; - - brcmf_dbg(SCAN, "Enter n_match_sets:%d n_ssids:%d\n", - req->n_match_sets, req->n_ssids); -@@ -3389,48 +3367,7 @@ brcmf_cfg80211_sched_scan_start(struct w - return -EINVAL; - } - -- /* clean up everything */ -- ret = brcmf_pno_clean(ifp); -- if (ret < 0) { -- brcmf_err("failed error=%d\n", ret); -- return ret; -- } -- -- /* configure pno */ -- ret = brcmf_pno_config(ifp, BRCMF_SCHED_SCAN_PERIOD, 0, 0); -- if (ret < 0) -- return ret; -- -- /* configure random mac */ -- if (req->flags & NL80211_SCAN_FLAG_RANDOM_ADDR) { -- ret = brcmf_pno_set_random(ifp, req->mac_addr, -- req->mac_addr_mask); -- if (ret < 0) -- return ret; -- } -- -- /* configure each match set */ -- for (i = 0; i < req->n_match_sets; i++) { -- -- ssid = &req->match_sets[i].ssid; -- -- if (!ssid->ssid_len) { -- brcmf_err("skip broadcast ssid\n"); -- continue; -- } -- -- ret = brcmf_pno_add_ssid(ifp, ssid, -- brcmf_is_ssid_active(ssid, req)); -- if (ret < 0) -- brcmf_dbg(SCAN, ">>> PNO filter %s for ssid (%s)\n", -- ret == 0 ? "set" : "failed", ssid->ssid); -- } -- /* Enable the PNO */ -- ret = brcmf_fil_iovar_int_set(ifp, "pfn", 1); -- if (ret < 0) -- brcmf_err("PNO enable failed!! ret=%d\n", ret); -- -- return ret; -+ return brcmf_pno_start_sched_scan(ifp, req); - } - - static int brcmf_cfg80211_sched_scan_stop(struct wiphy *wiphy, ---- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pno.c -+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pno.c -@@ -32,25 +32,10 @@ - #define BRCMF_PNO_SCAN_INCOMPLETE 0 - #define BRCMF_PNO_WPA_AUTH_ANY 0xFFFFFFFF - #define BRCMF_PNO_HIDDEN_BIT 2 -+#define BRCMF_PNO_SCHED_SCAN_PERIOD 30 - --int brcmf_pno_clean(struct brcmf_if *ifp) --{ -- int ret; -- -- /* Disable pfn */ -- ret = brcmf_fil_iovar_int_set(ifp, "pfn", 0); -- if (ret == 0) { -- /* clear pfn */ -- ret = brcmf_fil_iovar_data_set(ifp, "pfnclear", NULL, 0); -- } -- if (ret < 0) -- brcmf_err("failed code %d\n", ret); -- -- return ret; --} -- --int brcmf_pno_config(struct brcmf_if *ifp, u32 scan_freq, -- u32 mscan, u32 bestn) -+static int brcmf_pno_config(struct brcmf_if *ifp, u32 scan_freq, -+ u32 mscan, u32 bestn) - { - struct brcmf_pno_param_le pfn_param; - u16 flags; -@@ -102,7 +87,8 @@ exit: - return err; - } - --int brcmf_pno_set_random(struct brcmf_if *ifp, u8 *mac_addr, u8 *mac_mask) -+static int brcmf_pno_set_random(struct brcmf_if *ifp, u8 *mac_addr, -+ u8 *mac_mask) - { - struct brcmf_pno_macaddr_le pfn_mac; - int err, i; -@@ -128,8 +114,8 @@ int brcmf_pno_set_random(struct brcmf_if - return err; - } - --int brcmf_pno_add_ssid(struct brcmf_if *ifp, struct cfg80211_ssid *ssid, -- bool active) -+static int brcmf_pno_add_ssid(struct brcmf_if *ifp, struct cfg80211_ssid *ssid, -+ bool active) - { - struct brcmf_pno_net_param_le pfn; - -@@ -144,3 +130,85 @@ int brcmf_pno_add_ssid(struct brcmf_if * - return brcmf_fil_iovar_data_set(ifp, "pfn_add", &pfn, sizeof(pfn)); - } - -+static bool brcmf_is_ssid_active(struct cfg80211_ssid *ssid, -+ struct cfg80211_sched_scan_request *req) -+{ -+ int i; -+ -+ if (!ssid || !req->ssids || !req->n_ssids) -+ return false; -+ -+ for (i = 0; i < req->n_ssids; i++) { -+ if (ssid->ssid_len == req->ssids[i].ssid_len) { -+ if (!strncmp(ssid->ssid, req->ssids[i].ssid, -+ ssid->ssid_len)) -+ return true; -+ } -+ } -+ return false; -+} -+ -+int brcmf_pno_clean(struct brcmf_if *ifp) -+{ -+ int ret; -+ -+ /* Disable pfn */ -+ ret = brcmf_fil_iovar_int_set(ifp, "pfn", 0); -+ if (ret == 0) { -+ /* clear pfn */ -+ ret = brcmf_fil_iovar_data_set(ifp, "pfnclear", NULL, 0); -+ } -+ if (ret < 0) -+ brcmf_err("failed code %d\n", ret); -+ -+ return ret; -+} -+ -+int brcmf_pno_start_sched_scan(struct brcmf_if *ifp, -+ struct cfg80211_sched_scan_request *req) -+{ -+ struct cfg80211_ssid *ssid; -+ int i, ret; -+ -+ /* clean up everything */ -+ ret = brcmf_pno_clean(ifp); -+ if (ret < 0) { -+ brcmf_err("failed error=%d\n", ret); -+ return ret; -+ } -+ -+ /* configure pno */ -+ ret = brcmf_pno_config(ifp, BRCMF_PNO_SCHED_SCAN_PERIOD, 0, 0); -+ if (ret < 0) -+ return ret; -+ -+ /* configure random mac */ -+ if (req->flags & NL80211_SCAN_FLAG_RANDOM_ADDR) { -+ ret = brcmf_pno_set_random(ifp, req->mac_addr, -+ req->mac_addr_mask); -+ if (ret < 0) -+ return ret; -+ } -+ -+ /* configure each match set */ -+ for (i = 0; i < req->n_match_sets; i++) { -+ ssid = &req->match_sets[i].ssid; -+ if (!ssid->ssid_len) { -+ brcmf_err("skip broadcast ssid\n"); -+ continue; -+ } -+ -+ ret = brcmf_pno_add_ssid(ifp, ssid, -+ brcmf_is_ssid_active(ssid, req)); -+ if (ret < 0) -+ brcmf_dbg(SCAN, ">>> PNO filter %s for ssid (%s)\n", -+ ret == 0 ? "set" : "failed", ssid->ssid); -+ } -+ /* Enable the PNO */ -+ ret = brcmf_fil_iovar_int_set(ifp, "pfn", 1); -+ if (ret < 0) -+ brcmf_err("PNO enable failed!! ret=%d\n", ret); -+ -+ return ret; -+} -+ ---- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pno.h -+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pno.h -@@ -27,33 +27,12 @@ - int brcmf_pno_clean(struct brcmf_if *ifp); - - /** -- * brcmf_pno_config - configure pno parameters. -+ * brcmf_pno_start_sched_scan - initiate scheduled scan on device. - * - * @ifp: interface object used. -- * @scan_freq: scan frequency period in seconds. -- * @mscan: maximum number of scans stored in firmware. -- * @bestn: maximum number of APs per scan stored in firmware. -+ * @req: configuration parameters for scheduled scan. - */ --int brcmf_pno_config(struct brcmf_if *ifp, u32 scan_freq, -- u32 mscan, u32 bestn); -- --/** -- * brcmf_pno_set_random - setup randomisation mac address for pno. -- * -- * @ifp: interface object used. -- * @mac_addr: MAC address used with randomisation. -- * @mac_mask: MAC address mask used for randomisation. -- */ --int brcmf_pno_set_random(struct brcmf_if *ifp, u8 *mac_addr, u8 *mac_mask); -- --/** -- * brcmf_pno_add_ssid - add ssid for pno in firmware. -- * -- * @ifp: interface object used. -- * @ssid: ssid information. -- * @active: indicate this ssid needs to be actively probed. -- */ --int brcmf_pno_add_ssid(struct brcmf_if *ifp, struct cfg80211_ssid *ssid, -- bool active); -+int brcmf_pno_start_sched_scan(struct brcmf_if *ifp, -+ struct cfg80211_sched_scan_request *req); - - #endif /* _BRCMF_PNO_H */ diff --git a/package/kernel/mac80211/patches/357-0009-brcmfmac-use-provided-channels-for-scheduled-scan.patch b/package/kernel/mac80211/patches/357-0009-brcmfmac-use-provided-channels-for-scheduled-scan.patch deleted file mode 100644 index fae844c02a..0000000000 --- a/package/kernel/mac80211/patches/357-0009-brcmfmac-use-provided-channels-for-scheduled-scan.patch +++ /dev/null @@ -1,111 +0,0 @@ -From 331e789443618ca9cc3ed48ada4e670225cca036 Mon Sep 17 00:00:00 2001 -From: Arend Van Spriel -Date: Wed, 23 Nov 2016 10:25:28 +0000 -Subject: [PATCH] brcmfmac: use provided channels for scheduled scan - -User-space can provide list of channels in the schedule scan request. -This was ignored so all channels supported and allowed by the device -were used. This patch configures the device to use the channels as -listed in the request. - -Reviewed-by: Hante Meuleman -Reviewed-by: Pieter-Paul Giesberts -Reviewed-by: Franky Lin -Signed-off-by: Arend van Spriel -Signed-off-by: Kalle Valo ---- - .../broadcom/brcm80211/brcmfmac/fwil_types.h | 16 +++++++++++++ - .../net/wireless/broadcom/brcm80211/brcmfmac/pno.c | 26 +++++++++++++++++++++- - 2 files changed, 41 insertions(+), 1 deletion(-) - ---- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h -+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h -@@ -131,6 +131,7 @@ - #define BRCMF_TXBF_MU_BFR_CAP BIT(1) - - #define BRCMF_MAXPMKID 16 /* max # PMKID cache entries */ -+#define BRCMF_NUMCHANNELS 64 - - #define BRCMF_PFN_MACADDR_CFG_VER 1 - #define BRCMF_PFN_MAC_OUI_ONLY BIT(0) -@@ -719,6 +720,21 @@ struct brcmf_pno_param_le { - }; - - /** -+ * struct brcmf_pno_config_le - PNO channel configuration. -+ * -+ * @reporttype: determines what is reported. -+ * @channel_num: number of channels specified in @channel_list. -+ * @channel_list: channels to use in PNO scan. -+ * @flags: reserved. -+ */ -+struct brcmf_pno_config_le { -+ __le32 reporttype; -+ __le32 channel_num; -+ __le16 channel_list[BRCMF_NUMCHANNELS]; -+ __le32 flags; -+}; -+ -+/** - * struct brcmf_pno_net_param_le - scan parameters per preferred network. - * - * @ssid: ssid name and its length. ---- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pno.c -+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pno.c -@@ -18,9 +18,10 @@ - - #include "core.h" - #include "debug.h" --#include "pno.h" - #include "fwil.h" - #include "fwil_types.h" -+#include "cfg80211.h" -+#include "pno.h" - - #define BRCMF_PNO_VERSION 2 - #define BRCMF_PNO_REPEAT 4 -@@ -34,6 +35,15 @@ - #define BRCMF_PNO_HIDDEN_BIT 2 - #define BRCMF_PNO_SCHED_SCAN_PERIOD 30 - -+static int brcmf_pno_channel_config(struct brcmf_if *ifp, -+ struct brcmf_pno_config_le *cfg) -+{ -+ cfg->reporttype = 0; -+ cfg->flags = 0; -+ -+ return brcmf_fil_iovar_data_set(ifp, "pfn_cfg", cfg, sizeof(*cfg)); -+} -+ - static int brcmf_pno_config(struct brcmf_if *ifp, u32 scan_freq, - u32 mscan, u32 bestn) - { -@@ -167,7 +177,10 @@ int brcmf_pno_clean(struct brcmf_if *ifp - int brcmf_pno_start_sched_scan(struct brcmf_if *ifp, - struct cfg80211_sched_scan_request *req) - { -+ struct brcmu_d11inf *d11inf; -+ struct brcmf_pno_config_le pno_cfg; - struct cfg80211_ssid *ssid; -+ u16 chan; - int i, ret; - - /* clean up everything */ -@@ -190,6 +203,17 @@ int brcmf_pno_start_sched_scan(struct br - return ret; - } - -+ /* configure channels to use */ -+ d11inf = &ifp->drvr->config->d11inf; -+ for (i = 0; i < req->n_channels; i++) { -+ chan = req->channels[i]->hw_value; -+ pno_cfg.channel_list[i] = cpu_to_le16(chan); -+ } -+ if (req->n_channels) { -+ pno_cfg.channel_num = cpu_to_le32(req->n_channels); -+ brcmf_pno_channel_config(ifp, &pno_cfg); -+ } -+ - /* configure each match set */ - for (i = 0; i < req->n_match_sets; i++) { - ssid = &req->match_sets[i].ssid; diff --git a/package/kernel/mac80211/patches/357-0010-brcmfmac-remove-restriction-from-.sched_scan_start-c.patch b/package/kernel/mac80211/patches/357-0010-brcmfmac-remove-restriction-from-.sched_scan_start-c.patch deleted file mode 100644 index d14a60a826..0000000000 --- a/package/kernel/mac80211/patches/357-0010-brcmfmac-remove-restriction-from-.sched_scan_start-c.patch +++ /dev/null @@ -1,34 +0,0 @@ -From dfe5b0d52d5880bd9d4b427e1a53c9e9e4c3c820 Mon Sep 17 00:00:00 2001 -From: Arend Van Spriel -Date: Wed, 23 Nov 2016 10:25:29 +0000 -Subject: [PATCH] brcmfmac: remove restriction from .sched_scan_start() - callback - -In the .sched_scan_start() callback a condition was checked whether a -normal scan was ongoing. However, there is no need for this check as -it is ok to start the scheduled scan irrespective whether or not a -normal scan is ongoing. - -Reviewed-by: Hante Meuleman -Reviewed-by: Pieter-Paul Giesberts -Reviewed-by: Franky Lin -Signed-off-by: Arend van Spriel -Signed-off-by: Kalle Valo ---- - drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | 5 +---- - 1 file changed, 1 insertion(+), 4 deletions(-) - ---- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c -+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c -@@ -3351,10 +3351,7 @@ brcmf_cfg80211_sched_scan_start(struct w - - brcmf_dbg(SCAN, "Enter n_match_sets:%d n_ssids:%d\n", - req->n_match_sets, req->n_ssids); -- if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) { -- brcmf_err("Scanning already: status (%lu)\n", cfg->scan_status); -- return -EAGAIN; -- } -+ - if (test_bit(BRCMF_SCAN_STATUS_SUPPRESS, &cfg->scan_status)) { - brcmf_err("Scanning suppressed: status (%lu)\n", - cfg->scan_status); diff --git a/package/kernel/mac80211/patches/357-0011-brcmfmac-use-requested-scan-interval-in-scheduled-sc.patch b/package/kernel/mac80211/patches/357-0011-brcmfmac-use-requested-scan-interval-in-scheduled-sc.patch deleted file mode 100644 index eb1d5d304e..0000000000 --- a/package/kernel/mac80211/patches/357-0011-brcmfmac-use-requested-scan-interval-in-scheduled-sc.patch +++ /dev/null @@ -1,67 +0,0 @@ -From c6989fd55ceb633d2f18c12ffae01b9123125c89 Mon Sep 17 00:00:00 2001 -From: Arend Van Spriel -Date: Wed, 23 Nov 2016 10:25:30 +0000 -Subject: [PATCH] brcmfmac: use requested scan interval in scheduled scan - -User-space can specify the interval for the scheduled scan. This -interval is found in scheduled scan plan. The driver supports only -one plan, which is legacy behaviour. - -Reviewed-by: Hante Meuleman -Reviewed-by: Pieter-Paul Giesberts -Reviewed-by: Franky Lin -Signed-off-by: Arend van Spriel -Signed-off-by: Kalle Valo ---- - drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | 1 + - drivers/net/wireless/broadcom/brcm80211/brcmfmac/pno.c | 6 +++++- - drivers/net/wireless/broadcom/brcm80211/brcmfmac/pno.h | 6 ++++-- - 3 files changed, 10 insertions(+), 3 deletions(-) - ---- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c -+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c -@@ -6312,6 +6312,7 @@ static void brcmf_wiphy_pno_params(struc - wiphy->max_sched_scan_ssids = BRCMF_PNO_MAX_PFN_COUNT; - wiphy->max_match_sets = BRCMF_PNO_MAX_PFN_COUNT; - wiphy->max_sched_scan_ie_len = BRCMF_SCAN_IE_LEN_MAX; -+ wiphy->max_sched_scan_plan_interval = BRCMF_PNO_SCHED_SCAN_MAX_PERIOD; - wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN; - } - ---- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pno.c -+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pno.c -@@ -63,6 +63,10 @@ static int brcmf_pno_config(struct brcmf - pfn_param.exp = BRCMF_PNO_FREQ_EXPO_MAX; - - /* set up pno scan fr */ -+ if (scan_freq < BRCMF_PNO_SCHED_SCAN_MIN_PERIOD) { -+ brcmf_dbg(SCAN, "scan period too small, using minimum\n"); -+ scan_freq = BRCMF_PNO_SCHED_SCAN_MIN_PERIOD; -+ } - pfn_param.scan_freq = cpu_to_le32(scan_freq); - - if (mscan) { -@@ -191,7 +195,7 @@ int brcmf_pno_start_sched_scan(struct br - } - - /* configure pno */ -- ret = brcmf_pno_config(ifp, BRCMF_PNO_SCHED_SCAN_PERIOD, 0, 0); -+ ret = brcmf_pno_config(ifp, req->scan_plans[0].interval, 0, 0); - if (ret < 0) - return ret; - ---- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pno.h -+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pno.h -@@ -16,8 +16,10 @@ - #ifndef _BRCMF_PNO_H - #define _BRCMF_PNO_H - --#define BRCMF_PNO_SCAN_COMPLETE 1 --#define BRCMF_PNO_MAX_PFN_COUNT 16 -+#define BRCMF_PNO_SCAN_COMPLETE 1 -+#define BRCMF_PNO_MAX_PFN_COUNT 16 -+#define BRCMF_PNO_SCHED_SCAN_MIN_PERIOD 10 -+#define BRCMF_PNO_SCHED_SCAN_MAX_PERIOD 508 - - /** - * brcmf_pno_clean - disable and clear pno in firmware. diff --git a/package/kernel/mac80211/patches/357-0012-brcmfmac-fix-scheduled-scan-result-handling-for-newe.patch b/package/kernel/mac80211/patches/357-0012-brcmfmac-fix-scheduled-scan-result-handling-for-newe.patch deleted file mode 100644 index bbd877426e..0000000000 --- a/package/kernel/mac80211/patches/357-0012-brcmfmac-fix-scheduled-scan-result-handling-for-newe.patch +++ /dev/null @@ -1,76 +0,0 @@ -From 53e3a80d80c80bf50ab64cf6c44fb0fa41aa22d8 Mon Sep 17 00:00:00 2001 -From: Arend Van Spriel -Date: Wed, 23 Nov 2016 10:25:31 +0000 -Subject: [PATCH] brcmfmac: fix scheduled scan result handling for newer chips - -The scan results for scheduled scan as retrieved from the device -have changed. A field has been added which is not needed. However, -the appended info is. Luckily they are versioned so check that to -find out the location of the appended data. - -Reviewed-by: Hante Meuleman -Reviewed-by: Pieter-Paul Giesberts -Reviewed-by: Franky Lin -Signed-off-by: Arend van Spriel -Signed-off-by: Kalle Valo ---- - .../broadcom/brcm80211/brcmfmac/cfg80211.c | 24 +++++++++++++++++++++- - .../broadcom/brcm80211/brcmfmac/fwil_types.h | 7 +++++++ - 2 files changed, 30 insertions(+), 1 deletion(-) - ---- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c -+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c -@@ -3257,6 +3257,28 @@ static int brcmf_start_internal_escan(st - return 0; - } - -+static struct brcmf_pno_net_info_le * -+brcmf_get_netinfo_array(struct brcmf_pno_scanresults_le *pfn_v1) -+{ -+ struct brcmf_pno_scanresults_v2_le *pfn_v2; -+ struct brcmf_pno_net_info_le *netinfo; -+ -+ switch (pfn_v1->version) { -+ default: -+ WARN_ON(1); -+ /* fall-thru */ -+ case cpu_to_le32(1): -+ netinfo = (struct brcmf_pno_net_info_le *)(pfn_v1 + 1); -+ break; -+ case cpu_to_le32(2): -+ pfn_v2 = (struct brcmf_pno_scanresults_v2_le *)pfn_v1; -+ netinfo = (struct brcmf_pno_net_info_le *)(pfn_v2 + 1); -+ break; -+ } -+ -+ return netinfo; -+} -+ - /* PFN result doesn't have all the info which are required by the supplicant - * (For e.g IEs) Do a target Escan so that sched scan results are reported - * via wl_inform_single_bss in the required format. Escan does require the -@@ -3309,7 +3331,7 @@ brcmf_notify_sched_scan_results(struct b - } - - data += sizeof(struct brcmf_pno_scanresults_le); -- netinfo_start = (struct brcmf_pno_net_info_le *)data; -+ netinfo_start = brcmf_get_netinfo_array(pfn_result); - - for (i = 0; i < result_count; i++) { - netinfo = &netinfo_start[i]; ---- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h -+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h -@@ -785,6 +785,13 @@ struct brcmf_pno_scanresults_le { - __le32 count; - }; - -+struct brcmf_pno_scanresults_v2_le { -+ __le32 version; -+ __le32 status; -+ __le32 count; -+ __le32 scan_ch_bucket; -+}; -+ - /** - * struct brcmf_pno_macaddr_le - to configure PNO macaddr randomization. - * diff --git a/package/kernel/mac80211/patches/358-0001-brcmfmac-fix-memory-leak-in-brcmf_cfg80211_attach.patch b/package/kernel/mac80211/patches/358-0001-brcmfmac-fix-memory-leak-in-brcmf_cfg80211_attach.patch deleted file mode 100644 index 005db2b786..0000000000 --- a/package/kernel/mac80211/patches/358-0001-brcmfmac-fix-memory-leak-in-brcmf_cfg80211_attach.patch +++ /dev/null @@ -1,47 +0,0 @@ -From cb853da3a368c40300a0e940f86be582037bb082 Mon Sep 17 00:00:00 2001 -From: Arend Van Spriel -Date: Fri, 9 Dec 2016 11:34:13 +0000 -Subject: [PATCH] brcmfmac: fix memory leak in brcmf_cfg80211_attach() - -In brcmf_cfg80211_attach() there was one error path not properly -handled as it leaked memory allocated in brcmf_btcoex_attach(). - -Reviewed-by: Hante Meuleman -Reviewed-by: Pieter-Paul Giesberts -Reviewed-by: Franky Lin -Signed-off-by: Arend van Spriel -Signed-off-by: Kalle Valo ---- - drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | 7 +++++-- - 1 file changed, 5 insertions(+), 2 deletions(-) - ---- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c -+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c -@@ -6866,7 +6866,7 @@ struct brcmf_cfg80211_info *brcmf_cfg802 - - err = brcmf_p2p_attach(cfg, p2pdev_forced); - if (err) { -- brcmf_err("P2P initilisation failed (%d)\n", err); -+ brcmf_err("P2P initialisation failed (%d)\n", err); - goto wiphy_unreg_out; - } - err = brcmf_btcoex_attach(cfg); -@@ -6891,7 +6891,7 @@ struct brcmf_cfg80211_info *brcmf_cfg802 - err = brcmf_fweh_activate_events(ifp); - if (err) { - brcmf_err("FWEH activation failed (%d)\n", err); -- goto wiphy_unreg_out; -+ goto detach; - } - - /* Fill in some of the advertised nl80211 supported features */ -@@ -6906,6 +6906,9 @@ struct brcmf_cfg80211_info *brcmf_cfg802 - - return cfg; - -+detach: -+ brcmf_btcoex_detach(cfg); -+ brcmf_p2p_detach(&cfg->p2p); - wiphy_unreg_out: - wiphy_unregister(cfg->wiphy); - priv_out: diff --git a/package/kernel/mac80211/patches/358-0002-brcmfmac-fix-uninitialized-field-in-scheduled-scan-s.patch b/package/kernel/mac80211/patches/358-0002-brcmfmac-fix-uninitialized-field-in-scheduled-scan-s.patch deleted file mode 100644 index ebdf1ccd91..0000000000 --- a/package/kernel/mac80211/patches/358-0002-brcmfmac-fix-uninitialized-field-in-scheduled-scan-s.patch +++ /dev/null @@ -1,29 +0,0 @@ -From 2b66325d5ea7c2a39ac69ed83b6979afe480d81a Mon Sep 17 00:00:00 2001 -From: Arend Van Spriel -Date: Fri, 9 Dec 2016 11:34:14 +0000 -Subject: [PATCH] brcmfmac: fix uninitialized field in scheduled scan ssid - configuration - -The scheduled scan ssid configuration in firmware has a flags field that -was not initialized resulting in unexpected behaviour. - -Fixes: e3bdb7cc0300 ("brcmfmac: fix handling ssids in .sched_scan_start() callback") -Reviewed-by: Hante Meuleman -Reviewed-by: Pieter-Paul Giesberts -Reviewed-by: Franky Lin -Signed-off-by: Arend van Spriel -Signed-off-by: Kalle Valo ---- - drivers/net/wireless/broadcom/brcm80211/brcmfmac/pno.c | 1 + - 1 file changed, 1 insertion(+) - ---- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pno.c -+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pno.c -@@ -137,6 +137,7 @@ static int brcmf_pno_add_ssid(struct brc - pfn.wpa_auth = cpu_to_le32(BRCMF_PNO_WPA_AUTH_ANY); - pfn.wsec = cpu_to_le32(0); - pfn.infra = cpu_to_le32(1); -+ pfn.flags = 0; - if (active) - pfn.flags = cpu_to_le32(1 << BRCMF_PNO_HIDDEN_BIT); - pfn.ssid.SSID_len = cpu_to_le32(ssid->ssid_len); diff --git a/package/kernel/mac80211/patches/359-0001-brcmfmac-fix-spelling-mistakes-on-Ivalid.patch b/package/kernel/mac80211/patches/359-0001-brcmfmac-fix-spelling-mistakes-on-Ivalid.patch deleted file mode 100644 index 0afc10b277..0000000000 --- a/package/kernel/mac80211/patches/359-0001-brcmfmac-fix-spelling-mistakes-on-Ivalid.patch +++ /dev/null @@ -1,35 +0,0 @@ -From ad334bbb07b07e2873942571b0c9f3c34571bd47 Mon Sep 17 00:00:00 2001 -From: Colin Ian King -Date: Fri, 23 Dec 2016 00:43:22 +0000 -Subject: [PATCH] brcmfmac: fix spelling mistakes on "Ivalid" - -Trivial fixes to spelling mistake "Ivalid" to "Invalid" in -brcmf_err error messages. - -Signed-off-by: Colin Ian King -Acked-by: Arend van Spriel -Signed-off-by: Kalle Valo ---- - drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - ---- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c -+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c -@@ -3969,7 +3969,7 @@ brcmf_configure_wpaie(struct brcmf_if *i - pval |= AES_ENABLED; - break; - default: -- brcmf_err("Ivalid unicast security info\n"); -+ brcmf_err("Invalid unicast security info\n"); - } - offset++; - } -@@ -4013,7 +4013,7 @@ brcmf_configure_wpaie(struct brcmf_if *i - wpa_auth |= WPA2_AUTH_1X_SHA256; - break; - default: -- brcmf_err("Ivalid key mgmt info\n"); -+ brcmf_err("Invalid key mgmt info\n"); - } - offset++; - } diff --git a/package/kernel/mac80211/patches/360-0001-brcmfmac-avoid-writing-channel-out-of-allocated-arra.patch b/package/kernel/mac80211/patches/360-0001-brcmfmac-avoid-writing-channel-out-of-allocated-arra.patch deleted file mode 100644 index c2ea368323..0000000000 --- a/package/kernel/mac80211/patches/360-0001-brcmfmac-avoid-writing-channel-out-of-allocated-arra.patch +++ /dev/null @@ -1,101 +0,0 @@ -From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= -Date: Wed, 4 Jan 2017 12:09:41 +0100 -Subject: [PATCH] brcmfmac: avoid writing channel out of allocated array -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Our code was assigning number of channels to the index variable by -default. If firmware reported channel we didn't predict this would -result in using that initial index value and writing out of array. This -never happened so far (we got a complete list of supported channels) but -it means possible memory corruption so we should handle it anyway. - -This patch simply detects unexpected channel and ignores it. - -As we don't try to create new entry now, it's also safe to drop hw_value -and center_freq assignment. For known channels we have these set anyway. - -I decided to fix this issue by assigning NULL or a target channel to the -channel variable. This was one of possible ways, I prefefred this one as -it also avoids using channel[index] over and over. - -Fixes: 58de92d2f95e ("brcmfmac: use static superset of channels for wiphy bands") -Signed-off-by: Rafał Miłecki -Acked-by: Arend van Spriel -Signed-off-by: Kalle Valo ---- - ---- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c -+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c -@@ -5823,7 +5823,6 @@ static int brcmf_construct_chaninfo(stru - u32 i, j; - u32 total; - u32 chaninfo; -- u32 index; - - pbuf = kzalloc(BRCMF_DCMD_MEDLEN, GFP_KERNEL); - -@@ -5871,33 +5870,36 @@ static int brcmf_construct_chaninfo(stru - ch.bw == BRCMU_CHAN_BW_80) - continue; - -- channel = band->channels; -- index = band->n_channels; -+ channel = NULL; - for (j = 0; j < band->n_channels; j++) { -- if (channel[j].hw_value == ch.control_ch_num) { -- index = j; -+ if (band->channels[j].hw_value == ch.control_ch_num) { -+ channel = &band->channels[j]; - break; - } - } -- channel[index].center_freq = -- ieee80211_channel_to_frequency(ch.control_ch_num, -- band->band); -- channel[index].hw_value = ch.control_ch_num; -+ if (!channel) { -+ /* It seems firmware supports some channel we never -+ * considered. Something new in IEEE standard? -+ */ -+ brcmf_err("Ignoring unexpected firmware channel %d\n", -+ ch.control_ch_num); -+ continue; -+ } - - /* assuming the chanspecs order is HT20, - * HT40 upper, HT40 lower, and VHT80. - */ - if (ch.bw == BRCMU_CHAN_BW_80) { -- channel[index].flags &= ~IEEE80211_CHAN_NO_80MHZ; -+ channel->flags &= ~IEEE80211_CHAN_NO_80MHZ; - } else if (ch.bw == BRCMU_CHAN_BW_40) { -- brcmf_update_bw40_channel_flag(&channel[index], &ch); -+ brcmf_update_bw40_channel_flag(channel, &ch); - } else { - /* enable the channel and disable other bandwidths - * for now as mentioned order assure they are enabled - * for subsequent chanspecs. - */ -- channel[index].flags = IEEE80211_CHAN_NO_HT40 | -- IEEE80211_CHAN_NO_80MHZ; -+ channel->flags = IEEE80211_CHAN_NO_HT40 | -+ IEEE80211_CHAN_NO_80MHZ; - ch.bw = BRCMU_CHAN_BW_20; - cfg->d11inf.encchspec(&ch); - chaninfo = ch.chspec; -@@ -5905,11 +5907,11 @@ static int brcmf_construct_chaninfo(stru - &chaninfo); - if (!err) { - if (chaninfo & WL_CHAN_RADAR) -- channel[index].flags |= -+ channel->flags |= - (IEEE80211_CHAN_RADAR | - IEEE80211_CHAN_NO_IR); - if (chaninfo & WL_CHAN_PASSIVE) -- channel[index].flags |= -+ channel->flags |= - IEEE80211_CHAN_NO_IR; - } - } diff --git a/package/kernel/mac80211/patches/360-0002-brcmfmac-don-t-preset-all-channels-as-disabled.patch b/package/kernel/mac80211/patches/360-0002-brcmfmac-don-t-preset-all-channels-as-disabled.patch deleted file mode 100644 index 5a66a3518e..0000000000 --- a/package/kernel/mac80211/patches/360-0002-brcmfmac-don-t-preset-all-channels-as-disabled.patch +++ /dev/null @@ -1,35 +0,0 @@ -From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= -Date: Sat, 7 Jan 2017 21:36:04 +0100 -Subject: [PATCH] brcmfmac: don't preset all channels as disabled -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -During init we take care of regulatory stuff by disabling all -unavailable channels (see brcmf_construct_chaninfo) so this predisabling -them is not really required (and this patch won't change any behavior). -It will on the other hand allow more detailed runtime control over -channels which is the main reason for this change. - -Signed-off-by: Rafał Miłecki -Signed-off-by: Kalle Valo ---- - ---- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c -+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c -@@ -138,7 +138,6 @@ static struct ieee80211_rate __wl_rates[ - .band = NL80211_BAND_2GHZ, \ - .center_freq = (_freq), \ - .hw_value = (_channel), \ -- .flags = IEEE80211_CHAN_DISABLED, \ - .max_antenna_gain = 0, \ - .max_power = 30, \ - } -@@ -147,7 +146,6 @@ static struct ieee80211_rate __wl_rates[ - .band = NL80211_BAND_5GHZ, \ - .center_freq = 5000 + (5 * (_channel)), \ - .hw_value = (_channel), \ -- .flags = IEEE80211_CHAN_DISABLED, \ - .max_antenna_gain = 0, \ - .max_power = 30, \ - } diff --git a/package/kernel/mac80211/patches/360-0003-brcmfmac-setup-wiphy-bands-after-registering-it-firs.patch b/package/kernel/mac80211/patches/360-0003-brcmfmac-setup-wiphy-bands-after-registering-it-firs.patch deleted file mode 100644 index 29ebad7ba2..0000000000 --- a/package/kernel/mac80211/patches/360-0003-brcmfmac-setup-wiphy-bands-after-registering-it-firs.patch +++ /dev/null @@ -1,50 +0,0 @@ -From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= -Date: Sat, 7 Jan 2017 21:36:05 +0100 -Subject: [PATCH] brcmfmac: setup wiphy bands after registering it first -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -During bands setup we disable all channels that firmware doesn't support -in the current regulatory setup. If we do this before wiphy_register -it will result in copying set flags (including IEEE80211_CHAN_DISABLED) -to the orig_flags which is supposed to be persistent. We don't want this -as regulatory change may result in enabling some channels. We shouldn't -mess with orig_flags then (by changing them or ignoring them) so it's -better to just take care of their proper values. - -This patch cleanups code a bit (by taking orig_flags more seriously) and -allows further improvements like disabling really unavailable channels. -We will need that e.g. if some frequencies should be disabled for good -due to hardware setup (design). - -Signed-off-by: Rafał Miłecki -Acked-by: Arend van Spriel -Signed-off-by: Kalle Valo ---- - ---- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c -+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c -@@ -6475,8 +6475,7 @@ static int brcmf_setup_wiphy(struct wiph - wiphy->bands[NL80211_BAND_5GHZ] = band; - } - } -- err = brcmf_setup_wiphybands(wiphy); -- return err; -+ return 0; - } - - static s32 brcmf_config_dongle(struct brcmf_cfg80211_info *cfg) -@@ -6841,6 +6840,12 @@ struct brcmf_cfg80211_info *brcmf_cfg802 - goto priv_out; - } - -+ err = brcmf_setup_wiphybands(wiphy); -+ if (err) { -+ brcmf_err("Setting wiphy bands failed (%d)\n", err); -+ goto wiphy_unreg_out; -+ } -+ - /* If cfg80211 didn't disable 40MHz HT CAP in wiphy_register(), - * setup 40MHz in 2GHz band and enable OBSS scanning. - */ diff --git a/package/kernel/mac80211/patches/361-0001-brcmfmac-make-brcmf_of_probe-more-generic.patch b/package/kernel/mac80211/patches/361-0001-brcmfmac-make-brcmf_of_probe-more-generic.patch deleted file mode 100644 index 23bbe667c5..0000000000 --- a/package/kernel/mac80211/patches/361-0001-brcmfmac-make-brcmf_of_probe-more-generic.patch +++ /dev/null @@ -1,78 +0,0 @@ -From e457a8a01a19277e96830d3d95887e0e3c1e2f26 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= -Date: Sat, 7 Jan 2017 23:43:45 +0100 -Subject: [PATCH] brcmfmac: make brcmf_of_probe more generic -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -We may want to use Open Firmware for other devices than just SDIO ones. -In future we may want to support more Broadcom properties so there is -really no reason for such limitation. - -Call brcmf_of_probe for all kind of devices & move extra conditions to -the body of that funcion. - -Signed-off-by: Rafał Miłecki -Signed-off-by: Kalle Valo ---- - drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c | 8 +++----- - drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c | 7 +++++-- - drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.h | 6 ++++-- - 3 files changed, 12 insertions(+), 9 deletions(-) - ---- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c -+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c -@@ -299,11 +299,9 @@ struct brcmf_mp_device *brcmf_get_module - } - } - } -- if ((bus_type == BRCMF_BUSTYPE_SDIO) && (!found)) { -- /* No platform data for this device. In case of SDIO try OF -- * (Open Firwmare) Device Tree. -- */ -- brcmf_of_probe(dev, &settings->bus.sdio); -+ if (!found) { -+ /* No platform data for this device, try OF (Open Firwmare) */ -+ brcmf_of_probe(dev, bus_type, settings); - } - return settings; - } ---- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c -+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c -@@ -23,14 +23,17 @@ - #include "common.h" - #include "of.h" - --void brcmf_of_probe(struct device *dev, struct brcmfmac_sdio_pd *sdio) -+void brcmf_of_probe(struct device *dev, enum brcmf_bus_type bus_type, -+ struct brcmf_mp_device *settings) - { -+ struct brcmfmac_sdio_pd *sdio = &settings->bus.sdio; - struct device_node *np = dev->of_node; - int irq; - u32 irqf; - u32 val; - -- if (!np || !of_device_is_compatible(np, "brcm,bcm4329-fmac")) -+ if (!np || bus_type != BRCMF_BUSTYPE_SDIO || -+ !of_device_is_compatible(np, "brcm,bcm4329-fmac")) - return; - - if (of_property_read_u32(np, "brcm,drive-strength", &val) == 0) ---- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.h -+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.h -@@ -14,9 +14,11 @@ - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - #ifdef CONFIG_OF --void brcmf_of_probe(struct device *dev, struct brcmfmac_sdio_pd *sdio); -+void brcmf_of_probe(struct device *dev, enum brcmf_bus_type bus_type, -+ struct brcmf_mp_device *settings); - #else --static void brcmf_of_probe(struct device *dev, struct brcmfmac_sdio_pd *sdio) -+static void brcmf_of_probe(struct device *dev, enum brcmf_bus_type bus_type, -+ struct brcmf_mp_device *settings) - { - } - #endif /* CONFIG_OF */ diff --git a/package/kernel/mac80211/patches/361-0002-brcmfmac-add-support-for-BCM43455-with-modalias-sdio.patch b/package/kernel/mac80211/patches/361-0002-brcmfmac-add-support-for-BCM43455-with-modalias-sdio.patch deleted file mode 100644 index 4e456ca40f..0000000000 --- a/package/kernel/mac80211/patches/361-0002-brcmfmac-add-support-for-BCM43455-with-modalias-sdio.patch +++ /dev/null @@ -1,46 +0,0 @@ -From a62a77881b1b6708ffeddd9bf0529494f7b199e3 Mon Sep 17 00:00:00 2001 -From: Martin Blumenstingl -Date: Mon, 16 Jan 2017 11:17:57 +0100 -Subject: [PATCH] brcmfmac: add support for BCM43455 with modalias - sdio:c00v02D0dA9BF -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -BCM43455 is a more recent revision of the BCM4345. Some of the BCM43455 -got a dedicated SDIO device ID which is currently not supported by -brcmfmac. -Adding the new sdio_device_id to brcmfmac is enough to get the BCM43455 -supported because the chip itself is already supported (due to BCM4345 -support in the driver). - -Signed-off-by: Martin Blumenstingl -Acked-by: Arend van Spriel -Reviewed-by: Andreas Färber -Tested-by: Andreas Färber -Signed-off-by: Kalle Valo ---- - drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c | 1 + - include/linux/mmc/sdio_ids.h | 1 + - 2 files changed, 2 insertions(+) - ---- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c -+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c -@@ -1104,6 +1104,7 @@ static const struct sdio_device_id brcmf - BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_4339), - BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_43430), - BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_4345), -+ BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_43455), - BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_4354), - BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_4356), - { /* end: all zeroes */ } ---- a/include/linux/mmc/sdio_ids.h -+++ b/include/linux/mmc/sdio_ids.h -@@ -36,6 +36,7 @@ - #define SDIO_DEVICE_ID_BROADCOM_43362 0xa962 - #define SDIO_DEVICE_ID_BROADCOM_43430 0xa9a6 - #define SDIO_DEVICE_ID_BROADCOM_4345 0x4345 -+#define SDIO_DEVICE_ID_BROADCOM_43455 0xa9bf - #define SDIO_DEVICE_ID_BROADCOM_4354 0x4354 - #define SDIO_DEVICE_ID_BROADCOM_4356 0x4356 - diff --git a/package/kernel/mac80211/patches/361-0003-brcmfmac-fix-incorrect-event-channel-deduction.patch b/package/kernel/mac80211/patches/361-0003-brcmfmac-fix-incorrect-event-channel-deduction.patch deleted file mode 100644 index aa97762830..0000000000 --- a/package/kernel/mac80211/patches/361-0003-brcmfmac-fix-incorrect-event-channel-deduction.patch +++ /dev/null @@ -1,34 +0,0 @@ -From 8e290cecdd0178f3d4cf7d463c51dc7e462843b4 Mon Sep 17 00:00:00 2001 -From: Gavin Li -Date: Tue, 17 Jan 2017 15:24:05 -0800 -Subject: [PATCH] brcmfmac: fix incorrect event channel deduction - -brcmf_sdio_fromevntchan() was being called on the the data frame -rather than the software header, causing some frames to be -mischaracterized as on the event channel rather than the data channel. - -This fixes a major performance regression (due to dropped packets). With -this patch the download speed jumped from 1Mbit/s back up to 40MBit/s due -to the sheer amount of packets being incorrectly processed. - -Fixes: c56caa9db8ab ("brcmfmac: screening firmware event packet") -Signed-off-by: Gavin Li -Cc: # 4.7+ -Acked-by: Arend van Spriel -[kvalo@codeaurora.org: improve commit logs based on email discussion] -Signed-off-by: Kalle Valo ---- - drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c -+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c -@@ -1661,7 +1661,7 @@ static u8 brcmf_sdio_rxglom(struct brcmf - pfirst->len, pfirst->next, - pfirst->prev); - skb_unlink(pfirst, &bus->glom); -- if (brcmf_sdio_fromevntchan(pfirst->data)) -+ if (brcmf_sdio_fromevntchan(&dptr[SDPCM_HWHDR_LEN])) - brcmf_rx_event(bus->sdiodev->dev, pfirst); - else - brcmf_rx_frame(bus->sdiodev->dev, pfirst, diff --git a/package/kernel/mac80211/patches/362-0001-brcmfmac-drop-unneeded-function-declarations-from-he.patch b/package/kernel/mac80211/patches/362-0001-brcmfmac-drop-unneeded-function-declarations-from-he.patch deleted file mode 100644 index 17d4a2e3e3..0000000000 --- a/package/kernel/mac80211/patches/362-0001-brcmfmac-drop-unneeded-function-declarations-from-he.patch +++ /dev/null @@ -1,63 +0,0 @@ -From c8d870794d5dd42d6e05a78cc92d1ff7acf11f6a Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= -Date: Wed, 18 Jan 2017 11:48:51 +0100 -Subject: [PATCH] brcmfmac: drop unneeded function declarations from headers -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Functions brcmf_c_prec_enq and brcmf_sdio_init don't exist so we -really don't need their declarations. Function brcmf_parse_tlvs is used -in cfg80211.c only so make it static and drop from header as well. - -Signed-off-by: Rafał Miłecki -Acked-by: Arend van Spriel -Signed-off-by: Kalle Valo ---- - drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h | 4 ---- - drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | 2 +- - drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h | 2 -- - 3 files changed, 1 insertion(+), 7 deletions(-) - ---- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h -+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h -@@ -218,9 +218,6 @@ int brcmf_bus_get_memdump(struct brcmf_b - * interface functions from common layer - */ - --bool brcmf_c_prec_enq(struct device *dev, struct pktq *q, struct sk_buff *pkt, -- int prec); -- - /* Receive frame for delivery to OS. Callee disposes of rxp. */ - void brcmf_rx_frame(struct device *dev, struct sk_buff *rxp, bool handle_event); - /* Receive async event packet from firmware. Callee disposes of rxp. */ -@@ -247,7 +244,6 @@ void brcmf_bus_add_txhdrlen(struct devic - - #ifdef CPTCFG_BRCMFMAC_SDIO - void brcmf_sdio_exit(void); --void brcmf_sdio_init(void); - void brcmf_sdio_register(void); - #endif - #ifdef CPTCFG_BRCMFMAC_USB ---- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c -+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c -@@ -326,7 +326,7 @@ u16 channel_to_chanspec(struct brcmu_d11 - * triples, returning a pointer to the substring whose first element - * matches tag - */ --const struct brcmf_tlv * -+static const struct brcmf_tlv * - brcmf_parse_tlvs(const void *buf, int buflen, uint key) - { - const struct brcmf_tlv *elt = buf; ---- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h -+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h -@@ -396,8 +396,6 @@ void brcmf_free_vif(struct brcmf_cfg8021 - s32 brcmf_vif_set_mgmt_ie(struct brcmf_cfg80211_vif *vif, s32 pktflag, - const u8 *vndr_ie_buf, u32 vndr_ie_len); - s32 brcmf_vif_clear_mgmt_ies(struct brcmf_cfg80211_vif *vif); --const struct brcmf_tlv * --brcmf_parse_tlvs(const void *buf, int buflen, uint key); - u16 channel_to_chanspec(struct brcmu_d11inf *d11inf, - struct ieee80211_channel *ch); - bool brcmf_get_vif_state_any(struct brcmf_cfg80211_info *cfg, diff --git a/package/kernel/mac80211/patches/362-0002-brcmfmac-move-brcmf_c_set_joinpref_default-declarati.patch b/package/kernel/mac80211/patches/362-0002-brcmfmac-move-brcmf_c_set_joinpref_default-declarati.patch deleted file mode 100644 index 4ded6d6a29..0000000000 --- a/package/kernel/mac80211/patches/362-0002-brcmfmac-move-brcmf_c_set_joinpref_default-declarati.patch +++ /dev/null @@ -1,41 +0,0 @@ -From f5611e038172101561b570554c81e290a39517ed Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= -Date: Wed, 18 Jan 2017 11:48:52 +0100 -Subject: [PATCH] brcmfmac: move brcmf_c_set_joinpref_default declaration to - common.h -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Function brcmf_c_set_joinpref_default is in common.c, so move it to the -related header. - -Signed-off-by: Rafał Miłecki -Acked-by: Arend van Spriel -Signed-off-by: Kalle Valo ---- - drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h | 2 ++ - drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h | 1 - - 2 files changed, 2 insertions(+), 1 deletion(-) - ---- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h -+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h -@@ -65,6 +65,8 @@ struct brcmf_mp_device { - } bus; - }; - -+void brcmf_c_set_joinpref_default(struct brcmf_if *ifp); -+ - struct brcmf_mp_device *brcmf_get_module_param(struct device *dev, - enum brcmf_bus_type bus_type, - u32 chip, u32 chiprev); ---- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h -+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h -@@ -216,7 +216,6 @@ void brcmf_txflowblock_if(struct brcmf_i - void brcmf_txfinalize(struct brcmf_if *ifp, struct sk_buff *txp, bool success); - void brcmf_netif_rx(struct brcmf_if *ifp, struct sk_buff *skb); - void brcmf_net_setcarrier(struct brcmf_if *ifp, bool on); --void brcmf_c_set_joinpref_default(struct brcmf_if *ifp); - int __init brcmf_core_init(void); - void __exit brcmf_core_exit(void); - diff --git a/package/kernel/mac80211/patches/362-0003-brcmfmac-drop-brcmf_bus_detach-and-inline-its-code.patch b/package/kernel/mac80211/patches/362-0003-brcmfmac-drop-brcmf_bus_detach-and-inline-its-code.patch deleted file mode 100644 index 13e5d52bd0..0000000000 --- a/package/kernel/mac80211/patches/362-0003-brcmfmac-drop-brcmf_bus_detach-and-inline-its-code.patch +++ /dev/null @@ -1,49 +0,0 @@ -From bfa7295e5b4d32cdab28d4cdc3a9791f73aed089 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= -Date: Wed, 18 Jan 2017 11:48:53 +0100 -Subject: [PATCH] brcmfmac: drop brcmf_bus_detach and inline its code -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Driver used to call brcmf_bus_detach only from one place and it already -contained a check for drvr not being NULL. We can get rid of this extra -function, call brcmf_bus_stop directly and simplify the code. -There also isn't brcmf_bus_attach function which one could expect so it -looks more consistent this way. - -Signed-off-by: Rafał Miłecki -Acked-by: Arend van Spriel -Signed-off-by: Kalle Valo ---- - drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c | 12 +----------- - 1 file changed, 1 insertion(+), 11 deletions(-) - ---- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c -+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c -@@ -1075,16 +1075,6 @@ void brcmf_bus_add_txhdrlen(struct devic - } - } - --static void brcmf_bus_detach(struct brcmf_pub *drvr) --{ -- brcmf_dbg(TRACE, "Enter\n"); -- -- if (drvr) { -- /* Stop the bus module */ -- brcmf_bus_stop(drvr->bus_if); -- } --} -- - void brcmf_dev_reset(struct device *dev) - { - struct brcmf_bus *bus_if = dev_get_drvdata(dev); -@@ -1131,7 +1121,7 @@ void brcmf_detach(struct device *dev) - - brcmf_fws_deinit(drvr); - -- brcmf_bus_detach(drvr); -+ brcmf_bus_stop(drvr->bus_if); - - brcmf_proto_detach(drvr); - diff --git a/package/kernel/mac80211/patches/362-0004-brcmfmac-rename-brcmf_bus_start-function-to-brcmf_bu.patch b/package/kernel/mac80211/patches/362-0004-brcmfmac-rename-brcmf_bus_start-function-to-brcmf_bu.patch deleted file mode 100644 index 8cf6c38a95..0000000000 --- a/package/kernel/mac80211/patches/362-0004-brcmfmac-rename-brcmf_bus_start-function-to-brcmf_bu.patch +++ /dev/null @@ -1,93 +0,0 @@ -From e8cd47501fa0c0a591bb07d5878dcc8d63d60e57 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= -Date: Wed, 18 Jan 2017 11:48:54 +0100 -Subject: [PATCH] brcmfmac: rename brcmf_bus_start function to - brcmf_bus_started -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -This intends to make init/attach process slightly easier to follow. - -What driver was doing in brcmf_bus_start wasn't bus specific at all and -function brcmf_bus_stop wasn't undoing things done there. This function -is supposed to be called by bus specific code when the bus is ready. - -Signed-off-by: Rafał Miłecki -Acked-by: Arend van Spriel -Signed-off-by: Kalle Valo ---- - drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h | 2 +- - drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c | 2 +- - drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c | 2 +- - drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c | 2 +- - drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c | 2 +- - drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c | 2 +- - 6 files changed, 6 insertions(+), 6 deletions(-) - ---- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h -+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h -@@ -238,7 +238,7 @@ void brcmf_txcomplete(struct device *dev - /* Configure the "global" bus state used by upper layers */ - void brcmf_bus_change_state(struct brcmf_bus *bus, enum brcmf_bus_state state); - --int brcmf_bus_start(struct device *dev); -+int brcmf_bus_started(struct device *dev); - s32 brcmf_iovar_data_set(struct device *dev, char *name, void *data, u32 len); - void brcmf_bus_add_txhdrlen(struct device *dev, uint len); - ---- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c -+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c -@@ -74,7 +74,7 @@ module_param_named(roamoff, brcmf_roamof - MODULE_PARM_DESC(roamoff, "Do not use internal roaming engine"); - - #ifdef DEBUG --/* always succeed brcmf_bus_start() */ -+/* always succeed brcmf_bus_started() */ - static int brcmf_ignore_probe_fail; - module_param_named(ignore_probe_fail, brcmf_ignore_probe_fail, int, 0); - MODULE_PARM_DESC(ignore_probe_fail, "always succeed probe for debugging"); ---- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c -+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c -@@ -966,7 +966,7 @@ static int brcmf_revinfo_read(struct seq - return 0; - } - --int brcmf_bus_start(struct device *dev) -+int brcmf_bus_started(struct device *dev) - { - int ret = -1; - struct brcmf_bus *bus_if = dev_get_drvdata(dev); ---- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c -+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c -@@ -1572,7 +1572,7 @@ static int brcmf_pcie_attach_bus(struct - if (ret) { - brcmf_err("brcmf_attach failed\n"); - } else { -- ret = brcmf_bus_start(&devinfo->pdev->dev); -+ ret = brcmf_bus_started(&devinfo->pdev->dev); - if (ret) - brcmf_err("dongle is not responding\n"); - } ---- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c -+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c -@@ -4065,7 +4065,7 @@ static void brcmf_sdio_firmware_callback - - sdio_release_host(sdiodev->func[1]); - -- err = brcmf_bus_start(dev); -+ err = brcmf_bus_started(dev); - if (err != 0) { - brcmf_err("dongle is not responding\n"); - goto fail; ---- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c -+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c -@@ -1148,7 +1148,7 @@ static int brcmf_usb_bus_setup(struct br - if (ret) - goto fail; - -- ret = brcmf_bus_start(devinfo->dev); -+ ret = brcmf_bus_started(devinfo->dev); - if (ret) - goto fail; - diff --git a/package/kernel/mac80211/patches/363-brcmfmac-drop-duplicated-core-selection-from-brcmf_p.patch b/package/kernel/mac80211/patches/363-brcmfmac-drop-duplicated-core-selection-from-brcmf_p.patch deleted file mode 100644 index f066a4f63f..0000000000 --- a/package/kernel/mac80211/patches/363-brcmfmac-drop-duplicated-core-selection-from-brcmf_p.patch +++ /dev/null @@ -1,30 +0,0 @@ -From b3d75a81f07c757ab73c9022631170c3baefe380 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= -Date: Thu, 19 Jan 2017 10:51:25 +0100 -Subject: [PATCH] brcmfmac: drop duplicated core selection from - brcmf_pcie_attach -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -It was left after reworking PCIe reset in commit 07fe2e38c7fd -("brcmfmac: Reset PCIE devices after recognition."). - -Cc: Hante Meuleman -Signed-off-by: Rafał Miłecki -Acked-by: Arend van Spriel -Signed-off-by: Kalle Valo ---- - drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c | 1 - - 1 file changed, 1 deletion(-) - ---- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c -+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c -@@ -601,7 +601,6 @@ static void brcmf_pcie_attach(struct brc - { - u32 config; - -- brcmf_pcie_select_core(devinfo, BCMA_CORE_PCIE2); - /* BAR1 window may not be sized properly */ - brcmf_pcie_select_core(devinfo, BCMA_CORE_PCIE2); - brcmf_pcie_write_reg32(devinfo, BRCMF_PCIE_PCIE2REG_CONFIGADDR, 0x4e0); diff --git a/package/kernel/mac80211/patches/364-0001-brcmfmac-provide-a-value-for-struct-wowlan_support-m.patch b/package/kernel/mac80211/patches/364-0001-brcmfmac-provide-a-value-for-struct-wowlan_support-m.patch deleted file mode 100644 index ec127d3c93..0000000000 --- a/package/kernel/mac80211/patches/364-0001-brcmfmac-provide-a-value-for-struct-wowlan_support-m.patch +++ /dev/null @@ -1,30 +0,0 @@ -From 2ef0359031b9ed891ca381b2687186fb52b277f8 Mon Sep 17 00:00:00 2001 -From: Arend Van Spriel -Date: Fri, 27 Jan 2017 12:27:45 +0000 -Subject: [PATCH] brcmfmac: provide a value for struct - wowlan_support::max_nd_match_sets - -The driver advertises support for WOWLAN_NETDETECT but did not specify -maximum amount of netdetect match sets. This was no issue due to a bug -in nl80211. As that has been fixed, brcmfmac also needs fixing. - -Reviewed-by: Hante Meuleman -Reviewed-by: Pieter-Paul Giesberts -Reviewed-by: Franky Lin -Signed-off-by: Arend van Spriel -Signed-off-by: Kalle Valo ---- - drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | 2 ++ - 1 file changed, 2 insertions(+) - ---- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c -+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c -@@ -6356,6 +6356,8 @@ static void brcmf_wiphy_wowl_params(stru - if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_PNO)) { - if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_WOWL_ND)) { - brcmf_wowlan_support.flags |= WIPHY_WOWLAN_NET_DETECT; -+ brcmf_wowlan_support.max_nd_match_sets = -+ BRCMF_PNO_MAX_PFN_COUNT; - init_waitqueue_head(&cfg->wowl.nd_data_wait); - } - } diff --git a/package/kernel/mac80211/patches/364-0002-brcmfmac-fix-handling-firmware-results-for-wowl-netd.patch b/package/kernel/mac80211/patches/364-0002-brcmfmac-fix-handling-firmware-results-for-wowl-netd.patch deleted file mode 100644 index 52541ed3d0..0000000000 --- a/package/kernel/mac80211/patches/364-0002-brcmfmac-fix-handling-firmware-results-for-wowl-netd.patch +++ /dev/null @@ -1,39 +0,0 @@ -From d29afe91af5995306d940b3dfee2419e0bb24a51 Mon Sep 17 00:00:00 2001 -From: Arend Van Spriel -Date: Fri, 27 Jan 2017 12:27:46 +0000 -Subject: [PATCH] brcmfmac: fix handling firmware results for wowl netdetect - -For wowl netdetect the event data changed for newer chips. This -was recently fixed for scheduled scan, but same change is needed -for wowl netdetect. Removing now pointles += operation from both -result handlers. - -Reviewed-by: Hante Meuleman -Reviewed-by: Pieter-Paul Giesberts -Reviewed-by: Franky Lin -Signed-off-by: Arend van Spriel -Signed-off-by: Kalle Valo ---- - drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | 4 +--- - 1 file changed, 1 insertion(+), 3 deletions(-) - ---- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c -+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c -@@ -3328,7 +3328,6 @@ brcmf_notify_sched_scan_results(struct b - goto out_err; - } - -- data += sizeof(struct brcmf_pno_scanresults_le); - netinfo_start = brcmf_get_netinfo_array(pfn_result); - - for (i = 0; i < result_count; i++) { -@@ -3476,8 +3475,7 @@ brcmf_wowl_nd_results(struct brcmf_if *i - return -EINVAL; - } - -- data += sizeof(struct brcmf_pno_scanresults_le); -- netinfo = (struct brcmf_pno_net_info_le *)data; -+ netinfo = brcmf_get_netinfo_array(pfn_result); - memcpy(cfg->wowl.nd->ssid.ssid, netinfo->SSID, netinfo->SSID_len); - cfg->wowl.nd->ssid.ssid_len = netinfo->SSID_len; - cfg->wowl.nd->n_channels = 1; diff --git a/package/kernel/mac80211/patches/364-0003-brcmfmac-allow-wowlan-support-to-be-per-device.patch b/package/kernel/mac80211/patches/364-0003-brcmfmac-allow-wowlan-support-to-be-per-device.patch deleted file mode 100644 index 79c9c65c2b..0000000000 --- a/package/kernel/mac80211/patches/364-0003-brcmfmac-allow-wowlan-support-to-be-per-device.patch +++ /dev/null @@ -1,78 +0,0 @@ -From 0b57010fc18e12c19d14379cd739d4eb7c3898f3 Mon Sep 17 00:00:00 2001 -From: Arend Van Spriel -Date: Fri, 27 Jan 2017 12:27:47 +0000 -Subject: [PATCH] brcmfmac: allow wowlan support to be per device - -The wowlan support is (partially) determined dynamic by checking the -device/firmware capabilities. So they can differ per device. So it -is not possible to use a static global. Instead use the global as a -template and use kmemdup(). When kmemdup() fails the template is used -unmodified. - -Reviewed-by: Hante Meuleman -Reviewed-by: Pieter-Paul Giesberts -Reviewed-by: Franky Lin -Signed-off-by: Arend van Spriel -Signed-off-by: Kalle Valo ---- - .../broadcom/brcm80211/brcmfmac/cfg80211.c | 26 ++++++++++++++++------ - 1 file changed, 19 insertions(+), 7 deletions(-) - ---- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c -+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c -@@ -6337,7 +6337,7 @@ static void brcmf_wiphy_pno_params(struc - } - - #ifdef CONFIG_PM --static struct wiphy_wowlan_support brcmf_wowlan_support = { -+static const struct wiphy_wowlan_support brcmf_wowlan_support = { - .flags = WIPHY_WOWLAN_MAGIC_PKT | WIPHY_WOWLAN_DISCONNECT, - .n_patterns = BRCMF_WOWL_MAXPATTERNS, - .pattern_max_len = BRCMF_WOWL_MAXPATTERNSIZE, -@@ -6350,21 +6350,29 @@ static void brcmf_wiphy_wowl_params(stru - { - #ifdef CONFIG_PM - struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); -+ struct wiphy_wowlan_support *wowl; -+ -+ wowl = kmemdup(&brcmf_wowlan_support, sizeof(brcmf_wowlan_support), -+ GFP_KERNEL); -+ if (!wowl) { -+ brcmf_err("only support basic wowlan features\n"); -+ wiphy->wowlan = &brcmf_wowlan_support; -+ return; -+ } - - if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_PNO)) { - if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_WOWL_ND)) { -- brcmf_wowlan_support.flags |= WIPHY_WOWLAN_NET_DETECT; -- brcmf_wowlan_support.max_nd_match_sets = -- BRCMF_PNO_MAX_PFN_COUNT; -+ wowl->flags |= WIPHY_WOWLAN_NET_DETECT; -+ wowl->max_nd_match_sets = BRCMF_PNO_MAX_PFN_COUNT; - init_waitqueue_head(&cfg->wowl.nd_data_wait); - } - } - if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_WOWL_GTK)) { -- brcmf_wowlan_support.flags |= WIPHY_WOWLAN_SUPPORTS_GTK_REKEY; -- brcmf_wowlan_support.flags |= WIPHY_WOWLAN_GTK_REKEY_FAILURE; -+ wowl->flags |= WIPHY_WOWLAN_SUPPORTS_GTK_REKEY; -+ wowl->flags |= WIPHY_WOWLAN_GTK_REKEY_FAILURE; - } - -- wiphy->wowlan = &brcmf_wowlan_support; -+ wiphy->wowlan = wowl; - #endif - } - -@@ -6745,6 +6753,10 @@ static void brcmf_free_wiphy(struct wiph - kfree(wiphy->bands[NL80211_BAND_5GHZ]->channels); - kfree(wiphy->bands[NL80211_BAND_5GHZ]); - } -+#if IS_ENABLED(CONFIG_PM) -+ if (wiphy->wowlan != &brcmf_wowlan_support) -+ kfree(wiphy->wowlan); -+#endif - wiphy_free(wiphy); - } - diff --git a/package/kernel/mac80211/patches/365-0001-brcmfmac-check-brcmf_bus_get_memdump-result-for-erro.patch b/package/kernel/mac80211/patches/365-0001-brcmfmac-check-brcmf_bus_get_memdump-result-for-erro.patch deleted file mode 100644 index ef2e80f8a7..0000000000 --- a/package/kernel/mac80211/patches/365-0001-brcmfmac-check-brcmf_bus_get_memdump-result-for-erro.patch +++ /dev/null @@ -1,55 +0,0 @@ -From f4737a62033d7f3e0db740c449fc62119da7ab8a Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= -Date: Mon, 30 Jan 2017 16:09:51 +0100 -Subject: [PATCH] brcmfmac: check brcmf_bus_get_memdump result for error -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -This method may be unsupported (see: USB bus) or may just fail (see: -SDIO bus). -While at it rework logic in brcmf_sdio_bus_get_memdump function to avoid -too many conditional code nesting levels. - -Signed-off-by: Rafał Miłecki -Acked-by: Arend van Spriel -Signed-off-by: Kalle Valo ---- - .../wireless/broadcom/brcm80211/brcmfmac/debug.c | 23 +++++++++++++++------- - 1 file changed, 16 insertions(+), 7 deletions(-) - ---- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/debug.c -+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/debug.c -@@ -32,16 +32,25 @@ static int brcmf_debug_create_memdump(st - { - void *dump; - size_t ramsize; -+ int err; - - ramsize = brcmf_bus_get_ramsize(bus); -- if (ramsize) { -- dump = vzalloc(len + ramsize); -- if (!dump) -- return -ENOMEM; -- memcpy(dump, data, len); -- brcmf_bus_get_memdump(bus, dump + len, ramsize); -- dev_coredumpv(bus->dev, dump, len + ramsize, GFP_KERNEL); -+ if (!ramsize) -+ return -ENOTSUPP; -+ -+ dump = vzalloc(len + ramsize); -+ if (!dump) -+ return -ENOMEM; -+ -+ memcpy(dump, data, len); -+ err = brcmf_bus_get_memdump(bus, dump + len, ramsize); -+ if (err) { -+ vfree(dump); -+ return err; - } -+ -+ dev_coredumpv(bus->dev, dump, len + ramsize, GFP_KERNEL); -+ - return 0; - } - diff --git a/package/kernel/mac80211/patches/365-0002-brcmfmac-be-more-verbose-when-PSM-s-watchdog-fires.patch b/package/kernel/mac80211/patches/365-0002-brcmfmac-be-more-verbose-when-PSM-s-watchdog-fires.patch deleted file mode 100644 index 54210dfe97..0000000000 --- a/package/kernel/mac80211/patches/365-0002-brcmfmac-be-more-verbose-when-PSM-s-watchdog-fires.patch +++ /dev/null @@ -1,41 +0,0 @@ -From 36401cb7ffae731295a6dd1ce2b40d7ad74245f4 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= -Date: Mon, 30 Jan 2017 16:09:52 +0100 -Subject: [PATCH] brcmfmac: be more verbose when PSM's watchdog fires -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -It's important to inform user so he knows things went wrong. He may also -want to get memory dump for further debugging purposes. - -Signed-off-by: Rafał Miłecki -Acked-by: Arend van Spriel -Signed-off-by: Kalle Valo ---- - drivers/net/wireless/broadcom/brcm80211/brcmfmac/debug.c | 12 ++++++++++-- - 1 file changed, 10 insertions(+), 2 deletions(-) - ---- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/debug.c -+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/debug.c -@@ -58,10 +58,18 @@ static int brcmf_debug_psm_watchdog_noti - const struct brcmf_event_msg *evtmsg, - void *data) - { -+ int err; -+ - brcmf_dbg(TRACE, "enter: bsscfgidx=%d\n", ifp->bsscfgidx); - -- return brcmf_debug_create_memdump(ifp->drvr->bus_if, data, -- evtmsg->datalen); -+ brcmf_err("PSM's watchdog has fired!\n"); -+ -+ err = brcmf_debug_create_memdump(ifp->drvr->bus_if, data, -+ evtmsg->datalen); -+ if (err) -+ brcmf_err("Failed to get memory dump, %d\n", err); -+ -+ return err; - } - - void brcmf_debugfs_init(void) diff --git a/package/kernel/mac80211/patches/400-ath_move_debug_code.patch b/package/kernel/mac80211/patches/400-ath_move_debug_code.patch index a5e1f067c5..ed65053d77 100644 --- a/package/kernel/mac80211/patches/400-ath_move_debug_code.patch +++ b/package/kernel/mac80211/patches/400-ath_move_debug_code.patch @@ -11,7 +11,7 @@ -ath-$(CPTCFG_ATH_DEBUG) += debug.o ath-$(CPTCFG_ATH_TRACEPOINTS) += trace.o - ccflags-y += -D__CHECK_ENDIAN__ + CFLAGS_trace.o := -I$(src) --- a/drivers/net/wireless/ath/ath.h +++ b/drivers/net/wireless/ath/ath.h @@ -318,14 +318,7 @@ void _ath_dbg(struct ath_common *common, diff --git a/package/kernel/mac80211/patches/402-ath_regd_optional.patch b/package/kernel/mac80211/patches/402-ath_regd_optional.patch index 7a7c2d4174..0d6d3dbdbd 100644 --- a/package/kernel/mac80211/patches/402-ath_regd_optional.patch +++ b/package/kernel/mac80211/patches/402-ath_regd_optional.patch @@ -49,7 +49,7 @@ if (!wiphy->bands[NL80211_BAND_5GHZ]) return; -@@ -633,6 +647,10 @@ ath_regd_init_wiphy(struct ath_regulator +@@ -634,6 +648,10 @@ ath_regd_init_wiphy(struct ath_regulator const struct ieee80211_regdomain *regd; wiphy->reg_notifier = reg_notifier; @@ -74,7 +74,7 @@ ---help--- --- a/.local-symbols +++ b/.local-symbols -@@ -127,6 +127,7 @@ ADM8211= +@@ -130,6 +130,7 @@ ADM8211= ATH_COMMON= WLAN_VENDOR_ATH= ATH_DEBUG= diff --git a/package/kernel/mac80211/patches/406-ath_relax_default_regd.patch b/package/kernel/mac80211/patches/406-ath_relax_default_regd.patch index 5b20b4518e..b6190b9363 100644 --- a/package/kernel/mac80211/patches/406-ath_relax_default_regd.patch +++ b/package/kernel/mac80211/patches/406-ath_relax_default_regd.patch @@ -39,7 +39,7 @@ bool ath_is_world_regd(struct ath_regulatory *reg) { return is_wwr_sku(ath_regd_get_eepromRD(reg)); -@@ -651,6 +659,9 @@ ath_regd_init_wiphy(struct ath_regulator +@@ -652,6 +660,9 @@ ath_regd_init_wiphy(struct ath_regulator if (IS_ENABLED(CPTCFG_ATH_USER_REGD)) return 0; diff --git a/package/kernel/mac80211/patches/410-ath9k_allow_adhoc_and_ap.patch b/package/kernel/mac80211/patches/410-ath9k_allow_adhoc_and_ap.patch index 1d3e4bea13..86f96e8e97 100644 --- a/package/kernel/mac80211/patches/410-ath9k_allow_adhoc_and_ap.patch +++ b/package/kernel/mac80211/patches/410-ath9k_allow_adhoc_and_ap.patch @@ -7,4 +7,4 @@ + { .max = 1, .types = BIT(NL80211_IFTYPE_ADHOC) }, }; - static const struct ieee80211_iface_limit wds_limits[] = { + #ifdef CPTCFG_WIRELESS_WDS diff --git a/package/kernel/mac80211/patches/440-ath5k_channel_bw_debugfs.patch b/package/kernel/mac80211/patches/440-ath5k_channel_bw_debugfs.patch index 924b62e0d4..1d249a9723 100644 --- a/package/kernel/mac80211/patches/440-ath5k_channel_bw_debugfs.patch +++ b/package/kernel/mac80211/patches/440-ath5k_channel_bw_debugfs.patch @@ -11,7 +11,7 @@ drivers/net/wireless/ath/ath5k/debug.c | 86 ++++++++++++++++++++++++++++++++ --- a/drivers/net/wireless/ath/ath5k/debug.c +++ b/drivers/net/wireless/ath/ath5k/debug.c -@@ -823,6 +823,97 @@ static const struct file_operations fops +@@ -822,6 +822,97 @@ static const struct file_operations fops .llseek = default_llseek, }; @@ -109,7 +109,7 @@ drivers/net/wireless/ath/ath5k/debug.c | 86 ++++++++++++++++++++++++++++++++ /* debugfs: queues etc */ -@@ -1010,6 +1101,9 @@ ath5k_debug_init_device(struct ath5k_hw +@@ -1009,6 +1100,9 @@ ath5k_debug_init_device(struct ath5k_hw debugfs_create_file("beacon", S_IWUSR | S_IRUSR, phydir, ah, &fops_beacon); diff --git a/package/kernel/mac80211/patches/501-ath9k_ahb_init.patch b/package/kernel/mac80211/patches/501-ath9k_ahb_init.patch index 59bc5fc577..d076e3c2eb 100644 --- a/package/kernel/mac80211/patches/501-ath9k_ahb_init.patch +++ b/package/kernel/mac80211/patches/501-ath9k_ahb_init.patch @@ -1,6 +1,6 @@ --- a/drivers/net/wireless/ath/ath9k/init.c +++ b/drivers/net/wireless/ath/ath9k/init.c -@@ -1080,23 +1080,23 @@ static int __init ath9k_init(void) +@@ -1086,23 +1086,23 @@ static int __init ath9k_init(void) { int error; diff --git a/package/kernel/mac80211/patches/513-ath9k_add_pci_ids.patch b/package/kernel/mac80211/patches/513-ath9k_add_pci_ids.patch index 78b22e71a9..59daf4fe11 100644 --- a/package/kernel/mac80211/patches/513-ath9k_add_pci_ids.patch +++ b/package/kernel/mac80211/patches/513-ath9k_add_pci_ids.patch @@ -20,7 +20,7 @@ #define AR9160_DEVID_PCI 0x0027 --- a/drivers/net/wireless/ath/ath9k/pci.c +++ b/drivers/net/wireless/ath/ath9k/pci.c -@@ -760,6 +760,7 @@ static const struct pci_device_id ath_pc +@@ -763,6 +763,7 @@ static const struct pci_device_id ath_pc .driver_data = ATH9K_PCI_BT_ANT_DIV }, #endif diff --git a/package/kernel/mac80211/patches/522-mac80211_configure_antenna_gain.patch b/package/kernel/mac80211/patches/522-mac80211_configure_antenna_gain.patch index 9e767ffa8d..9a0f6f5dbd 100644 --- a/package/kernel/mac80211/patches/522-mac80211_configure_antenna_gain.patch +++ b/package/kernel/mac80211/patches/522-mac80211_configure_antenna_gain.patch @@ -1,6 +1,6 @@ --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h -@@ -2590,6 +2590,7 @@ struct cfg80211_nan_func { +@@ -2660,6 +2660,7 @@ struct cfg80211_nan_func { * (as advertised by the nl80211 feature flag.) * @get_tx_power: store the current TX power into the dbm variable; * return 0 if successful @@ -8,7 +8,7 @@ * * @set_wds_peer: set the WDS peer for a WDS interface * -@@ -2864,6 +2865,7 @@ struct cfg80211_ops { +@@ -2940,6 +2941,7 @@ struct cfg80211_ops { enum nl80211_tx_power_setting type, int mbm); int (*get_tx_power)(struct wiphy *wiphy, struct wireless_dev *wdev, int *dbm); @@ -18,7 +18,7 @@ const u8 *addr); --- a/include/net/mac80211.h +++ b/include/net/mac80211.h -@@ -1319,6 +1319,7 @@ enum ieee80211_smps_mode { +@@ -1325,6 +1325,7 @@ enum ieee80211_smps_mode { * * @power_level: requested transmit power (in dBm), backward compatibility * value only that is set to the minimum of all interfaces @@ -26,7 +26,7 @@ * * @chandef: the channel definition to tune to * @radar_enabled: whether radar detection is enabled -@@ -1339,6 +1340,7 @@ enum ieee80211_smps_mode { +@@ -1345,6 +1346,7 @@ enum ieee80211_smps_mode { struct ieee80211_conf { u32 flags; int power_level, dynamic_ps_timeout; @@ -36,9 +36,9 @@ u8 ps_dtim_period; --- a/include/uapi/linux/nl80211.h +++ b/include/uapi/linux/nl80211.h -@@ -1937,6 +1937,9 @@ enum nl80211_commands { - * @NL80211_ATTR_NAN_MATCH: used to report a match. This is a nested attribute. - * See &enum nl80211_nan_match_attributes. +@@ -2002,6 +2002,9 @@ enum nl80211_commands { + * u32 attribute with an &enum nl80211_timeout_reason value. This is used, + * e.g., with %NL80211_CMD_CONNECT event. * + * @NL80211_ATTR_WIPHY_ANTENNA_GAIN: Configured antenna gain. Used to reduce + * transmit power to stay within regulatory limits. u32, dBi. @@ -46,9 +46,9 @@ * @NUM_NL80211_ATTR: total number of nl80211_attrs available * @NL80211_ATTR_MAX: highest attribute number currently defined * @__NL80211_ATTR_AFTER_LAST: internal use -@@ -2336,6 +2339,8 @@ enum nl80211_attrs { - NL80211_ATTR_NAN_FUNC, - NL80211_ATTR_NAN_MATCH, +@@ -2413,6 +2416,8 @@ enum nl80211_attrs { + + NL80211_ATTR_TIMEOUT_REASON, + NL80211_ATTR_WIPHY_ANTENNA_GAIN, + @@ -57,7 +57,7 @@ __NL80211_ATTR_AFTER_LAST, --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c -@@ -2406,6 +2406,19 @@ static int ieee80211_get_tx_power(struct +@@ -2396,6 +2396,19 @@ static int ieee80211_get_tx_power(struct return 0; } @@ -77,7 +77,7 @@ static int ieee80211_set_wds_peer(struct wiphy *wiphy, struct net_device *dev, const u8 *addr) { -@@ -3633,6 +3646,7 @@ const struct cfg80211_ops mac80211_confi +@@ -3627,6 +3640,7 @@ const struct cfg80211_ops mac80211_confi .set_wiphy_params = ieee80211_set_wiphy_params, .set_tx_power = ieee80211_set_tx_power, .get_tx_power = ieee80211_get_tx_power, @@ -87,7 +87,7 @@ CFG80211_TESTMODE_CMD(ieee80211_testmode_cmd) --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h -@@ -1363,6 +1363,7 @@ struct ieee80211_local { +@@ -1370,6 +1370,7 @@ struct ieee80211_local { int dynamic_ps_forced_timeout; int user_power_level; /* in dBm, for all interfaces */ @@ -119,7 +119,7 @@ if (local->hw.conf.power_level != power) { changed |= IEEE80211_CONF_CHANGE_POWER; local->hw.conf.power_level = power; -@@ -588,6 +594,7 @@ struct ieee80211_hw *ieee80211_alloc_hw_ +@@ -589,6 +595,7 @@ struct ieee80211_hw *ieee80211_alloc_hw_ IEEE80211_RADIOTAP_MCS_HAVE_BW; local->hw.radiotap_vht_details = IEEE80211_RADIOTAP_VHT_KNOWN_GI | IEEE80211_RADIOTAP_VHT_KNOWN_BANDWIDTH; @@ -129,15 +129,15 @@ local->user_power_level = IEEE80211_UNSET_POWER_LEVEL; --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c -@@ -416,6 +416,7 @@ static const struct nla_policy nl80211_p - [NL80211_ATTR_NAN_MASTER_PREF] = { .type = NLA_U8 }, - [NL80211_ATTR_NAN_DUAL] = { .type = NLA_U8 }, - [NL80211_ATTR_NAN_FUNC] = { .type = NLA_NESTED }, +@@ -424,6 +424,7 @@ static const struct nla_policy nl80211_p + .len = sizeof(struct nl80211_bss_select_rssi_adjust) + }, + [NL80211_ATTR_TIMEOUT_REASON] = { .type = NLA_U32 }, + [NL80211_ATTR_WIPHY_ANTENNA_GAIN] = { .type = NLA_U32 }, }; /* policy for the key attributes */ -@@ -2353,6 +2354,20 @@ static int nl80211_set_wiphy(struct sk_b +@@ -2385,6 +2386,20 @@ static int nl80211_set_wiphy(struct sk_b if (result) return result; } diff --git a/package/kernel/mac80211/patches/530-ath9k_extra_leds.patch b/package/kernel/mac80211/patches/530-ath9k_extra_leds.patch index 31b77532b5..bc2c8fd310 100644 --- a/package/kernel/mac80211/patches/530-ath9k_extra_leds.patch +++ b/package/kernel/mac80211/patches/530-ath9k_extra_leds.patch @@ -103,7 +103,8 @@ + GFP_KERNEL); + if (!led) + return -ENOMEM; -+ + +- ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, val); + led->gpio = gpio = (struct gpio_led *) (led + 1); + _name = (char *) (led->gpio + 1); + @@ -116,8 +117,7 @@ + ret = ath_add_led(sc, led); + if (unlikely(ret < 0)) + kfree(led); - -- ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, val); ++ + return ret; } @@ -125,11 +125,11 @@ { - if (!sc->led_registered) - return; -+ struct ath_led *led; - +- - ath_led_brightness(&sc->led_cdev, LED_OFF); - led_classdev_unregister(&sc->led_cdev); -- ++ struct ath_led *led; + - ath9k_hw_gpio_free(sc->sc_ah, sc->sc_ah->led_pin); + while (!list_empty(&sc->leds)) { + led = list_first_entry(&sc->leds, struct ath_led, list); @@ -181,7 +181,7 @@ --- a/drivers/net/wireless/ath/ath9k/init.c +++ b/drivers/net/wireless/ath/ath9k/init.c -@@ -992,7 +992,7 @@ int ath9k_init_device(u16 devid, struct +@@ -998,7 +998,7 @@ int ath9k_init_device(u16 devid, struct #ifdef CPTCFG_MAC80211_LEDS /* must be initialized before ieee80211_register_hw */ diff --git a/package/kernel/mac80211/patches/543-ath9k_entropy_from_adc.patch b/package/kernel/mac80211/patches/543-ath9k_entropy_from_adc.patch index bca23d3d3d..6f7370203b 100644 --- a/package/kernel/mac80211/patches/543-ath9k_entropy_from_adc.patch +++ b/package/kernel/mac80211/patches/543-ath9k_entropy_from_adc.patch @@ -65,7 +65,7 @@ } static const struct ieee80211_iface_limit if_limits[] = { -@@ -952,6 +953,18 @@ static void ath9k_set_hw_capab(struct at +@@ -958,6 +959,18 @@ static void ath9k_set_hw_capab(struct at SET_IEEE80211_PERM_ADDR(hw, common->macaddr); } @@ -84,7 +84,7 @@ int ath9k_init_device(u16 devid, struct ath_softc *sc, const struct ath_bus_ops *bus_ops) { -@@ -997,6 +1010,8 @@ int ath9k_init_device(u16 devid, struct +@@ -1003,6 +1016,8 @@ int ath9k_init_device(u16 devid, struct ARRAY_SIZE(ath9k_tpt_blink)); #endif diff --git a/package/kernel/mac80211/patches/550-ath9k-Add-a-define-for-the-EEPROM-eepmisc-endianness.patch b/package/kernel/mac80211/patches/550-ath9k-Add-a-define-for-the-EEPROM-eepmisc-endianness.patch deleted file mode 100644 index a17f95682f..0000000000 --- a/package/kernel/mac80211/patches/550-ath9k-Add-a-define-for-the-EEPROM-eepmisc-endianness.patch +++ /dev/null @@ -1,95 +0,0 @@ -From 9692ab1ff30ae0abc1000d11b2f929b6e2e4cb7f Mon Sep 17 00:00:00 2001 -From: Martin Blumenstingl -Date: Mon, 3 Oct 2016 00:29:07 +0200 -Subject: [v2 PATCH 1/7] ath9k: Add a #define for the EEPROM "eepmisc" endianness - bit - -This replaces a magic number with a named #define. Additionally it -removes two "eeprom format" specific #defines for the "big endianness" -bit which are the same on all eeprom formats. - -Signed-off-by: Martin Blumenstingl ---- - drivers/net/wireless/ath/ath9k/ar9003_eeprom.c | 3 ++- - drivers/net/wireless/ath/ath9k/ar9003_eeprom.h | 1 - - drivers/net/wireless/ath/ath9k/eeprom.h | 4 +++- - drivers/net/wireless/ath/ath9k/eeprom_4k.c | 2 +- - drivers/net/wireless/ath/ath9k/eeprom_9287.c | 2 +- - drivers/net/wireless/ath/ath9k/eeprom_def.c | 2 +- - 6 files changed, 8 insertions(+), 6 deletions(-) - ---- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c -+++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c -@@ -3468,7 +3468,8 @@ static u32 ath9k_hw_ar9003_dump_eeprom(s - AR5416_OPFLAGS_N_5G_HT20)); - PR_EEP("Disable 5Ghz HT40", !!(pBase->opCapFlags.opFlags & - AR5416_OPFLAGS_N_5G_HT40)); -- PR_EEP("Big Endian", !!(pBase->opCapFlags.eepMisc & 0x01)); -+ PR_EEP("Big Endian", !!(pBase->opCapFlags.eepMisc & -+ AR5416_EEPMISC_BIG_ENDIAN)); - PR_EEP("RF Silent", pBase->rfSilent); - PR_EEP("BT option", pBase->blueToothOptions); - PR_EEP("Device Cap", pBase->deviceCap); ---- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h -+++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h -@@ -38,7 +38,6 @@ - #define AR9300_NUM_CTLS_2G 12 - #define AR9300_NUM_BAND_EDGES_5G 8 - #define AR9300_NUM_BAND_EDGES_2G 4 --#define AR9300_EEPMISC_BIG_ENDIAN 0x01 - #define AR9300_EEPMISC_WOW 0x02 - #define AR9300_CUSTOMER_DATA_SIZE 20 - ---- a/drivers/net/wireless/ath/ath9k/eeprom.h -+++ b/drivers/net/wireless/ath/ath9k/eeprom.h -@@ -161,6 +161,9 @@ - #define AR5416_EEP_TXGAIN_ORIGINAL 0 - #define AR5416_EEP_TXGAIN_HIGH_POWER 1 - -+/* Endianness of EEPROM content */ -+#define AR5416_EEPMISC_BIG_ENDIAN 0x01 -+ - #define AR5416_EEP4K_START_LOC 64 - #define AR5416_EEP4K_NUM_2G_CAL_PIERS 3 - #define AR5416_EEP4K_NUM_2G_CCK_TARGET_POWERS 3 -@@ -191,7 +194,6 @@ - #define AR9287_NUM_CTLS 12 - #define AR9287_NUM_BAND_EDGES 4 - #define AR9287_PD_GAIN_ICEPTS 1 --#define AR9287_EEPMISC_BIG_ENDIAN 0x01 - #define AR9287_EEPMISC_WOW 0x02 - #define AR9287_MAX_CHAINS 2 - #define AR9287_ANT_16S 32 ---- a/drivers/net/wireless/ath/ath9k/eeprom_4k.c -+++ b/drivers/net/wireless/ath/ath9k/eeprom_4k.c -@@ -154,7 +154,7 @@ static u32 ath9k_hw_4k_dump_eeprom(struc - AR5416_OPFLAGS_N_5G_HT20)); - PR_EEP("Disable 5Ghz HT40", !!(pBase->opCapFlags & - AR5416_OPFLAGS_N_5G_HT40)); -- PR_EEP("Big Endian", !!(pBase->eepMisc & 0x01)); -+ PR_EEP("Big Endian", !!(pBase->eepMisc & AR5416_EEPMISC_BIG_ENDIAN)); - PR_EEP("Cal Bin Major Ver", (pBase->binBuildNumber >> 24) & 0xFF); - PR_EEP("Cal Bin Minor Ver", (pBase->binBuildNumber >> 16) & 0xFF); - PR_EEP("Cal Bin Build", (pBase->binBuildNumber >> 8) & 0xFF); ---- a/drivers/net/wireless/ath/ath9k/eeprom_9287.c -+++ b/drivers/net/wireless/ath/ath9k/eeprom_9287.c -@@ -150,7 +150,7 @@ static u32 ath9k_hw_ar9287_dump_eeprom(s - AR5416_OPFLAGS_N_5G_HT20)); - PR_EEP("Disable 5Ghz HT40", !!(pBase->opCapFlags & - AR5416_OPFLAGS_N_5G_HT40)); -- PR_EEP("Big Endian", !!(pBase->eepMisc & 0x01)); -+ PR_EEP("Big Endian", !!(pBase->eepMisc & AR5416_EEPMISC_BIG_ENDIAN)); - PR_EEP("Cal Bin Major Ver", (pBase->binBuildNumber >> 24) & 0xFF); - PR_EEP("Cal Bin Minor Ver", (pBase->binBuildNumber >> 16) & 0xFF); - PR_EEP("Cal Bin Build", (pBase->binBuildNumber >> 8) & 0xFF); ---- a/drivers/net/wireless/ath/ath9k/eeprom_def.c -+++ b/drivers/net/wireless/ath/ath9k/eeprom_def.c -@@ -232,7 +232,7 @@ static u32 ath9k_hw_def_dump_eeprom(stru - AR5416_OPFLAGS_N_5G_HT20)); - PR_EEP("Disable 5Ghz HT40", !!(pBase->opCapFlags & - AR5416_OPFLAGS_N_5G_HT40)); -- PR_EEP("Big Endian", !!(pBase->eepMisc & 0x01)); -+ PR_EEP("Big Endian", !!(pBase->eepMisc & AR5416_EEPMISC_BIG_ENDIAN)); - PR_EEP("Cal Bin Major Ver", (pBase->binBuildNumber >> 24) & 0xFF); - PR_EEP("Cal Bin Minor Ver", (pBase->binBuildNumber >> 16) & 0xFF); - PR_EEP("Cal Bin Build", (pBase->binBuildNumber >> 8) & 0xFF); diff --git a/package/kernel/mac80211/patches/550-ath9k-disable-bands-via-dt.patch b/package/kernel/mac80211/patches/550-ath9k-disable-bands-via-dt.patch new file mode 100644 index 0000000000..55f040f170 --- /dev/null +++ b/package/kernel/mac80211/patches/550-ath9k-disable-bands-via-dt.patch @@ -0,0 +1,15 @@ +--- a/drivers/net/wireless/ath/ath9k/init.c ++++ b/drivers/net/wireless/ath/ath9k/init.c +@@ -571,6 +571,12 @@ static int ath9k_of_init(struct ath_soft + + ath_dbg(common, CONFIG, "parsing configuration from OF node\n"); + ++ if (of_property_read_bool(np, "qca,disable-2ghz")) ++ ah->disable_2ghz = true; ++ ++ if (of_property_read_bool(np, "qca,disable-5ghz")) ++ ah->disable_5ghz = true; ++ + if (of_property_read_bool(np, "qca,no-eeprom")) { + /* ath9k-eeprom--.bin */ + scnprintf(eeprom_name, sizeof(eeprom_name), diff --git a/package/kernel/mac80211/patches/551-ath9k-indicate-that-the-AR9003-EEPROM-template-value.patch b/package/kernel/mac80211/patches/551-ath9k-indicate-that-the-AR9003-EEPROM-template-value.patch deleted file mode 100644 index a4a3595531..0000000000 --- a/package/kernel/mac80211/patches/551-ath9k-indicate-that-the-AR9003-EEPROM-template-value.patch +++ /dev/null @@ -1,78 +0,0 @@ -From e88ab4a2649d0fbf675193fb2c176f65375bdd2d Mon Sep 17 00:00:00 2001 -From: Martin Blumenstingl -Date: Mon, 3 Oct 2016 00:29:08 +0200 -Subject: [v2 PATCH 2/7] ath9k: indicate that the AR9003 EEPROM template values - are little endian - -The eepMisc field was not set explicitly. The default value of 0 means -that the values in the EEPROM (template) should be interpreted as little -endian. However, this is not clear until comparing the AR9003 code with -the other EEPROM formats. -To make the code easier to understand we explicitly state that the values -are little endian - there are no functional changes with this patch. - -Signed-off-by: Martin Blumenstingl ---- - drivers/net/wireless/ath/ath9k/ar9003_eeprom.c | 10 +++++----- - drivers/net/wireless/ath/ath9k/ar9003_eeprom.h | 3 +++ - 2 files changed, 8 insertions(+), 5 deletions(-) - ---- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c -+++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c -@@ -53,7 +53,7 @@ static const struct ar9300_eeprom ar9300 - .txrxMask = 0x77, /* 4 bits tx and 4 bits rx */ - .opCapFlags = { - .opFlags = AR5416_OPFLAGS_11G | AR5416_OPFLAGS_11A, -- .eepMisc = 0, -+ .eepMisc = AR9300_EEPMISC_LITTLE_ENDIAN, - }, - .rfSilent = 0, - .blueToothOptions = 0, -@@ -631,7 +631,7 @@ static const struct ar9300_eeprom ar9300 - .txrxMask = 0x77, /* 4 bits tx and 4 bits rx */ - .opCapFlags = { - .opFlags = AR5416_OPFLAGS_11A, -- .eepMisc = 0, -+ .eepMisc = AR9300_EEPMISC_LITTLE_ENDIAN, - }, - .rfSilent = 0, - .blueToothOptions = 0, -@@ -1210,7 +1210,7 @@ static const struct ar9300_eeprom ar9300 - .txrxMask = 0x77, /* 4 bits tx and 4 bits rx */ - .opCapFlags = { - .opFlags = AR5416_OPFLAGS_11G | AR5416_OPFLAGS_11A, -- .eepMisc = 0, -+ .eepMisc = AR9300_EEPMISC_LITTLE_ENDIAN, - }, - .rfSilent = 0, - .blueToothOptions = 0, -@@ -1789,7 +1789,7 @@ static const struct ar9300_eeprom ar9300 - .txrxMask = 0x77, /* 4 bits tx and 4 bits rx */ - .opCapFlags = { - .opFlags = AR5416_OPFLAGS_11G | AR5416_OPFLAGS_11A, -- .eepMisc = 0, -+ .eepMisc = AR9300_EEPMISC_LITTLE_ENDIAN, - }, - .rfSilent = 0, - .blueToothOptions = 0, -@@ -2367,7 +2367,7 @@ static const struct ar9300_eeprom ar9300 - .txrxMask = 0x33, /* 4 bits tx and 4 bits rx */ - .opCapFlags = { - .opFlags = AR5416_OPFLAGS_11G | AR5416_OPFLAGS_11A, -- .eepMisc = 0, -+ .eepMisc = AR9300_EEPMISC_LITTLE_ENDIAN, - }, - .rfSilent = 0, - .blueToothOptions = 0, ---- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h -+++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h -@@ -69,6 +69,9 @@ - #define AR9300_BASE_ADDR 0x3ff - #define AR9300_BASE_ADDR_512 0x1ff - -+/* AR5416_EEPMISC_BIG_ENDIAN not set indicates little endian */ -+#define AR9300_EEPMISC_LITTLE_ENDIAN 0 -+ - #define AR9300_OTP_BASE \ - ((AR_SREV_9340(ah) || AR_SREV_9550(ah)) ? 0x30000 : 0x14000) - #define AR9300_OTP_STATUS \ diff --git a/package/kernel/mac80211/patches/551-ath9k_ubnt_uap_plus_hsr.patch b/package/kernel/mac80211/patches/551-ath9k_ubnt_uap_plus_hsr.patch new file mode 100644 index 0000000000..45284c71ee --- /dev/null +++ b/package/kernel/mac80211/patches/551-ath9k_ubnt_uap_plus_hsr.patch @@ -0,0 +1,418 @@ +--- a/drivers/net/wireless/ath/ath9k/channel.c ++++ b/drivers/net/wireless/ath/ath9k/channel.c +@@ -15,6 +15,8 @@ + */ + + #include "ath9k.h" ++#include ++#include "hsr.h" + + /* Set/change channels. If the channel is really being changed, it's done + * by reseting the chip. To accomplish this we must first cleanup any pending +@@ -22,6 +24,7 @@ + */ + static int ath_set_channel(struct ath_softc *sc) + { ++ struct ath9k_platform_data *pdata = sc->dev->platform_data; + struct ath_hw *ah = sc->sc_ah; + struct ath_common *common = ath9k_hw_common(ah); + struct ieee80211_hw *hw = sc->hw; +@@ -41,6 +44,11 @@ static int ath_set_channel(struct ath_so + ath_dbg(common, CONFIG, "Set channel: %d MHz width: %d\n", + chan->center_freq, chandef->width); + ++ if (pdata && pdata->ubnt_hsr) { ++ ath9k_hsr_enable(ah, chandef->width, chan->center_freq); ++ ath9k_hsr_status(ah); ++ } ++ + /* update survey stats for the old channel before switching */ + spin_lock_bh(&common->cc_lock); + ath_update_survey_stats(sc); +--- /dev/null ++++ b/drivers/net/wireless/ath/ath9k/hsr.c +@@ -0,0 +1,247 @@ ++/* ++ * ++ * The MIT License (MIT) ++ * ++ * Copyright (c) 2015 Kirill Berezin ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining a copy ++ * of this software and associated documentation files (the "Software"), to deal ++ * in the Software without restriction, including without limitation the rights ++ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell ++ * copies of the Software, and to permit persons to whom the Software is ++ * furnished to do so, subject to the following conditions: ++ * ++ * The above copyright notice and this permission notice shall be included in ++ * all copies or substantial portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE ++ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER ++ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, ++ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE ++ * SOFTWARE. ++ * ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "hw.h" ++#include "ath9k.h" ++ ++#define HSR_GPIO_CSN 8 ++#define HSR_GPIO_CLK 6 ++#define HSR_GPIO_DOUT 7 ++#define HSR_GPIO_DIN 5 ++ ++/* delays are in useconds */ ++#define HSR_DELAY_HALF_TICK 100 ++#define HSR_DELAY_PRE_WRITE 75 ++#define HSR_DELAY_FINAL 20000 ++#define HSR_DELAY_TRAILING 200 ++ ++void ath9k_hsr_init(struct ath_hw *ah) ++{ ++ ath9k_hw_gpio_request_in(ah, HSR_GPIO_DIN, NULL); ++ ath9k_hw_gpio_request_out(ah, HSR_GPIO_CSN, NULL, ++ AR_GPIO_OUTPUT_MUX_AS_OUTPUT); ++ ath9k_hw_gpio_request_out(ah, HSR_GPIO_CLK, NULL, ++ AR_GPIO_OUTPUT_MUX_AS_OUTPUT); ++ ath9k_hw_gpio_request_out(ah, HSR_GPIO_DOUT, NULL, ++ AR_GPIO_OUTPUT_MUX_AS_OUTPUT); ++ ++ ath9k_hw_set_gpio(ah, HSR_GPIO_CSN, 1); ++ ath9k_hw_set_gpio(ah, HSR_GPIO_CLK, 0); ++ ath9k_hw_set_gpio(ah, HSR_GPIO_DOUT, 0); ++ ++ udelay(HSR_DELAY_TRAILING); ++} ++ ++static u32 ath9k_hsr_write_byte(struct ath_hw *ah, int delay, u32 value) ++{ ++ struct ath_common *common = ath9k_hw_common(ah); ++ int i; ++ u32 rval = 0; ++ ++ udelay(delay); ++ ++ ath9k_hw_set_gpio(ah, HSR_GPIO_CLK, 0); ++ udelay(HSR_DELAY_HALF_TICK); ++ ++ ath9k_hw_set_gpio(ah, HSR_GPIO_CSN, 0); ++ udelay(HSR_DELAY_HALF_TICK); ++ ++ for (i = 0; i < 8; ++i) { ++ rval = rval << 1; ++ ++ /* pattern is left to right, that is 7-th bit runs first */ ++ ath9k_hw_set_gpio(ah, HSR_GPIO_DOUT, (value >> (7 - i)) & 0x1); ++ udelay(HSR_DELAY_HALF_TICK); ++ ++ ath9k_hw_set_gpio(ah, HSR_GPIO_CLK, 1); ++ udelay(HSR_DELAY_HALF_TICK); ++ ++ rval |= ath9k_hw_gpio_get(ah, HSR_GPIO_DIN); ++ ++ ath9k_hw_set_gpio(ah, HSR_GPIO_CLK, 0); ++ udelay(HSR_DELAY_HALF_TICK); ++ } ++ ++ ath9k_hw_set_gpio(ah, HSR_GPIO_CSN, 1); ++ udelay(HSR_DELAY_HALF_TICK); ++ ++ ath_dbg(common, CONFIG, "ath9k_hsr_write_byte: write byte %d return value is %d %c\n", ++ value, rval, rval > 32 ? rval : '-'); ++ ++ return rval & 0xff; ++} ++ ++static int ath9k_hsr_write_a_chain(struct ath_hw *ah, char *chain, int items) ++{ ++ int status = 0; ++ int i = 0; ++ int err; ++ ++ /* a preamble */ ++ ath9k_hsr_write_byte(ah, HSR_DELAY_PRE_WRITE, 0); ++ status = ath9k_hsr_write_byte(ah, HSR_DELAY_PRE_WRITE, 0); ++ ++ /* clear HSR's reply buffer */ ++ if (status) { ++ int loop = 0; ++ ++ for (loop = 0; (loop < 42) && status; ++loop) ++ status = ath9k_hsr_write_byte(ah, HSR_DELAY_PRE_WRITE, ++ 0); ++ ++ if (loop >= 42) { ++ ATH_DBG_WARN(1, ++ "ath9k_hsr_write_a_chain: can't clear an output buffer after a 42 cycles.\n"); ++ return -1; ++ } ++ } ++ ++ for (i = 0; (i < items) && (chain[i] != 0); ++i) ++ ath9k_hsr_write_byte(ah, HSR_DELAY_PRE_WRITE, (u32)chain[i]); ++ ++ ath9k_hsr_write_byte(ah, HSR_DELAY_PRE_WRITE, 0); ++ mdelay(HSR_DELAY_FINAL / 1000); ++ ++ /* reply */ ++ memset(chain, 0, items); ++ ++ ath9k_hsr_write_byte(ah, HSR_DELAY_PRE_WRITE, 0); ++ udelay(HSR_DELAY_TRAILING); ++ ++ for (i = 0; i < (items - 1); ++i) { ++ u32 ret; ++ ++ ret = ath9k_hsr_write_byte(ah, HSR_DELAY_PRE_WRITE, 0); ++ if (ret != 0) ++ chain[i] = (char)ret; ++ else ++ break; ++ ++ udelay(HSR_DELAY_TRAILING); ++ } ++ ++ if (i <= 1) ++ return 0; ++ ++ err = kstrtoint(chain + 1, 10, &i); ++ if (err) ++ return err; ++ ++ return i; ++} ++ ++int ath9k_hsr_disable(struct ath_hw *ah) ++{ ++ char cmd[10] = {'b', '4', '0', 0, 0, 0, 0, 0, 0, 0}; ++ int ret; ++ ++ ret = ath9k_hsr_write_a_chain(ah, cmd, sizeof(cmd)); ++ if ((ret > 0) && (*cmd == 'B')) ++ return 0; ++ ++ return -1; ++} ++ ++int ath9k_hsr_enable(struct ath_hw *ah, int bw, int fq) ++{ ++ char cmd[10]; ++ int ret; ++ ++ /* Bandwidth argument is 0 sometimes. Assume default 802.11bgn ++ * 20MHz on invalid values ++ */ ++ if ((bw != 5) && (bw != 10) && (bw != 20) && (bw != 40)) ++ bw = 20; ++ ++ memset(cmd, 0, sizeof(cmd)); ++ *cmd = 'b'; ++ snprintf(cmd + 1, 3, "%02d", bw); ++ ++ ret = ath9k_hsr_write_a_chain(ah, cmd, sizeof(cmd)); ++ if ((*cmd != 'B') || (ret != bw)) { ++ ATH_DBG_WARN(1, ++ "ath9k_hsr_enable: failed changing bandwidth -> set (%d,%d) reply (%d, %d)\n", ++ 'b', bw, *cmd, ret); ++ return -1; ++ } ++ ++ memset(cmd, 0, sizeof(cmd)); ++ *cmd = 'x'; ++ ret = ath9k_hsr_write_a_chain(ah, cmd, sizeof(cmd)); ++ if (*cmd != 'X') { ++ ATH_DBG_WARN(1, ++ "ath9k_hsr_enable: failed 'x' command -> reply (%d, %d)\n", ++ *cmd, ret); ++ return -1; ++ } ++ ++ memset(cmd, 0, sizeof(cmd)); ++ *cmd = 'm'; ++ ret = ath9k_hsr_write_a_chain(ah, cmd, sizeof(cmd)); ++ if (*cmd != 'M') { ++ ATH_DBG_WARN(1, ++ "ath9k_hsr_enable: failed 'm' command -> reply (%d, %d)\n", ++ *cmd, ret); ++ return -1; ++ } ++ ++ memset(cmd, 0, sizeof(cmd)); ++ *cmd = 'f'; ++ snprintf(cmd + 1, 6, "%05d", fq); ++ ret = ath9k_hsr_write_a_chain(ah, cmd, sizeof(cmd)); ++ if ((*cmd != 'F') && (ret != fq)) { ++ ATH_DBG_WARN(1, ++ "ath9k_hsr_enable: failed set frequency -> reply (%d, %d)\n", ++ *cmd, ret); ++ return -1; ++ } ++ ++ return 0; ++} ++ ++int ath9k_hsr_status(struct ath_hw *ah) ++{ ++ char cmd[10] = {'s', 0, 0, 0, 0, 0, 0, 0, 0, 0}; ++ int ret; ++ ++ ret = ath9k_hsr_write_a_chain(ah, cmd, sizeof(cmd)); ++ if (*cmd != 'S') { ++ ATH_DBG_WARN(1, "ath9k_hsr_status: returned %d,%d\n", *cmd, ++ ret); ++ return -1; ++ } ++ ++ return 0; ++} +--- /dev/null ++++ b/drivers/net/wireless/ath/ath9k/hsr.h +@@ -0,0 +1,48 @@ ++/* ++ * The MIT License (MIT) ++ * ++ * Copyright (c) 2015 Kirill Berezin ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining a copy ++ * of this software and associated documentation files (the "Software"), to deal ++ * in the Software without restriction, including without limitation the rights ++ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell ++ * copies of the Software, and to permit persons to whom the Software is ++ * furnished to do so, subject to the following conditions: ++ * ++ * The above copyright notice and this permission notice shall be included in ++ * all copies or substantial portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE ++ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER ++ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, ++ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE ++ * SOFTWARE. ++ */ ++ ++#ifndef HSR_H ++#define HSR_H ++ ++#ifdef CPTCFG_ATH9K_UBNTHSR ++ ++void ath9k_hsr_init(struct ath_hw *ah); ++int ath9k_hsr_disable(struct ath_hw *ah); ++int ath9k_hsr_enable(struct ath_hw *ah, int bw, int fq); ++int ath9k_hsr_status(struct ath_hw *ah); ++ ++#else ++static inline void ath9k_hsr_init(struct ath_hw *ah) {} ++ ++static inline int ath9k_hsr_enable(struct ath_hw *ah, int bw, int fq) ++{ ++ return 0; ++} ++ ++static inline int ath9k_hsr_disable(struct ath_hw *ah) { return 0; } ++static inline int ath9k_hsr_status(struct ath_hw *ah) { return 0; } ++ ++#endif ++ ++#endif /* HSR_H */ +--- a/drivers/net/wireless/ath/ath9k/main.c ++++ b/drivers/net/wireless/ath/ath9k/main.c +@@ -16,8 +16,10 @@ + + #include + #include ++#include + #include "ath9k.h" + #include "btcoex.h" ++#include "hsr.h" + + u8 ath9k_parse_mpdudensity(u8 mpdudensity) + { +@@ -648,6 +650,7 @@ void ath_reset_work(struct work_struct * + static int ath9k_start(struct ieee80211_hw *hw) + { + struct ath_softc *sc = hw->priv; ++ struct ath9k_platform_data *pdata = sc->dev->platform_data; + struct ath_hw *ah = sc->sc_ah; + struct ath_common *common = ath9k_hw_common(ah); + struct ieee80211_channel *curchan = sc->cur_chan->chandef.chan; +@@ -726,6 +729,11 @@ static int ath9k_start(struct ieee80211_ + AR_GPIO_OUTPUT_MUX_AS_OUTPUT); + } + ++ if (pdata && pdata->ubnt_hsr) { ++ ath9k_hsr_init(ah); ++ ath9k_hsr_disable(ah); ++ } ++ + /* + * Reset key cache to sane defaults (all entries cleared) instead of + * semi-random values after suspend/resume. +--- a/drivers/net/wireless/ath/ath9k/Makefile ++++ b/drivers/net/wireless/ath/ath9k/Makefile +@@ -16,6 +16,7 @@ ath9k-$(CPTCFG_ATH9K_DFS_CERTIFIED) += d + ath9k-$(CPTCFG_ATH9K_TX99) += tx99.o + ath9k-$(CPTCFG_ATH9K_WOW) += wow.o + ath9k-$(CPTCFG_ATH9K_HWRNG) += rng.o ++ath9k-$(CPTCFG_ATH9K_UBNTHSR) += hsr.o + + ath9k-$(CPTCFG_ATH9K_DEBUGFS) += debug.o + +--- a/include/linux/ath9k_platform.h ++++ b/include/linux/ath9k_platform.h +@@ -54,6 +54,8 @@ struct ath9k_platform_data { + unsigned num_btns; + const struct gpio_keys_button *btns; + unsigned btn_poll_interval; ++ ++ bool ubnt_hsr; + }; + + #endif /* _LINUX_ATH9K_PLATFORM_H */ +--- a/.local-symbols ++++ b/.local-symbols +@@ -157,6 +157,7 @@ ATH9K_WOW= + ATH9K_RFKILL= + ATH9K_CHANNEL_CONTEXT= + ATH9K_PCOEM= ++ATH9K_UBNTHSR= + ATH9K_HTC= + ATH9K_HTC_DEBUGFS= + ATH9K_HWRNG= +--- a/drivers/net/wireless/ath/ath9k/Kconfig ++++ b/drivers/net/wireless/ath/ath9k/Kconfig +@@ -59,6 +59,19 @@ config ATH9K_AHB + Say Y, if you have a SoC with a compatible built-in + wireless MAC. Say N if unsure. + ++config ATH9K_UBNTHSR ++ bool "Ubiquiti UniFi Outdoor Plus HSR support" ++ depends on ATH9K ++ ---help--- ++ This options enables code to control the HSR RF ++ filter in the receive path of the Ubiquiti UniFi ++ Outdoor Plus access point. ++ ++ Say Y if you want to use the access point. The ++ code will only be used if the device is detected, ++ so it does not harm other setup other than occupying ++ a bit of memory. ++ + config ATH9K_DEBUGFS + bool "Atheros ath9k debugging" + depends on ATH9K && DEBUG_FS diff --git a/package/kernel/mac80211/patches/552-ath9k-Add-an-eeprom_ops-callback-for-retrieving-the-.patch b/package/kernel/mac80211/patches/552-ath9k-Add-an-eeprom_ops-callback-for-retrieving-the-.patch deleted file mode 100644 index 1b4dd3d134..0000000000 --- a/package/kernel/mac80211/patches/552-ath9k-Add-an-eeprom_ops-callback-for-retrieving-the-.patch +++ /dev/null @@ -1,117 +0,0 @@ -From e8f60fa28e619ad238457ac84fb292541be180d3 Mon Sep 17 00:00:00 2001 -From: Martin Blumenstingl -Date: Mon, 3 Oct 2016 00:29:09 +0200 -Subject: [v2 PATCH 3/7] ath9k: Add an eeprom_ops callback for retrieving the - eepmisc value - -This allows deciding if we have to swap the EEPROM data (so it matches -the system's native endianness) even if no byte-swapping (swab16, based on -the first two bytes in the EEPROM) is needed. - -Signed-off-by: Martin Blumenstingl ---- - drivers/net/wireless/ath/ath9k/ar9003_eeprom.c | 8 +++++++- - drivers/net/wireless/ath/ath9k/eeprom.h | 1 + - drivers/net/wireless/ath/ath9k/eeprom_4k.c | 8 +++++++- - drivers/net/wireless/ath/ath9k/eeprom_9287.c | 8 +++++++- - drivers/net/wireless/ath/ath9k/eeprom_def.c | 8 +++++++- - 5 files changed, 29 insertions(+), 4 deletions(-) - ---- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c -+++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c -@@ -5498,6 +5498,11 @@ unsigned int ar9003_get_paprd_scale_fact - } - } - -+static u8 ar9003_get_eepmisc(struct ath_hw *ah) -+{ -+ return ah->eeprom.map4k.baseEepHeader.eepMisc; -+} -+ - const struct eeprom_ops eep_ar9300_ops = { - .check_eeprom = ath9k_hw_ar9300_check_eeprom, - .get_eeprom = ath9k_hw_ar9300_get_eeprom, -@@ -5508,5 +5513,6 @@ const struct eeprom_ops eep_ar9300_ops = - .set_board_values = ath9k_hw_ar9300_set_board_values, - .set_addac = ath9k_hw_ar9300_set_addac, - .set_txpower = ath9k_hw_ar9300_set_txpower, -- .get_spur_channel = ath9k_hw_ar9300_get_spur_channel -+ .get_spur_channel = ath9k_hw_ar9300_get_spur_channel, -+ .get_eepmisc = ar9003_get_eepmisc - }; ---- a/drivers/net/wireless/ath/ath9k/eeprom.h -+++ b/drivers/net/wireless/ath/ath9k/eeprom.h -@@ -655,6 +655,7 @@ struct eeprom_ops { - u16 cfgCtl, u8 twiceAntennaReduction, - u8 powerLimit, bool test); - u16 (*get_spur_channel)(struct ath_hw *ah, u16 i, bool is2GHz); -+ u8 (*get_eepmisc)(struct ath_hw *ah); - }; - - void ath9k_hw_analog_shift_regwrite(struct ath_hw *ah, u32 reg, u32 val); ---- a/drivers/net/wireless/ath/ath9k/eeprom_4k.c -+++ b/drivers/net/wireless/ath/ath9k/eeprom_4k.c -@@ -1064,6 +1064,11 @@ static u16 ath9k_hw_4k_get_spur_channel( - return ah->eeprom.map4k.modalHeader.spurChans[i].spurChan; - } - -+static u8 ath9k_hw_4k_get_eepmisc(struct ath_hw *ah) -+{ -+ return ah->eeprom.map4k.baseEepHeader.eepMisc; -+} -+ - const struct eeprom_ops eep_4k_ops = { - .check_eeprom = ath9k_hw_4k_check_eeprom, - .get_eeprom = ath9k_hw_4k_get_eeprom, -@@ -1073,5 +1078,6 @@ const struct eeprom_ops eep_4k_ops = { - .get_eeprom_rev = ath9k_hw_4k_get_eeprom_rev, - .set_board_values = ath9k_hw_4k_set_board_values, - .set_txpower = ath9k_hw_4k_set_txpower, -- .get_spur_channel = ath9k_hw_4k_get_spur_channel -+ .get_spur_channel = ath9k_hw_4k_get_spur_channel, -+ .get_eepmisc = ath9k_hw_4k_get_eepmisc - }; ---- a/drivers/net/wireless/ath/ath9k/eeprom_9287.c -+++ b/drivers/net/wireless/ath/ath9k/eeprom_9287.c -@@ -986,6 +986,11 @@ static u16 ath9k_hw_ar9287_get_spur_chan - return ah->eeprom.map9287.modalHeader.spurChans[i].spurChan; - } - -+static u8 ath9k_hw_ar9287_get_eepmisc(struct ath_hw *ah) -+{ -+ return ah->eeprom.map9287.baseEepHeader.eepMisc; -+} -+ - const struct eeprom_ops eep_ar9287_ops = { - .check_eeprom = ath9k_hw_ar9287_check_eeprom, - .get_eeprom = ath9k_hw_ar9287_get_eeprom, -@@ -995,5 +1000,6 @@ const struct eeprom_ops eep_ar9287_ops = - .get_eeprom_rev = ath9k_hw_ar9287_get_eeprom_rev, - .set_board_values = ath9k_hw_ar9287_set_board_values, - .set_txpower = ath9k_hw_ar9287_set_txpower, -- .get_spur_channel = ath9k_hw_ar9287_get_spur_channel -+ .get_spur_channel = ath9k_hw_ar9287_get_spur_channel, -+ .get_eepmisc = ath9k_hw_ar9287_get_eepmisc - }; ---- a/drivers/net/wireless/ath/ath9k/eeprom_def.c -+++ b/drivers/net/wireless/ath/ath9k/eeprom_def.c -@@ -1317,6 +1317,11 @@ static u16 ath9k_hw_def_get_spur_channel - return ah->eeprom.def.modalHeader[is2GHz].spurChans[i].spurChan; - } - -+static u8 ath9k_hw_def_get_eepmisc(struct ath_hw *ah) -+{ -+ return ah->eeprom.def.baseEepHeader.eepMisc; -+} -+ - const struct eeprom_ops eep_def_ops = { - .check_eeprom = ath9k_hw_def_check_eeprom, - .get_eeprom = ath9k_hw_def_get_eeprom, -@@ -1327,5 +1332,6 @@ const struct eeprom_ops eep_def_ops = { - .set_board_values = ath9k_hw_def_set_board_values, - .set_addac = ath9k_hw_def_set_addac, - .set_txpower = ath9k_hw_def_set_txpower, -- .get_spur_channel = ath9k_hw_def_get_spur_channel -+ .get_spur_channel = ath9k_hw_def_get_spur_channel, -+ .get_eepmisc = ath9k_hw_def_get_eepmisc - }; diff --git a/package/kernel/mac80211/patches/553-ath9k-replace-eeprom_param-EEP_MINOR_REV-with-get_ee.patch b/package/kernel/mac80211/patches/553-ath9k-replace-eeprom_param-EEP_MINOR_REV-with-get_ee.patch deleted file mode 100644 index 277aa6f61c..0000000000 --- a/package/kernel/mac80211/patches/553-ath9k-replace-eeprom_param-EEP_MINOR_REV-with-get_ee.patch +++ /dev/null @@ -1,117 +0,0 @@ -From 9f247f908d5166e16e1cc6a50b0901e0f6733410 Mon Sep 17 00:00:00 2001 -From: Martin Blumenstingl -Date: Mon, 3 Oct 2016 00:29:10 +0200 -Subject: [v2 PATCH 4/7] ath9k: replace eeprom_param EEP_MINOR_REV with - get_eeprom_rev - -get_eeprom(ah, EEP_MINOR_REV) and get_eeprom_rev(ah) are both doing the -same thing: returning the EEPROM revision (12 lowest bits). Make the -code consistent by using get_eeprom_rev(ah) everywhere. - -Signed-off-by: Martin Blumenstingl ---- - drivers/net/wireless/ath/ath9k/ar5008_phy.c | 2 +- - drivers/net/wireless/ath/ath9k/ar9002_hw.c | 6 ++---- - drivers/net/wireless/ath/ath9k/eeprom.h | 1 - - drivers/net/wireless/ath/ath9k/eeprom_4k.c | 5 ----- - drivers/net/wireless/ath/ath9k/eeprom_9287.c | 6 +----- - drivers/net/wireless/ath/ath9k/eeprom_def.c | 2 -- - 6 files changed, 4 insertions(+), 18 deletions(-) - ---- a/drivers/net/wireless/ath/ath9k/ar5008_phy.c -+++ b/drivers/net/wireless/ath/ath9k/ar5008_phy.c -@@ -524,7 +524,7 @@ static bool ar5008_hw_set_rf_regs(struct - return true; - - /* Setup rf parameters */ -- eepMinorRev = ah->eep_ops->get_eeprom(ah, EEP_MINOR_REV); -+ eepMinorRev = ah->eep_ops->get_eeprom_rev(ah); - - for (i = 0; i < ah->iniBank6.ia_rows; i++) - ah->analogBank6Data[i] = INI_RA(&ah->iniBank6, i, modesIndex); ---- a/drivers/net/wireless/ath/ath9k/ar9002_hw.c -+++ b/drivers/net/wireless/ath/ath9k/ar9002_hw.c -@@ -108,8 +108,7 @@ static void ar9280_20_hw_init_rxgain_ini - { - u32 rxgain_type; - -- if (ah->eep_ops->get_eeprom(ah, EEP_MINOR_REV) >= -- AR5416_EEP_MINOR_VER_17) { -+ if (ah->eep_ops->get_eeprom_rev(ah) >= AR5416_EEP_MINOR_VER_17) { - rxgain_type = ah->eep_ops->get_eeprom(ah, EEP_RXGAIN_TYPE); - - if (rxgain_type == AR5416_EEP_RXGAIN_13DB_BACKOFF) -@@ -129,8 +128,7 @@ static void ar9280_20_hw_init_rxgain_ini - - static void ar9280_20_hw_init_txgain_ini(struct ath_hw *ah, u32 txgain_type) - { -- if (ah->eep_ops->get_eeprom(ah, EEP_MINOR_REV) >= -- AR5416_EEP_MINOR_VER_19) { -+ if (ah->eep_ops->get_eeprom_rev(ah) >= AR5416_EEP_MINOR_VER_19) { - if (txgain_type == AR5416_EEP_TXGAIN_HIGH_POWER) - INIT_INI_ARRAY(&ah->iniModesTxGain, - ar9280Modes_high_power_tx_gain_9280_2); ---- a/drivers/net/wireless/ath/ath9k/eeprom.h -+++ b/drivers/net/wireless/ath/ath9k/eeprom.h -@@ -230,7 +230,6 @@ enum eeprom_param { - EEP_DB_5, - EEP_OB_2, - EEP_DB_2, -- EEP_MINOR_REV, - EEP_TX_MASK, - EEP_RX_MASK, - EEP_FSTCLK_5G, ---- a/drivers/net/wireless/ath/ath9k/eeprom_4k.c -+++ b/drivers/net/wireless/ath/ath9k/eeprom_4k.c -@@ -254,9 +254,6 @@ static u32 ath9k_hw_4k_get_eeprom(struct - struct ar5416_eeprom_4k *eep = &ah->eeprom.map4k; - struct modal_eep_4k_header *pModal = &eep->modalHeader; - struct base_eep_header_4k *pBase = &eep->baseEepHeader; -- u16 ver_minor; -- -- ver_minor = pBase->version & AR5416_EEP_VER_MINOR_MASK; - - switch (param) { - case EEP_NFTHRESH_2: -@@ -279,8 +276,6 @@ static u32 ath9k_hw_4k_get_eeprom(struct - return pModal->ob_0; - case EEP_DB_2: - return pModal->db1_1; -- case EEP_MINOR_REV: -- return ver_minor; - case EEP_TX_MASK: - return pBase->txMask; - case EEP_RX_MASK: ---- a/drivers/net/wireless/ath/ath9k/eeprom_9287.c -+++ b/drivers/net/wireless/ath/ath9k/eeprom_9287.c -@@ -250,9 +250,7 @@ static u32 ath9k_hw_ar9287_get_eeprom(st - struct ar9287_eeprom *eep = &ah->eeprom.map9287; - struct modal_eep_ar9287_header *pModal = &eep->modalHeader; - struct base_eep_ar9287_header *pBase = &eep->baseEepHeader; -- u16 ver_minor; -- -- ver_minor = pBase->version & AR9287_EEP_VER_MINOR_MASK; -+ u16 ver_minor = ath9k_hw_ar9287_get_eeprom_rev(ah); - - switch (param) { - case EEP_NFTHRESH_2: -@@ -271,8 +269,6 @@ static u32 ath9k_hw_ar9287_get_eeprom(st - return pBase->opCapFlags; - case EEP_RF_SILENT: - return pBase->rfSilent; -- case EEP_MINOR_REV: -- return ver_minor; - case EEP_TX_MASK: - return pBase->txMask; - case EEP_RX_MASK: ---- a/drivers/net/wireless/ath/ath9k/eeprom_def.c -+++ b/drivers/net/wireless/ath/ath9k/eeprom_def.c -@@ -380,8 +380,6 @@ static u32 ath9k_hw_def_get_eeprom(struc - return pModal[1].ob; - case EEP_DB_2: - return pModal[1].db; -- case EEP_MINOR_REV: -- return AR5416_VER_MASK; - case EEP_TX_MASK: - return pBase->txMask; - case EEP_RX_MASK: diff --git a/package/kernel/mac80211/patches/554-ath9k-consistently-use-get_eeprom_rev-ah.patch b/package/kernel/mac80211/patches/554-ath9k-consistently-use-get_eeprom_rev-ah.patch deleted file mode 100644 index 86809fd66a..0000000000 --- a/package/kernel/mac80211/patches/554-ath9k-consistently-use-get_eeprom_rev-ah.patch +++ /dev/null @@ -1,342 +0,0 @@ -From c763af71bcc2f01bd5ef6e65c7c34b46c7235a16 Mon Sep 17 00:00:00 2001 -From: Martin Blumenstingl -Date: Mon, 3 Oct 2016 00:29:11 +0200 -Subject: [v2 PATCH 5/7] ath9k: consistently use get_eeprom_rev(ah) - -The AR5416_VER_MASK macro does the same as get_eeprom_rev, except that -one has to know the actual EEPROM type (and providing a reference to -that in a variable named "eep"). Additionally the eeprom_*.c -implementations used the same shifting logic multiple times to get the -eeprom revision which was also unnecessary duplication of -get_eeprom_rev. - -Also use the AR5416_EEP_VER_MINOR_MASK macro where needed and introduce -a similar macro (AR5416_EEP_VER_MAJOR_MASK) for the major version. -Finally drop AR9287_EEP_VER_MINOR_MASK since it simply duplicates the -already defined AR5416_EEP_VER_MINOR_MASK. - -Signed-off-by: Martin Blumenstingl ---- - drivers/net/wireless/ath/ath9k/eeprom.h | 4 +-- - drivers/net/wireless/ath/ath9k/eeprom_4k.c | 32 ++++++++++------------ - drivers/net/wireless/ath/ath9k/eeprom_9287.c | 19 +++++++------ - drivers/net/wireless/ath/ath9k/eeprom_def.c | 41 +++++++++++++++------------- - drivers/net/wireless/ath/ath9k/xmit.c | 3 +- - 5 files changed, 52 insertions(+), 47 deletions(-) - ---- a/drivers/net/wireless/ath/ath9k/eeprom.h -+++ b/drivers/net/wireless/ath/ath9k/eeprom.h -@@ -99,7 +99,6 @@ - #define FBIN2FREQ(x, y) ((y) ? (2300 + x) : (4800 + 5 * x)) - #define ath9k_hw_use_flash(_ah) (!(_ah->ah_flags & AH_USE_EEPROM)) - --#define AR5416_VER_MASK (eep->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) - #define OLC_FOR_AR9280_20_LATER (AR_SREV_9280_20_OR_LATER(ah) && \ - ah->eep_ops->get_eeprom(ah, EEP_OL_PWRCTRL)) - #define OLC_FOR_AR9287_10_LATER (AR_SREV_9287_11_OR_LATER(ah) && \ -@@ -121,6 +120,8 @@ - - #define AR5416_EEP_NO_BACK_VER 0x1 - #define AR5416_EEP_VER 0xE -+#define AR5416_EEP_VER_MAJOR_SHIFT 12 -+#define AR5416_EEP_VER_MAJOR_MASK 0xF000 - #define AR5416_EEP_VER_MINOR_MASK 0x0FFF - #define AR5416_EEP_MINOR_VER_2 0x2 - #define AR5416_EEP_MINOR_VER_3 0x3 -@@ -177,7 +178,6 @@ - #define AR9280_TX_GAIN_TABLE_SIZE 22 - - #define AR9287_EEP_VER 0xE --#define AR9287_EEP_VER_MINOR_MASK 0xFFF - #define AR9287_EEP_MINOR_VER_1 0x1 - #define AR9287_EEP_MINOR_VER_2 0x2 - #define AR9287_EEP_MINOR_VER_3 0x3 ---- a/drivers/net/wireless/ath/ath9k/eeprom_4k.c -+++ b/drivers/net/wireless/ath/ath9k/eeprom_4k.c -@@ -20,12 +20,17 @@ - - static int ath9k_hw_4k_get_eeprom_ver(struct ath_hw *ah) - { -- return ((ah->eeprom.map4k.baseEepHeader.version >> 12) & 0xF); -+ u16 version = ah->eeprom.map4k.baseEepHeader.version; -+ -+ return (version & AR5416_EEP_VER_MAJOR_MASK) >> -+ AR5416_EEP_VER_MAJOR_SHIFT; - } - - static int ath9k_hw_4k_get_eeprom_rev(struct ath_hw *ah) - { -- return ((ah->eeprom.map4k.baseEepHeader.version) & 0xFFF); -+ u16 version = ah->eeprom.map4k.baseEepHeader.version; -+ -+ return version & AR5416_EEP_VER_MINOR_MASK; - } - - #define SIZE_EEPROM_4K (sizeof(struct ar5416_eeprom_4k) / sizeof(u16)) -@@ -136,8 +141,8 @@ static u32 ath9k_hw_4k_dump_eeprom(struc - goto out; - } - -- PR_EEP("Major Version", pBase->version >> 12); -- PR_EEP("Minor Version", pBase->version & 0xFFF); -+ PR_EEP("Major Version", ath9k_hw_4k_get_eeprom_ver(ah)); -+ PR_EEP("Minor Version", ath9k_hw_4k_get_eeprom_rev(ah)); - PR_EEP("Checksum", pBase->checksum); - PR_EEP("Length", pBase->length); - PR_EEP("RegDomain1", pBase->regDmn[0]); -@@ -314,14 +319,12 @@ static void ath9k_hw_set_4k_power_cal_ta - - xpdMask = pEepData->modalHeader.xpdGain; - -- if ((pEepData->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >= -- AR5416_EEP_MINOR_VER_2) { -+ if (ath9k_hw_4k_get_eeprom_rev(ah) >= AR5416_EEP_MINOR_VER_2) - pdGainOverlap_t2 = - pEepData->modalHeader.pdGainOverlap; -- } else { -+ else - pdGainOverlap_t2 = (u16)(MS(REG_READ(ah, AR_PHY_TPCRG5), - AR_PHY_TPCRG5_PD_GAIN_OVERLAP)); -- } - - pCalBChans = pEepData->calFreqPier2G; - numPiers = AR5416_EEP4K_NUM_2G_CAL_PIERS; -@@ -607,10 +610,8 @@ static void ath9k_hw_4k_set_txpower(stru - - memset(ratesArray, 0, sizeof(ratesArray)); - -- if ((pEepData->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >= -- AR5416_EEP_MINOR_VER_2) { -+ if (ath9k_hw_4k_get_eeprom_rev(ah) >= AR5416_EEP_MINOR_VER_2) - ht40PowerIncForPdadc = pModal->ht40PowerIncForPdadc; -- } - - ath9k_hw_set_4k_power_per_rate_table(ah, chan, - &ratesArray[0], cfgCtl, -@@ -730,8 +731,7 @@ static void ath9k_hw_4k_set_gain(struct - SM(pModal->iqCalQCh[0], AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF), - AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF | AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF); - -- if ((eep->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >= -- AR5416_EEP_MINOR_VER_3) { -+ if (ath9k_hw_4k_get_eeprom_rev(ah) >= AR5416_EEP_MINOR_VER_3) { - txRxAttenLocal = pModal->txRxAttenCh[0]; - - REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ, -@@ -1009,16 +1009,14 @@ static void ath9k_hw_4k_set_board_values - REG_RMW_FIELD(ah, AR_PHY_EXT_CCA0, AR_PHY_EXT_CCA0_THRESH62, - pModal->thresh62); - -- if ((eep->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >= -- AR5416_EEP_MINOR_VER_2) { -+ if (ath9k_hw_4k_get_eeprom_rev(ah) >= AR5416_EEP_MINOR_VER_2) { - REG_RMW_FIELD(ah, AR_PHY_RF_CTL2, AR_PHY_TX_END_DATA_START, - pModal->txFrameToDataStart); - REG_RMW_FIELD(ah, AR_PHY_RF_CTL2, AR_PHY_TX_END_PA_ON, - pModal->txFrameToPaOn); - } - -- if ((eep->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >= -- AR5416_EEP_MINOR_VER_3) { -+ if (ath9k_hw_4k_get_eeprom_rev(ah) >= AR5416_EEP_MINOR_VER_3) { - if (IS_CHAN_HT40(chan)) - REG_RMW_FIELD(ah, AR_PHY_SETTLING, - AR_PHY_SETTLING_SWITCH, ---- a/drivers/net/wireless/ath/ath9k/eeprom_9287.c -+++ b/drivers/net/wireless/ath/ath9k/eeprom_9287.c -@@ -22,12 +22,17 @@ - - static int ath9k_hw_ar9287_get_eeprom_ver(struct ath_hw *ah) - { -- return (ah->eeprom.map9287.baseEepHeader.version >> 12) & 0xF; -+ u16 version = ah->eeprom.map9287.baseEepHeader.version; -+ -+ return (version & AR5416_EEP_VER_MAJOR_MASK) >> -+ AR5416_EEP_VER_MAJOR_SHIFT; - } - - static int ath9k_hw_ar9287_get_eeprom_rev(struct ath_hw *ah) - { -- return (ah->eeprom.map9287.baseEepHeader.version) & 0xFFF; -+ u16 version = ah->eeprom.map9287.baseEepHeader.version; -+ -+ return version & AR5416_EEP_VER_MINOR_MASK; - } - - static bool __ath9k_hw_ar9287_fill_eeprom(struct ath_hw *ah) -@@ -132,8 +137,8 @@ static u32 ath9k_hw_ar9287_dump_eeprom(s - goto out; - } - -- PR_EEP("Major Version", pBase->version >> 12); -- PR_EEP("Minor Version", pBase->version & 0xFFF); -+ PR_EEP("Major Version", ath9k_hw_ar9287_get_eeprom_ver(ah)); -+ PR_EEP("Minor Version", ath9k_hw_ar9287_get_eeprom_rev(ah)); - PR_EEP("Checksum", pBase->checksum); - PR_EEP("Length", pBase->length); - PR_EEP("RegDomain1", pBase->regDmn[0]); -@@ -383,8 +388,7 @@ static void ath9k_hw_set_ar9287_power_ca - - xpdMask = pEepData->modalHeader.xpdGain; - -- if ((pEepData->baseEepHeader.version & AR9287_EEP_VER_MINOR_MASK) >= -- AR9287_EEP_MINOR_VER_2) -+ if (ath9k_hw_ar9287_get_eeprom_rev(ah) >= AR9287_EEP_MINOR_VER_2) - pdGainOverlap_t2 = pEepData->modalHeader.pdGainOverlap; - else - pdGainOverlap_t2 = (u16)(MS(REG_READ(ah, AR_PHY_TPCRG5), -@@ -733,8 +737,7 @@ static void ath9k_hw_ar9287_set_txpower( - - memset(ratesArray, 0, sizeof(ratesArray)); - -- if ((pEepData->baseEepHeader.version & AR9287_EEP_VER_MINOR_MASK) >= -- AR9287_EEP_MINOR_VER_2) -+ if (ath9k_hw_ar9287_get_eeprom_rev(ah) >= AR9287_EEP_MINOR_VER_2) - ht40PowerIncForPdadc = pModal->ht40PowerIncForPdadc; - - ath9k_hw_set_ar9287_power_per_rate_table(ah, chan, ---- a/drivers/net/wireless/ath/ath9k/eeprom_def.c -+++ b/drivers/net/wireless/ath/ath9k/eeprom_def.c -@@ -79,12 +79,17 @@ static void ath9k_olc_get_pdadcs(struct - - static int ath9k_hw_def_get_eeprom_ver(struct ath_hw *ah) - { -- return ((ah->eeprom.def.baseEepHeader.version >> 12) & 0xF); -+ u16 version = ah->eeprom.def.baseEepHeader.version; -+ -+ return (version & AR5416_EEP_VER_MAJOR_MASK) >> -+ AR5416_EEP_VER_MAJOR_SHIFT; - } - - static int ath9k_hw_def_get_eeprom_rev(struct ath_hw *ah) - { -- return ((ah->eeprom.def.baseEepHeader.version) & 0xFFF); -+ u16 version = ah->eeprom.def.baseEepHeader.version; -+ -+ return version & AR5416_EEP_VER_MINOR_MASK; - } - - #define SIZE_EEPROM_DEF (sizeof(struct ar5416_eeprom_def) / sizeof(u16)) -@@ -214,8 +219,8 @@ static u32 ath9k_hw_def_dump_eeprom(stru - goto out; - } - -- PR_EEP("Major Version", pBase->version >> 12); -- PR_EEP("Minor Version", pBase->version & 0xFFF); -+ PR_EEP("Major Version", ath9k_hw_def_get_eeprom_ver(ah)); -+ PR_EEP("Minor Version", ath9k_hw_def_get_eeprom_rev(ah)); - PR_EEP("Checksum", pBase->checksum); - PR_EEP("Length", pBase->length); - PR_EEP("RegDomain1", pBase->regDmn[0]); -@@ -391,27 +396,27 @@ static u32 ath9k_hw_def_get_eeprom(struc - case EEP_TXGAIN_TYPE: - return pBase->txGainType; - case EEP_OL_PWRCTRL: -- if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_19) -+ if (ath9k_hw_def_get_eeprom_rev(ah) >= AR5416_EEP_MINOR_VER_19) - return pBase->openLoopPwrCntl ? true : false; - else - return false; - case EEP_RC_CHAIN_MASK: -- if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_19) -+ if (ath9k_hw_def_get_eeprom_rev(ah) >= AR5416_EEP_MINOR_VER_19) - return pBase->rcChainMask; - else - return 0; - case EEP_DAC_HPWR_5G: -- if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_20) -+ if (ath9k_hw_def_get_eeprom_rev(ah) >= AR5416_EEP_MINOR_VER_20) - return pBase->dacHiPwrMode_5G; - else - return 0; - case EEP_FRAC_N_5G: -- if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_22) -+ if (ath9k_hw_def_get_eeprom_rev(ah) >= AR5416_EEP_MINOR_VER_22) - return pBase->frac_n_5g; - else - return 0; - case EEP_PWR_TABLE_OFFSET: -- if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_21) -+ if (ath9k_hw_def_get_eeprom_rev(ah) >= AR5416_EEP_MINOR_VER_21) - return pBase->pwr_table_offset; - else - return AR5416_PWR_TABLE_OFFSET_DB; -@@ -434,7 +439,7 @@ static void ath9k_hw_def_set_gain(struct - u8 txRxAttenLocal, int regChainOffset, int i) - { - ENABLE_REG_RMW_BUFFER(ah); -- if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_3) { -+ if (ath9k_hw_def_get_eeprom_rev(ah) >= AR5416_EEP_MINOR_VER_3) { - txRxAttenLocal = pModal->txRxAttenCh[i]; - - if (AR_SREV_9280_20_OR_LATER(ah)) { -@@ -603,7 +608,7 @@ static void ath9k_hw_def_set_board_value - pModal->thresh62); - } - -- if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_2) { -+ if (ath9k_hw_def_get_eeprom_rev(ah) >= AR5416_EEP_MINOR_VER_2) { - REG_RMW_FIELD(ah, AR_PHY_RF_CTL2, - AR_PHY_TX_END_DATA_START, - pModal->txFrameToDataStart); -@@ -611,7 +616,7 @@ static void ath9k_hw_def_set_board_value - pModal->txFrameToPaOn); - } - -- if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_3) { -+ if (ath9k_hw_def_get_eeprom_rev(ah) >= AR5416_EEP_MINOR_VER_3) { - if (IS_CHAN_HT40(chan)) - REG_RMW_FIELD(ah, AR_PHY_SETTLING, - AR_PHY_SETTLING_SWITCH, -@@ -619,13 +624,14 @@ static void ath9k_hw_def_set_board_value - } - - if (AR_SREV_9280_20_OR_LATER(ah) && -- AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_19) -+ ath9k_hw_def_get_eeprom_rev(ah) >= AR5416_EEP_MINOR_VER_19) - REG_RMW_FIELD(ah, AR_PHY_CCK_TX_CTRL, - AR_PHY_CCK_TX_CTRL_TX_DAC_SCALE_CCK, - pModal->miscBits); - - -- if (AR_SREV_9280_20(ah) && AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_20) { -+ if (AR_SREV_9280_20(ah) && -+ ath9k_hw_def_get_eeprom_rev(ah) >= AR5416_EEP_MINOR_VER_20) { - if (IS_CHAN_2GHZ(chan)) - REG_RMW_FIELD(ah, AR_AN_TOP1, AR_AN_TOP1_DACIPMODE, - eep->baseEepHeader.dacLpMode); -@@ -796,8 +802,7 @@ static void ath9k_hw_set_def_power_cal_t - - pwr_table_offset = ah->eep_ops->get_eeprom(ah, EEP_PWR_TABLE_OFFSET); - -- if ((pEepData->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >= -- AR5416_EEP_MINOR_VER_2) { -+ if (ath9k_hw_def_get_eeprom_rev(ah) >= AR5416_EEP_MINOR_VER_2) { - pdGainOverlap_t2 = - pEepData->modalHeader[modalIdx].pdGainOverlap; - } else { -@@ -1169,10 +1174,8 @@ static void ath9k_hw_def_set_txpower(str - - memset(ratesArray, 0, sizeof(ratesArray)); - -- if ((pEepData->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >= -- AR5416_EEP_MINOR_VER_2) { -+ if (ath9k_hw_def_get_eeprom_rev(ah) >= AR5416_EEP_MINOR_VER_2) - ht40PowerIncForPdadc = pModal->ht40PowerIncForPdadc; -- } - - ath9k_hw_set_def_power_per_rate_table(ah, chan, - &ratesArray[0], cfgCtl, ---- a/drivers/net/wireless/ath/ath9k/xmit.c -+++ b/drivers/net/wireless/ath/ath9k/xmit.c -@@ -1236,8 +1236,9 @@ static u8 ath_get_rate_txpower(struct at - if (is_40) { - u8 power_ht40delta; - struct ar5416_eeprom_def *eep = &ah->eeprom.def; -+ u16 eeprom_rev = ah->eep_ops->get_eeprom_rev(ah); - -- if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_2) { -+ if (eeprom_rev >= AR5416_EEP_MINOR_VER_2) { - bool is_2ghz; - struct modal_eep_header *pmodal; - diff --git a/package/kernel/mac80211/patches/555-ath9k-Make-the-EEPROM-swapping-check-use-the-eepmisc.patch b/package/kernel/mac80211/patches/555-ath9k-Make-the-EEPROM-swapping-check-use-the-eepmisc.patch deleted file mode 100644 index 3e3c2ea7a3..0000000000 --- a/package/kernel/mac80211/patches/555-ath9k-Make-the-EEPROM-swapping-check-use-the-eepmisc.patch +++ /dev/null @@ -1,128 +0,0 @@ -From 1f796f9265c10384a274ac330f671ef4ac6d56e5 Mon Sep 17 00:00:00 2001 -From: Martin Blumenstingl -Date: Mon, 3 Oct 2016 00:29:12 +0200 -Subject: [v2 PATCH 6/7] ath9k: Make the EEPROM swapping check use the eepmisc - register - -There are two ways of swapping the EEPROM data in the ath9k driver: -1) swab16 based on the first two EEPROM "magic" bytes (same for all - EEPROM formats) -2) field and EEPROM format specific swab16/swab32 (different for - eeprom_def, eeprom_4k and eeprom_9287) - -The result of the first check was used to also enable the second swap. -This behavior seems incorrect, since the data may only be byte-swapped -(afterwards the data could be in the correct endianness). -Thus we introduce a separate check based on the "eepmisc" register -(which is part of the EEPROM data). When bit 0 is set, then the EEPROM -format specific values are in "big endian". This is also done by the -FreeBSD kernel, see [0] for example. - -This allows us to parse EEPROMs with the "correct" magic bytes but -swapped EEPROM format specific values. These EEPROMs (mostly found in -lantiq and broadcom based big endian MIPS based devices) only worked -due to platform specific "hacks" which swapped the EEPROM so the -magic was inverted, which also enabled the format specific swapping. -With this patch the old behavior is still supported, but neither -recommended nor needed anymore. - -[0] -https://github.com/freebsd/freebsd/blob/50719b56d9ce8d7d4beb53b16e9edb2e9a4a7a18/sys/dev/ath/ath_hal/ah_eeprom_9287.c#L351 - -Signed-off-by: Martin Blumenstingl ---- - drivers/net/wireless/ath/ath9k/eeprom.c | 57 ++++++++++++++++++++++++--------- - 1 file changed, 41 insertions(+), 16 deletions(-) - ---- a/drivers/net/wireless/ath/ath9k/eeprom.c -+++ b/drivers/net/wireless/ath/ath9k/eeprom.c -@@ -155,11 +155,19 @@ bool ath9k_hw_nvram_read(struct ath_hw * - return ret; - } - -+#ifdef __BIG_ENDIAN -+#define EXPECTED_EEPMISC_ENDIAN AR5416_EEPMISC_BIG_ENDIAN -+#else -+#define EXPECTED_EEPMISC_ENDIAN 0 -+#endif -+ - int ath9k_hw_nvram_swap_data(struct ath_hw *ah, bool *swap_needed, int size) - { - u16 magic; - u16 *eepdata; -+ u8 eepmisc; - int i; -+ bool needs_byteswap = false; - struct ath_common *common = ath9k_hw_common(ah); - - if (!ath9k_hw_nvram_read(ah, AR5416_EEPROM_MAGIC_OFFSET, &magic)) { -@@ -167,36 +175,53 @@ int ath9k_hw_nvram_swap_data(struct ath_ - return -EIO; - } - -- *swap_needed = false; - if (swab16(magic) == AR5416_EEPROM_MAGIC) { -+ needs_byteswap = true; -+ ath_dbg(common, EEPROM, -+ "EEPROM needs byte-swapping to correct endianness.\n"); -+ } else if (magic != AR5416_EEPROM_MAGIC) { -+ if (ath9k_hw_use_flash(ah)) { -+ ath_dbg(common, EEPROM, -+ "Ignoring invalid EEPROM magic (0x%04x).\n", -+ magic); -+ } else { -+ ath_err(common, -+ "Invalid EEPROM magic (0x%04x).\n", magic); -+ return -EINVAL; -+ } -+ } -+ -+ if (needs_byteswap) { - if (ah->ah_flags & AH_NO_EEP_SWAP) { - ath_info(common, - "Ignoring endianness difference in EEPROM magic bytes.\n"); - } else { -- *swap_needed = true; -- } -- } else if (magic != AR5416_EEPROM_MAGIC) { -- if (ath9k_hw_use_flash(ah)) -- return 0; -+ eepdata = (u16 *)(&ah->eeprom); - -- ath_err(common, -- "Invalid EEPROM Magic (0x%04x).\n", magic); -- return -EINVAL; -+ for (i = 0; i < size; i++) -+ eepdata[i] = swab16(eepdata[i]); -+ } - } - -- eepdata = (u16 *)(&ah->eeprom); -- -- if (*swap_needed) { -- ath_dbg(common, EEPROM, -- "EEPROM Endianness is not native.. Changing.\n"); -+ *swap_needed = false; - -- for (i = 0; i < size; i++) -- eepdata[i] = swab16(eepdata[i]); -+ eepmisc = ah->eep_ops->get_eepmisc(ah); -+ if ((eepmisc & AR5416_EEPMISC_BIG_ENDIAN) != EXPECTED_EEPMISC_ENDIAN) { -+ if (ah->ah_flags & AH_NO_EEP_SWAP) { -+ ath_info(common, -+ "Ignoring endianness difference in eepmisc register.\n"); -+ } else { -+ *swap_needed = true; -+ ath_dbg(common, EEPROM, -+ "EEPROM needs swapping according to the eepmisc register.\n"); -+ } - } - - return 0; - } - -+#undef EXPECTED_EEPMISC_VAL -+ - bool ath9k_hw_nvram_validate_checksum(struct ath_hw *ah, int size) - { - u32 i, sum = 0; diff --git a/package/kernel/mac80211/patches/556-ath9k-define-all-EEPROM-fields-in-Little-Endian-form.patch b/package/kernel/mac80211/patches/556-ath9k-define-all-EEPROM-fields-in-Little-Endian-form.patch deleted file mode 100644 index 04714f8169..0000000000 --- a/package/kernel/mac80211/patches/556-ath9k-define-all-EEPROM-fields-in-Little-Endian-form.patch +++ /dev/null @@ -1,853 +0,0 @@ -From 7e1047f3cf8dcdb4825f3c785f7f708d07508096 Mon Sep 17 00:00:00 2001 -From: Martin Blumenstingl -Date: Mon, 3 Oct 2016 00:29:13 +0200 -Subject: [v2 PATCH 7/7] ath9k: define all EEPROM fields in Little Endian format - -The ar9300_eeprom logic is already using only 8-bit (endian neutral), -__le16 and __le32 fields to state explicitly how the values should be -interpreted. -All other EEPROM implementations (4k, 9287 and def) were using u16 and -u32 fields with additional logic to swap the values (read from the -original EEPROM) so they match the current CPUs endianness. - -The EEPROM format defaults to "all values are Little Endian", indicated -by the absence of the AR5416_EEPMISC_BIG_ENDIAN in the u8 EEPMISC -register. If we detect that the EEPROM indicates Big Endian mode -(AR5416_EEPMISC_BIG_ENDIAN is set in the EEPMISC register) then we'll -swap the values to convert them into Little Endian. This is done by -activating the EEPMISC based logic in ath9k_hw_nvram_swap_data even if -AH_NO_EEP_SWAP is set (this makes ath9k behave like the FreeBSD driver, -which also does not have a flag to enable swapping based on the -AR5416_EEPMISC_BIG_ENDIAN bit). Before this logic was only used to -enable swapping when "current CPU endianness != EEPROM endianness". - -After changing all relevant fields to __le16 and __le32 sparse was used -to check that all code which reads any of these fields uses -le{16,32}_to_cpu. - -Signed-off-by: Martin Blumenstingl ---- - drivers/net/wireless/ath/ath9k/eeprom.c | 27 ++----- - drivers/net/wireless/ath/ath9k/eeprom.h | 75 ++++++++++-------- - drivers/net/wireless/ath/ath9k/eeprom_4k.c | 94 +++++++++------------- - drivers/net/wireless/ath/ath9k/eeprom_9287.c | 98 ++++++++++------------- - drivers/net/wireless/ath/ath9k/eeprom_def.c | 114 ++++++++++++--------------- - 5 files changed, 174 insertions(+), 234 deletions(-) - ---- a/drivers/net/wireless/ath/ath9k/eeprom.c -+++ b/drivers/net/wireless/ath/ath9k/eeprom.c -@@ -155,17 +155,10 @@ bool ath9k_hw_nvram_read(struct ath_hw * - return ret; - } - --#ifdef __BIG_ENDIAN --#define EXPECTED_EEPMISC_ENDIAN AR5416_EEPMISC_BIG_ENDIAN --#else --#define EXPECTED_EEPMISC_ENDIAN 0 --#endif -- - int ath9k_hw_nvram_swap_data(struct ath_hw *ah, bool *swap_needed, int size) - { - u16 magic; - u16 *eepdata; -- u8 eepmisc; - int i; - bool needs_byteswap = false; - struct ath_common *common = ath9k_hw_common(ah); -@@ -203,25 +196,17 @@ int ath9k_hw_nvram_swap_data(struct ath_ - } - } - -- *swap_needed = false; -- -- eepmisc = ah->eep_ops->get_eepmisc(ah); -- if ((eepmisc & AR5416_EEPMISC_BIG_ENDIAN) != EXPECTED_EEPMISC_ENDIAN) { -- if (ah->ah_flags & AH_NO_EEP_SWAP) { -- ath_info(common, -- "Ignoring endianness difference in eepmisc register.\n"); -- } else { -- *swap_needed = true; -- ath_dbg(common, EEPROM, -- "EEPROM needs swapping according to the eepmisc register.\n"); -- } -+ if (ah->eep_ops->get_eepmisc(ah) & AR5416_EEPMISC_BIG_ENDIAN) { -+ *swap_needed = true; -+ ath_dbg(common, EEPROM, -+ "Big Endian EEPROM detected according to EEPMISC register.\n"); -+ } else { -+ *swap_needed = false; - } - - return 0; - } - --#undef EXPECTED_EEPMISC_VAL -- - bool ath9k_hw_nvram_validate_checksum(struct ath_hw *ah, int size) - { - u32 i, sum = 0; ---- a/drivers/net/wireless/ath/ath9k/eeprom.h -+++ b/drivers/net/wireless/ath/ath9k/eeprom.h -@@ -23,6 +23,17 @@ - #include - #include "ar9003_eeprom.h" - -+/* helpers to swap EEPROM fields, which are stored as __le16 or __le32. Since -+ * we are 100% sure about it we __force these to u16/u32 for the swab calls to -+ * silence the sparse checks. These macros are used when we have a Big Endian -+ * EEPROM (according to AR5416_EEPMISC_BIG_ENDIAN) and need to convert the -+ * fields to __le16/__le32. -+ */ -+#define EEPROM_FIELD_SWAB16(field) \ -+ (field = (__force __le16)swab16((__force u16)field)) -+#define EEPROM_FIELD_SWAB32(field) \ -+ (field = (__force __le32)swab32((__force u32)field)) -+ - #ifdef __BIG_ENDIAN - #define AR5416_EEPROM_MAGIC 0x5aa5 - #else -@@ -270,19 +281,19 @@ enum ath9k_hal_freq_band { - }; - - struct base_eep_header { -- u16 length; -- u16 checksum; -- u16 version; -+ __le16 length; -+ __le16 checksum; -+ __le16 version; - u8 opCapFlags; - u8 eepMisc; -- u16 regDmn[2]; -+ __le16 regDmn[2]; - u8 macAddr[6]; - u8 rxMask; - u8 txMask; -- u16 rfSilent; -- u16 blueToothOptions; -- u16 deviceCap; -- u32 binBuildNumber; -+ __le16 rfSilent; -+ __le16 blueToothOptions; -+ __le16 deviceCap; -+ __le32 binBuildNumber; - u8 deviceType; - u8 pwdclkind; - u8 fastClk5g; -@@ -300,33 +311,33 @@ struct base_eep_header { - } __packed; - - struct base_eep_header_4k { -- u16 length; -- u16 checksum; -- u16 version; -+ __le16 length; -+ __le16 checksum; -+ __le16 version; - u8 opCapFlags; - u8 eepMisc; -- u16 regDmn[2]; -+ __le16 regDmn[2]; - u8 macAddr[6]; - u8 rxMask; - u8 txMask; -- u16 rfSilent; -- u16 blueToothOptions; -- u16 deviceCap; -- u32 binBuildNumber; -+ __le16 rfSilent; -+ __le16 blueToothOptions; -+ __le16 deviceCap; -+ __le32 binBuildNumber; - u8 deviceType; - u8 txGainType; - } __packed; - - - struct spur_chan { -- u16 spurChan; -+ __le16 spurChan; - u8 spurRangeLow; - u8 spurRangeHigh; - } __packed; - - struct modal_eep_header { -- u32 antCtrlChain[AR5416_MAX_CHAINS]; -- u32 antCtrlCommon; -+ __le32 antCtrlChain[AR5416_MAX_CHAINS]; -+ __le32 antCtrlCommon; - u8 antennaGainCh[AR5416_MAX_CHAINS]; - u8 switchSettling; - u8 txRxAttenCh[AR5416_MAX_CHAINS]; -@@ -361,7 +372,7 @@ struct modal_eep_header { - u8 db_ch1; - u8 lna_ctl; - u8 miscBits; -- u16 xpaBiasLvlFreq[3]; -+ __le16 xpaBiasLvlFreq[3]; - u8 futureModal[6]; - - struct spur_chan spurChans[AR_EEPROM_MODAL_SPURS]; -@@ -375,8 +386,8 @@ struct calDataPerFreqOpLoop { - } __packed; - - struct modal_eep_4k_header { -- u32 antCtrlChain[AR5416_EEP4K_MAX_CHAINS]; -- u32 antCtrlCommon; -+ __le32 antCtrlChain[AR5416_EEP4K_MAX_CHAINS]; -+ __le32 antCtrlCommon; - u8 antennaGainCh[AR5416_EEP4K_MAX_CHAINS]; - u8 switchSettling; - u8 txRxAttenCh[AR5416_EEP4K_MAX_CHAINS]; -@@ -440,19 +451,19 @@ struct modal_eep_4k_header { - } __packed; - - struct base_eep_ar9287_header { -- u16 length; -- u16 checksum; -- u16 version; -+ __le16 length; -+ __le16 checksum; -+ __le16 version; - u8 opCapFlags; - u8 eepMisc; -- u16 regDmn[2]; -+ __le16 regDmn[2]; - u8 macAddr[6]; - u8 rxMask; - u8 txMask; -- u16 rfSilent; -- u16 blueToothOptions; -- u16 deviceCap; -- u32 binBuildNumber; -+ __le16 rfSilent; -+ __le16 blueToothOptions; -+ __le16 deviceCap; -+ __le32 binBuildNumber; - u8 deviceType; - u8 openLoopPwrCntl; - int8_t pwrTableOffset; -@@ -462,8 +473,8 @@ struct base_eep_ar9287_header { - } __packed; - - struct modal_eep_ar9287_header { -- u32 antCtrlChain[AR9287_MAX_CHAINS]; -- u32 antCtrlCommon; -+ __le32 antCtrlChain[AR9287_MAX_CHAINS]; -+ __le32 antCtrlCommon; - int8_t antennaGainCh[AR9287_MAX_CHAINS]; - u8 switchSettling; - u8 txRxAttenCh[AR9287_MAX_CHAINS]; ---- a/drivers/net/wireless/ath/ath9k/eeprom_4k.c -+++ b/drivers/net/wireless/ath/ath9k/eeprom_4k.c -@@ -20,7 +20,7 @@ - - static int ath9k_hw_4k_get_eeprom_ver(struct ath_hw *ah) - { -- u16 version = ah->eeprom.map4k.baseEepHeader.version; -+ u16 version = le16_to_cpu(ah->eeprom.map4k.baseEepHeader.version); - - return (version & AR5416_EEP_VER_MAJOR_MASK) >> - AR5416_EEP_VER_MAJOR_SHIFT; -@@ -28,7 +28,7 @@ static int ath9k_hw_4k_get_eeprom_ver(st - - static int ath9k_hw_4k_get_eeprom_rev(struct ath_hw *ah) - { -- u16 version = ah->eeprom.map4k.baseEepHeader.version; -+ u16 version = le16_to_cpu(ah->eeprom.map4k.baseEepHeader.version); - - return version & AR5416_EEP_VER_MINOR_MASK; - } -@@ -76,8 +76,8 @@ static bool ath9k_hw_4k_fill_eeprom(stru - static u32 ath9k_dump_4k_modal_eeprom(char *buf, u32 len, u32 size, - struct modal_eep_4k_header *modal_hdr) - { -- PR_EEP("Chain0 Ant. Control", modal_hdr->antCtrlChain[0]); -- PR_EEP("Ant. Common Control", modal_hdr->antCtrlCommon); -+ PR_EEP("Chain0 Ant. Control", le16_to_cpu(modal_hdr->antCtrlChain[0])); -+ PR_EEP("Ant. Common Control", le32_to_cpu(modal_hdr->antCtrlCommon)); - PR_EEP("Chain0 Ant. Gain", modal_hdr->antennaGainCh[0]); - PR_EEP("Switch Settle", modal_hdr->switchSettling); - PR_EEP("Chain0 TxRxAtten", modal_hdr->txRxAttenCh[0]); -@@ -132,6 +132,7 @@ static u32 ath9k_hw_4k_dump_eeprom(struc - { - struct ar5416_eeprom_4k *eep = &ah->eeprom.map4k; - struct base_eep_header_4k *pBase = &eep->baseEepHeader; -+ u32 binBuildNumber = le32_to_cpu(pBase->binBuildNumber); - - if (!dump_base_hdr) { - len += scnprintf(buf + len, size - len, -@@ -143,10 +144,10 @@ static u32 ath9k_hw_4k_dump_eeprom(struc - - PR_EEP("Major Version", ath9k_hw_4k_get_eeprom_ver(ah)); - PR_EEP("Minor Version", ath9k_hw_4k_get_eeprom_rev(ah)); -- PR_EEP("Checksum", pBase->checksum); -- PR_EEP("Length", pBase->length); -- PR_EEP("RegDomain1", pBase->regDmn[0]); -- PR_EEP("RegDomain2", pBase->regDmn[1]); -+ PR_EEP("Checksum", le16_to_cpu(pBase->checksum)); -+ PR_EEP("Length", le16_to_cpu(pBase->length)); -+ PR_EEP("RegDomain1", le16_to_cpu(pBase->regDmn[0])); -+ PR_EEP("RegDomain2", le16_to_cpu(pBase->regDmn[1])); - PR_EEP("TX Mask", pBase->txMask); - PR_EEP("RX Mask", pBase->rxMask); - PR_EEP("Allow 5GHz", !!(pBase->opCapFlags & AR5416_OPFLAGS_11A)); -@@ -160,9 +161,9 @@ static u32 ath9k_hw_4k_dump_eeprom(struc - PR_EEP("Disable 5Ghz HT40", !!(pBase->opCapFlags & - AR5416_OPFLAGS_N_5G_HT40)); - PR_EEP("Big Endian", !!(pBase->eepMisc & AR5416_EEPMISC_BIG_ENDIAN)); -- PR_EEP("Cal Bin Major Ver", (pBase->binBuildNumber >> 24) & 0xFF); -- PR_EEP("Cal Bin Minor Ver", (pBase->binBuildNumber >> 16) & 0xFF); -- PR_EEP("Cal Bin Build", (pBase->binBuildNumber >> 8) & 0xFF); -+ PR_EEP("Cal Bin Major Ver", (binBuildNumber >> 24) & 0xFF); -+ PR_EEP("Cal Bin Minor Ver", (binBuildNumber >> 16) & 0xFF); -+ PR_EEP("Cal Bin Build", (binBuildNumber >> 8) & 0xFF); - PR_EEP("TX Gain type", pBase->txGainType); - - len += scnprintf(buf + len, size - len, "%20s : %pM\n", "MacAddress", -@@ -194,54 +195,31 @@ static int ath9k_hw_4k_check_eeprom(stru - return err; - - if (need_swap) -- el = swab16(eep->baseEepHeader.length); -+ el = swab16((__force u16)eep->baseEepHeader.length); - else -- el = eep->baseEepHeader.length; -+ el = le16_to_cpu(eep->baseEepHeader.length); - - el = min(el / sizeof(u16), SIZE_EEPROM_4K); - if (!ath9k_hw_nvram_validate_checksum(ah, el)) - return -EINVAL; - - if (need_swap) { -- u32 integer; -- u16 word; -- -- word = swab16(eep->baseEepHeader.length); -- eep->baseEepHeader.length = word; -- -- word = swab16(eep->baseEepHeader.checksum); -- eep->baseEepHeader.checksum = word; -- -- word = swab16(eep->baseEepHeader.version); -- eep->baseEepHeader.version = word; -- -- word = swab16(eep->baseEepHeader.regDmn[0]); -- eep->baseEepHeader.regDmn[0] = word; -- -- word = swab16(eep->baseEepHeader.regDmn[1]); -- eep->baseEepHeader.regDmn[1] = word; -- -- word = swab16(eep->baseEepHeader.rfSilent); -- eep->baseEepHeader.rfSilent = word; -- -- word = swab16(eep->baseEepHeader.blueToothOptions); -- eep->baseEepHeader.blueToothOptions = word; -- -- word = swab16(eep->baseEepHeader.deviceCap); -- eep->baseEepHeader.deviceCap = word; -- -- integer = swab32(eep->modalHeader.antCtrlCommon); -- eep->modalHeader.antCtrlCommon = integer; -- -- for (i = 0; i < AR5416_EEP4K_MAX_CHAINS; i++) { -- integer = swab32(eep->modalHeader.antCtrlChain[i]); -- eep->modalHeader.antCtrlChain[i] = integer; -- } -- -- for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) { -- word = swab16(eep->modalHeader.spurChans[i].spurChan); -- eep->modalHeader.spurChans[i].spurChan = word; -- } -+ EEPROM_FIELD_SWAB16(eep->baseEepHeader.length); -+ EEPROM_FIELD_SWAB16(eep->baseEepHeader.checksum); -+ EEPROM_FIELD_SWAB16(eep->baseEepHeader.version); -+ EEPROM_FIELD_SWAB16(eep->baseEepHeader.regDmn[0]); -+ EEPROM_FIELD_SWAB16(eep->baseEepHeader.regDmn[1]); -+ EEPROM_FIELD_SWAB16(eep->baseEepHeader.rfSilent); -+ EEPROM_FIELD_SWAB16(eep->baseEepHeader.blueToothOptions); -+ EEPROM_FIELD_SWAB16(eep->baseEepHeader.deviceCap); -+ EEPROM_FIELD_SWAB32(eep->modalHeader.antCtrlCommon); -+ -+ for (i = 0; i < AR5416_EEP4K_MAX_CHAINS; i++) -+ EEPROM_FIELD_SWAB32(eep->modalHeader.antCtrlChain[i]); -+ -+ for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) -+ EEPROM_FIELD_SWAB16( -+ eep->modalHeader.spurChans[i].spurChan); - } - - if (!ath9k_hw_nvram_check_version(ah, AR5416_EEP_VER, -@@ -270,13 +248,13 @@ static u32 ath9k_hw_4k_get_eeprom(struct - case EEP_MAC_MSW: - return get_unaligned_be16(pBase->macAddr + 4); - case EEP_REG_0: -- return pBase->regDmn[0]; -+ return le16_to_cpu(pBase->regDmn[0]); - case EEP_OP_CAP: -- return pBase->deviceCap; -+ return le16_to_cpu(pBase->deviceCap); - case EEP_OP_MODE: - return pBase->opCapFlags; - case EEP_RF_SILENT: -- return pBase->rfSilent; -+ return le16_to_cpu(pBase->rfSilent); - case EEP_OB_2: - return pModal->ob_0; - case EEP_DB_2: -@@ -724,7 +702,7 @@ static void ath9k_hw_4k_set_gain(struct - { - ENABLE_REG_RMW_BUFFER(ah); - REG_RMW(ah, AR_PHY_SWITCH_CHAIN_0, -- pModal->antCtrlChain[0], 0); -+ le32_to_cpu(pModal->antCtrlChain[0]), 0); - - REG_RMW(ah, AR_PHY_TIMING_CTRL4(0), - SM(pModal->iqCalICh[0], AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF) | -@@ -790,7 +768,7 @@ static void ath9k_hw_4k_set_board_values - pModal = &eep->modalHeader; - txRxAttenLocal = 23; - -- REG_WRITE(ah, AR_PHY_SWITCH_COM, pModal->antCtrlCommon); -+ REG_WRITE(ah, AR_PHY_SWITCH_COM, le32_to_cpu(pModal->antCtrlCommon)); - - /* Single chain for 4K EEPROM*/ - ath9k_hw_4k_set_gain(ah, pModal, eep, txRxAttenLocal); -@@ -1054,7 +1032,7 @@ static void ath9k_hw_4k_set_board_values - - static u16 ath9k_hw_4k_get_spur_channel(struct ath_hw *ah, u16 i, bool is2GHz) - { -- return ah->eeprom.map4k.modalHeader.spurChans[i].spurChan; -+ return le16_to_cpu(ah->eeprom.map4k.modalHeader.spurChans[i].spurChan); - } - - static u8 ath9k_hw_4k_get_eepmisc(struct ath_hw *ah) ---- a/drivers/net/wireless/ath/ath9k/eeprom_9287.c -+++ b/drivers/net/wireless/ath/ath9k/eeprom_9287.c -@@ -22,7 +22,7 @@ - - static int ath9k_hw_ar9287_get_eeprom_ver(struct ath_hw *ah) - { -- u16 version = ah->eeprom.map9287.baseEepHeader.version; -+ u16 version = le16_to_cpu(ah->eeprom.map9287.baseEepHeader.version); - - return (version & AR5416_EEP_VER_MAJOR_MASK) >> - AR5416_EEP_VER_MAJOR_SHIFT; -@@ -30,7 +30,7 @@ static int ath9k_hw_ar9287_get_eeprom_ve - - static int ath9k_hw_ar9287_get_eeprom_rev(struct ath_hw *ah) - { -- u16 version = ah->eeprom.map9287.baseEepHeader.version; -+ u16 version = le16_to_cpu(ah->eeprom.map9287.baseEepHeader.version); - - return version & AR5416_EEP_VER_MINOR_MASK; - } -@@ -79,9 +79,9 @@ static bool ath9k_hw_ar9287_fill_eeprom( - static u32 ar9287_dump_modal_eeprom(char *buf, u32 len, u32 size, - struct modal_eep_ar9287_header *modal_hdr) - { -- PR_EEP("Chain0 Ant. Control", modal_hdr->antCtrlChain[0]); -- PR_EEP("Chain1 Ant. Control", modal_hdr->antCtrlChain[1]); -- PR_EEP("Ant. Common Control", modal_hdr->antCtrlCommon); -+ PR_EEP("Chain0 Ant. Control", le16_to_cpu(modal_hdr->antCtrlChain[0])); -+ PR_EEP("Chain1 Ant. Control", le16_to_cpu(modal_hdr->antCtrlChain[1])); -+ PR_EEP("Ant. Common Control", le32_to_cpu(modal_hdr->antCtrlCommon)); - PR_EEP("Chain0 Ant. Gain", modal_hdr->antennaGainCh[0]); - PR_EEP("Chain1 Ant. Gain", modal_hdr->antennaGainCh[1]); - PR_EEP("Switch Settle", modal_hdr->switchSettling); -@@ -128,6 +128,7 @@ static u32 ath9k_hw_ar9287_dump_eeprom(s - { - struct ar9287_eeprom *eep = &ah->eeprom.map9287; - struct base_eep_ar9287_header *pBase = &eep->baseEepHeader; -+ u32 binBuildNumber = le32_to_cpu(pBase->binBuildNumber); - - if (!dump_base_hdr) { - len += scnprintf(buf + len, size - len, -@@ -139,10 +140,10 @@ static u32 ath9k_hw_ar9287_dump_eeprom(s - - PR_EEP("Major Version", ath9k_hw_ar9287_get_eeprom_ver(ah)); - PR_EEP("Minor Version", ath9k_hw_ar9287_get_eeprom_rev(ah)); -- PR_EEP("Checksum", pBase->checksum); -- PR_EEP("Length", pBase->length); -- PR_EEP("RegDomain1", pBase->regDmn[0]); -- PR_EEP("RegDomain2", pBase->regDmn[1]); -+ PR_EEP("Checksum", le16_to_cpu(pBase->checksum)); -+ PR_EEP("Length", le16_to_cpu(pBase->length)); -+ PR_EEP("RegDomain1", le16_to_cpu(pBase->regDmn[0])); -+ PR_EEP("RegDomain2", le16_to_cpu(pBase->regDmn[1])); - PR_EEP("TX Mask", pBase->txMask); - PR_EEP("RX Mask", pBase->rxMask); - PR_EEP("Allow 5GHz", !!(pBase->opCapFlags & AR5416_OPFLAGS_11A)); -@@ -156,9 +157,9 @@ static u32 ath9k_hw_ar9287_dump_eeprom(s - PR_EEP("Disable 5Ghz HT40", !!(pBase->opCapFlags & - AR5416_OPFLAGS_N_5G_HT40)); - PR_EEP("Big Endian", !!(pBase->eepMisc & AR5416_EEPMISC_BIG_ENDIAN)); -- PR_EEP("Cal Bin Major Ver", (pBase->binBuildNumber >> 24) & 0xFF); -- PR_EEP("Cal Bin Minor Ver", (pBase->binBuildNumber >> 16) & 0xFF); -- PR_EEP("Cal Bin Build", (pBase->binBuildNumber >> 8) & 0xFF); -+ PR_EEP("Cal Bin Major Ver", (binBuildNumber >> 24) & 0xFF); -+ PR_EEP("Cal Bin Minor Ver", (binBuildNumber >> 16) & 0xFF); -+ PR_EEP("Cal Bin Build", (binBuildNumber >> 8) & 0xFF); - PR_EEP("Power Table Offset", pBase->pwrTableOffset); - PR_EEP("OpenLoop Power Ctrl", pBase->openLoopPwrCntl); - -@@ -182,8 +183,7 @@ static u32 ath9k_hw_ar9287_dump_eeprom(s - - static int ath9k_hw_ar9287_check_eeprom(struct ath_hw *ah) - { -- u32 el, integer; -- u16 word; -+ u32 el; - int i, err; - bool need_swap; - struct ar9287_eeprom *eep = &ah->eeprom.map9287; -@@ -193,51 +193,31 @@ static int ath9k_hw_ar9287_check_eeprom( - return err; - - if (need_swap) -- el = swab16(eep->baseEepHeader.length); -+ el = swab16((__force u16)eep->baseEepHeader.length); - else -- el = eep->baseEepHeader.length; -+ el = le16_to_cpu(eep->baseEepHeader.length); - - el = min(el / sizeof(u16), SIZE_EEPROM_AR9287); - if (!ath9k_hw_nvram_validate_checksum(ah, el)) - return -EINVAL; - - if (need_swap) { -- word = swab16(eep->baseEepHeader.length); -- eep->baseEepHeader.length = word; -- -- word = swab16(eep->baseEepHeader.checksum); -- eep->baseEepHeader.checksum = word; -- -- word = swab16(eep->baseEepHeader.version); -- eep->baseEepHeader.version = word; -- -- word = swab16(eep->baseEepHeader.regDmn[0]); -- eep->baseEepHeader.regDmn[0] = word; -- -- word = swab16(eep->baseEepHeader.regDmn[1]); -- eep->baseEepHeader.regDmn[1] = word; -- -- word = swab16(eep->baseEepHeader.rfSilent); -- eep->baseEepHeader.rfSilent = word; -- -- word = swab16(eep->baseEepHeader.blueToothOptions); -- eep->baseEepHeader.blueToothOptions = word; -- -- word = swab16(eep->baseEepHeader.deviceCap); -- eep->baseEepHeader.deviceCap = word; -- -- integer = swab32(eep->modalHeader.antCtrlCommon); -- eep->modalHeader.antCtrlCommon = integer; -- -- for (i = 0; i < AR9287_MAX_CHAINS; i++) { -- integer = swab32(eep->modalHeader.antCtrlChain[i]); -- eep->modalHeader.antCtrlChain[i] = integer; -- } -- -- for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) { -- word = swab16(eep->modalHeader.spurChans[i].spurChan); -- eep->modalHeader.spurChans[i].spurChan = word; -- } -+ EEPROM_FIELD_SWAB16(eep->baseEepHeader.length); -+ EEPROM_FIELD_SWAB16(eep->baseEepHeader.checksum); -+ EEPROM_FIELD_SWAB16(eep->baseEepHeader.version); -+ EEPROM_FIELD_SWAB16(eep->baseEepHeader.regDmn[0]); -+ EEPROM_FIELD_SWAB16(eep->baseEepHeader.regDmn[1]); -+ EEPROM_FIELD_SWAB16(eep->baseEepHeader.rfSilent); -+ EEPROM_FIELD_SWAB16(eep->baseEepHeader.blueToothOptions); -+ EEPROM_FIELD_SWAB16(eep->baseEepHeader.deviceCap); -+ EEPROM_FIELD_SWAB32(eep->modalHeader.antCtrlCommon); -+ -+ for (i = 0; i < AR9287_MAX_CHAINS; i++) -+ EEPROM_FIELD_SWAB32(eep->modalHeader.antCtrlChain[i]); -+ -+ for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) -+ EEPROM_FIELD_SWAB16( -+ eep->modalHeader.spurChans[i].spurChan); - } - - if (!ath9k_hw_nvram_check_version(ah, AR9287_EEP_VER, -@@ -267,13 +247,13 @@ static u32 ath9k_hw_ar9287_get_eeprom(st - case EEP_MAC_MSW: - return get_unaligned_be16(pBase->macAddr + 4); - case EEP_REG_0: -- return pBase->regDmn[0]; -+ return le16_to_cpu(pBase->regDmn[0]); - case EEP_OP_CAP: -- return pBase->deviceCap; -+ return le16_to_cpu(pBase->deviceCap); - case EEP_OP_MODE: - return pBase->opCapFlags; - case EEP_RF_SILENT: -- return pBase->rfSilent; -+ return le16_to_cpu(pBase->rfSilent); - case EEP_TX_MASK: - return pBase->txMask; - case EEP_RX_MASK: -@@ -878,13 +858,13 @@ static void ath9k_hw_ar9287_set_board_va - - pModal = &eep->modalHeader; - -- REG_WRITE(ah, AR_PHY_SWITCH_COM, pModal->antCtrlCommon); -+ REG_WRITE(ah, AR_PHY_SWITCH_COM, le32_to_cpu(pModal->antCtrlCommon)); - - for (i = 0; i < AR9287_MAX_CHAINS; i++) { - regChainOffset = i * 0x1000; - - REG_WRITE(ah, AR_PHY_SWITCH_CHAIN_0 + regChainOffset, -- pModal->antCtrlChain[i]); -+ le32_to_cpu(pModal->antCtrlChain[i])); - - REG_WRITE(ah, AR_PHY_TIMING_CTRL4(0) + regChainOffset, - (REG_READ(ah, AR_PHY_TIMING_CTRL4(0) + regChainOffset) -@@ -982,7 +962,9 @@ static void ath9k_hw_ar9287_set_board_va - static u16 ath9k_hw_ar9287_get_spur_channel(struct ath_hw *ah, - u16 i, bool is2GHz) - { -- return ah->eeprom.map9287.modalHeader.spurChans[i].spurChan; -+ __le16 spur_ch = ah->eeprom.map9287.modalHeader.spurChans[i].spurChan; -+ -+ return le16_to_cpu(spur_ch); - } - - static u8 ath9k_hw_ar9287_get_eepmisc(struct ath_hw *ah) ---- a/drivers/net/wireless/ath/ath9k/eeprom_def.c -+++ b/drivers/net/wireless/ath/ath9k/eeprom_def.c -@@ -79,7 +79,7 @@ static void ath9k_olc_get_pdadcs(struct - - static int ath9k_hw_def_get_eeprom_ver(struct ath_hw *ah) - { -- u16 version = ah->eeprom.def.baseEepHeader.version; -+ u16 version = le16_to_cpu(ah->eeprom.def.baseEepHeader.version); - - return (version & AR5416_EEP_VER_MAJOR_MASK) >> - AR5416_EEP_VER_MAJOR_SHIFT; -@@ -87,7 +87,7 @@ static int ath9k_hw_def_get_eeprom_ver(s - - static int ath9k_hw_def_get_eeprom_rev(struct ath_hw *ah) - { -- u16 version = ah->eeprom.def.baseEepHeader.version; -+ u16 version = le16_to_cpu(ah->eeprom.def.baseEepHeader.version); - - return version & AR5416_EEP_VER_MINOR_MASK; - } -@@ -135,10 +135,10 @@ static bool ath9k_hw_def_fill_eeprom(str - static u32 ath9k_def_dump_modal_eeprom(char *buf, u32 len, u32 size, - struct modal_eep_header *modal_hdr) - { -- PR_EEP("Chain0 Ant. Control", modal_hdr->antCtrlChain[0]); -- PR_EEP("Chain1 Ant. Control", modal_hdr->antCtrlChain[1]); -- PR_EEP("Chain2 Ant. Control", modal_hdr->antCtrlChain[2]); -- PR_EEP("Ant. Common Control", modal_hdr->antCtrlCommon); -+ PR_EEP("Chain0 Ant. Control", le16_to_cpu(modal_hdr->antCtrlChain[0])); -+ PR_EEP("Chain1 Ant. Control", le16_to_cpu(modal_hdr->antCtrlChain[1])); -+ PR_EEP("Chain2 Ant. Control", le16_to_cpu(modal_hdr->antCtrlChain[2])); -+ PR_EEP("Ant. Common Control", le32_to_cpu(modal_hdr->antCtrlCommon)); - PR_EEP("Chain0 Ant. Gain", modal_hdr->antennaGainCh[0]); - PR_EEP("Chain1 Ant. Gain", modal_hdr->antennaGainCh[1]); - PR_EEP("Chain2 Ant. Gain", modal_hdr->antennaGainCh[2]); -@@ -194,9 +194,9 @@ static u32 ath9k_def_dump_modal_eeprom(c - PR_EEP("Chain1 OutputBias", modal_hdr->ob_ch1); - PR_EEP("Chain1 DriverBias", modal_hdr->db_ch1); - PR_EEP("LNA Control", modal_hdr->lna_ctl); -- PR_EEP("XPA Bias Freq0", modal_hdr->xpaBiasLvlFreq[0]); -- PR_EEP("XPA Bias Freq1", modal_hdr->xpaBiasLvlFreq[1]); -- PR_EEP("XPA Bias Freq2", modal_hdr->xpaBiasLvlFreq[2]); -+ PR_EEP("XPA Bias Freq0", le16_to_cpu(modal_hdr->xpaBiasLvlFreq[0])); -+ PR_EEP("XPA Bias Freq1", le16_to_cpu(modal_hdr->xpaBiasLvlFreq[1])); -+ PR_EEP("XPA Bias Freq2", le16_to_cpu(modal_hdr->xpaBiasLvlFreq[2])); - - return len; - } -@@ -206,6 +206,7 @@ static u32 ath9k_hw_def_dump_eeprom(stru - { - struct ar5416_eeprom_def *eep = &ah->eeprom.def; - struct base_eep_header *pBase = &eep->baseEepHeader; -+ u32 binBuildNumber = le32_to_cpu(pBase->binBuildNumber); - - if (!dump_base_hdr) { - len += scnprintf(buf + len, size - len, -@@ -221,10 +222,10 @@ static u32 ath9k_hw_def_dump_eeprom(stru - - PR_EEP("Major Version", ath9k_hw_def_get_eeprom_ver(ah)); - PR_EEP("Minor Version", ath9k_hw_def_get_eeprom_rev(ah)); -- PR_EEP("Checksum", pBase->checksum); -- PR_EEP("Length", pBase->length); -- PR_EEP("RegDomain1", pBase->regDmn[0]); -- PR_EEP("RegDomain2", pBase->regDmn[1]); -+ PR_EEP("Checksum", le16_to_cpu(pBase->checksum)); -+ PR_EEP("Length", le16_to_cpu(pBase->length)); -+ PR_EEP("RegDomain1", le16_to_cpu(pBase->regDmn[0])); -+ PR_EEP("RegDomain2", le16_to_cpu(pBase->regDmn[1])); - PR_EEP("TX Mask", pBase->txMask); - PR_EEP("RX Mask", pBase->rxMask); - PR_EEP("Allow 5GHz", !!(pBase->opCapFlags & AR5416_OPFLAGS_11A)); -@@ -238,9 +239,9 @@ static u32 ath9k_hw_def_dump_eeprom(stru - PR_EEP("Disable 5Ghz HT40", !!(pBase->opCapFlags & - AR5416_OPFLAGS_N_5G_HT40)); - PR_EEP("Big Endian", !!(pBase->eepMisc & AR5416_EEPMISC_BIG_ENDIAN)); -- PR_EEP("Cal Bin Major Ver", (pBase->binBuildNumber >> 24) & 0xFF); -- PR_EEP("Cal Bin Minor Ver", (pBase->binBuildNumber >> 16) & 0xFF); -- PR_EEP("Cal Bin Build", (pBase->binBuildNumber >> 8) & 0xFF); -+ PR_EEP("Cal Bin Major Ver", (binBuildNumber >> 24) & 0xFF); -+ PR_EEP("Cal Bin Minor Ver", (binBuildNumber >> 16) & 0xFF); -+ PR_EEP("Cal Bin Build", (binBuildNumber >> 8) & 0xFF); - PR_EEP("OpenLoop Power Ctrl", pBase->openLoopPwrCntl); - - len += scnprintf(buf + len, size - len, "%20s : %pM\n", "MacAddress", -@@ -273,61 +274,40 @@ static int ath9k_hw_def_check_eeprom(str - return err; - - if (need_swap) -- el = swab16(eep->baseEepHeader.length); -+ el = swab16((__force u16)eep->baseEepHeader.length); - else -- el = eep->baseEepHeader.length; -+ el = le16_to_cpu(eep->baseEepHeader.length); - - el = min(el / sizeof(u16), SIZE_EEPROM_DEF); - if (!ath9k_hw_nvram_validate_checksum(ah, el)) - return -EINVAL; - - if (need_swap) { -- u32 integer, j; -- u16 word; -+ u32 j; - -- word = swab16(eep->baseEepHeader.length); -- eep->baseEepHeader.length = word; -- -- word = swab16(eep->baseEepHeader.checksum); -- eep->baseEepHeader.checksum = word; -- -- word = swab16(eep->baseEepHeader.version); -- eep->baseEepHeader.version = word; -- -- word = swab16(eep->baseEepHeader.regDmn[0]); -- eep->baseEepHeader.regDmn[0] = word; -- -- word = swab16(eep->baseEepHeader.regDmn[1]); -- eep->baseEepHeader.regDmn[1] = word; -- -- word = swab16(eep->baseEepHeader.rfSilent); -- eep->baseEepHeader.rfSilent = word; -- -- word = swab16(eep->baseEepHeader.blueToothOptions); -- eep->baseEepHeader.blueToothOptions = word; -- -- word = swab16(eep->baseEepHeader.deviceCap); -- eep->baseEepHeader.deviceCap = word; -+ EEPROM_FIELD_SWAB16(eep->baseEepHeader.length); -+ EEPROM_FIELD_SWAB16(eep->baseEepHeader.checksum); -+ EEPROM_FIELD_SWAB16(eep->baseEepHeader.version); -+ EEPROM_FIELD_SWAB16(eep->baseEepHeader.regDmn[0]); -+ EEPROM_FIELD_SWAB16(eep->baseEepHeader.regDmn[1]); -+ EEPROM_FIELD_SWAB16(eep->baseEepHeader.rfSilent); -+ EEPROM_FIELD_SWAB16(eep->baseEepHeader.blueToothOptions); -+ EEPROM_FIELD_SWAB16(eep->baseEepHeader.deviceCap); - - for (j = 0; j < ARRAY_SIZE(eep->modalHeader); j++) { - struct modal_eep_header *pModal = - &eep->modalHeader[j]; -- integer = swab32(pModal->antCtrlCommon); -- pModal->antCtrlCommon = integer; -+ EEPROM_FIELD_SWAB32(pModal->antCtrlCommon); - -- for (i = 0; i < AR5416_MAX_CHAINS; i++) { -- integer = swab32(pModal->antCtrlChain[i]); -- pModal->antCtrlChain[i] = integer; -- } -- for (i = 0; i < 3; i++) { -- word = swab16(pModal->xpaBiasLvlFreq[i]); -- pModal->xpaBiasLvlFreq[i] = word; -- } -+ for (i = 0; i < AR5416_MAX_CHAINS; i++) -+ EEPROM_FIELD_SWAB32(pModal->antCtrlChain[i]); - -- for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) { -- word = swab16(pModal->spurChans[i].spurChan); -- pModal->spurChans[i].spurChan = word; -- } -+ for (i = 0; i < 3; i++) -+ EEPROM_FIELD_SWAB16(pModal->xpaBiasLvlFreq[i]); -+ -+ for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) -+ EEPROM_FIELD_SWAB16( -+ pModal->spurChans[i].spurChan); - } - } - -@@ -337,7 +317,7 @@ static int ath9k_hw_def_check_eeprom(str - - /* Enable fixup for AR_AN_TOP2 if necessary */ - if ((ah->hw_version.devid == AR9280_DEVID_PCI) && -- ((eep->baseEepHeader.version & 0xff) > 0x0a) && -+ ((le16_to_cpu(eep->baseEepHeader.version) & 0xff) > 0x0a) && - (eep->baseEepHeader.pwdclkind == 0)) - ah->need_an_top2_fixup = true; - -@@ -370,13 +350,13 @@ static u32 ath9k_hw_def_get_eeprom(struc - case EEP_MAC_MSW: - return get_unaligned_be16(pBase->macAddr + 4); - case EEP_REG_0: -- return pBase->regDmn[0]; -+ return le16_to_cpu(pBase->regDmn[0]); - case EEP_OP_CAP: -- return pBase->deviceCap; -+ return le16_to_cpu(pBase->deviceCap); - case EEP_OP_MODE: - return pBase->opCapFlags; - case EEP_RF_SILENT: -- return pBase->rfSilent; -+ return le16_to_cpu(pBase->rfSilent); - case EEP_OB_5: - return pModal[0].ob; - case EEP_DB_5: -@@ -490,11 +470,13 @@ static void ath9k_hw_def_set_board_value - struct ar5416_eeprom_def *eep = &ah->eeprom.def; - int i, regChainOffset; - u8 txRxAttenLocal; -+ u32 antCtrlCommon; - - pModal = &(eep->modalHeader[IS_CHAN_2GHZ(chan)]); - txRxAttenLocal = IS_CHAN_2GHZ(chan) ? 23 : 44; -+ antCtrlCommon = le32_to_cpu(pModal->antCtrlCommon); - -- REG_WRITE(ah, AR_PHY_SWITCH_COM, pModal->antCtrlCommon & 0xffff); -+ REG_WRITE(ah, AR_PHY_SWITCH_COM, antCtrlCommon & 0xffff); - - for (i = 0; i < AR5416_MAX_CHAINS; i++) { - if (AR_SREV_9280(ah)) { -@@ -508,7 +490,7 @@ static void ath9k_hw_def_set_board_value - regChainOffset = i * 0x1000; - - REG_WRITE(ah, AR_PHY_SWITCH_CHAIN_0 + regChainOffset, -- pModal->antCtrlChain[i]); -+ le32_to_cpu(pModal->antCtrlChain[i])); - - REG_WRITE(ah, AR_PHY_TIMING_CTRL4(0) + regChainOffset, - (REG_READ(ah, AR_PHY_TIMING_CTRL4(0) + regChainOffset) & -@@ -655,7 +637,7 @@ static void ath9k_hw_def_set_board_value - static void ath9k_hw_def_set_addac(struct ath_hw *ah, - struct ath9k_channel *chan) - { --#define XPA_LVL_FREQ(cnt) (pModal->xpaBiasLvlFreq[cnt]) -+#define XPA_LVL_FREQ(cnt) (le16_to_cpu(pModal->xpaBiasLvlFreq[cnt])) - struct modal_eep_header *pModal; - struct ar5416_eeprom_def *eep = &ah->eeprom.def; - u8 biaslevel; -@@ -1315,7 +1297,9 @@ static void ath9k_hw_def_set_txpower(str - - static u16 ath9k_hw_def_get_spur_channel(struct ath_hw *ah, u16 i, bool is2GHz) - { -- return ah->eeprom.def.modalHeader[is2GHz].spurChans[i].spurChan; -+ __le16 spch = ah->eeprom.def.modalHeader[is2GHz].spurChans[i].spurChan; -+ -+ return le16_to_cpu(spch); - } - - static u8 ath9k_hw_def_get_eepmisc(struct ath_hw *ah) diff --git a/package/kernel/mac80211/patches/557-ath9k-disable-bands-via-dt.patch b/package/kernel/mac80211/patches/557-ath9k-disable-bands-via-dt.patch deleted file mode 100644 index ae447ce1f5..0000000000 --- a/package/kernel/mac80211/patches/557-ath9k-disable-bands-via-dt.patch +++ /dev/null @@ -1,32 +0,0 @@ ---- a/Documentation/devicetree/bindings/net/wireless/qca,ath9k.txt -+++ b/Documentation/devicetree/bindings/net/wireless/qca,ath9k.txt -@@ -34,6 +34,14 @@ Optional properties: - ath9k wireless chip (in this case the calibration / - EEPROM data will be loaded from userspace using the - kernel firmware loader). -+- qca,disable-2ghz: Overrides the settings from the EEPROM and disables the -+ 2.4GHz band. Setting this property is only needed -+ when the RF circuit does not support the 2.4GHz band -+ while it is enabled nevertheless in the EEPROM. -+- qca,disable-5ghz: Overrides the settings from the EEPROM and disables the -+ 5GHz band. Setting this property is only needed when -+ the RF circuit does not support the 5GHz band while -+ it is enabled nevertheless in the EEPROM. - - mac-address: See ethernet.txt in the parent directory - - local-mac-address: See ethernet.txt in the parent directory - ---- a/drivers/net/wireless/ath/ath9k/init.c -+++ b/drivers/net/wireless/ath/ath9k/init.c -@@ -571,6 +571,12 @@ static int ath9k_of_init(struct ath_soft - - ath_dbg(common, CONFIG, "parsing configuration from OF node\n"); - -+ if (of_property_read_bool(np, "qca,disable-2ghz")) -+ ah->disable_2ghz = true; -+ -+ if (of_property_read_bool(np, "qca,disable-5ghz")) -+ ah->disable_5ghz = true; -+ - if (of_property_read_bool(np, "qca,no-eeprom")) { - /* ath9k-eeprom--.bin */ - scnprintf(eeprom_name, sizeof(eeprom_name), diff --git a/package/kernel/mac80211/patches/560-ath9k_ubnt_uap_plus_hsr.patch b/package/kernel/mac80211/patches/560-ath9k_ubnt_uap_plus_hsr.patch deleted file mode 100644 index 63335cf29f..0000000000 --- a/package/kernel/mac80211/patches/560-ath9k_ubnt_uap_plus_hsr.patch +++ /dev/null @@ -1,418 +0,0 @@ ---- a/drivers/net/wireless/ath/ath9k/channel.c -+++ b/drivers/net/wireless/ath/ath9k/channel.c -@@ -15,6 +15,8 @@ - */ - - #include "ath9k.h" -+#include -+#include "hsr.h" - - /* Set/change channels. If the channel is really being changed, it's done - * by reseting the chip. To accomplish this we must first cleanup any pending -@@ -22,6 +24,7 @@ - */ - static int ath_set_channel(struct ath_softc *sc) - { -+ struct ath9k_platform_data *pdata = sc->dev->platform_data; - struct ath_hw *ah = sc->sc_ah; - struct ath_common *common = ath9k_hw_common(ah); - struct ieee80211_hw *hw = sc->hw; -@@ -41,6 +44,11 @@ static int ath_set_channel(struct ath_so - ath_dbg(common, CONFIG, "Set channel: %d MHz width: %d\n", - chan->center_freq, chandef->width); - -+ if (pdata && pdata->ubnt_hsr) { -+ ath9k_hsr_enable(ah, chandef->width, chan->center_freq); -+ ath9k_hsr_status(ah); -+ } -+ - /* update survey stats for the old channel before switching */ - spin_lock_bh(&common->cc_lock); - ath_update_survey_stats(sc); ---- /dev/null -+++ b/drivers/net/wireless/ath/ath9k/hsr.c -@@ -0,0 +1,247 @@ -+/* -+ * -+ * The MIT License (MIT) -+ * -+ * Copyright (c) 2015 Kirill Berezin -+ * -+ * Permission is hereby granted, free of charge, to any person obtaining a copy -+ * of this software and associated documentation files (the "Software"), to deal -+ * in the Software without restriction, including without limitation the rights -+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+ * copies of the Software, and to permit persons to whom the Software is -+ * furnished to do so, subject to the following conditions: -+ * -+ * The above copyright notice and this permission notice shall be included in -+ * all copies or substantial portions of the Software. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -+ * SOFTWARE. -+ * -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "hw.h" -+#include "ath9k.h" -+ -+#define HSR_GPIO_CSN 8 -+#define HSR_GPIO_CLK 6 -+#define HSR_GPIO_DOUT 7 -+#define HSR_GPIO_DIN 5 -+ -+/* delays are in useconds */ -+#define HSR_DELAY_HALF_TICK 100 -+#define HSR_DELAY_PRE_WRITE 75 -+#define HSR_DELAY_FINAL 20000 -+#define HSR_DELAY_TRAILING 200 -+ -+void ath9k_hsr_init(struct ath_hw *ah) -+{ -+ ath9k_hw_gpio_request_in(ah, HSR_GPIO_DIN, NULL); -+ ath9k_hw_gpio_request_out(ah, HSR_GPIO_CSN, NULL, -+ AR_GPIO_OUTPUT_MUX_AS_OUTPUT); -+ ath9k_hw_gpio_request_out(ah, HSR_GPIO_CLK, NULL, -+ AR_GPIO_OUTPUT_MUX_AS_OUTPUT); -+ ath9k_hw_gpio_request_out(ah, HSR_GPIO_DOUT, NULL, -+ AR_GPIO_OUTPUT_MUX_AS_OUTPUT); -+ -+ ath9k_hw_set_gpio(ah, HSR_GPIO_CSN, 1); -+ ath9k_hw_set_gpio(ah, HSR_GPIO_CLK, 0); -+ ath9k_hw_set_gpio(ah, HSR_GPIO_DOUT, 0); -+ -+ udelay(HSR_DELAY_TRAILING); -+} -+ -+static u32 ath9k_hsr_write_byte(struct ath_hw *ah, int delay, u32 value) -+{ -+ struct ath_common *common = ath9k_hw_common(ah); -+ int i; -+ u32 rval = 0; -+ -+ udelay(delay); -+ -+ ath9k_hw_set_gpio(ah, HSR_GPIO_CLK, 0); -+ udelay(HSR_DELAY_HALF_TICK); -+ -+ ath9k_hw_set_gpio(ah, HSR_GPIO_CSN, 0); -+ udelay(HSR_DELAY_HALF_TICK); -+ -+ for (i = 0; i < 8; ++i) { -+ rval = rval << 1; -+ -+ /* pattern is left to right, that is 7-th bit runs first */ -+ ath9k_hw_set_gpio(ah, HSR_GPIO_DOUT, (value >> (7 - i)) & 0x1); -+ udelay(HSR_DELAY_HALF_TICK); -+ -+ ath9k_hw_set_gpio(ah, HSR_GPIO_CLK, 1); -+ udelay(HSR_DELAY_HALF_TICK); -+ -+ rval |= ath9k_hw_gpio_get(ah, HSR_GPIO_DIN); -+ -+ ath9k_hw_set_gpio(ah, HSR_GPIO_CLK, 0); -+ udelay(HSR_DELAY_HALF_TICK); -+ } -+ -+ ath9k_hw_set_gpio(ah, HSR_GPIO_CSN, 1); -+ udelay(HSR_DELAY_HALF_TICK); -+ -+ ath_dbg(common, CONFIG, "ath9k_hsr_write_byte: write byte %d return value is %d %c\n", -+ value, rval, rval > 32 ? rval : '-'); -+ -+ return rval & 0xff; -+} -+ -+static int ath9k_hsr_write_a_chain(struct ath_hw *ah, char *chain, int items) -+{ -+ int status = 0; -+ int i = 0; -+ int err; -+ -+ /* a preamble */ -+ ath9k_hsr_write_byte(ah, HSR_DELAY_PRE_WRITE, 0); -+ status = ath9k_hsr_write_byte(ah, HSR_DELAY_PRE_WRITE, 0); -+ -+ /* clear HSR's reply buffer */ -+ if (status) { -+ int loop = 0; -+ -+ for (loop = 0; (loop < 42) && status; ++loop) -+ status = ath9k_hsr_write_byte(ah, HSR_DELAY_PRE_WRITE, -+ 0); -+ -+ if (loop >= 42) { -+ ATH_DBG_WARN(1, -+ "ath9k_hsr_write_a_chain: can't clear an output buffer after a 42 cycles.\n"); -+ return -1; -+ } -+ } -+ -+ for (i = 0; (i < items) && (chain[i] != 0); ++i) -+ ath9k_hsr_write_byte(ah, HSR_DELAY_PRE_WRITE, (u32)chain[i]); -+ -+ ath9k_hsr_write_byte(ah, HSR_DELAY_PRE_WRITE, 0); -+ mdelay(HSR_DELAY_FINAL / 1000); -+ -+ /* reply */ -+ memset(chain, 0, items); -+ -+ ath9k_hsr_write_byte(ah, HSR_DELAY_PRE_WRITE, 0); -+ udelay(HSR_DELAY_TRAILING); -+ -+ for (i = 0; i < (items - 1); ++i) { -+ u32 ret; -+ -+ ret = ath9k_hsr_write_byte(ah, HSR_DELAY_PRE_WRITE, 0); -+ if (ret != 0) -+ chain[i] = (char)ret; -+ else -+ break; -+ -+ udelay(HSR_DELAY_TRAILING); -+ } -+ -+ if (i <= 1) -+ return 0; -+ -+ err = kstrtoint(chain + 1, 10, &i); -+ if (err) -+ return err; -+ -+ return i; -+} -+ -+int ath9k_hsr_disable(struct ath_hw *ah) -+{ -+ char cmd[10] = {'b', '4', '0', 0, 0, 0, 0, 0, 0, 0}; -+ int ret; -+ -+ ret = ath9k_hsr_write_a_chain(ah, cmd, sizeof(cmd)); -+ if ((ret > 0) && (*cmd == 'B')) -+ return 0; -+ -+ return -1; -+} -+ -+int ath9k_hsr_enable(struct ath_hw *ah, int bw, int fq) -+{ -+ char cmd[10]; -+ int ret; -+ -+ /* Bandwidth argument is 0 sometimes. Assume default 802.11bgn -+ * 20MHz on invalid values -+ */ -+ if ((bw != 5) && (bw != 10) && (bw != 20) && (bw != 40)) -+ bw = 20; -+ -+ memset(cmd, 0, sizeof(cmd)); -+ *cmd = 'b'; -+ snprintf(cmd + 1, 3, "%02d", bw); -+ -+ ret = ath9k_hsr_write_a_chain(ah, cmd, sizeof(cmd)); -+ if ((*cmd != 'B') || (ret != bw)) { -+ ATH_DBG_WARN(1, -+ "ath9k_hsr_enable: failed changing bandwidth -> set (%d,%d) reply (%d, %d)\n", -+ 'b', bw, *cmd, ret); -+ return -1; -+ } -+ -+ memset(cmd, 0, sizeof(cmd)); -+ *cmd = 'x'; -+ ret = ath9k_hsr_write_a_chain(ah, cmd, sizeof(cmd)); -+ if (*cmd != 'X') { -+ ATH_DBG_WARN(1, -+ "ath9k_hsr_enable: failed 'x' command -> reply (%d, %d)\n", -+ *cmd, ret); -+ return -1; -+ } -+ -+ memset(cmd, 0, sizeof(cmd)); -+ *cmd = 'm'; -+ ret = ath9k_hsr_write_a_chain(ah, cmd, sizeof(cmd)); -+ if (*cmd != 'M') { -+ ATH_DBG_WARN(1, -+ "ath9k_hsr_enable: failed 'm' command -> reply (%d, %d)\n", -+ *cmd, ret); -+ return -1; -+ } -+ -+ memset(cmd, 0, sizeof(cmd)); -+ *cmd = 'f'; -+ snprintf(cmd + 1, 6, "%05d", fq); -+ ret = ath9k_hsr_write_a_chain(ah, cmd, sizeof(cmd)); -+ if ((*cmd != 'F') && (ret != fq)) { -+ ATH_DBG_WARN(1, -+ "ath9k_hsr_enable: failed set frequency -> reply (%d, %d)\n", -+ *cmd, ret); -+ return -1; -+ } -+ -+ return 0; -+} -+ -+int ath9k_hsr_status(struct ath_hw *ah) -+{ -+ char cmd[10] = {'s', 0, 0, 0, 0, 0, 0, 0, 0, 0}; -+ int ret; -+ -+ ret = ath9k_hsr_write_a_chain(ah, cmd, sizeof(cmd)); -+ if (*cmd != 'S') { -+ ATH_DBG_WARN(1, "ath9k_hsr_status: returned %d,%d\n", *cmd, -+ ret); -+ return -1; -+ } -+ -+ return 0; -+} ---- /dev/null -+++ b/drivers/net/wireless/ath/ath9k/hsr.h -@@ -0,0 +1,48 @@ -+/* -+ * The MIT License (MIT) -+ * -+ * Copyright (c) 2015 Kirill Berezin -+ * -+ * Permission is hereby granted, free of charge, to any person obtaining a copy -+ * of this software and associated documentation files (the "Software"), to deal -+ * in the Software without restriction, including without limitation the rights -+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+ * copies of the Software, and to permit persons to whom the Software is -+ * furnished to do so, subject to the following conditions: -+ * -+ * The above copyright notice and this permission notice shall be included in -+ * all copies or substantial portions of the Software. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -+ * SOFTWARE. -+ */ -+ -+#ifndef HSR_H -+#define HSR_H -+ -+#ifdef CPTCFG_ATH9K_UBNTHSR -+ -+void ath9k_hsr_init(struct ath_hw *ah); -+int ath9k_hsr_disable(struct ath_hw *ah); -+int ath9k_hsr_enable(struct ath_hw *ah, int bw, int fq); -+int ath9k_hsr_status(struct ath_hw *ah); -+ -+#else -+static inline void ath9k_hsr_init(struct ath_hw *ah) {} -+ -+static inline int ath9k_hsr_enable(struct ath_hw *ah, int bw, int fq) -+{ -+ return 0; -+} -+ -+static inline int ath9k_hsr_disable(struct ath_hw *ah) { return 0; } -+static inline int ath9k_hsr_status(struct ath_hw *ah) { return 0; } -+ -+#endif -+ -+#endif /* HSR_H */ ---- a/drivers/net/wireless/ath/ath9k/main.c -+++ b/drivers/net/wireless/ath/ath9k/main.c -@@ -16,8 +16,10 @@ - - #include - #include -+#include - #include "ath9k.h" - #include "btcoex.h" -+#include "hsr.h" - - u8 ath9k_parse_mpdudensity(u8 mpdudensity) - { -@@ -648,6 +650,7 @@ void ath_reset_work(struct work_struct * - static int ath9k_start(struct ieee80211_hw *hw) - { - struct ath_softc *sc = hw->priv; -+ struct ath9k_platform_data *pdata = sc->dev->platform_data; - struct ath_hw *ah = sc->sc_ah; - struct ath_common *common = ath9k_hw_common(ah); - struct ieee80211_channel *curchan = sc->cur_chan->chandef.chan; -@@ -726,6 +729,11 @@ static int ath9k_start(struct ieee80211_ - AR_GPIO_OUTPUT_MUX_AS_OUTPUT); - } - -+ if (pdata && pdata->ubnt_hsr) { -+ ath9k_hsr_init(ah); -+ ath9k_hsr_disable(ah); -+ } -+ - /* - * Reset key cache to sane defaults (all entries cleared) instead of - * semi-random values after suspend/resume. ---- a/drivers/net/wireless/ath/ath9k/Makefile -+++ b/drivers/net/wireless/ath/ath9k/Makefile -@@ -16,6 +16,7 @@ ath9k-$(CPTCFG_ATH9K_DFS_CERTIFIED) += d - ath9k-$(CPTCFG_ATH9K_TX99) += tx99.o - ath9k-$(CPTCFG_ATH9K_WOW) += wow.o - ath9k-$(CPTCFG_ATH9K_HWRNG) += rng.o -+ath9k-$(CPTCFG_ATH9K_UBNTHSR) += hsr.o - - ath9k-$(CPTCFG_ATH9K_DEBUGFS) += debug.o - ---- a/include/linux/ath9k_platform.h -+++ b/include/linux/ath9k_platform.h -@@ -54,6 +54,8 @@ struct ath9k_platform_data { - unsigned num_btns; - const struct gpio_keys_button *btns; - unsigned btn_poll_interval; -+ -+ bool ubnt_hsr; - }; - - #endif /* _LINUX_ATH9K_PLATFORM_H */ ---- a/.local-symbols -+++ b/.local-symbols -@@ -153,6 +153,7 @@ ATH9K_WOW= - ATH9K_RFKILL= - ATH9K_CHANNEL_CONTEXT= - ATH9K_PCOEM= -+ATH9K_UBNTHSR= - ATH9K_HTC= - ATH9K_HTC_DEBUGFS= - ATH9K_HWRNG= ---- a/drivers/net/wireless/ath/ath9k/Kconfig -+++ b/drivers/net/wireless/ath/ath9k/Kconfig -@@ -59,6 +59,19 @@ config ATH9K_AHB - Say Y, if you have a SoC with a compatible built-in - wireless MAC. Say N if unsure. - -+config ATH9K_UBNTHSR -+ bool "Ubiquiti UniFi Outdoor Plus HSR support" -+ depends on ATH9K -+ ---help--- -+ This options enables code to control the HSR RF -+ filter in the receive path of the Ubiquiti UniFi -+ Outdoor Plus access point. -+ -+ Say Y if you want to use the access point. The -+ code will only be used if the device is detected, -+ so it does not harm other setup other than occupying -+ a bit of memory. -+ - config ATH9K_DEBUGFS - bool "Atheros ath9k debugging" - depends on ATH9K && DEBUG_FS diff --git a/package/kernel/mac80211/patches/600-0001-rt2x00-rt2800lib-move-rt2800_drv_data-declaration-in.patch b/package/kernel/mac80211/patches/600-0001-rt2x00-rt2800lib-move-rt2800_drv_data-declaration-in.patch deleted file mode 100644 index bd81555ac1..0000000000 --- a/package/kernel/mac80211/patches/600-0001-rt2x00-rt2800lib-move-rt2800_drv_data-declaration-in.patch +++ /dev/null @@ -1,66 +0,0 @@ -From 7a69da907de668fb22a30ae218062d6f081864ea Mon Sep 17 00:00:00 2001 -From: Gabor Juhos -Date: Sat, 17 Aug 2013 19:31:41 +0200 -Subject: [PATCH] rt2x00: rt2800lib: move rt2800_drv_data declaration into - rt2800lib.h - -The rt2800_drv_data structure contains driver specific -information. Move the declaration into the rt2800lib.h -header which is a more logical place for it. Also fix -the comment style to avoid checkpatch warning. - -The patch contains no functional changes, it is in -preparation for the next patch. - -Signed-off-by: Gabor Juhos ---- -Changes since v1: --- ---- - drivers/net/wireless/ralink/rt2x00/rt2800.h | 13 ------------- - drivers/net/wireless/ralink/rt2x00/rt2800lib.h | 11 +++++++++++ - 2 files changed, 11 insertions(+), 13 deletions(-) - ---- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.h -+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.h -@@ -20,6 +20,20 @@ - #ifndef RT2800LIB_H - #define RT2800LIB_H - -+#include "rt2800.h" -+ -+/* RT2800 driver data structure */ -+struct rt2800_drv_data { -+ u8 calibration_bw20; -+ u8 calibration_bw40; -+ u8 bbp25; -+ u8 bbp26; -+ u8 txmixer_gain_24g; -+ u8 txmixer_gain_5g; -+ unsigned int tbtt_tick; -+ DECLARE_BITMAP(sta_ids, STA_IDS_SIZE); -+}; -+ - struct rt2800_ops { - void (*register_read)(struct rt2x00_dev *rt2x00dev, - const unsigned int offset, u32 *value); ---- a/drivers/net/wireless/ralink/rt2x00/rt2800.h -+++ b/drivers/net/wireless/ralink/rt2x00/rt2800.h -@@ -2969,18 +2969,4 @@ enum rt2800_eeprom_word { - #define WCID_END 222 - #define STA_IDS_SIZE (WCID_END - WCID_START + 2) - --/* -- * RT2800 driver data structure -- */ --struct rt2800_drv_data { -- u8 calibration_bw20; -- u8 calibration_bw40; -- u8 bbp25; -- u8 bbp26; -- u8 txmixer_gain_24g; -- u8 txmixer_gain_5g; -- unsigned int tbtt_tick; -- DECLARE_BITMAP(sta_ids, STA_IDS_SIZE); --}; -- - #endif /* RT2800_H */ diff --git a/package/kernel/mac80211/patches/600-0002-rt2x00-rt2800lib-introduce-RT2800_HAS_HIGH_SHARED_ME.patch b/package/kernel/mac80211/patches/600-0002-rt2x00-rt2800lib-introduce-RT2800_HAS_HIGH_SHARED_ME.patch deleted file mode 100644 index db70a334bd..0000000000 --- a/package/kernel/mac80211/patches/600-0002-rt2x00-rt2800lib-introduce-RT2800_HAS_HIGH_SHARED_ME.patch +++ /dev/null @@ -1,80 +0,0 @@ -From a7f268af31dddf763fe3dbe9cbf96ea77e0540e0 Mon Sep 17 00:00:00 2001 -From: Gabor Juhos -Date: Sat, 17 Aug 2013 19:31:41 +0200 -Subject: [PATCH] rt2x00: rt2800lib: introduce RT2800_HAS_HIGH_SHARED_MEM flag - -Some chipsets have more than 16KB of shared memory. -Introduce a new rt2800 specific flag to indicate that -and add a helper function which helps to check the -presence of the new flag. - -Also enable the new flag for the RT3593 chipset which -has 24KB of shared memory. The flag can also be used -for other chipsets, but none of those has been tested -yet. - -Signed-off-by: Gabor Juhos ---- -Changes since v1: - - don't enable the new flag for RT3071 and RT5592 ---- - drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 4 ++++ - drivers/net/wireless/ralink/rt2x00/rt2800lib.h | 13 +++++++++++++ - 2 files changed, 17 insertions(+) - ---- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c -+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c -@@ -7726,6 +7726,7 @@ static int rt2800_probe_rt(struct rt2x00 - - int rt2800_probe_hw(struct rt2x00_dev *rt2x00dev) - { -+ struct rt2800_drv_data *drv_data = rt2x00dev->drv_data; - int retval; - u32 reg; - -@@ -7733,6 +7734,9 @@ int rt2800_probe_hw(struct rt2x00_dev *r - if (retval) - return retval; - -+ if (rt2x00_rt(rt2x00dev, RT3593)) -+ __set_bit(RT2800_HAS_HIGH_SHARED_MEM, &drv_data->rt2800_flags); -+ - /* - * Allocate eeprom data. - */ ---- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.h -+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.h -@@ -22,6 +22,10 @@ - - #include "rt2800.h" - -+enum rt2800_flag { -+ RT2800_HAS_HIGH_SHARED_MEM, -+}; -+ - /* RT2800 driver data structure */ - struct rt2800_drv_data { - u8 calibration_bw20; -@@ -32,6 +36,8 @@ struct rt2800_drv_data { - u8 txmixer_gain_5g; - unsigned int tbtt_tick; - DECLARE_BITMAP(sta_ids, STA_IDS_SIZE); -+ -+ unsigned long rt2800_flags; - }; - - struct rt2800_ops { -@@ -64,6 +70,13 @@ struct rt2800_ops { - __le32 *(*drv_get_txwi)(struct queue_entry *entry); - }; - -+static inline bool rt2800_has_high_shared_mem(struct rt2x00_dev *rt2x00dev) -+{ -+ struct rt2800_drv_data *drv_data = rt2x00dev->drv_data; -+ -+ return test_bit(RT2800_HAS_HIGH_SHARED_MEM, &drv_data->rt2800_flags); -+} -+ - static inline void rt2800_register_read(struct rt2x00_dev *rt2x00dev, - const unsigned int offset, - u32 *value) diff --git a/package/kernel/mac80211/patches/600-0003-rt2x00-rt2800-serialize-shared-memory-access.patch b/package/kernel/mac80211/patches/600-0003-rt2x00-rt2800-serialize-shared-memory-access.patch deleted file mode 100644 index a3b62bcc14..0000000000 --- a/package/kernel/mac80211/patches/600-0003-rt2x00-rt2800-serialize-shared-memory-access.patch +++ /dev/null @@ -1,531 +0,0 @@ -From 250a1b520cd7fdc0df4fc3fedea9066913f49ecf Mon Sep 17 00:00:00 2001 -From: Gabor Juhos -Date: Sat, 17 Aug 2013 19:31:42 +0200 -Subject: [PATCH] rt2x00: rt2800: serialize shared memory access - -The shared memory of the rt2800 devices is accessible -through the register offset range between 0x4000 and -0x8000. The size of this range is 16KB only and on -devices which have more than 16KB of shared memory either -the low or the high part of the memory is accessible at a -time. - -Serialize all accesses to the shared memory by a mutex, -in order to avoid concurrent use of that. - -Signed-off-by: Gabor Juhos ---- -Changes since v1: --- ---- - drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 55 +++++++++++++++++++++++++++++- - drivers/net/wireless/ralink/rt2x00/rt2800lib.h | 32 +++++++++++++++++ - drivers/net/wireless/ralink/rt2x00/rt2800mmio.c | 26 ++++++++++++++ - drivers/net/wireless/ralink/rt2x00/rt2800mmio.h | 4 +++ - drivers/net/wireless/ralink/rt2x00/rt2800pci.c | 14 ++++++++ - drivers/net/wireless/ralink/rt2x00/rt2800soc.c | 3 ++ - drivers/net/wireless/ralink/rt2x00/rt2800usb.c | 31 +++++++++++++++++ - 7 files changed, 164 insertions(+), 1 deletion(-) - ---- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c -+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c -@@ -451,11 +451,13 @@ void rt2800_mcu_request(struct rt2x00_de - rt2x00_set_field32(®, H2M_MAILBOX_CSR_CMD_TOKEN, token); - rt2x00_set_field32(®, H2M_MAILBOX_CSR_ARG0, arg0); - rt2x00_set_field32(®, H2M_MAILBOX_CSR_ARG1, arg1); -+ rt2800_shared_mem_lock(rt2x00dev); - rt2800_register_write_lock(rt2x00dev, H2M_MAILBOX_CSR, reg); - - reg = 0; - rt2x00_set_field32(®, HOST_CMD_CSR_HOST_COMMAND, command); - rt2800_register_write_lock(rt2x00dev, HOST_CMD_CSR, reg); -+ rt2800_shared_mem_unlock(rt2x00dev); - } - - mutex_unlock(&rt2x00dev->csr_mutex); -@@ -674,7 +676,9 @@ int rt2800_load_firmware(struct rt2x00_d - * Wait for device to stabilize. - */ - for (i = 0; i < REGISTER_BUSY_COUNT; i++) { -+ rt2800_shared_mem_lock(rt2x00dev); - rt2800_register_read(rt2x00dev, PBF_SYS_CTRL, ®); -+ rt2800_shared_mem_unlock(rt2x00dev); - if (rt2x00_get_field32(reg, PBF_SYS_CTRL_READY)) - break; - msleep(1); -@@ -694,10 +698,16 @@ int rt2800_load_firmware(struct rt2x00_d - /* - * Initialize firmware. - */ -+ rt2800_shared_mem_lock(rt2x00dev); - rt2800_register_write(rt2x00dev, H2M_BBP_AGENT, 0); - rt2800_register_write(rt2x00dev, H2M_MAILBOX_CSR, 0); -+ rt2800_shared_mem_unlock(rt2x00dev); -+ - if (rt2x00_is_usb(rt2x00dev)) { -+ rt2800_shared_mem_lock(rt2x00dev); - rt2800_register_write(rt2x00dev, H2M_INT_SRC, 0); -+ rt2800_shared_mem_unlock(rt2x00dev); -+ - rt2800_mcu_request(rt2x00dev, MCU_BOOT_SIGNAL, 0, 0, 0); - } - msleep(1); -@@ -1035,8 +1045,10 @@ void rt2800_write_beacon(struct queue_en - - beacon_base = rt2800_hw_beacon_base(rt2x00dev, entry->entry_idx); - -+ rt2800_shared_mem_lock(rt2x00dev); - rt2800_register_multiwrite(rt2x00dev, beacon_base, entry->skb->data, - entry->skb->len + padding_len); -+ rt2800_shared_mem_unlock(rt2x00dev); - __set_bit(ENTRY_BCN_ENABLED, &entry->flags); - - /* -@@ -1066,6 +1078,8 @@ static inline void rt2800_clear_beacon_r - - beacon_base = rt2800_hw_beacon_base(rt2x00dev, index); - -+ rt2800_shared_mem_lock(rt2x00dev); -+ - /* - * For the Beacon base registers we only need to clear - * the whole TXWI which (when set to 0) will invalidate -@@ -1073,6 +1087,8 @@ static inline void rt2800_clear_beacon_r - */ - for (i = 0; i < txwi_desc_size; i += sizeof(__le32)) - rt2800_register_write(rt2x00dev, beacon_base + i, 0); -+ -+ rt2800_shared_mem_unlock(rt2x00dev); - } - - void rt2800_clear_beacon(struct queue_entry *entry) -@@ -1261,7 +1277,9 @@ static void rt2800_delete_wcid_attr(stru - { - u32 offset; - offset = MAC_WCID_ATTR_ENTRY(wcid); -+ rt2800_shared_mem_lock(rt2x00dev); - rt2800_register_write(rt2x00dev, offset, 0); -+ rt2800_shared_mem_unlock(rt2x00dev); - } - - static void rt2800_config_wcid_attr_bssidx(struct rt2x00_dev *rt2x00dev, -@@ -1274,11 +1292,13 @@ static void rt2800_config_wcid_attr_bssi - * The BSS Idx numbers is split in a main value of 3 bits, - * and a extended field for adding one additional bit to the value. - */ -+ rt2800_shared_mem_lock(rt2x00dev); - rt2800_register_read(rt2x00dev, offset, ®); - rt2x00_set_field32(®, MAC_WCID_ATTRIBUTE_BSS_IDX, (bssidx & 0x7)); - rt2x00_set_field32(®, MAC_WCID_ATTRIBUTE_BSS_IDX_EXT, - (bssidx & 0x8) >> 3); - rt2800_register_write(rt2x00dev, offset, reg); -+ rt2800_shared_mem_unlock(rt2x00dev); - } - - static void rt2800_config_wcid_attr_cipher(struct rt2x00_dev *rt2x00dev, -@@ -1291,6 +1311,7 @@ static void rt2800_config_wcid_attr_ciph - - offset = MAC_WCID_ATTR_ENTRY(key->hw_key_idx); - -+ rt2800_shared_mem_lock(rt2x00dev); - if (crypto->cmd == SET_KEY) { - rt2800_register_read(rt2x00dev, offset, ®); - rt2x00_set_field32(®, MAC_WCID_ATTRIBUTE_KEYTAB, -@@ -1315,6 +1336,7 @@ static void rt2800_config_wcid_attr_ciph - rt2x00_set_field32(®, MAC_WCID_ATTRIBUTE_RX_WIUDF, 0); - rt2800_register_write(rt2x00dev, offset, reg); - } -+ rt2800_shared_mem_unlock(rt2x00dev); - - offset = MAC_IVEIV_ENTRY(key->hw_key_idx); - -@@ -1324,8 +1346,11 @@ static void rt2800_config_wcid_attr_ciph - (crypto->cipher == CIPHER_AES)) - iveiv_entry.iv[3] |= 0x20; - iveiv_entry.iv[3] |= key->keyidx << 6; -+ -+ rt2800_shared_mem_lock(rt2x00dev); - rt2800_register_multiwrite(rt2x00dev, offset, - &iveiv_entry, sizeof(iveiv_entry)); -+ rt2800_shared_mem_unlock(rt2x00dev); - } - - int rt2800_config_shared_key(struct rt2x00_dev *rt2x00dev, -@@ -1348,8 +1373,11 @@ int rt2800_config_shared_key(struct rt2x - sizeof(key_entry.rx_mic)); - - offset = SHARED_KEY_ENTRY(key->hw_key_idx); -+ -+ rt2800_shared_mem_lock(rt2x00dev); - rt2800_register_multiwrite(rt2x00dev, offset, - &key_entry, sizeof(key_entry)); -+ rt2800_shared_mem_unlock(rt2x00dev); - } - - /* -@@ -1364,10 +1392,12 @@ int rt2800_config_shared_key(struct rt2x - - offset = SHARED_KEY_MODE_ENTRY(key->hw_key_idx / 8); - -+ rt2800_shared_mem_lock(rt2x00dev); - rt2800_register_read(rt2x00dev, offset, ®); - rt2x00_set_field32(®, field, - (crypto->cmd == SET_KEY) * crypto->cipher); - rt2800_register_write(rt2x00dev, offset, reg); -+ rt2800_shared_mem_unlock(rt2x00dev); - - /* - * Update WCID information -@@ -1405,8 +1435,11 @@ int rt2800_config_pairwise_key(struct rt - sizeof(key_entry.rx_mic)); - - offset = PAIRWISE_KEY_ENTRY(key->hw_key_idx); -+ -+ rt2800_shared_mem_lock(rt2x00dev); - rt2800_register_multiwrite(rt2x00dev, offset, - &key_entry, sizeof(key_entry)); -+ rt2800_shared_mem_unlock(rt2x00dev); - } - - /* -@@ -4885,14 +4918,19 @@ static int rt2800_init_registers(struct - /* - * ASIC will keep garbage value after boot, clear encryption keys. - */ -+ rt2800_shared_mem_lock(rt2x00dev); - for (i = 0; i < 4; i++) - rt2800_register_write(rt2x00dev, - SHARED_KEY_MODE_ENTRY(i), 0); -+ rt2800_shared_mem_unlock(rt2x00dev); - - for (i = 0; i < 256; i++) { - rt2800_config_wcid(rt2x00dev, NULL, i); - rt2800_delete_wcid_attr(rt2x00dev, i); -+ -+ rt2800_shared_mem_lock(rt2x00dev); - rt2800_register_write(rt2x00dev, MAC_IVEIV_ENTRY(i), 0); -+ rt2800_shared_mem_unlock(rt2x00dev); - } - - /* -@@ -5018,8 +5056,10 @@ static int rt2800_wait_bbp_ready(struct - * BBP was enabled after firmware was loaded, - * but we need to reactivate it now. - */ -+ rt2800_shared_mem_lock(rt2x00dev); - rt2800_register_write(rt2x00dev, H2M_BBP_AGENT, 0); - rt2800_register_write(rt2x00dev, H2M_MAILBOX_CSR, 0); -+ rt2800_shared_mem_unlock(rt2x00dev); - msleep(1); - - for (i = 0; i < REGISTER_BUSY_COUNT; i++) { -@@ -6715,11 +6755,19 @@ int rt2800_enable_radio(struct rt2x00_de - /* - * Send signal during boot time to initialize firmware. - */ -+ rt2800_shared_mem_lock(rt2x00dev); - rt2800_register_write(rt2x00dev, H2M_BBP_AGENT, 0); - rt2800_register_write(rt2x00dev, H2M_MAILBOX_CSR, 0); -- if (rt2x00_is_usb(rt2x00dev)) -+ rt2800_shared_mem_unlock(rt2x00dev); -+ -+ if (rt2x00_is_usb(rt2x00dev)) { -+ rt2800_shared_mem_lock(rt2x00dev); - rt2800_register_write(rt2x00dev, H2M_INT_SRC, 0); -+ rt2800_shared_mem_unlock(rt2x00dev); -+ } -+ - rt2800_mcu_request(rt2x00dev, MCU_BOOT_SIGNAL, 0, 0, 0); -+ - msleep(1); - - /* -@@ -7730,6 +7778,8 @@ int rt2800_probe_hw(struct rt2x00_dev *r - int retval; - u32 reg; - -+ rt2800_shared_mem_init_lock(rt2x00dev); -+ - retval = rt2800_probe_rt(rt2x00dev); - if (retval) - return retval; -@@ -7813,8 +7863,11 @@ void rt2800_get_key_seq(struct ieee80211 - return; - - offset = MAC_IVEIV_ENTRY(key->hw_key_idx); -+ -+ rt2800_shared_mem_lock(rt2x00dev); - rt2800_register_multiread(rt2x00dev, offset, - &iveiv_entry, sizeof(iveiv_entry)); -+ rt2800_shared_mem_unlock(rt2x00dev); - - memcpy(&seq->tkip.iv16, &iveiv_entry.iv[0], 2); - memcpy(&seq->tkip.iv32, &iveiv_entry.iv[4], 4); ---- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.h -+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.h -@@ -38,6 +38,11 @@ struct rt2800_drv_data { - DECLARE_BITMAP(sta_ids, STA_IDS_SIZE); - - unsigned long rt2800_flags; -+ -+ union { -+ spinlock_t spin; -+ struct mutex mutex; -+ } shmem_lock; - }; - - struct rt2800_ops { -@@ -68,6 +73,10 @@ struct rt2800_ops { - const u8 *data, const size_t len); - int (*drv_init_registers)(struct rt2x00_dev *rt2x00dev); - __le32 *(*drv_get_txwi)(struct queue_entry *entry); -+ -+ void (*shmem_init_lock)(struct rt2x00_dev *rt2x00dev); -+ void (*shmem_lock)(struct rt2x00_dev *rt2x00dev); -+ void (*shmem_unlock)(struct rt2x00_dev *rt2x00dev); - }; - - static inline bool rt2800_has_high_shared_mem(struct rt2x00_dev *rt2x00dev) -@@ -77,6 +86,29 @@ static inline bool rt2800_has_high_share - return test_bit(RT2800_HAS_HIGH_SHARED_MEM, &drv_data->rt2800_flags); - } - -+static inline void rt2800_shared_mem_init_lock(struct rt2x00_dev *rt2x00dev) -+{ -+ const struct rt2800_ops *rt2800ops = rt2x00dev->ops->drv; -+ -+ rt2800ops->shmem_init_lock(rt2x00dev); -+} -+ -+static inline void rt2800_shared_mem_lock(struct rt2x00_dev *rt2x00dev) -+{ -+ const struct rt2800_ops *rt2800ops = rt2x00dev->ops->drv; -+ -+ if (rt2800_has_high_shared_mem(rt2x00dev)) -+ rt2800ops->shmem_lock(rt2x00dev); -+} -+ -+static inline void rt2800_shared_mem_unlock(struct rt2x00_dev *rt2x00dev) -+{ -+ const struct rt2800_ops *rt2800ops = rt2x00dev->ops->drv; -+ -+ if (rt2800_has_high_shared_mem(rt2x00dev)) -+ rt2800ops->shmem_unlock(rt2x00dev); -+} -+ - static inline void rt2800_register_read(struct rt2x00_dev *rt2x00dev, - const unsigned int offset, - u32 *value) ---- a/drivers/net/wireless/ralink/rt2x00/rt2800mmio.c -+++ b/drivers/net/wireless/ralink/rt2x00/rt2800mmio.c -@@ -820,8 +820,10 @@ int rt2800mmio_init_registers(struct rt2 - rt2x00_set_field32(®, WPDMA_RST_IDX_DRX_IDX0, 1); - rt2x00mmio_register_write(rt2x00dev, WPDMA_RST_IDX, reg); - -+ rt2800_shared_mem_lock(rt2x00dev); - rt2x00mmio_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00000e1f); - rt2x00mmio_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00000e00); -+ rt2800_shared_mem_unlock(rt2x00dev); - - if (rt2x00_is_pcie(rt2x00dev) && - (rt2x00_rt(rt2x00dev, RT3090) || -@@ -865,6 +867,30 @@ int rt2800mmio_enable_radio(struct rt2x0 - } - EXPORT_SYMBOL_GPL(rt2800mmio_enable_radio); - -+void rt2800mmio_shmem_init_lock(struct rt2x00_dev *rt2x00dev) -+{ -+ struct rt2800_drv_data *drv_data = rt2x00dev->drv_data; -+ -+ spin_lock_init(&drv_data->shmem_lock.spin); -+} -+EXPORT_SYMBOL_GPL(rt2800mmio_shmem_init_lock); -+ -+void rt2800mmio_shmem_lock(struct rt2x00_dev *rt2x00dev) -+{ -+ struct rt2800_drv_data *drv_data = rt2x00dev->drv_data; -+ -+ spin_lock_bh(&drv_data->shmem_lock.spin); -+} -+EXPORT_SYMBOL_GPL(rt2800mmio_shmem_lock); -+ -+void rt2800mmio_shmem_unlock(struct rt2x00_dev *rt2x00dev) -+{ -+ struct rt2800_drv_data *drv_data = rt2x00dev->drv_data; -+ -+ spin_unlock_bh(&drv_data->shmem_lock.spin); -+} -+EXPORT_SYMBOL_GPL(rt2800mmio_shmem_unlock); -+ - MODULE_AUTHOR(DRV_PROJECT); - MODULE_VERSION(DRV_VERSION); - MODULE_DESCRIPTION("rt2800 MMIO library"); ---- a/drivers/net/wireless/ralink/rt2x00/rt2800mmio.h -+++ b/drivers/net/wireless/ralink/rt2x00/rt2800mmio.h -@@ -160,4 +160,8 @@ int rt2800mmio_init_registers(struct rt2 - /* Device state switch handlers. */ - int rt2800mmio_enable_radio(struct rt2x00_dev *rt2x00dev); - -+void rt2800mmio_shmem_init_lock(struct rt2x00_dev *rt2x00dev); -+void rt2800mmio_shmem_lock(struct rt2x00_dev *rt2x00dev); -+void rt2800mmio_shmem_unlock(struct rt2x00_dev *rt2x00dev); -+ - #endif /* RT2800MMIO_H */ ---- a/drivers/net/wireless/ralink/rt2x00/rt2800pci.c -+++ b/drivers/net/wireless/ralink/rt2x00/rt2800pci.c -@@ -69,7 +69,9 @@ static void rt2800pci_mcu_status(struct - return; - - for (i = 0; i < 200; i++) { -+ rt2800_shared_mem_lock(rt2x00dev); - rt2x00mmio_register_read(rt2x00dev, H2M_MAILBOX_CID, ®); -+ rt2800_shared_mem_unlock(rt2x00dev); - - if ((rt2x00_get_field32(reg, H2M_MAILBOX_CID_CMD0) == token) || - (rt2x00_get_field32(reg, H2M_MAILBOX_CID_CMD1) == token) || -@@ -83,8 +85,10 @@ static void rt2800pci_mcu_status(struct - if (i == 200) - rt2x00_err(rt2x00dev, "MCU request failed, no response from hardware\n"); - -+ rt2800_shared_mem_lock(rt2x00dev); - rt2x00mmio_register_write(rt2x00dev, H2M_MAILBOX_STATUS, ~0); - rt2x00mmio_register_write(rt2x00dev, H2M_MAILBOX_CID, ~0); -+ rt2800_shared_mem_unlock(rt2x00dev); - } - - static void rt2800pci_eepromregister_read(struct eeprom_93cx6 *eeprom) -@@ -184,6 +188,8 @@ static int rt2800pci_write_firmware(stru - */ - reg = 0; - rt2x00_set_field32(®, PBF_SYS_CTRL_HOST_RAM_WRITE, 1); -+ -+ rt2800_shared_mem_lock(rt2x00dev); - rt2x00mmio_register_write(rt2x00dev, PBF_SYS_CTRL, reg); - - /* -@@ -197,6 +203,7 @@ static int rt2800pci_write_firmware(stru - - rt2x00mmio_register_write(rt2x00dev, H2M_BBP_AGENT, 0); - rt2x00mmio_register_write(rt2x00dev, H2M_MAILBOX_CSR, 0); -+ rt2800_shared_mem_unlock(rt2x00dev); - - return 0; - } -@@ -213,8 +220,10 @@ static int rt2800pci_enable_radio(struct - return retval; - - /* After resume MCU_BOOT_SIGNAL will trash these. */ -+ rt2800_shared_mem_lock(rt2x00dev); - rt2x00mmio_register_write(rt2x00dev, H2M_MAILBOX_STATUS, ~0); - rt2x00mmio_register_write(rt2x00dev, H2M_MAILBOX_CID, ~0); -+ rt2800_shared_mem_unlock(rt2x00dev); - - rt2800_mcu_request(rt2x00dev, MCU_SLEEP, TOKEN_RADIO_OFF, 0xff, 0x02); - rt2800pci_mcu_status(rt2x00dev, TOKEN_RADIO_OFF); -@@ -233,10 +242,12 @@ static int rt2800pci_set_state(struct rt - 0, 0x02); - rt2800pci_mcu_status(rt2x00dev, TOKEN_WAKEUP); - } else if (state == STATE_SLEEP) { -+ rt2800_shared_mem_lock(rt2x00dev); - rt2x00mmio_register_write(rt2x00dev, H2M_MAILBOX_STATUS, - 0xffffffff); - rt2x00mmio_register_write(rt2x00dev, H2M_MAILBOX_CID, - 0xffffffff); -+ rt2800_shared_mem_unlock(rt2x00dev); - rt2800_mcu_request(rt2x00dev, MCU_SLEEP, TOKEN_SLEEP, - 0xff, 0x01); - } -@@ -337,6 +348,9 @@ static const struct rt2800_ops rt2800pci - .drv_write_firmware = rt2800pci_write_firmware, - .drv_init_registers = rt2800mmio_init_registers, - .drv_get_txwi = rt2800mmio_get_txwi, -+ .shmem_init_lock = rt2800mmio_shmem_init_lock, -+ .shmem_lock = rt2800mmio_shmem_lock, -+ .shmem_unlock = rt2800mmio_shmem_unlock, - }; - - static const struct rt2x00lib_ops rt2800pci_rt2x00_ops = { ---- a/drivers/net/wireless/ralink/rt2x00/rt2800soc.c -+++ b/drivers/net/wireless/ralink/rt2x00/rt2800soc.c -@@ -176,6 +176,9 @@ static const struct rt2800_ops rt2800soc - .drv_write_firmware = rt2800soc_write_firmware, - .drv_init_registers = rt2800mmio_init_registers, - .drv_get_txwi = rt2800mmio_get_txwi, -+ .shmem_init_lock = rt2800mmio_shmem_init_lock, -+ .shmem_lock = rt2800mmio_shmem_lock, -+ .shmem_unlock = rt2800mmio_shmem_unlock, - }; - - static const struct rt2x00lib_ops rt2800soc_rt2x00_ops = { ---- a/drivers/net/wireless/ralink/rt2x00/rt2800usb.c -+++ b/drivers/net/wireless/ralink/rt2x00/rt2800usb.c -@@ -51,6 +51,27 @@ static bool rt2800usb_hwcrypt_disabled(s - return modparam_nohwcrypt; - } - -+static void rt2800usb_shmem_init_lock(struct rt2x00_dev *rt2x00dev) -+{ -+ struct rt2800_drv_data *drv_data = rt2x00dev->drv_data; -+ -+ mutex_init(&drv_data->shmem_lock.mutex); -+} -+ -+static void rt2800usb_shmem_lock(struct rt2x00_dev *rt2x00dev) -+{ -+ struct rt2800_drv_data *drv_data = rt2x00dev->drv_data; -+ -+ mutex_lock(&drv_data->shmem_lock.mutex); -+} -+ -+static void rt2800usb_shmem_unlock(struct rt2x00_dev *rt2x00dev) -+{ -+ struct rt2800_drv_data *drv_data = rt2x00dev->drv_data; -+ -+ mutex_unlock(&drv_data->shmem_lock.mutex); -+} -+ - /* - * Queue handlers. - */ -@@ -299,8 +320,10 @@ static int rt2800usb_write_firmware(stru - data + offset, length); - } - -+ rt2800_shared_mem_lock(rt2x00dev); - rt2x00usb_register_write(rt2x00dev, H2M_MAILBOX_CID, ~0); - rt2x00usb_register_write(rt2x00dev, H2M_MAILBOX_STATUS, ~0); -+ rt2800_shared_mem_unlock(rt2x00dev); - - /* - * Send firmware request to device to load firmware, -@@ -315,7 +338,10 @@ static int rt2800usb_write_firmware(stru - } - - msleep(10); -+ -+ rt2800_shared_mem_lock(rt2x00dev); - rt2x00usb_register_write(rt2x00dev, H2M_MAILBOX_CSR, 0); -+ rt2800_shared_mem_unlock(rt2x00dev); - - return 0; - } -@@ -333,8 +359,10 @@ static int rt2800usb_init_registers(stru - if (rt2800_wait_csr_ready(rt2x00dev)) - return -EBUSY; - -+ rt2800_shared_mem_lock(rt2x00dev); - rt2x00usb_register_read(rt2x00dev, PBF_SYS_CTRL, ®); - rt2x00usb_register_write(rt2x00dev, PBF_SYS_CTRL, reg & ~0x00002000); -+ rt2800_shared_mem_unlock(rt2x00dev); - - reg = 0; - rt2x00_set_field32(®, MAC_SYS_CTRL_RESET_CSR, 1); -@@ -863,6 +891,9 @@ static const struct rt2800_ops rt2800usb - .drv_write_firmware = rt2800usb_write_firmware, - .drv_init_registers = rt2800usb_init_registers, - .drv_get_txwi = rt2800usb_get_txwi, -+ .shmem_init_lock = rt2800usb_shmem_init_lock, -+ .shmem_lock = rt2800usb_shmem_lock, -+ .shmem_unlock = rt2800usb_shmem_unlock, - }; - - static const struct rt2x00lib_ops rt2800usb_rt2x00_ops = { diff --git a/package/kernel/mac80211/patches/600-0004-rt2x00-rt2800lib-fix-beacon-generation-on-RT3593.patch b/package/kernel/mac80211/patches/600-0004-rt2x00-rt2800lib-fix-beacon-generation-on-RT3593.patch deleted file mode 100644 index 985a3b91f1..0000000000 --- a/package/kernel/mac80211/patches/600-0004-rt2x00-rt2800lib-fix-beacon-generation-on-RT3593.patch +++ /dev/null @@ -1,131 +0,0 @@ -From dcfe3dd46242050f100162dce2bcad24d2c942c6 Mon Sep 17 00:00:00 2001 -From: Gabor Juhos -Date: Sat, 17 Aug 2013 19:31:42 +0200 -Subject: [PATCH] rt2x00: rt2800lib: fix beacon generation on RT3593 - -On the RT3593 chipset, the beacon registers are located -in the high 8KB part of the shared memory. - -The high part of the shared memory is only accessible -if it is explicitly selected. Add a helper function -in order to be able to control the SHR_MSEL bit in -the PBF_SYS_CTRL register. Also add a few more helper -functions and use those to select the correct part of -the shared memory before and after accessing the beacon -registers. - -The base addresses of the beacon registers are also -different from the actually used values, so fix the -'rt2800_hw_beacon_base' function to return the correct -values. - -Signed-off-by: Gabor Juhos ---- -Changes since v1: --- ---- - drivers/net/wireless/ralink/rt2x00/rt2800.h | 3 +++ - drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 44 +++++++++++++++++++++++++++++++ - 2 files changed, 47 insertions(+) - ---- a/drivers/net/wireless/ralink/rt2x00/rt2800.h -+++ b/drivers/net/wireless/ralink/rt2x00/rt2800.h -@@ -574,6 +574,7 @@ - #define PBF_SYS_CTRL 0x0400 - #define PBF_SYS_CTRL_READY FIELD32(0x00000080) - #define PBF_SYS_CTRL_HOST_RAM_WRITE FIELD32(0x00010000) -+#define PBF_SYS_CTRL_SHR_MSEL FIELD32(0x00080000) - - /* - * HOST-MCU shared memory -@@ -2026,6 +2027,8 @@ struct mac_iveiv_entry { - (((__index) < 6) ? (HW_BEACON_BASE4 + ((__index - 4) * 0x0200)) : \ - (HW_BEACON_BASE6 - ((__index - 6) * 0x0200)))) - -+#define HW_BEACON_BASE_HIGH(__index) (0x4000 + (__index) * 512) -+ - #define BEACON_BASE_TO_OFFSET(_base) (((_base) - 0x4000) / 64) - - /* ---- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c -+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c -@@ -82,6 +82,39 @@ static inline bool rt2800_is_305x_soc(st - return false; - } - -+static inline void rt2800_shared_mem_select(struct rt2x00_dev *rt2x00dev, -+ bool high) -+{ -+ u32 reg; -+ -+ if (WARN_ON_ONCE(!rt2800_has_high_shared_mem(rt2x00dev))) -+ return; -+ -+ rt2800_register_read(rt2x00dev, PBF_SYS_CTRL, ®); -+ rt2x00_set_field32(®, PBF_SYS_CTRL_SHR_MSEL, high); -+ rt2800_register_write(rt2x00dev, PBF_SYS_CTRL, reg); -+} -+ -+static inline bool rt2800_beacon_uses_high_mem(struct rt2x00_dev *rt2x00dev) -+{ -+ if (rt2x00_rt(rt2x00dev, RT3593)) -+ return true; -+ -+ return false; -+} -+ -+static inline void rt2800_select_beacon_mem(struct rt2x00_dev *rt2x00dev) -+{ -+ if (rt2800_beacon_uses_high_mem(rt2x00dev)) -+ rt2800_shared_mem_select(rt2x00dev, true); -+} -+ -+static inline void rt2800_deselect_beacon_mem(struct rt2x00_dev *rt2x00dev) -+{ -+ if (rt2800_beacon_uses_high_mem(rt2x00dev)) -+ rt2800_shared_mem_select(rt2x00dev, false); -+} -+ - static void rt2800_bbp_write(struct rt2x00_dev *rt2x00dev, - const unsigned int word, const u8 value) - { -@@ -948,6 +981,9 @@ EXPORT_SYMBOL_GPL(rt2800_txdone_entry); - static unsigned int rt2800_hw_beacon_base(struct rt2x00_dev *rt2x00dev, - unsigned int index) - { -+ if (rt2x00_rt(rt2x00dev, RT3593)) -+ return HW_BEACON_BASE_HIGH(index); -+ - return HW_BEACON_BASE(index); - } - -@@ -1046,8 +1082,12 @@ void rt2800_write_beacon(struct queue_en - beacon_base = rt2800_hw_beacon_base(rt2x00dev, entry->entry_idx); - - rt2800_shared_mem_lock(rt2x00dev); -+ -+ rt2800_select_beacon_mem(rt2x00dev); - rt2800_register_multiwrite(rt2x00dev, beacon_base, entry->skb->data, - entry->skb->len + padding_len); -+ rt2800_deselect_beacon_mem(rt2x00dev); -+ - rt2800_shared_mem_unlock(rt2x00dev); - __set_bit(ENTRY_BCN_ENABLED, &entry->flags); - -@@ -1080,6 +1120,8 @@ static inline void rt2800_clear_beacon_r - - rt2800_shared_mem_lock(rt2x00dev); - -+ rt2800_select_beacon_mem(rt2x00dev); -+ - /* - * For the Beacon base registers we only need to clear - * the whole TXWI which (when set to 0) will invalidate -@@ -1088,6 +1130,8 @@ static inline void rt2800_clear_beacon_r - for (i = 0; i < txwi_desc_size; i += sizeof(__le32)) - rt2800_register_write(rt2x00dev, beacon_base + i, 0); - -+ rt2800_deselect_beacon_mem(rt2x00dev); -+ - rt2800_shared_mem_unlock(rt2x00dev); - } - diff --git a/package/kernel/mac80211/patches/600-0005-rt2x00-rt2800lib-add-hw_beacon_count-field-to-struct.patch b/package/kernel/mac80211/patches/600-0005-rt2x00-rt2800lib-add-hw_beacon_count-field-to-struct.patch deleted file mode 100644 index f41a160d3f..0000000000 --- a/package/kernel/mac80211/patches/600-0005-rt2x00-rt2800lib-add-hw_beacon_count-field-to-struct.patch +++ /dev/null @@ -1,62 +0,0 @@ -From a058825fa7b53fab3b003d8928b60e5b686b3421 Mon Sep 17 00:00:00 2001 -From: Gabor Juhos -Date: Sun, 4 Aug 2013 14:36:11 +0200 -Subject: [PATCH] rt2x00: rt2800lib: add hw_beacon_count field to struct - rt2800_drv_data - -Some chipsets can handle more than 8 beacons at once. -Add a new field to the rt2800_drv_data structure which -will hold the number of supported beacons of the given -chipset. - -Update the rt2x00_init_registers function to get the -beacon count from the new field instead of using a -hardcoded value. - -In order to keep the current behaviour, initialize the -new field with the actually used value. - -Signed-off-by: Gabor Juhos ---- - drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 5 ++++- - drivers/net/wireless/ralink/rt2x00/rt2800lib.h | 1 + - 2 files changed, 5 insertions(+), 1 deletion(-) - ---- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c -+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c -@@ -4615,6 +4615,7 @@ EXPORT_SYMBOL_GPL(rt2800_link_tuner); - */ - static int rt2800_init_registers(struct rt2x00_dev *rt2x00dev) - { -+ struct rt2800_drv_data *drv_data = rt2x00dev->drv_data; - u32 reg; - u16 eeprom; - unsigned int i; -@@ -4980,7 +4981,7 @@ static int rt2800_init_registers(struct - /* - * Clear all beacons - */ -- for (i = 0; i < 8; i++) -+ for (i = 0; i < drv_data->hw_beacon_count; i++) - rt2800_clear_beacon_register(rt2x00dev, i); - - if (rt2x00_is_usb(rt2x00dev)) { -@@ -7831,6 +7832,8 @@ int rt2800_probe_hw(struct rt2x00_dev *r - if (rt2x00_rt(rt2x00dev, RT3593)) - __set_bit(RT2800_HAS_HIGH_SHARED_MEM, &drv_data->rt2800_flags); - -+ drv_data->hw_beacon_count = 8; -+ - /* - * Allocate eeprom data. - */ ---- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.h -+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.h -@@ -35,6 +35,7 @@ struct rt2800_drv_data { - u8 txmixer_gain_24g; - u8 txmixer_gain_5g; - unsigned int tbtt_tick; -+ unsigned int hw_beacon_count; - DECLARE_BITMAP(sta_ids, STA_IDS_SIZE); - - unsigned long rt2800_flags; diff --git a/package/kernel/mac80211/patches/600-0006-rt2x00-rt2800lib-init-additional-beacon-offset-regis.patch b/package/kernel/mac80211/patches/600-0006-rt2x00-rt2800lib-init-additional-beacon-offset-regis.patch deleted file mode 100644 index 4e735d348a..0000000000 --- a/package/kernel/mac80211/patches/600-0006-rt2x00-rt2800lib-init-additional-beacon-offset-regis.patch +++ /dev/null @@ -1,67 +0,0 @@ -From 1bfa43ca8f30be53ce4fa79cfc3e219642a812b6 Mon Sep 17 00:00:00 2001 -From: Gabor Juhos -Date: Mon, 2 Sep 2013 10:58:32 +0200 -Subject: [PATCH] rt2x00: rt2800lib: init additional beacon offset registers - -Signed-off-by: Gabor Juhos ---- - drivers/net/wireless/ralink/rt2x00/rt2800.h | 14 ++++++++++++++ - drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 24 ++++++++++++++++++++++++ - 2 files changed, 38 insertions(+) - ---- a/drivers/net/wireless/ralink/rt2x00/rt2800.h -+++ b/drivers/net/wireless/ralink/rt2x00/rt2800.h -@@ -629,6 +629,20 @@ - */ - #define PBF_DBG 0x043c - -+/* BCN_OFFSET2 */ -+#define BCN_OFFSET2 0x0444 -+#define BCN_OFFSET2_BCN8 FIELD32(0x000000ff) -+#define BCN_OFFSET2_BCN9 FIELD32(0x0000ff00) -+#define BCN_OFFSET2_BCN10 FIELD32(0x00ff0000) -+#define BCN_OFFSET2_BCN11 FIELD32(0xff000000) -+ -+/* BCN_OFFSET3 */ -+#define BCN_OFFSET3 0x0448 -+#define BCN_OFFSET3_BCN12 FIELD32(0x000000ff) -+#define BCN_OFFSET3_BCN13 FIELD32(0x0000ff00) -+#define BCN_OFFSET3_BCN14 FIELD32(0x00ff0000) -+#define BCN_OFFSET3_BCN15 FIELD32(0xff000000) -+ - /* - * RF registers - */ ---- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c -+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c -@@ -4627,6 +4627,30 @@ static int rt2800_init_registers(struct - if (ret) - return ret; - -+ if (drv_data->hw_beacon_count == 16) { -+ rt2800_register_read(rt2x00dev, BCN_OFFSET2, ®); -+ rt2x00_set_field32(®, BCN_OFFSET2_BCN8, -+ rt2800_get_beacon_offset(rt2x00dev, 8)); -+ rt2x00_set_field32(®, BCN_OFFSET2_BCN9, -+ rt2800_get_beacon_offset(rt2x00dev, 9)); -+ rt2x00_set_field32(®, BCN_OFFSET2_BCN10, -+ rt2800_get_beacon_offset(rt2x00dev, 10)); -+ rt2x00_set_field32(®, BCN_OFFSET2_BCN11, -+ rt2800_get_beacon_offset(rt2x00dev, 11)); -+ rt2800_register_write(rt2x00dev, BCN_OFFSET2, reg); -+ -+ rt2800_register_read(rt2x00dev, BCN_OFFSET3, ®); -+ rt2x00_set_field32(®, BCN_OFFSET3_BCN12, -+ rt2800_get_beacon_offset(rt2x00dev, 12)); -+ rt2x00_set_field32(®, BCN_OFFSET3_BCN13, -+ rt2800_get_beacon_offset(rt2x00dev, 13)); -+ rt2x00_set_field32(®, BCN_OFFSET3_BCN14, -+ rt2800_get_beacon_offset(rt2x00dev, 14)); -+ rt2x00_set_field32(®, BCN_OFFSET3_BCN15, -+ rt2800_get_beacon_offset(rt2x00dev, 15)); -+ rt2800_register_write(rt2x00dev, BCN_OFFSET3, reg); -+ } -+ - rt2800_register_write(rt2x00dev, LEGACY_BASIC_RATE, 0x0000013f); - rt2800_register_write(rt2x00dev, HT_BASIC_RATE, 0x00008003); - diff --git a/package/kernel/mac80211/patches/600-0007-rt2x00-rt2800lib-fix-max-supported-beacon-count-for-.patch b/package/kernel/mac80211/patches/600-0007-rt2x00-rt2800lib-fix-max-supported-beacon-count-for-.patch deleted file mode 100644 index 5099c64492..0000000000 --- a/package/kernel/mac80211/patches/600-0007-rt2x00-rt2800lib-fix-max-supported-beacon-count-for-.patch +++ /dev/null @@ -1,24 +0,0 @@ -From 9bea8b61f6025cd633bd5ac71be258620b49bcb3 Mon Sep 17 00:00:00 2001 -From: Gabor Juhos -Date: Mon, 2 Sep 2013 11:00:06 +0200 -Subject: [PATCH] rt2x00: rt2800lib: fix max supported beacon count for RT3593 - -Signed-off-by: Gabor Juhos ---- - drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 5 ++++- - 1 file changed, 4 insertions(+), 1 deletion(-) - ---- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c -+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c -@@ -7856,7 +7856,10 @@ int rt2800_probe_hw(struct rt2x00_dev *r - if (rt2x00_rt(rt2x00dev, RT3593)) - __set_bit(RT2800_HAS_HIGH_SHARED_MEM, &drv_data->rt2800_flags); - -- drv_data->hw_beacon_count = 8; -+ if (rt2x00_rt(rt2x00dev, RT3593)) -+ drv_data->hw_beacon_count = 16; -+ else -+ drv_data->hw_beacon_count = 8; - - /* - * Allocate eeprom data. diff --git a/package/kernel/mac80211/patches/600-0008-rt2x00-allow-to-build-rt2800soc-module-for-RT3883.patch b/package/kernel/mac80211/patches/600-0008-rt2x00-allow-to-build-rt2800soc-module-for-RT3883.patch deleted file mode 100644 index 565e39de5f..0000000000 --- a/package/kernel/mac80211/patches/600-0008-rt2x00-allow-to-build-rt2800soc-module-for-RT3883.patch +++ /dev/null @@ -1,30 +0,0 @@ -From 91094ed065f7794886b4a5490fd6de942f036bb4 Mon Sep 17 00:00:00 2001 -From: Gabor Juhos -Date: Sun, 24 Mar 2013 19:26:26 +0100 -Subject: [PATCH] rt2x00: allow to build rt2800soc module for RT3883 - -Signed-off-by: Gabor Juhos ---- - drivers/net/wireless/ralink/rt2x00/Kconfig | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/net/wireless/ralink/rt2x00/Kconfig -+++ b/drivers/net/wireless/ralink/rt2x00/Kconfig -@@ -210,7 +210,7 @@ endif - config RT2800SOC - tristate "Ralink WiSoC support" - depends on m -- depends on SOC_RT288X || SOC_RT305X -+ depends on SOC_RT288X || SOC_RT305X || SOC_RT3883 - select RT2X00_LIB_SOC - select RT2X00_LIB_MMIO - select RT2X00_LIB_CRYPTO -@@ -245,7 +245,7 @@ config RT2X00_LIB_PCI - - config RT2X00_LIB_SOC - tristate "RT2x00 SoC support" -- depends on SOC_RT288X || SOC_RT305X -+ depends on SOC_RT288X || SOC_RT305X || SOC_RT3883 - depends on m - select RT2X00_LIB - diff --git a/package/kernel/mac80211/patches/600-0009-rt2x00-rt2800lib-enable-support-for-RT3883.patch b/package/kernel/mac80211/patches/600-0009-rt2x00-rt2800lib-enable-support-for-RT3883.patch deleted file mode 100644 index a2e701527b..0000000000 --- a/package/kernel/mac80211/patches/600-0009-rt2x00-rt2800lib-enable-support-for-RT3883.patch +++ /dev/null @@ -1,20 +0,0 @@ -From 4f16582c93a71eba9d389e0f0a8aa9099a9587cd Mon Sep 17 00:00:00 2001 -From: Gabor Juhos -Date: Sun, 24 Mar 2013 19:26:26 +0100 -Subject: [PATCH] rt2x00: rt2800lib: enable support for RT3883 - -Signed-off-by: Gabor Juhos ---- - drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 1 + - 1 file changed, 1 insertion(+) - ---- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c -+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c -@@ -7826,6 +7826,7 @@ static int rt2800_probe_rt(struct rt2x00 - case RT3390: - case RT3572: - case RT3593: -+ case RT3883: - case RT5390: - case RT5392: - case RT5592: diff --git a/package/kernel/mac80211/patches/600-0010-rt2x00-rt2800lib-add-rf_vals-for-RF3853.patch b/package/kernel/mac80211/patches/600-0010-rt2x00-rt2800lib-add-rf_vals-for-RF3853.patch deleted file mode 100644 index 89bd0acb87..0000000000 --- a/package/kernel/mac80211/patches/600-0010-rt2x00-rt2800lib-add-rf_vals-for-RF3853.patch +++ /dev/null @@ -1,112 +0,0 @@ -From ecb394ccf248d8652c463133c4f404458a57a9c1 Mon Sep 17 00:00:00 2001 -From: Gabor Juhos -Date: Sun, 24 Mar 2013 19:26:26 +0100 -Subject: [PATCH] rt2x00: rt2800lib: add rf_vals for RF3853 - -Signed-off-by: Gabor Juhos ---- - drivers/net/wireless/ralink/rt2x00/rt2800.h | 4 +- - drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 65 +++++++++++++++++++++++++++++++ - 2 files changed, 68 insertions(+), 1 deletion(-) - ---- a/drivers/net/wireless/ralink/rt2x00/rt2800.h -+++ b/drivers/net/wireless/ralink/rt2x00/rt2800.h -@@ -48,7 +48,8 @@ - * RF2853 2.4G/5G 3T3R - * RF3320 2.4G 1T1R(RT3350/RT3370/RT3390) - * RF3322 2.4G 2T2R(RT3352/RT3371/RT3372/RT3391/RT3392) -- * RF3053 2.4G/5G 3T3R(RT3883/RT3563/RT3573/RT3593/RT3662) -+ * RF3053 2.4G/5G 3T3R(RT3563/RT3573/RT3593) -+ * RF3853 2.4G/5G 3T3R(RT3883/RT3662) - * RF5592 2.4G/5G 2T2R - * RF3070 2.4G 1T1R - * RF5360 2.4G 1T1R -@@ -72,6 +73,7 @@ - #define RF5592 0x000f - #define RF3070 0x3070 - #define RF3290 0x3290 -+#define RF3853 0x3853 - #define RF5360 0x5360 - #define RF5362 0x5362 - #define RF5370 0x5370 ---- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c -+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c -@@ -7442,6 +7442,66 @@ static const struct rf_channel rf_vals_3 - {173, 0x61, 0, 9}, - }; - -+static const struct rf_channel rf_vals_3853[] = { -+ {1, 241, 6, 2}, -+ {2, 241, 6, 7}, -+ {3, 242, 6, 2}, -+ {4, 242, 6, 7}, -+ {5, 243, 6, 2}, -+ {6, 243, 6, 7}, -+ {7, 244, 6, 2}, -+ {8, 244, 6, 7}, -+ {9, 245, 6, 2}, -+ {10, 245, 6, 7}, -+ {11, 246, 6, 2}, -+ {12, 246, 6, 7}, -+ {13, 247, 6, 2}, -+ {14, 248, 6, 4}, -+ -+ {36, 0x56, 8, 4}, -+ {38, 0x56, 8, 6}, -+ {40, 0x56, 8, 8}, -+ {44, 0x57, 8, 0}, -+ {46, 0x57, 8, 2}, -+ {48, 0x57, 8, 4}, -+ {52, 0x57, 8, 8}, -+ {54, 0x57, 8, 10}, -+ {56, 0x58, 8, 0}, -+ {60, 0x58, 8, 4}, -+ {62, 0x58, 8, 6}, -+ {64, 0x58, 8, 8}, -+ -+ {100, 0x5b, 8, 8}, -+ {102, 0x5b, 8, 10}, -+ {104, 0x5c, 8, 0}, -+ {108, 0x5c, 8, 4}, -+ {110, 0x5c, 8, 6}, -+ {112, 0x5c, 8, 8}, -+ {114, 0x5c, 8, 10}, -+ {116, 0x5d, 8, 0}, -+ {118, 0x5d, 8, 2}, -+ {120, 0x5d, 8, 4}, -+ {124, 0x5d, 8, 8}, -+ {126, 0x5d, 8, 10}, -+ {128, 0x5e, 8, 0}, -+ {132, 0x5e, 8, 4}, -+ {134, 0x5e, 8, 6}, -+ {136, 0x5e, 8, 8}, -+ {140, 0x5f, 8, 0}, -+ -+ {149, 0x5f, 8, 9}, -+ {151, 0x5f, 8, 11}, -+ {153, 0x60, 8, 1}, -+ {157, 0x60, 8, 5}, -+ {159, 0x60, 8, 7}, -+ {161, 0x60, 8, 9}, -+ {165, 0x61, 8, 1}, -+ {167, 0x61, 8, 3}, -+ {169, 0x61, 8, 5}, -+ {171, 0x61, 8, 7}, -+ {173, 0x61, 8, 9}, -+}; -+ - static const struct rf_channel rf_vals_5592_xtal20[] = { - /* Channel, N, K, mod, R */ - {1, 482, 4, 10, 3}, -@@ -7673,6 +7733,11 @@ static int rt2800_probe_hw_mode(struct r - spec->channels = rf_vals_3x; - break; - -+ case RF3853: -+ spec->num_channels = ARRAY_SIZE(rf_vals_3853); -+ spec->channels = rf_vals_3853; -+ break; -+ - case RF5592: - rt2800_register_read(rt2x00dev, MAC_DEBUG_INDEX, ®); - if (rt2x00_get_field32(reg, MAC_DEBUG_INDEX_XTAL)) { diff --git a/package/kernel/mac80211/patches/600-0011-rt2x00-rt2800lib-enable-VCO-calibration-for-RF3853.patch b/package/kernel/mac80211/patches/600-0011-rt2x00-rt2800lib-enable-VCO-calibration-for-RF3853.patch deleted file mode 100644 index b7efc9f31b..0000000000 --- a/package/kernel/mac80211/patches/600-0011-rt2x00-rt2800lib-enable-VCO-calibration-for-RF3853.patch +++ /dev/null @@ -1,28 +0,0 @@ -From f8e3fcf18e1f2d7f9e6a9680c5452da090f33d88 Mon Sep 17 00:00:00 2001 -From: Gabor Juhos -Date: Thu, 1 Aug 2013 14:40:44 +0200 -Subject: [PATCH] rt2x00: rt2800lib: enable VCO calibration for RF3853 - -Signed-off-by: Gabor Juhos ---- - drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 2 ++ - 1 file changed, 2 insertions(+) - ---- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c -+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c -@@ -4379,6 +4379,7 @@ void rt2800_vco_calibration(struct rt2x0 - case RF3053: - case RF3070: - case RF3290: -+ case RF3853: - case RF5360: - case RF5362: - case RF5370: -@@ -7852,6 +7853,7 @@ static int rt2800_probe_hw_mode(struct r - case RF3053: - case RF3070: - case RF3290: -+ case RF3853: - case RF5360: - case RF5362: - case RF5370: diff --git a/package/kernel/mac80211/patches/600-0012-rt2x00-rt2800lib-add-channel-configuration-function-.patch b/package/kernel/mac80211/patches/600-0012-rt2x00-rt2800lib-add-channel-configuration-function-.patch deleted file mode 100644 index c120f2c1d1..0000000000 --- a/package/kernel/mac80211/patches/600-0012-rt2x00-rt2800lib-add-channel-configuration-function-.patch +++ /dev/null @@ -1,235 +0,0 @@ -From 6e3a17190815c6aa4dc53c2cfe9125fb1154f187 Mon Sep 17 00:00:00 2001 -From: Gabor Juhos -Date: Sun, 24 Mar 2013 19:26:27 +0100 -Subject: [PATCH] rt2x00: rt2800lib: add channel configuration function for - RF3853 - -Signed-off-by: Gabor Juhos ---- - drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 208 +++++++++++++++++++++++++++++++ - 1 file changed, 208 insertions(+) - ---- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c -+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c -@@ -2626,6 +2626,211 @@ static void rt2800_config_channel_rf3053 - } - } - -+static void rt2800_config_channel_rf3853(struct rt2x00_dev *rt2x00dev, -+ struct ieee80211_conf *conf, -+ struct rf_channel *rf, -+ struct channel_info *info) -+{ -+ u8 rfcsr; -+ u8 bbp; -+ u8 pwr1, pwr2, pwr3; -+ -+ const bool txbf_enabled = false; /* TODO */ -+ -+ /* TODO: add band selection */ -+ -+ if (rf->channel <= 14) -+ rt2800_rfcsr_write(rt2x00dev, 6, 0x40); -+ else if (rf->channel < 132) -+ rt2800_rfcsr_write(rt2x00dev, 6, 0x80); -+ else -+ rt2800_rfcsr_write(rt2x00dev, 6, 0x40); -+ -+ rt2800_rfcsr_write(rt2x00dev, 8, rf->rf1); -+ rt2800_rfcsr_write(rt2x00dev, 9, rf->rf3); -+ -+ if (rf->channel <= 14) -+ rt2800_rfcsr_write(rt2x00dev, 11, 0x46); -+ else -+ rt2800_rfcsr_write(rt2x00dev, 11, 0x48); -+ -+ if (rf->channel <= 14) -+ rt2800_rfcsr_write(rt2x00dev, 12, 0x1a); -+ else -+ rt2800_rfcsr_write(rt2x00dev, 12, 0x52); -+ -+ rt2800_rfcsr_write(rt2x00dev, 13, 0x12); -+ -+ rt2800_rfcsr_read(rt2x00dev, 1, &rfcsr); -+ rt2x00_set_field8(&rfcsr, RFCSR1_RX0_PD, 0); -+ rt2x00_set_field8(&rfcsr, RFCSR1_TX0_PD, 0); -+ rt2x00_set_field8(&rfcsr, RFCSR1_RX1_PD, 0); -+ rt2x00_set_field8(&rfcsr, RFCSR1_TX1_PD, 0); -+ rt2x00_set_field8(&rfcsr, RFCSR1_RX2_PD, 0); -+ rt2x00_set_field8(&rfcsr, RFCSR1_TX2_PD, 0); -+ rt2x00_set_field8(&rfcsr, RFCSR1_RF_BLOCK_EN, 1); -+ rt2x00_set_field8(&rfcsr, RFCSR1_PLL_PD, 1); -+ -+ switch (rt2x00dev->default_ant.tx_chain_num) { -+ case 3: -+ rt2x00_set_field8(&rfcsr, RFCSR1_TX2_PD, 1); -+ /* fallthrough */ -+ case 2: -+ rt2x00_set_field8(&rfcsr, RFCSR1_TX1_PD, 1); -+ /* fallthrough */ -+ case 1: -+ rt2x00_set_field8(&rfcsr, RFCSR1_TX0_PD, 1); -+ break; -+ } -+ -+ switch (rt2x00dev->default_ant.rx_chain_num) { -+ case 3: -+ rt2x00_set_field8(&rfcsr, RFCSR1_RX2_PD, 1); -+ /* fallthrough */ -+ case 2: -+ rt2x00_set_field8(&rfcsr, RFCSR1_RX1_PD, 1); -+ /* fallthrough */ -+ case 1: -+ rt2x00_set_field8(&rfcsr, RFCSR1_RX0_PD, 1); -+ break; -+ } -+ rt2800_rfcsr_write(rt2x00dev, 1, rfcsr); -+ -+ rt2800_adjust_freq_offset(rt2x00dev); -+ -+ rt2800_rfcsr_read(rt2x00dev, 30, &rfcsr); -+ if (!conf_is_ht40(conf)) -+ rfcsr &= ~(0x06); -+ else -+ rfcsr |= 0x06; -+ rt2800_rfcsr_write(rt2x00dev, 30, rfcsr); -+ -+ if (rf->channel <= 14) -+ rt2800_rfcsr_write(rt2x00dev, 31, 0xa0); -+ else -+ rt2800_rfcsr_write(rt2x00dev, 31, 0x80); -+ -+ if (conf_is_ht40(conf)) -+ rt2800_rfcsr_write(rt2x00dev, 32, 0x80); -+ else -+ rt2800_rfcsr_write(rt2x00dev, 32, 0xd8); -+ -+ if (rf->channel <= 14) -+ rt2800_rfcsr_write(rt2x00dev, 34, 0x3c); -+ else -+ rt2800_rfcsr_write(rt2x00dev, 34, 0x20); -+ -+ /* loopback RF_BS */ -+ rt2800_rfcsr_read(rt2x00dev, 36, &rfcsr); -+ if (rf->channel <= 14) -+ rt2x00_set_field8(&rfcsr, RFCSR36_RF_BS, 1); -+ else -+ rt2x00_set_field8(&rfcsr, RFCSR36_RF_BS, 0); -+ rt2800_rfcsr_write(rt2x00dev, 36, rfcsr); -+ -+ if (rf->channel <= 14) -+ rfcsr = 0x23; -+ else if (rf->channel < 100) -+ rfcsr = 0x36; -+ else if (rf->channel < 132) -+ rfcsr = 0x32; -+ else -+ rfcsr = 0x30; -+ -+ if (txbf_enabled) -+ rfcsr |= 0x40; -+ -+ rt2800_rfcsr_write(rt2x00dev, 39, rfcsr); -+ -+ if (rf->channel <= 14) -+ rt2800_rfcsr_write(rt2x00dev, 44, 0x93); -+ else -+ rt2800_rfcsr_write(rt2x00dev, 44, 0x9b); -+ -+ if (rf->channel <= 14) -+ rfcsr = 0xbb; -+ else if (rf->channel < 100) -+ rfcsr = 0xeb; -+ else if (rf->channel < 132) -+ rfcsr = 0xb3; -+ else -+ rfcsr = 0x9b; -+ rt2800_rfcsr_write(rt2x00dev, 45, rfcsr); -+ -+ if (rf->channel <= 14) -+ rfcsr = 0x8e; -+ else -+ rfcsr = 0x8a; -+ -+ if (txbf_enabled) -+ rfcsr |= 0x20; -+ -+ rt2800_rfcsr_write(rt2x00dev, 49, rfcsr); -+ -+ rt2800_rfcsr_write(rt2x00dev, 50, 0x86); -+ -+ rt2800_rfcsr_read(rt2x00dev, 51, &rfcsr); -+ if (rf->channel <= 14) -+ rt2800_rfcsr_write(rt2x00dev, 51, 0x75); -+ else -+ rt2800_rfcsr_write(rt2x00dev, 51, 0x51); -+ -+ rt2800_rfcsr_read(rt2x00dev, 52, &rfcsr); -+ if (rf->channel <= 14) -+ rt2800_rfcsr_write(rt2x00dev, 52, 0x45); -+ else -+ rt2800_rfcsr_write(rt2x00dev, 52, 0x05); -+ -+ if (rf->channel <= 14) { -+ pwr1 = info->default_power1 & 0x1f; -+ pwr2 = info->default_power2 & 0x1f; -+ pwr3 = info->default_power3 & 0x1f; -+ } else { -+ pwr1 = 0x48 | ((info->default_power1 & 0x18) << 1) | -+ (info->default_power1 & 0x7); -+ pwr2 = 0x48 | ((info->default_power2 & 0x18) << 1) | -+ (info->default_power2 & 0x7); -+ pwr3 = 0x48 | ((info->default_power3 & 0x18) << 1) | -+ (info->default_power3 & 0x7); -+ } -+ -+ rt2800_rfcsr_write(rt2x00dev, 53, pwr1); -+ rt2800_rfcsr_write(rt2x00dev, 54, pwr2); -+ rt2800_rfcsr_write(rt2x00dev, 55, pwr3); -+ -+ rt2x00_dbg(rt2x00dev, "Channel:%d, pwr1:%02x, pwr2:%02x, pwr3:%02x\n", -+ rf->channel, pwr1, pwr2, pwr3); -+ -+ bbp = (info->default_power1 >> 5) | -+ ((info->default_power2 & 0xe0) >> 1); -+ rt2800_bbp_write(rt2x00dev, 109, bbp); -+ -+ rt2800_bbp_read(rt2x00dev, 110, &bbp); -+ bbp &= 0x0f; -+ bbp |= (info->default_power3 & 0xe0) >> 1; -+ rt2800_bbp_write(rt2x00dev, 110, bbp); -+ -+ rt2800_rfcsr_read(rt2x00dev, 57, &rfcsr); -+ if (rf->channel <= 14) -+ rt2800_rfcsr_write(rt2x00dev, 57, 0x6e); -+ else -+ rt2800_rfcsr_write(rt2x00dev, 57, 0x3e); -+ -+ /* Enable RF tuning */ -+ rt2800_rfcsr_read(rt2x00dev, 3, &rfcsr); -+ rt2x00_set_field8(&rfcsr, RFCSR3_VCOCAL_EN, 1); -+ rt2800_rfcsr_write(rt2x00dev, 3, rfcsr); -+ -+ udelay(2000); -+ -+ rt2800_bbp_read(rt2x00dev, 49, &bbp); -+ /* clear update flag */ -+ rt2800_bbp_write(rt2x00dev, 49, bbp & 0xfe); -+ rt2800_bbp_write(rt2x00dev, 49, bbp); -+ -+ /* TODO: add calibration for TxBF */ -+} -+ - #define POWER_BOUND 0x27 - #define POWER_BOUND_5G 0x2b - -@@ -3238,6 +3443,9 @@ static void rt2800_config_channel(struct - case RF3322: - rt2800_config_channel_rf3322(rt2x00dev, conf, rf, info); - break; -+ case RF3853: -+ rt2800_config_channel_rf3853(rt2x00dev, conf, rf, info); -+ break; - case RF3070: - case RF5360: - case RF5362: diff --git a/package/kernel/mac80211/patches/600-0013-rt2x00-rt2800lib-enable-RF3853-support.patch b/package/kernel/mac80211/patches/600-0013-rt2x00-rt2800lib-enable-RF3853-support.patch deleted file mode 100644 index f006304e7f..0000000000 --- a/package/kernel/mac80211/patches/600-0013-rt2x00-rt2800lib-enable-RF3853-support.patch +++ /dev/null @@ -1,20 +0,0 @@ -From afd38ae82226551bf879b6c7c4b620c271fee9d2 Mon Sep 17 00:00:00 2001 -From: Gabor Juhos -Date: Thu, 1 Aug 2013 14:42:05 +0200 -Subject: [PATCH] rt2x00: rt2800lib: enable RF3853 support - -Signed-off-by: Gabor Juhos ---- - drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 1 + - 1 file changed, 1 insertion(+) - ---- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c -+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c -@@ -7407,6 +7407,7 @@ static int rt2800_init_eeprom(struct rt2 - case RF3290: - case RF3320: - case RF3322: -+ case RF3853: - case RF5360: - case RF5362: - case RF5370: diff --git a/package/kernel/mac80211/patches/600-0014-rt2x00-rt2800lib-add-MAC-register-initialization-for.patch b/package/kernel/mac80211/patches/600-0014-rt2x00-rt2800lib-add-MAC-register-initialization-for.patch deleted file mode 100644 index a56bfa865e..0000000000 --- a/package/kernel/mac80211/patches/600-0014-rt2x00-rt2800lib-add-MAC-register-initialization-for.patch +++ /dev/null @@ -1,77 +0,0 @@ -From 0094872a5e8e4664c6ea1b2dfa487063d39ae363 Mon Sep 17 00:00:00 2001 -From: Gabor Juhos -Date: Sun, 24 Mar 2013 19:26:26 +0100 -Subject: [PATCH] rt2x00: rt2800lib: add MAC register initialization for - RT3883 - -Signed-off-by: Gabor Juhos ---- - drivers/net/wireless/ralink/rt2x00/rt2800.h | 14 ++++++++++++++ - drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 19 ++++++++++++++++--- - 2 files changed, 30 insertions(+), 3 deletions(-) - ---- a/drivers/net/wireless/ralink/rt2x00/rt2800.h -+++ b/drivers/net/wireless/ralink/rt2x00/rt2800.h -@@ -1588,6 +1588,20 @@ - #define TX_PWR_CFG_9_STBC7_CH2 FIELD32(0x00000f00) - - /* -+ * TX_TXBF_CFG: -+ */ -+#define TX_TXBF_CFG_0 0x138c -+#define TX_TXBF_CFG_1 0x13a4 -+#define TX_TXBF_CFG_2 0x13a8 -+#define TX_TXBF_CFG_3 0x13ac -+ -+/* -+ * TX_FBK_CFG_3S: -+ */ -+#define TX_FBK_CFG_3S_0 0x13c4 -+#define TX_FBK_CFG_3S_1 0x13c8 -+ -+/* - * RX_FILTER_CFG: RX configuration register. - */ - #define RX_FILTER_CFG 0x1400 ---- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c -+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c -@@ -4982,6 +4982,12 @@ static int rt2800_init_registers(struct - rt2800_register_write(rt2x00dev, TX_SW_CFG2, - 0x00000000); - } -+ } else if (rt2x00_rt(rt2x00dev, RT3883)) { -+ rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000402); -+ rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00000000); -+ rt2800_register_write(rt2x00dev, TX_SW_CFG2, 0x00040000); -+ rt2800_register_write(rt2x00dev, TX_TXBF_CFG_0, 0x8000fc21); -+ rt2800_register_write(rt2x00dev, TX_TXBF_CFG_3, 0x00009c40); - } else if (rt2x00_rt(rt2x00dev, RT5390) || - rt2x00_rt(rt2x00dev, RT5392) || - rt2x00_rt(rt2x00dev, RT5592)) { -@@ -5012,9 +5018,11 @@ static int rt2800_init_registers(struct - - rt2800_register_read(rt2x00dev, MAX_LEN_CFG, ®); - rt2x00_set_field32(®, MAX_LEN_CFG_MAX_MPDU, AGGREGATION_SIZE); -- if (rt2x00_rt_rev_gte(rt2x00dev, RT2872, REV_RT2872E) || -- rt2x00_rt(rt2x00dev, RT2883) || -- rt2x00_rt_rev_lt(rt2x00dev, RT3070, REV_RT3070E)) -+ if (rt2x00_rt(rt2x00dev, RT3883)) -+ rt2x00_set_field32(®, MAX_LEN_CFG_MAX_PSDU, 3); -+ else if (rt2x00_rt_rev_gte(rt2x00dev, RT2872, REV_RT2872E) || -+ rt2x00_rt(rt2x00dev, RT2883) || -+ rt2x00_rt_rev_lt(rt2x00dev, RT3070, REV_RT3070E)) - rt2x00_set_field32(®, MAX_LEN_CFG_MAX_PSDU, 2); - else - rt2x00_set_field32(®, MAX_LEN_CFG_MAX_PSDU, 1); -@@ -5167,6 +5175,11 @@ static int rt2800_init_registers(struct - reg = rt2x00_rt(rt2x00dev, RT5592) ? 0x00000082 : 0x00000002; - rt2800_register_write(rt2x00dev, TXOP_HLDR_ET, reg); - -+ if (rt2x00_rt(rt2x00dev, RT3883)) { -+ rt2800_register_write(rt2x00dev, TX_FBK_CFG_3S_0, 0x12111008); -+ rt2800_register_write(rt2x00dev, TX_FBK_CFG_3S_1, 0x16151413); -+ } -+ - rt2800_register_read(rt2x00dev, TX_RTS_CFG, ®); - rt2x00_set_field32(®, TX_RTS_CFG_AUTO_RTS_RETRY_LIMIT, 32); - rt2x00_set_field32(®, TX_RTS_CFG_RTS_THRES, diff --git a/package/kernel/mac80211/patches/600-0015-rt2x00-rt2800soc-fix-rt2800soc_disable_radio-for-RT3.patch b/package/kernel/mac80211/patches/600-0015-rt2x00-rt2800soc-fix-rt2800soc_disable_radio-for-RT3.patch deleted file mode 100644 index d68ad50447..0000000000 --- a/package/kernel/mac80211/patches/600-0015-rt2x00-rt2800soc-fix-rt2800soc_disable_radio-for-RT3.patch +++ /dev/null @@ -1,30 +0,0 @@ -From 6c2d32478159fffff0b85abb6817a21bb2338231 Mon Sep 17 00:00:00 2001 -From: Gabor Juhos -Date: Sun, 24 Mar 2013 19:26:27 +0100 -Subject: [PATCH] rt2x00: rt2800soc: fix rt2800soc_disable_radio for RT3883 - -Signed-off-by: Gabor Juhos ---- - drivers/net/wireless/ralink/rt2x00/rt2800soc.c | 9 ++++++++- - 1 file changed, 8 insertions(+), 1 deletion(-) - ---- a/drivers/net/wireless/ralink/rt2x00/rt2800soc.c -+++ b/drivers/net/wireless/ralink/rt2x00/rt2800soc.c -@@ -51,9 +51,16 @@ static bool rt2800soc_hwcrypt_disabled(s - - static void rt2800soc_disable_radio(struct rt2x00_dev *rt2x00dev) - { -+ u32 reg; -+ - rt2800_disable_radio(rt2x00dev); - rt2x00mmio_register_write(rt2x00dev, PWR_PIN_CFG, 0); -- rt2x00mmio_register_write(rt2x00dev, TX_PIN_CFG, 0); -+ -+ reg = 0; -+ if (rt2x00_rt(rt2x00dev, RT3883)) -+ rt2x00_set_field32(®, TX_PIN_CFG_RFTR_EN, 1); -+ -+ rt2x00mmio_register_write(rt2x00dev, TX_PIN_CFG, reg); - } - - static int rt2800soc_set_device_state(struct rt2x00_dev *rt2x00dev, diff --git a/package/kernel/mac80211/patches/600-0016-rt2x00-rt2800lib-add-BBP-register-initialization-for.patch b/package/kernel/mac80211/patches/600-0016-rt2x00-rt2800lib-add-BBP-register-initialization-for.patch deleted file mode 100644 index 953263226c..0000000000 --- a/package/kernel/mac80211/patches/600-0016-rt2x00-rt2800lib-add-BBP-register-initialization-for.patch +++ /dev/null @@ -1,71 +0,0 @@ -From 84833056aa7dd25f5b097e31c78f2a0914c5160c Mon Sep 17 00:00:00 2001 -From: Gabor Juhos -Date: Sun, 24 Mar 2013 19:26:26 +0100 -Subject: [PATCH] rt2x00: rt2800lib: add BBP register initialization for - RT3883 - -Signed-off-by: Gabor Juhos ---- - drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 44 +++++++++++++++++++++++++++++++ - 1 file changed, 44 insertions(+) - ---- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c -+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c -@@ -5785,6 +5785,47 @@ static void rt2800_init_bbp_3593(struct - rt2800_bbp_write(rt2x00dev, 103, 0xc0); - } - -+static void rt2800_init_bbp_3883(struct rt2x00_dev *rt2x00dev) -+{ -+ rt2800_init_bbp_early(rt2x00dev); -+ -+ rt2800_bbp_write(rt2x00dev, 4, 0x50); -+ rt2800_bbp_write(rt2x00dev, 47, 0x48); -+ -+ rt2800_bbp_write(rt2x00dev, 86, 0x46); -+ rt2800_bbp_write(rt2x00dev, 88, 0x90); -+ -+ rt2800_bbp_write(rt2x00dev, 92, 0x02); -+ -+ rt2800_bbp_write(rt2x00dev, 103, 0xc0); -+ rt2800_bbp_write(rt2x00dev, 104, 0x92); -+ rt2800_bbp_write(rt2x00dev, 105, 0x34); -+ rt2800_bbp_write(rt2x00dev, 106, 0x12); -+ rt2800_bbp_write(rt2x00dev, 120, 0x50); -+ rt2800_bbp_write(rt2x00dev, 137, 0x0f); -+ rt2800_bbp_write(rt2x00dev, 163, 0x9d); -+ -+ /* Set ITxBF timeout to 0x9C40=1000msec */ -+ rt2800_bbp_write(rt2x00dev, 179, 0x02); -+ rt2800_bbp_write(rt2x00dev, 180, 0x00); -+ rt2800_bbp_write(rt2x00dev, 182, 0x40); -+ rt2800_bbp_write(rt2x00dev, 180, 0x01); -+ rt2800_bbp_write(rt2x00dev, 182, 0x9c); -+ -+ rt2800_bbp_write(rt2x00dev, 179, 0x00); -+ -+ /* Reprogram the inband interface to put right values in RXWI */ -+ rt2800_bbp_write(rt2x00dev, 142, 0x04); -+ rt2800_bbp_write(rt2x00dev, 143, 0x3b); -+ rt2800_bbp_write(rt2x00dev, 142, 0x06); -+ rt2800_bbp_write(rt2x00dev, 143, 0xa0); -+ rt2800_bbp_write(rt2x00dev, 142, 0x07); -+ rt2800_bbp_write(rt2x00dev, 143, 0xa1); -+ rt2800_bbp_write(rt2x00dev, 142, 0x08); -+ rt2800_bbp_write(rt2x00dev, 143, 0xa2); -+ rt2800_bbp_write(rt2x00dev, 148, 0xc8); -+} -+ - static void rt2800_init_bbp_53xx(struct rt2x00_dev *rt2x00dev) - { - int ant, div_mode; -@@ -6003,6 +6044,9 @@ static void rt2800_init_bbp(struct rt2x0 - case RT3593: - rt2800_init_bbp_3593(rt2x00dev); - return; -+ case RT3883: -+ rt2800_init_bbp_3883(rt2x00dev); -+ return; - case RT5390: - case RT5392: - rt2800_init_bbp_53xx(rt2x00dev); diff --git a/package/kernel/mac80211/patches/600-0017-rt2x00-rt2800lib-add-RFCSR-initialization-for-RT3883.patch b/package/kernel/mac80211/patches/600-0017-rt2x00-rt2800lib-add-RFCSR-initialization-for-RT3883.patch deleted file mode 100644 index 936fa35a00..0000000000 --- a/package/kernel/mac80211/patches/600-0017-rt2x00-rt2800lib-add-RFCSR-initialization-for-RT3883.patch +++ /dev/null @@ -1,178 +0,0 @@ -From 99c659cf345640fd0f733cbcaf4583cc2c868ec0 Mon Sep 17 00:00:00 2001 -From: Gabor Juhos -Date: Mon, 29 Apr 2013 13:21:48 +0200 -Subject: [PATCH] rt2x00: rt2800lib: add RFCSR initialization for RT3883 - -Signed-off-by: Gabor Juhos ---- - drivers/net/wireless/ralink/rt2x00/rt2800.h | 1 + - drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 141 +++++++++++++++++++++++++++++++ - 2 files changed, 142 insertions(+) - ---- a/drivers/net/wireless/ralink/rt2x00/rt2800.h -+++ b/drivers/net/wireless/ralink/rt2x00/rt2800.h -@@ -2171,6 +2171,7 @@ struct mac_iveiv_entry { - /* - * RFCSR 2: - */ -+#define RFCSR2_RESCAL_BP FIELD8(0x40) - #define RFCSR2_RESCAL_EN FIELD8(0x80) - - /* ---- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c -+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c -@@ -6820,6 +6820,144 @@ static void rt2800_init_rfcsr_3593(struc - /* TODO: enable stream mode support */ - } - -+static void rt2800_init_rfcsr_3883(struct rt2x00_dev *rt2x00dev) -+{ -+ u8 rfcsr; -+ -+ /* TODO: get the actual ECO value from the SoC */ -+ const unsigned int eco = 5; -+ -+ rt2800_rf_init_calibration(rt2x00dev, 2); -+ -+ rt2800_rfcsr_write(rt2x00dev, 0, 0xe0); -+ rt2800_rfcsr_write(rt2x00dev, 1, 0x03); -+ rt2800_rfcsr_write(rt2x00dev, 2, 0x50); -+ rt2800_rfcsr_write(rt2x00dev, 3, 0x20); -+ rt2800_rfcsr_write(rt2x00dev, 4, 0x00); -+ rt2800_rfcsr_write(rt2x00dev, 5, 0x00); -+ rt2800_rfcsr_write(rt2x00dev, 6, 0x40); -+ rt2800_rfcsr_write(rt2x00dev, 7, 0x00); -+ rt2800_rfcsr_write(rt2x00dev, 8, 0x5b); -+ rt2800_rfcsr_write(rt2x00dev, 9, 0x08); -+ rt2800_rfcsr_write(rt2x00dev, 10, 0xd3); -+ rt2800_rfcsr_write(rt2x00dev, 11, 0x48); -+ rt2800_rfcsr_write(rt2x00dev, 12, 0x1a); -+ rt2800_rfcsr_write(rt2x00dev, 13, 0x12); -+ rt2800_rfcsr_write(rt2x00dev, 14, 0x00); -+ rt2800_rfcsr_write(rt2x00dev, 15, 0x00); -+ rt2800_rfcsr_write(rt2x00dev, 16, 0x00); -+ -+ /* RFCSR 17 will be initialized later based on the -+ * frequency offset stored in the EEPROM -+ */ -+ -+ rt2800_rfcsr_write(rt2x00dev, 18, 0x40); -+ rt2800_rfcsr_write(rt2x00dev, 19, 0x00); -+ rt2800_rfcsr_write(rt2x00dev, 20, 0x00); -+ rt2800_rfcsr_write(rt2x00dev, 21, 0x00); -+ rt2800_rfcsr_write(rt2x00dev, 22, 0x20); -+ rt2800_rfcsr_write(rt2x00dev, 23, 0xc0); -+ rt2800_rfcsr_write(rt2x00dev, 24, 0x00); -+ rt2800_rfcsr_write(rt2x00dev, 25, 0x00); -+ rt2800_rfcsr_write(rt2x00dev, 26, 0x00); -+ rt2800_rfcsr_write(rt2x00dev, 27, 0x00); -+ rt2800_rfcsr_write(rt2x00dev, 28, 0x00); -+ rt2800_rfcsr_write(rt2x00dev, 29, 0x00); -+ rt2800_rfcsr_write(rt2x00dev, 30, 0x10); -+ rt2800_rfcsr_write(rt2x00dev, 31, 0x80); -+ rt2800_rfcsr_write(rt2x00dev, 32, 0x80); -+ rt2800_rfcsr_write(rt2x00dev, 33, 0x00); -+ rt2800_rfcsr_write(rt2x00dev, 34, 0x20); -+ rt2800_rfcsr_write(rt2x00dev, 35, 0x00); -+ rt2800_rfcsr_write(rt2x00dev, 36, 0x00); -+ rt2800_rfcsr_write(rt2x00dev, 37, 0x00); -+ rt2800_rfcsr_write(rt2x00dev, 38, 0x86); -+ rt2800_rfcsr_write(rt2x00dev, 39, 0x23); -+ rt2800_rfcsr_write(rt2x00dev, 40, 0x00); -+ rt2800_rfcsr_write(rt2x00dev, 41, 0x00); -+ rt2800_rfcsr_write(rt2x00dev, 42, 0x00); -+ rt2800_rfcsr_write(rt2x00dev, 43, 0x00); -+ rt2800_rfcsr_write(rt2x00dev, 44, 0x93); -+ rt2800_rfcsr_write(rt2x00dev, 45, 0xbb); -+ rt2800_rfcsr_write(rt2x00dev, 46, 0x60); -+ rt2800_rfcsr_write(rt2x00dev, 47, 0x00); -+ rt2800_rfcsr_write(rt2x00dev, 48, 0x00); -+ rt2800_rfcsr_write(rt2x00dev, 49, 0x8e); -+ rt2800_rfcsr_write(rt2x00dev, 50, 0x86); -+ rt2800_rfcsr_write(rt2x00dev, 51, 0x51); -+ rt2800_rfcsr_write(rt2x00dev, 52, 0x05); -+ rt2800_rfcsr_write(rt2x00dev, 53, 0x76); -+ rt2800_rfcsr_write(rt2x00dev, 54, 0x76); -+ rt2800_rfcsr_write(rt2x00dev, 55, 0x76); -+ rt2800_rfcsr_write(rt2x00dev, 56, 0xdb); -+ rt2800_rfcsr_write(rt2x00dev, 57, 0x3e); -+ rt2800_rfcsr_write(rt2x00dev, 58, 0x00); -+ rt2800_rfcsr_write(rt2x00dev, 59, 0x00); -+ rt2800_rfcsr_write(rt2x00dev, 60, 0x00); -+ rt2800_rfcsr_write(rt2x00dev, 61, 0x00); -+ rt2800_rfcsr_write(rt2x00dev, 62, 0x00); -+ rt2800_rfcsr_write(rt2x00dev, 63, 0x00); -+ -+ /* TODO: rx filter calibration? */ -+ -+ rt2800_bbp_write(rt2x00dev, 137, 0x0f); -+ -+ rt2800_bbp_write(rt2x00dev, 163, 0x9d); -+ -+ rt2800_bbp_write(rt2x00dev, 105, 0x05); -+ -+ rt2800_bbp_write(rt2x00dev, 179, 0x02); -+ rt2800_bbp_write(rt2x00dev, 180, 0x00); -+ rt2800_bbp_write(rt2x00dev, 182, 0x40); -+ rt2800_bbp_write(rt2x00dev, 180, 0x01); -+ rt2800_bbp_write(rt2x00dev, 182, 0x9c); -+ -+ rt2800_bbp_write(rt2x00dev, 179, 0x00); -+ -+ rt2800_bbp_write(rt2x00dev, 142, 0x04); -+ rt2800_bbp_write(rt2x00dev, 143, 0x3b); -+ rt2800_bbp_write(rt2x00dev, 142, 0x06); -+ rt2800_bbp_write(rt2x00dev, 143, 0xa0); -+ rt2800_bbp_write(rt2x00dev, 142, 0x07); -+ rt2800_bbp_write(rt2x00dev, 143, 0xa1); -+ rt2800_bbp_write(rt2x00dev, 142, 0x08); -+ rt2800_bbp_write(rt2x00dev, 143, 0xa2); -+ rt2800_bbp_write(rt2x00dev, 148, 0xc8); -+ -+ if (eco == 5) { -+ rt2800_rfcsr_write(rt2x00dev, 32, 0xd8); -+ rt2800_rfcsr_write(rt2x00dev, 33, 0x32); -+ } -+ -+ rt2800_rfcsr_read(rt2x00dev, 2, &rfcsr); -+ rt2x00_set_field8(&rfcsr, RFCSR2_RESCAL_BP, 0); -+ rt2x00_set_field8(&rfcsr, RFCSR2_RESCAL_EN, 1); -+ rt2800_rfcsr_write(rt2x00dev, 2, rfcsr); -+ msleep(1); -+ rt2x00_set_field8(&rfcsr, RFCSR2_RESCAL_EN, 0); -+ rt2800_rfcsr_write(rt2x00dev, 2, rfcsr); -+ -+ rt2800_rfcsr_read(rt2x00dev, 1, &rfcsr); -+ rt2x00_set_field8(&rfcsr, RFCSR1_RF_BLOCK_EN, 1); -+ rt2800_rfcsr_write(rt2x00dev, 1, rfcsr); -+ -+ rt2800_rfcsr_read(rt2x00dev, 6, &rfcsr); -+ rfcsr |= 0xc0; -+ rt2800_rfcsr_write(rt2x00dev, 6, rfcsr); -+ -+ rt2800_rfcsr_read(rt2x00dev, 22, &rfcsr); -+ rfcsr |= 0x20; -+ rt2800_rfcsr_write(rt2x00dev, 22, rfcsr); -+ -+ rt2800_rfcsr_read(rt2x00dev, 46, &rfcsr); -+ rfcsr |= 0x20; -+ rt2800_rfcsr_write(rt2x00dev, 46, rfcsr); -+ -+ rt2800_rfcsr_read(rt2x00dev, 20, &rfcsr); -+ rfcsr &= ~0xee; -+ rt2800_rfcsr_write(rt2x00dev, 20, rfcsr); -+} -+ - static void rt2800_init_rfcsr_5390(struct rt2x00_dev *rt2x00dev) - { - rt2800_rf_init_calibration(rt2x00dev, 2); -@@ -7051,6 +7189,9 @@ static void rt2800_init_rfcsr(struct rt2 - case RT3390: - rt2800_init_rfcsr_3390(rt2x00dev); - break; -+ case RT3883: -+ rt2800_init_rfcsr_3883(rt2x00dev); -+ break; - case RT3572: - rt2800_init_rfcsr_3572(rt2x00dev); - break; diff --git a/package/kernel/mac80211/patches/600-0018-rt2x00-rt2800lib-use-the-extended-EEPROM-map-for-RT3.patch b/package/kernel/mac80211/patches/600-0018-rt2x00-rt2800lib-use-the-extended-EEPROM-map-for-RT3.patch deleted file mode 100644 index ae899f73be..0000000000 --- a/package/kernel/mac80211/patches/600-0018-rt2x00-rt2800lib-use-the-extended-EEPROM-map-for-RT3.patch +++ /dev/null @@ -1,22 +0,0 @@ -From 86022438ffeb1b87dfcd018bf477fdbb43076691 Mon Sep 17 00:00:00 2001 -From: Gabor Juhos -Date: Wed, 8 May 2013 19:35:33 +0200 -Subject: [PATCH] rt2x00: rt2800lib: use the extended EEPROM map for RT3883 - -Signed-off-by: Gabor Juhos ---- - drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - ---- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c -+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c -@@ -342,7 +342,8 @@ static unsigned int rt2800_eeprom_word_i - wiphy_name(rt2x00dev->hw->wiphy), word)) - return 0; - -- if (rt2x00_rt(rt2x00dev, RT3593)) -+ if (rt2x00_rt(rt2x00dev, RT3593) || -+ rt2x00_rt(rt2x00dev, RT3883)) - map = rt2800_eeprom_map_ext; - else - map = rt2800_eeprom_map; diff --git a/package/kernel/mac80211/patches/600-0019-rt2x00-rt2800lib-force-rf-type-to-RF3853-on-RT3883.patch b/package/kernel/mac80211/patches/600-0019-rt2x00-rt2800lib-force-rf-type-to-RF3853-on-RT3883.patch deleted file mode 100644 index bcaf67677d..0000000000 --- a/package/kernel/mac80211/patches/600-0019-rt2x00-rt2800lib-force-rf-type-to-RF3853-on-RT3883.patch +++ /dev/null @@ -1,21 +0,0 @@ -From 4cf5403f02fa65dc2207f61d223cffa9ae50e907 Mon Sep 17 00:00:00 2001 -From: Gabor Juhos -Date: Thu, 1 Aug 2013 14:48:21 +0200 -Subject: [PATCH] rt2x00: rt2800lib: force rf type to RF3853 on RT3883 - -Signed-off-by: Gabor Juhos ---- - drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 2 ++ - 1 file changed, 2 insertions(+) - ---- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c -+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c -@@ -7588,6 +7588,8 @@ static int rt2800_init_eeprom(struct rt2 - rt2x00_rt(rt2x00dev, RT5390) || - rt2x00_rt(rt2x00dev, RT5392)) - rt2800_eeprom_read(rt2x00dev, EEPROM_CHIP_ID, &rf); -+ else if (rt2x00_rt(rt2x00dev, RT3883)) -+ rf = RF3853; - else - rf = rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_RF_TYPE); - diff --git a/package/kernel/mac80211/patches/600-0020-rt2x00-rt2800lib-add-channel-configuration-code-for-.patch b/package/kernel/mac80211/patches/600-0020-rt2x00-rt2800lib-add-channel-configuration-code-for-.patch deleted file mode 100644 index 3169c1048d..0000000000 --- a/package/kernel/mac80211/patches/600-0020-rt2x00-rt2800lib-add-channel-configuration-code-for-.patch +++ /dev/null @@ -1,136 +0,0 @@ -From 269f19c848a2380db03a3f207cafb88e28d71c53 Mon Sep 17 00:00:00 2001 -From: Gabor Juhos -Date: Sun, 24 Mar 2013 19:26:28 +0100 -Subject: [PATCH] rt2x00: rt2800lib: add channel configuration code for RT3883 - -Signed-off-by: Gabor Juhos ---- - drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 72 +++++++++++++++++++++++++++++-- - 1 file changed, 69 insertions(+), 3 deletions(-) - ---- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c -+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c -@@ -3406,6 +3406,36 @@ static char rt2800_txpower_to_dev(struct - return clamp_t(char, txpower, MIN_A_TXPOWER, MAX_A_TXPOWER); - } - -+static void rt3883_bbp_adjust(struct rt2x00_dev *rt2x00dev, -+ struct rf_channel *rf) -+{ -+ u8 bbp; -+ -+ bbp = (rf->channel > 14) ? 0x48 : 0x38; -+ rt2800_bbp_write_with_rx_chain(rt2x00dev, 66, bbp); -+ -+ rt2800_bbp_write(rt2x00dev, 69, 0x12); -+ -+ if (rf->channel <= 14) { -+ rt2800_bbp_write(rt2x00dev, 70, 0x0a); -+ } else { -+ /* Disable CCK packet detection */ -+ rt2800_bbp_write(rt2x00dev, 70, 0x00); -+ } -+ -+ rt2800_bbp_write(rt2x00dev, 73, 0x10); -+ -+ if (rf->channel > 14) { -+ rt2800_bbp_write(rt2x00dev, 62, 0x1d); -+ rt2800_bbp_write(rt2x00dev, 63, 0x1d); -+ rt2800_bbp_write(rt2x00dev, 64, 0x1d); -+ } else { -+ rt2800_bbp_write(rt2x00dev, 62, 0x2d); -+ rt2800_bbp_write(rt2x00dev, 63, 0x2d); -+ rt2800_bbp_write(rt2x00dev, 64, 0x2d); -+ } -+} -+ - static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev, - struct ieee80211_conf *conf, - struct rf_channel *rf, -@@ -3424,6 +3454,12 @@ static void rt2800_config_channel(struct - rt2800_txpower_to_dev(rt2x00dev, rf->channel, - info->default_power3); - -+ switch (rt2x00dev->chip.rt) { -+ case RT3883: -+ rt3883_bbp_adjust(rt2x00dev, rf); -+ break; -+ } -+ - switch (rt2x00dev->chip.rf) { - case RF2020: - case RF3020: -@@ -3507,6 +3543,15 @@ static void rt2800_config_channel(struct - rt2800_bbp_write(rt2x00dev, 63, 0x37 - rt2x00dev->lna_gain); - rt2800_bbp_write(rt2x00dev, 64, 0x37 - rt2x00dev->lna_gain); - rt2800_bbp_write(rt2x00dev, 77, 0x98); -+ } else if (rt2x00_rt(rt2x00dev, RT3883)) { -+ rt2800_bbp_write(rt2x00dev, 62, 0x37 - rt2x00dev->lna_gain); -+ rt2800_bbp_write(rt2x00dev, 63, 0x37 - rt2x00dev->lna_gain); -+ rt2800_bbp_write(rt2x00dev, 64, 0x37 - rt2x00dev->lna_gain); -+ -+ if (rt2x00dev->default_ant.rx_chain_num > 1) -+ rt2800_bbp_write(rt2x00dev, 86, 0x46); -+ else -+ rt2800_bbp_write(rt2x00dev, 86, 0); - } else { - rt2800_bbp_write(rt2x00dev, 62, 0x37 - rt2x00dev->lna_gain); - rt2800_bbp_write(rt2x00dev, 63, 0x37 - rt2x00dev->lna_gain); -@@ -3519,6 +3564,7 @@ static void rt2800_config_channel(struct - !rt2x00_rt(rt2x00dev, RT5392)) { - if (rt2x00_has_cap_external_lna_bg(rt2x00dev)) { - rt2800_bbp_write(rt2x00dev, 82, 0x62); -+ rt2800_bbp_write(rt2x00dev, 82, 0x62); - rt2800_bbp_write(rt2x00dev, 75, 0x46); - } else { - if (rt2x00_rt(rt2x00dev, RT3593)) -@@ -3527,19 +3573,22 @@ static void rt2800_config_channel(struct - rt2800_bbp_write(rt2x00dev, 82, 0x84); - rt2800_bbp_write(rt2x00dev, 75, 0x50); - } -- if (rt2x00_rt(rt2x00dev, RT3593)) -+ if (rt2x00_rt(rt2x00dev, RT3593) || -+ rt2x00_rt(rt2x00dev, RT3883)) - rt2800_bbp_write(rt2x00dev, 83, 0x8a); - } - - } else { - if (rt2x00_rt(rt2x00dev, RT3572)) - rt2800_bbp_write(rt2x00dev, 82, 0x94); -- else if (rt2x00_rt(rt2x00dev, RT3593)) -+ else if (rt2x00_rt(rt2x00dev, RT3593) || -+ rt2x00_rt(rt2x00dev, RT3883)) - rt2800_bbp_write(rt2x00dev, 82, 0x82); - else - rt2800_bbp_write(rt2x00dev, 82, 0xf2); - -- if (rt2x00_rt(rt2x00dev, RT3593)) -+ if (rt2x00_rt(rt2x00dev, RT3593) || -+ rt2x00_rt(rt2x00dev, RT3883)) - rt2800_bbp_write(rt2x00dev, 83, 0x9a); - - if (rt2x00_has_cap_external_lna_a(rt2x00dev)) -@@ -3661,6 +3710,23 @@ static void rt2800_config_channel(struct - - rt2800_bbp_write_with_rx_chain(rt2x00dev, 66, reg); - -+ usleep_range(1000, 1500); -+ } -+ -+ if (rt2x00_rt(rt2x00dev, RT3883)) { -+ if (!conf_is_ht40(conf)) -+ rt2800_bbp_write(rt2x00dev, 105, 0x34); -+ else -+ rt2800_bbp_write(rt2x00dev, 105, 0x04); -+ -+ /* AGC init */ -+ if (rf->channel <= 14) -+ reg = 0x2e + rt2x00dev->lna_gain; -+ else -+ reg = 0x20 + ((rt2x00dev->lna_gain * 5) / 3); -+ -+ rt2800_bbp_write_with_rx_chain(rt2x00dev, 66, reg); -+ - usleep_range(1000, 1500); - } - diff --git a/package/kernel/mac80211/patches/600-0021-rt2x00-rt2800lib-fix-txpower_to_dev-function-for-RT3.patch b/package/kernel/mac80211/patches/600-0021-rt2x00-rt2800lib-fix-txpower_to_dev-function-for-RT3.patch deleted file mode 100644 index fa646d2faf..0000000000 --- a/package/kernel/mac80211/patches/600-0021-rt2x00-rt2800lib-fix-txpower_to_dev-function-for-RT3.patch +++ /dev/null @@ -1,30 +0,0 @@ -From e37d93abaabe3ab72b0332a18092acc162307274 Mon Sep 17 00:00:00 2001 -From: Gabor Juhos -Date: Mon, 30 Sep 2013 13:57:26 +0200 -Subject: [PATCH] rt2x00: rt2800lib: fix txpower_to_dev function for RT3883 - -Signed-off-by: Gabor Juhos ---- - drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 6 ++++-- - 1 file changed, 4 insertions(+), 2 deletions(-) - ---- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c -+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c -@@ -3393,13 +3393,15 @@ static char rt2800_txpower_to_dev(struct - unsigned int channel, - char txpower) - { -- if (rt2x00_rt(rt2x00dev, RT3593)) -+ if (rt2x00_rt(rt2x00dev, RT3593) || -+ rt2x00_rt(rt2x00dev, RT3883)) - txpower = rt2x00_get_field8(txpower, EEPROM_TXPOWER_ALC); - - if (channel <= 14) - return clamp_t(char, txpower, MIN_G_TXPOWER, MAX_G_TXPOWER); - -- if (rt2x00_rt(rt2x00dev, RT3593)) -+ if (rt2x00_rt(rt2x00dev, RT3593) || -+ rt2x00_rt(rt2x00dev, RT3883)) - return clamp_t(char, txpower, MIN_A_TXPOWER_3593, - MAX_A_TXPOWER_3593); - else diff --git a/package/kernel/mac80211/patches/600-0022-rt2x00-rt2800lib-use-correct-txpower-calculation-fun.patch b/package/kernel/mac80211/patches/600-0022-rt2x00-rt2800lib-use-correct-txpower-calculation-fun.patch deleted file mode 100644 index c06876906b..0000000000 --- a/package/kernel/mac80211/patches/600-0022-rt2x00-rt2800lib-use-correct-txpower-calculation-fun.patch +++ /dev/null @@ -1,23 +0,0 @@ -From c4d79e344bd580d85821390d49f92dced7d8e125 Mon Sep 17 00:00:00 2001 -From: Gabor Juhos -Date: Sun, 24 Mar 2013 19:26:29 +0100 -Subject: [PATCH] rt2x00: rt2800lib: use correct txpower calculation function - for RT3883 - -Signed-off-by: Gabor Juhos ---- - drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - ---- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c -+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c -@@ -4612,7 +4612,8 @@ static void rt2800_config_txpower(struct - struct ieee80211_channel *chan, - int power_level) - { -- if (rt2x00_rt(rt2x00dev, RT3593)) -+ if (rt2x00_rt(rt2x00dev, RT3593) || -+ rt2x00_rt(rt2x00dev, RT3883)) - rt2800_config_txpower_rt3593(rt2x00dev, chan, power_level); - else - rt2800_config_txpower_rt28xx(rt2x00dev, chan, power_level); diff --git a/package/kernel/mac80211/patches/600-0023-rt2x00-rt2800lib-hardcode-txmixer-gain-values-to-zer.patch b/package/kernel/mac80211/patches/600-0023-rt2x00-rt2800lib-hardcode-txmixer-gain-values-to-zer.patch deleted file mode 100644 index 74d80ded1d..0000000000 --- a/package/kernel/mac80211/patches/600-0023-rt2x00-rt2800lib-hardcode-txmixer-gain-values-to-zer.patch +++ /dev/null @@ -1,33 +0,0 @@ -From caea0671cd8fd9ade4f5969cbe0ee545e94ae105 Mon Sep 17 00:00:00 2001 -From: Gabor Juhos -Date: Sat, 24 Aug 2013 11:49:55 +0200 -Subject: [PATCH] rt2x00: rt2800lib: hardcode txmixer gain values to zero for - RT3883 - -Signed-off-by: Gabor Juhos ---- - drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 6 ++++-- - 1 file changed, 4 insertions(+), 2 deletions(-) - ---- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c -+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c -@@ -7470,7 +7470,8 @@ static u8 rt2800_get_txmixer_gain_24g(st - { - u16 word; - -- if (rt2x00_rt(rt2x00dev, RT3593)) -+ if (rt2x00_rt(rt2x00dev, RT3593) || -+ rt2x00_rt(rt2x00dev, RT3883)) - return 0; - - rt2800_eeprom_read(rt2x00dev, EEPROM_TXMIXER_GAIN_BG, &word); -@@ -7484,7 +7485,8 @@ static u8 rt2800_get_txmixer_gain_5g(str - { - u16 word; - -- if (rt2x00_rt(rt2x00dev, RT3593)) -+ if (rt2x00_rt(rt2x00dev, RT3593) || -+ rt2x00_rt(rt2x00dev, RT3883)) - return 0; - - rt2800_eeprom_read(rt2x00dev, EEPROM_TXMIXER_GAIN_A, &word); diff --git a/package/kernel/mac80211/patches/600-0024-rt2x00-rt2800lib-use-correct-RT-XWI-size-for-RT3883.patch b/package/kernel/mac80211/patches/600-0024-rt2x00-rt2800lib-use-correct-RT-XWI-size-for-RT3883.patch deleted file mode 100644 index 125928642f..0000000000 --- a/package/kernel/mac80211/patches/600-0024-rt2x00-rt2800lib-use-correct-RT-XWI-size-for-RT3883.patch +++ /dev/null @@ -1,20 +0,0 @@ -From 11c40fb47c4a4dd6ad060c2ae127ced89ffb9fe1 Mon Sep 17 00:00:00 2001 -From: Gabor Juhos -Date: Thu, 18 Apr 2013 14:33:33 +0200 -Subject: [PATCH] rt2x00: rt2800lib: use correct [RT]XWI size for RT3883 - -Signed-off-by: Gabor Juhos ---- - drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 1 + - 1 file changed, 1 insertion(+) - ---- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c -+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c -@@ -558,6 +558,7 @@ void rt2800_get_txwi_rxwi_size(struct rt - { - switch (rt2x00dev->chip.rt) { - case RT3593: -+ case RT3883: - *txwi_size = TXWI_DESC_SIZE_4WORDS; - *rxwi_size = RXWI_DESC_SIZE_5WORDS; - break; diff --git a/package/kernel/mac80211/patches/600-0025-rt2x00-rt2800lib-use-correct-beacon-base-for-RT3883.patch b/package/kernel/mac80211/patches/600-0025-rt2x00-rt2800lib-use-correct-beacon-base-for-RT3883.patch deleted file mode 100644 index 0dcc027ffc..0000000000 --- a/package/kernel/mac80211/patches/600-0025-rt2x00-rt2800lib-use-correct-beacon-base-for-RT3883.patch +++ /dev/null @@ -1,22 +0,0 @@ -From b403bdfa00665ce6b53583bdb837ffad0b91c09f Mon Sep 17 00:00:00 2001 -From: Gabor Juhos -Date: Sun, 24 Mar 2013 19:26:29 +0100 -Subject: [PATCH] rt2x00: rt2800lib: use correct beacon base for RT3883 - -Signed-off-by: Gabor Juhos ---- - drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - ---- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c -+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c -@@ -983,7 +983,8 @@ EXPORT_SYMBOL_GPL(rt2800_txdone_entry); - static unsigned int rt2800_hw_beacon_base(struct rt2x00_dev *rt2x00dev, - unsigned int index) - { -- if (rt2x00_rt(rt2x00dev, RT3593)) -+ if (rt2x00_rt(rt2x00dev, RT3593) || -+ rt2x00_rt(rt2x00dev, RT3883)) - return HW_BEACON_BASE_HIGH(index); - - return HW_BEACON_BASE(index); diff --git a/package/kernel/mac80211/patches/600-0026-rt2x00-rt2800lib-use-correct-beacon-count-for-RT3883.patch b/package/kernel/mac80211/patches/600-0026-rt2x00-rt2800lib-use-correct-beacon-count-for-RT3883.patch deleted file mode 100644 index 220e35fe4c..0000000000 --- a/package/kernel/mac80211/patches/600-0026-rt2x00-rt2800lib-use-correct-beacon-count-for-RT3883.patch +++ /dev/null @@ -1,22 +0,0 @@ -From 74b7eaf75fc6eb86292056ef705e543f9cd6086b Mon Sep 17 00:00:00 2001 -From: Gabor Juhos -Date: Sun, 18 Aug 2013 09:57:58 +0200 -Subject: [PATCH] rt2x00: rt2800lib: use correct beacon count for RT3883 - -Signed-off-by: Gabor Juhos ---- - drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - ---- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c -+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c -@@ -8407,7 +8407,8 @@ int rt2800_probe_hw(struct rt2x00_dev *r - if (rt2x00_rt(rt2x00dev, RT3593)) - __set_bit(RT2800_HAS_HIGH_SHARED_MEM, &drv_data->rt2800_flags); - -- if (rt2x00_rt(rt2x00dev, RT3593)) -+ if (rt2x00_rt(rt2x00dev, RT3593) || -+ rt2x00_rt(rt2x00dev, RT3883)) - drv_data->hw_beacon_count = 16; - else - drv_data->hw_beacon_count = 8; diff --git a/package/kernel/mac80211/patches/600-0027-rt2x00-rt2800lib-fix-antenna-configuration-for-RT388.patch b/package/kernel/mac80211/patches/600-0027-rt2x00-rt2800lib-fix-antenna-configuration-for-RT388.patch deleted file mode 100644 index 39363685f4..0000000000 --- a/package/kernel/mac80211/patches/600-0027-rt2x00-rt2800lib-fix-antenna-configuration-for-RT388.patch +++ /dev/null @@ -1,22 +0,0 @@ -From fa5ad9c025610c22048add2f0ad03f62b6ca1e74 Mon Sep 17 00:00:00 2001 -From: Gabor Juhos -Date: Mon, 30 Sep 2013 16:53:33 +0200 -Subject: [PATCH] rt2x00: rt2800lib: fix antenna configuration for RT3883 - -Signed-off-by: Gabor Juhos ---- - drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - ---- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c -+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c -@@ -1938,7 +1938,8 @@ void rt2800_config_ant(struct rt2x00_dev - rt2800_bbp_write(rt2x00dev, 3, r3); - rt2800_bbp_write(rt2x00dev, 1, r1); - -- if (rt2x00_rt(rt2x00dev, RT3593)) { -+ if (rt2x00_rt(rt2x00dev, RT3593) || -+ rt2x00_rt(rt2x00dev, RT3883)) { - if (ant->rx_chain_num == 1) - rt2800_bbp_write(rt2x00dev, 86, 0x00); - else diff --git a/package/kernel/mac80211/patches/600-0028-rt2x00-rt2800lib-fix-LNA-gain-configuration-for-RT38.patch b/package/kernel/mac80211/patches/600-0028-rt2x00-rt2800lib-fix-LNA-gain-configuration-for-RT38.patch deleted file mode 100644 index f0285874da..0000000000 --- a/package/kernel/mac80211/patches/600-0028-rt2x00-rt2800lib-fix-LNA-gain-configuration-for-RT38.patch +++ /dev/null @@ -1,32 +0,0 @@ -From 6d668fef3a1baa60bdd715ee062ddb6333d2647c Mon Sep 17 00:00:00 2001 -From: Gabor Juhos -Date: Mon, 30 Sep 2013 16:58:23 +0200 -Subject: [PATCH] rt2x00: rt2800lib: fix LNA gain configuration for RT3883 - -Signed-off-by: Gabor Juhos ---- - drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 6 ++++-- - 1 file changed, 4 insertions(+), 2 deletions(-) - ---- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c -+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c -@@ -1961,7 +1961,8 @@ static void rt2800_config_lna_gain(struc - rt2800_eeprom_read(rt2x00dev, EEPROM_LNA, &eeprom); - lna_gain = rt2x00_get_field16(eeprom, EEPROM_LNA_A0); - } else if (libconf->rf.channel <= 128) { -- if (rt2x00_rt(rt2x00dev, RT3593)) { -+ if (rt2x00_rt(rt2x00dev, RT3593) || -+ rt2x00_rt(rt2x00dev, RT3883)) { - rt2800_eeprom_read(rt2x00dev, EEPROM_EXT_LNA2, &eeprom); - lna_gain = rt2x00_get_field16(eeprom, - EEPROM_EXT_LNA2_A1); -@@ -1971,7 +1972,8 @@ static void rt2800_config_lna_gain(struc - EEPROM_RSSI_BG2_LNA_A1); - } - } else { -- if (rt2x00_rt(rt2x00dev, RT3593)) { -+ if (rt2x00_rt(rt2x00dev, RT3593) || -+ rt2x00_rt(rt2x00dev, RT3883)) { - rt2800_eeprom_read(rt2x00dev, EEPROM_EXT_LNA2, &eeprom); - lna_gain = rt2x00_get_field16(eeprom, - EEPROM_EXT_LNA2_A2); diff --git a/package/kernel/mac80211/patches/600-0029-rt2x00-rt2800lib-fix-VGC-setup-for-RT3883.patch b/package/kernel/mac80211/patches/600-0029-rt2x00-rt2800lib-fix-VGC-setup-for-RT3883.patch deleted file mode 100644 index ab8c625c13..0000000000 --- a/package/kernel/mac80211/patches/600-0029-rt2x00-rt2800lib-fix-VGC-setup-for-RT3883.patch +++ /dev/null @@ -1,44 +0,0 @@ -From c49b2d829aa1c816a46a577cdec6d2ff14d9f06e Mon Sep 17 00:00:00 2001 -From: Gabor Juhos -Date: Tue, 1 Oct 2013 15:40:08 +0200 -Subject: [PATCH] rt2x00: rt2800lib: fix VGC setup for RT3883 - -Signed-off-by: Gabor Juhos ---- - drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 11 +++++++++-- - 1 file changed, 9 insertions(+), 2 deletions(-) - ---- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c -+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c -@@ -4812,7 +4812,8 @@ static u8 rt2800_get_default_vgc(struct - else - vgc = 0x2e + rt2x00dev->lna_gain; - } else { /* 5GHZ band */ -- if (rt2x00_rt(rt2x00dev, RT3593)) -+ if (rt2x00_rt(rt2x00dev, RT3593) || -+ rt2x00_rt(rt2x00dev, RT3883)) - vgc = 0x20 + (rt2x00dev->lna_gain * 5) / 3; - else if (rt2x00_rt(rt2x00dev, RT5592)) - vgc = 0x24 + (2 * rt2x00dev->lna_gain); -@@ -4832,7 +4833,8 @@ static inline void rt2800_set_vgc(struct - { - if (qual->vgc_level != vgc_level) { - if (rt2x00_rt(rt2x00dev, RT3572) || -- rt2x00_rt(rt2x00dev, RT3593)) { -+ rt2x00_rt(rt2x00dev, RT3593) || -+ rt2x00_rt(rt2x00dev, RT3883)) { - rt2800_bbp_write_with_rx_chain(rt2x00dev, 66, - vgc_level); - } else if (rt2x00_rt(rt2x00dev, RT5592)) { -@@ -4879,6 +4881,11 @@ void rt2800_link_tuner(struct rt2x00_dev - } - break; - -+ case RT3883: -+ if (qual->rssi > -65) -+ vgc += 0x10; -+ break; -+ - case RT5592: - if (qual->rssi > -65) - vgc += 0x20; diff --git a/package/kernel/mac80211/patches/600-0030-rt2x00-rt2800lib-fix-EEPROM-LNA-validation-for-RT388.patch b/package/kernel/mac80211/patches/600-0030-rt2x00-rt2800lib-fix-EEPROM-LNA-validation-for-RT388.patch deleted file mode 100644 index 49830a12f5..0000000000 --- a/package/kernel/mac80211/patches/600-0030-rt2x00-rt2800lib-fix-EEPROM-LNA-validation-for-RT388.patch +++ /dev/null @@ -1,42 +0,0 @@ -From 1616650aea676541d4dc8adc6f4219856d193c8b Mon Sep 17 00:00:00 2001 -From: Gabor Juhos -Date: Tue, 1 Oct 2013 17:27:57 +0200 -Subject: [PATCH] rt2x00: rt2800lib: fix EEPROM LNA validation for RT3883 - -Signed-off-by: Gabor Juhos ---- - drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 9 ++++++--- - 1 file changed, 6 insertions(+), 3 deletions(-) - ---- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c -+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c -@@ -7607,7 +7607,8 @@ static int rt2800_validate_eeprom(struct - rt2800_eeprom_read(rt2x00dev, EEPROM_RSSI_BG2, &word); - if (abs(rt2x00_get_field16(word, EEPROM_RSSI_BG2_OFFSET2)) > 10) - rt2x00_set_field16(&word, EEPROM_RSSI_BG2_OFFSET2, 0); -- if (!rt2x00_rt(rt2x00dev, RT3593)) { -+ if (!rt2x00_rt(rt2x00dev, RT3593) && -+ !rt2x00_rt(rt2x00dev, RT3883)) { - if (rt2x00_get_field16(word, EEPROM_RSSI_BG2_LNA_A1) == 0x00 || - rt2x00_get_field16(word, EEPROM_RSSI_BG2_LNA_A1) == 0xff) - rt2x00_set_field16(&word, EEPROM_RSSI_BG2_LNA_A1, -@@ -7627,7 +7628,8 @@ static int rt2800_validate_eeprom(struct - rt2800_eeprom_read(rt2x00dev, EEPROM_RSSI_A2, &word); - if (abs(rt2x00_get_field16(word, EEPROM_RSSI_A2_OFFSET2)) > 10) - rt2x00_set_field16(&word, EEPROM_RSSI_A2_OFFSET2, 0); -- if (!rt2x00_rt(rt2x00dev, RT3593)) { -+ if (!rt2x00_rt(rt2x00dev, RT3593) && -+ !rt2x00_rt(rt2x00dev, RT3883)) { - if (rt2x00_get_field16(word, EEPROM_RSSI_A2_LNA_A2) == 0x00 || - rt2x00_get_field16(word, EEPROM_RSSI_A2_LNA_A2) == 0xff) - rt2x00_set_field16(&word, EEPROM_RSSI_A2_LNA_A2, -@@ -7635,7 +7637,8 @@ static int rt2800_validate_eeprom(struct - } - rt2800_eeprom_write(rt2x00dev, EEPROM_RSSI_A2, word); - -- if (rt2x00_rt(rt2x00dev, RT3593)) { -+ if (rt2x00_rt(rt2x00dev, RT3593) || -+ rt2x00_rt(rt2x00dev, RT3883)) { - rt2800_eeprom_read(rt2x00dev, EEPROM_EXT_LNA2, &word); - if (rt2x00_get_field16(word, EEPROM_EXT_LNA2_A1) == 0x00 || - rt2x00_get_field16(word, EEPROM_EXT_LNA2_A1) == 0xff) diff --git a/package/kernel/mac80211/patches/600-0031-rt2x00-rt2800lib-fix-txpower-compensation-for-RT3883.patch b/package/kernel/mac80211/patches/600-0031-rt2x00-rt2800lib-fix-txpower-compensation-for-RT3883.patch deleted file mode 100644 index 6e228479b0..0000000000 --- a/package/kernel/mac80211/patches/600-0031-rt2x00-rt2800lib-fix-txpower-compensation-for-RT3883.patch +++ /dev/null @@ -1,22 +0,0 @@ -From e3871034a0e7c8a95152dc3eafbcc4535398cbdc Mon Sep 17 00:00:00 2001 -From: Gabor Juhos -Date: Wed, 2 Oct 2013 10:11:59 +0200 -Subject: [PATCH] rt2x00: rt2800lib: fix txpower compensation for RT3883 - -Signed-off-by: Gabor Juhos ---- - drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 3 +++ - 1 file changed, 3 insertions(+) - ---- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c -+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c -@@ -3982,6 +3982,9 @@ static u8 rt2800_compensate_txpower(stru - if (rt2x00_rt(rt2x00dev, RT3593)) - return min_t(u8, txpower, 0xc); - -+ if (rt2x00_rt(rt2x00dev, RT3883)) -+ return min_t(u8, txpower, 0xf); -+ - if (rt2x00_has_cap_power_limit(rt2x00dev)) { - /* - * Check if eirp txpower exceed txpower_limit. diff --git a/package/kernel/mac80211/patches/600-0032-rt2x00-rt2800lib-enable-RT2800_HAS_HIGH_SHARED_MEM-f.patch b/package/kernel/mac80211/patches/600-0032-rt2x00-rt2800lib-enable-RT2800_HAS_HIGH_SHARED_MEM-f.patch deleted file mode 100644 index 2ffa5a4162..0000000000 --- a/package/kernel/mac80211/patches/600-0032-rt2x00-rt2800lib-enable-RT2800_HAS_HIGH_SHARED_MEM-f.patch +++ /dev/null @@ -1,23 +0,0 @@ -From f6734ec72da936989a8ce4186b3ede28fbc47836 Mon Sep 17 00:00:00 2001 -From: Gabor Juhos -Date: Sun, 18 Aug 2013 21:57:34 +0200 -Subject: [PATCH] rt2x00: rt2800lib: enable RT2800_HAS_HIGH_SHARED_MEM for - RT3883 - -Signed-off-by: Gabor Juhos ---- - drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - ---- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c -+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c -@@ -8420,7 +8420,8 @@ int rt2800_probe_hw(struct rt2x00_dev *r - if (retval) - return retval; - -- if (rt2x00_rt(rt2x00dev, RT3593)) -+ if (rt2x00_rt(rt2x00dev, RT3593) || -+ rt2x00_rt(rt2x00dev, RT3883)) - __set_bit(RT2800_HAS_HIGH_SHARED_MEM, &drv_data->rt2800_flags); - - if (rt2x00_rt(rt2x00dev, RT3593) || diff --git a/package/kernel/mac80211/patches/600-0033-rt2x00-rt2800lib-use-high-memory-for-beacons-on-RT38.patch b/package/kernel/mac80211/patches/600-0033-rt2x00-rt2800lib-use-high-memory-for-beacons-on-RT38.patch deleted file mode 100644 index 4f2e754869..0000000000 --- a/package/kernel/mac80211/patches/600-0033-rt2x00-rt2800lib-use-high-memory-for-beacons-on-RT38.patch +++ /dev/null @@ -1,22 +0,0 @@ -From f1acfc2f397e86548ae1b479c198d4bef57050f6 Mon Sep 17 00:00:00 2001 -From: Gabor Juhos -Date: Sun, 29 Sep 2013 18:10:34 +0200 -Subject: [PATCH] rt2x00: rt2800lib: use high memory for beacons on RT3883 - -Signed-off-by: Gabor Juhos ---- - drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - ---- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c -+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c -@@ -97,7 +97,8 @@ static inline void rt2800_shared_mem_sel - - static inline bool rt2800_beacon_uses_high_mem(struct rt2x00_dev *rt2x00dev) - { -- if (rt2x00_rt(rt2x00dev, RT3593)) -+ if (rt2x00_rt(rt2x00dev, RT3593) || -+ rt2x00_rt(rt2x00dev, RT3883)) - return true; - - return false; diff --git a/package/kernel/mac80211/patches/600-0034-rt2x00-rt2800mmio-add-a-workaround-for-spurious-TX_F.patch b/package/kernel/mac80211/patches/600-0034-rt2x00-rt2800mmio-add-a-workaround-for-spurious-TX_F.patch deleted file mode 100644 index a497b5eead..0000000000 --- a/package/kernel/mac80211/patches/600-0034-rt2x00-rt2800mmio-add-a-workaround-for-spurious-TX_F.patch +++ /dev/null @@ -1,136 +0,0 @@ -From 5e67d4f8a46d19748b501c2ef86de3f50d3cfd51 Mon Sep 17 00:00:00 2001 -From: Gabor Juhos -Date: Sun, 24 Mar 2013 19:26:27 +0100 -Subject: [PATCH] rt2x00: rt2800mmio: add a workaround for spurious - TX_FIFO_STATUS interrupts - -Signed-off-by: Gabor Juhos ---- - drivers/net/wireless/ralink/rt2x00/rt2800mmio.c | 72 +++++++++++++++++++++++++----- - drivers/net/wireless/ralink/rt2x00/rt2x00.h | 5 +++ - 2 files changed, 65 insertions(+), 12 deletions(-) - ---- a/drivers/net/wireless/ralink/rt2x00/rt2800mmio.c -+++ b/drivers/net/wireless/ralink/rt2x00/rt2800mmio.c -@@ -415,9 +415,9 @@ void rt2800mmio_autowake_tasklet(unsigne - } - EXPORT_SYMBOL_GPL(rt2800mmio_autowake_tasklet); - --static void rt2800mmio_txstatus_interrupt(struct rt2x00_dev *rt2x00dev) -+static void rt2800mmio_txstatus_interrupt(struct rt2x00_dev *rt2x00dev, -+ u32 status) - { -- u32 status; - int i; - - /* -@@ -438,29 +438,77 @@ static void rt2800mmio_txstatus_interrup - * Since we have only one producer and one consumer we don't - * need to lock the kfifo. - */ -- for (i = 0; i < rt2x00dev->tx->limit; i++) { -- rt2x00mmio_register_read(rt2x00dev, TX_STA_FIFO, &status); -- -- if (!rt2x00_get_field32(status, TX_STA_FIFO_VALID)) -- break; -- -+ i = 0; -+ do { - if (!kfifo_put(&rt2x00dev->txstatus_fifo, status)) { -- rt2x00_warn(rt2x00dev, "TX status FIFO overrun, drop tx status report\n"); -+ rt2x00_warn(rt2x00dev, -+ "TX status FIFO overrun, drop TX status report\n"); - break; - } -- } -+ -+ if (++i >= rt2x00dev->tx->limit) -+ break; -+ -+ rt2x00mmio_register_read(rt2x00dev, TX_STA_FIFO, &status); -+ } while (rt2x00_get_field32(status, TX_STA_FIFO_VALID)); - - /* Schedule the tasklet for processing the tx status. */ - tasklet_schedule(&rt2x00dev->txstatus_tasklet); - } - -+#define RT2800MMIO_TXSTATUS_IRQ_MAX_RETRIES 4 -+ -+static bool rt2800mmio_txstatus_is_spurious(struct rt2x00_dev *rt2x00dev, -+ u32 txstatus) -+{ -+ if (likely(rt2x00_get_field32(txstatus, TX_STA_FIFO_VALID))) { -+ rt2x00dev->txstatus_irq_retries = 0; -+ return false; -+ } -+ -+ rt2x00dev->txstatus_irq_retries++; -+ -+ /* Ensure that we don't go into an infinite IRQ loop. */ -+ if (rt2x00dev->txstatus_irq_retries >= -+ RT2800MMIO_TXSTATUS_IRQ_MAX_RETRIES) { -+ rt2x00_warn(rt2x00dev, -+ "%u spurious TX_FIFO_STATUS interrupt(s)\n", -+ rt2x00dev->txstatus_irq_retries); -+ rt2x00dev->txstatus_irq_retries = 0; -+ return false; -+ } -+ -+ return true; -+} -+ - irqreturn_t rt2800mmio_interrupt(int irq, void *dev_instance) - { - struct rt2x00_dev *rt2x00dev = dev_instance; - u32 reg, mask; -+ u32 txstatus = 0; - -- /* Read status and ACK all interrupts */ -+ /* Read status */ - rt2x00mmio_register_read(rt2x00dev, INT_SOURCE_CSR, ®); -+ -+ if (rt2x00_get_field32(reg, INT_SOURCE_CSR_TX_FIFO_STATUS)) { -+ /* Due to unknown reason the hardware generates a -+ * TX_FIFO_STATUS interrupt before the TX_STA_FIFO -+ * register contain valid data. Read the TX status -+ * here to see if we have to process the actual -+ * request. -+ */ -+ rt2x00mmio_register_read(rt2x00dev, TX_STA_FIFO, &txstatus); -+ if (rt2800mmio_txstatus_is_spurious(rt2x00dev, txstatus)) { -+ /* Remove the TX_FIFO_STATUS bit so it won't be -+ * processed in this turn. The hardware will -+ * generate another IRQ for us. -+ */ -+ rt2x00_set_field32(®, -+ INT_SOURCE_CSR_TX_FIFO_STATUS, 0); -+ } -+ } -+ -+ /* ACK interrupts */ - rt2x00mmio_register_write(rt2x00dev, INT_SOURCE_CSR, reg); - - if (!reg) -@@ -477,7 +525,7 @@ irqreturn_t rt2800mmio_interrupt(int irq - mask = ~reg; - - if (rt2x00_get_field32(reg, INT_SOURCE_CSR_TX_FIFO_STATUS)) { -- rt2800mmio_txstatus_interrupt(rt2x00dev); -+ rt2800mmio_txstatus_interrupt(rt2x00dev, txstatus); - /* - * Never disable the TX_FIFO_STATUS interrupt. - */ ---- a/drivers/net/wireless/ralink/rt2x00/rt2x00.h -+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00.h -@@ -991,6 +991,11 @@ struct rt2x00_dev { - int rf_channel; - - /* -+ * Counter for tx status irq retries (rt2800pci). -+ */ -+ unsigned int txstatus_irq_retries; -+ -+ /* - * Protect the interrupt mask register. - */ - spinlock_t irqmask_lock; diff --git a/package/kernel/mac80211/patches/600-01-rt2x00-allow-to-build-rt2800soc-module-for-RT3883.patch b/package/kernel/mac80211/patches/600-01-rt2x00-allow-to-build-rt2800soc-module-for-RT3883.patch new file mode 100644 index 0000000000..565e39de5f --- /dev/null +++ b/package/kernel/mac80211/patches/600-01-rt2x00-allow-to-build-rt2800soc-module-for-RT3883.patch @@ -0,0 +1,30 @@ +From 91094ed065f7794886b4a5490fd6de942f036bb4 Mon Sep 17 00:00:00 2001 +From: Gabor Juhos +Date: Sun, 24 Mar 2013 19:26:26 +0100 +Subject: [PATCH] rt2x00: allow to build rt2800soc module for RT3883 + +Signed-off-by: Gabor Juhos +--- + drivers/net/wireless/ralink/rt2x00/Kconfig | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/net/wireless/ralink/rt2x00/Kconfig ++++ b/drivers/net/wireless/ralink/rt2x00/Kconfig +@@ -210,7 +210,7 @@ endif + config RT2800SOC + tristate "Ralink WiSoC support" + depends on m +- depends on SOC_RT288X || SOC_RT305X ++ depends on SOC_RT288X || SOC_RT305X || SOC_RT3883 + select RT2X00_LIB_SOC + select RT2X00_LIB_MMIO + select RT2X00_LIB_CRYPTO +@@ -245,7 +245,7 @@ config RT2X00_LIB_PCI + + config RT2X00_LIB_SOC + tristate "RT2x00 SoC support" +- depends on SOC_RT288X || SOC_RT305X ++ depends on SOC_RT288X || SOC_RT305X || SOC_RT3883 + depends on m + select RT2X00_LIB + diff --git a/package/kernel/mac80211/patches/600-02-rt2x00-rt2800lib-enable-support-for-RT3883.patch b/package/kernel/mac80211/patches/600-02-rt2x00-rt2800lib-enable-support-for-RT3883.patch new file mode 100644 index 0000000000..f8680108c8 --- /dev/null +++ b/package/kernel/mac80211/patches/600-02-rt2x00-rt2800lib-enable-support-for-RT3883.patch @@ -0,0 +1,20 @@ +From 4f16582c93a71eba9d389e0f0a8aa9099a9587cd Mon Sep 17 00:00:00 2001 +From: Gabor Juhos +Date: Sun, 24 Mar 2013 19:26:26 +0100 +Subject: [PATCH] rt2x00: rt2800lib: enable support for RT3883 + +Signed-off-by: Gabor Juhos +--- + drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c +@@ -7956,6 +7956,7 @@ static int rt2800_probe_rt(struct rt2x00 + case RT3390: + case RT3572: + case RT3593: ++ case RT3883: + case RT5350: + case RT5390: + case RT5392: diff --git a/package/kernel/mac80211/patches/600-03-rt2x00-rt2800lib-add-rf_vals-for-RF3853.patch b/package/kernel/mac80211/patches/600-03-rt2x00-rt2800lib-add-rf_vals-for-RF3853.patch new file mode 100644 index 0000000000..46e98aff0f --- /dev/null +++ b/package/kernel/mac80211/patches/600-03-rt2x00-rt2800lib-add-rf_vals-for-RF3853.patch @@ -0,0 +1,112 @@ +From ecb394ccf248d8652c463133c4f404458a57a9c1 Mon Sep 17 00:00:00 2001 +From: Gabor Juhos +Date: Sun, 24 Mar 2013 19:26:26 +0100 +Subject: [PATCH] rt2x00: rt2800lib: add rf_vals for RF3853 + +Signed-off-by: Gabor Juhos +--- + drivers/net/wireless/ralink/rt2x00/rt2800.h | 4 +- + drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 65 +++++++++++++++++++++++++++++++ + 2 files changed, 68 insertions(+), 1 deletion(-) + +--- a/drivers/net/wireless/ralink/rt2x00/rt2800.h ++++ b/drivers/net/wireless/ralink/rt2x00/rt2800.h +@@ -48,7 +48,8 @@ + * RF2853 2.4G/5G 3T3R + * RF3320 2.4G 1T1R(RT3350/RT3370/RT3390) + * RF3322 2.4G 2T2R(RT3352/RT3371/RT3372/RT3391/RT3392) +- * RF3053 2.4G/5G 3T3R(RT3883/RT3563/RT3573/RT3593/RT3662) ++ * RF3053 2.4G/5G 3T3R(RT3563/RT3573/RT3593) ++ * RF3853 2.4G/5G 3T3R(RT3883/RT3662) + * RF5592 2.4G/5G 2T2R + * RF3070 2.4G 1T1R + * RF5360 2.4G 1T1R +@@ -72,6 +73,7 @@ + #define RF5592 0x000f + #define RF3070 0x3070 + #define RF3290 0x3290 ++#define RF3853 0x3853 + #define RF5350 0x5350 + #define RF5360 0x5360 + #define RF5362 0x5362 +--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c +@@ -7557,6 +7557,66 @@ static const struct rf_channel rf_vals_3 + {14, 0xF0, 2, 0x18}, + }; + ++static const struct rf_channel rf_vals_3853[] = { ++ {1, 241, 6, 2}, ++ {2, 241, 6, 7}, ++ {3, 242, 6, 2}, ++ {4, 242, 6, 7}, ++ {5, 243, 6, 2}, ++ {6, 243, 6, 7}, ++ {7, 244, 6, 2}, ++ {8, 244, 6, 7}, ++ {9, 245, 6, 2}, ++ {10, 245, 6, 7}, ++ {11, 246, 6, 2}, ++ {12, 246, 6, 7}, ++ {13, 247, 6, 2}, ++ {14, 248, 6, 4}, ++ ++ {36, 0x56, 8, 4}, ++ {38, 0x56, 8, 6}, ++ {40, 0x56, 8, 8}, ++ {44, 0x57, 8, 0}, ++ {46, 0x57, 8, 2}, ++ {48, 0x57, 8, 4}, ++ {52, 0x57, 8, 8}, ++ {54, 0x57, 8, 10}, ++ {56, 0x58, 8, 0}, ++ {60, 0x58, 8, 4}, ++ {62, 0x58, 8, 6}, ++ {64, 0x58, 8, 8}, ++ ++ {100, 0x5b, 8, 8}, ++ {102, 0x5b, 8, 10}, ++ {104, 0x5c, 8, 0}, ++ {108, 0x5c, 8, 4}, ++ {110, 0x5c, 8, 6}, ++ {112, 0x5c, 8, 8}, ++ {114, 0x5c, 8, 10}, ++ {116, 0x5d, 8, 0}, ++ {118, 0x5d, 8, 2}, ++ {120, 0x5d, 8, 4}, ++ {124, 0x5d, 8, 8}, ++ {126, 0x5d, 8, 10}, ++ {128, 0x5e, 8, 0}, ++ {132, 0x5e, 8, 4}, ++ {134, 0x5e, 8, 6}, ++ {136, 0x5e, 8, 8}, ++ {140, 0x5f, 8, 0}, ++ ++ {149, 0x5f, 8, 9}, ++ {151, 0x5f, 8, 11}, ++ {153, 0x60, 8, 1}, ++ {157, 0x60, 8, 5}, ++ {159, 0x60, 8, 7}, ++ {161, 0x60, 8, 9}, ++ {165, 0x61, 8, 1}, ++ {167, 0x61, 8, 3}, ++ {169, 0x61, 8, 5}, ++ {171, 0x61, 8, 7}, ++ {173, 0x61, 8, 9}, ++}; ++ + static const struct rf_channel rf_vals_5592_xtal20[] = { + /* Channel, N, K, mod, R */ + {1, 482, 4, 10, 3}, +@@ -7798,6 +7858,11 @@ static int rt2800_probe_hw_mode(struct r + spec->channels = rf_vals_3x; + break; + ++ case RF3853: ++ spec->num_channels = ARRAY_SIZE(rf_vals_3853); ++ spec->channels = rf_vals_3853; ++ break; ++ + case RF5592: + rt2800_register_read(rt2x00dev, MAC_DEBUG_INDEX, ®); + if (rt2x00_get_field32(reg, MAC_DEBUG_INDEX_XTAL)) { diff --git a/package/kernel/mac80211/patches/600-04-rt2x00-rt2800lib-enable-VCO-calibration-for-RF3853.patch b/package/kernel/mac80211/patches/600-04-rt2x00-rt2800lib-enable-VCO-calibration-for-RF3853.patch new file mode 100644 index 0000000000..eca49773ec --- /dev/null +++ b/package/kernel/mac80211/patches/600-04-rt2x00-rt2800lib-enable-VCO-calibration-for-RF3853.patch @@ -0,0 +1,28 @@ +From f8e3fcf18e1f2d7f9e6a9680c5452da090f33d88 Mon Sep 17 00:00:00 2001 +From: Gabor Juhos +Date: Thu, 1 Aug 2013 14:40:44 +0200 +Subject: [PATCH] rt2x00: rt2800lib: enable VCO calibration for RF3853 + +Signed-off-by: Gabor Juhos +--- + drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c +@@ -4363,6 +4363,7 @@ void rt2800_vco_calibration(struct rt2x0 + case RF3053: + case RF3070: + case RF3290: ++ case RF3853: + case RF5350: + case RF5360: + case RF5362: +@@ -7980,6 +7981,7 @@ static int rt2800_probe_hw_mode(struct r + case RF3053: + case RF3070: + case RF3290: ++ case RF3853: + case RF5350: + case RF5360: + case RF5362: diff --git a/package/kernel/mac80211/patches/600-05-rt2x00-rt2800lib-add-channel-configuration-function-.patch b/package/kernel/mac80211/patches/600-05-rt2x00-rt2800lib-add-channel-configuration-function-.patch new file mode 100644 index 0000000000..a1e5883035 --- /dev/null +++ b/package/kernel/mac80211/patches/600-05-rt2x00-rt2800lib-add-channel-configuration-function-.patch @@ -0,0 +1,235 @@ +From 6e3a17190815c6aa4dc53c2cfe9125fb1154f187 Mon Sep 17 00:00:00 2001 +From: Gabor Juhos +Date: Sun, 24 Mar 2013 19:26:27 +0100 +Subject: [PATCH] rt2x00: rt2800lib: add channel configuration function for + RF3853 + +Signed-off-by: Gabor Juhos +--- + drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 208 +++++++++++++++++++++++++++++++ + 1 file changed, 208 insertions(+) + +--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c +@@ -2584,6 +2584,211 @@ static void rt2800_config_channel_rf3053 + } + } + ++static void rt2800_config_channel_rf3853(struct rt2x00_dev *rt2x00dev, ++ struct ieee80211_conf *conf, ++ struct rf_channel *rf, ++ struct channel_info *info) ++{ ++ u8 rfcsr; ++ u8 bbp; ++ u8 pwr1, pwr2, pwr3; ++ ++ const bool txbf_enabled = false; /* TODO */ ++ ++ /* TODO: add band selection */ ++ ++ if (rf->channel <= 14) ++ rt2800_rfcsr_write(rt2x00dev, 6, 0x40); ++ else if (rf->channel < 132) ++ rt2800_rfcsr_write(rt2x00dev, 6, 0x80); ++ else ++ rt2800_rfcsr_write(rt2x00dev, 6, 0x40); ++ ++ rt2800_rfcsr_write(rt2x00dev, 8, rf->rf1); ++ rt2800_rfcsr_write(rt2x00dev, 9, rf->rf3); ++ ++ if (rf->channel <= 14) ++ rt2800_rfcsr_write(rt2x00dev, 11, 0x46); ++ else ++ rt2800_rfcsr_write(rt2x00dev, 11, 0x48); ++ ++ if (rf->channel <= 14) ++ rt2800_rfcsr_write(rt2x00dev, 12, 0x1a); ++ else ++ rt2800_rfcsr_write(rt2x00dev, 12, 0x52); ++ ++ rt2800_rfcsr_write(rt2x00dev, 13, 0x12); ++ ++ rt2800_rfcsr_read(rt2x00dev, 1, &rfcsr); ++ rt2x00_set_field8(&rfcsr, RFCSR1_RX0_PD, 0); ++ rt2x00_set_field8(&rfcsr, RFCSR1_TX0_PD, 0); ++ rt2x00_set_field8(&rfcsr, RFCSR1_RX1_PD, 0); ++ rt2x00_set_field8(&rfcsr, RFCSR1_TX1_PD, 0); ++ rt2x00_set_field8(&rfcsr, RFCSR1_RX2_PD, 0); ++ rt2x00_set_field8(&rfcsr, RFCSR1_TX2_PD, 0); ++ rt2x00_set_field8(&rfcsr, RFCSR1_RF_BLOCK_EN, 1); ++ rt2x00_set_field8(&rfcsr, RFCSR1_PLL_PD, 1); ++ ++ switch (rt2x00dev->default_ant.tx_chain_num) { ++ case 3: ++ rt2x00_set_field8(&rfcsr, RFCSR1_TX2_PD, 1); ++ /* fallthrough */ ++ case 2: ++ rt2x00_set_field8(&rfcsr, RFCSR1_TX1_PD, 1); ++ /* fallthrough */ ++ case 1: ++ rt2x00_set_field8(&rfcsr, RFCSR1_TX0_PD, 1); ++ break; ++ } ++ ++ switch (rt2x00dev->default_ant.rx_chain_num) { ++ case 3: ++ rt2x00_set_field8(&rfcsr, RFCSR1_RX2_PD, 1); ++ /* fallthrough */ ++ case 2: ++ rt2x00_set_field8(&rfcsr, RFCSR1_RX1_PD, 1); ++ /* fallthrough */ ++ case 1: ++ rt2x00_set_field8(&rfcsr, RFCSR1_RX0_PD, 1); ++ break; ++ } ++ rt2800_rfcsr_write(rt2x00dev, 1, rfcsr); ++ ++ rt2800_freq_cal_mode1(rt2x00dev); ++ ++ rt2800_rfcsr_read(rt2x00dev, 30, &rfcsr); ++ if (!conf_is_ht40(conf)) ++ rfcsr &= ~(0x06); ++ else ++ rfcsr |= 0x06; ++ rt2800_rfcsr_write(rt2x00dev, 30, rfcsr); ++ ++ if (rf->channel <= 14) ++ rt2800_rfcsr_write(rt2x00dev, 31, 0xa0); ++ else ++ rt2800_rfcsr_write(rt2x00dev, 31, 0x80); ++ ++ if (conf_is_ht40(conf)) ++ rt2800_rfcsr_write(rt2x00dev, 32, 0x80); ++ else ++ rt2800_rfcsr_write(rt2x00dev, 32, 0xd8); ++ ++ if (rf->channel <= 14) ++ rt2800_rfcsr_write(rt2x00dev, 34, 0x3c); ++ else ++ rt2800_rfcsr_write(rt2x00dev, 34, 0x20); ++ ++ /* loopback RF_BS */ ++ rt2800_rfcsr_read(rt2x00dev, 36, &rfcsr); ++ if (rf->channel <= 14) ++ rt2x00_set_field8(&rfcsr, RFCSR36_RF_BS, 1); ++ else ++ rt2x00_set_field8(&rfcsr, RFCSR36_RF_BS, 0); ++ rt2800_rfcsr_write(rt2x00dev, 36, rfcsr); ++ ++ if (rf->channel <= 14) ++ rfcsr = 0x23; ++ else if (rf->channel < 100) ++ rfcsr = 0x36; ++ else if (rf->channel < 132) ++ rfcsr = 0x32; ++ else ++ rfcsr = 0x30; ++ ++ if (txbf_enabled) ++ rfcsr |= 0x40; ++ ++ rt2800_rfcsr_write(rt2x00dev, 39, rfcsr); ++ ++ if (rf->channel <= 14) ++ rt2800_rfcsr_write(rt2x00dev, 44, 0x93); ++ else ++ rt2800_rfcsr_write(rt2x00dev, 44, 0x9b); ++ ++ if (rf->channel <= 14) ++ rfcsr = 0xbb; ++ else if (rf->channel < 100) ++ rfcsr = 0xeb; ++ else if (rf->channel < 132) ++ rfcsr = 0xb3; ++ else ++ rfcsr = 0x9b; ++ rt2800_rfcsr_write(rt2x00dev, 45, rfcsr); ++ ++ if (rf->channel <= 14) ++ rfcsr = 0x8e; ++ else ++ rfcsr = 0x8a; ++ ++ if (txbf_enabled) ++ rfcsr |= 0x20; ++ ++ rt2800_rfcsr_write(rt2x00dev, 49, rfcsr); ++ ++ rt2800_rfcsr_write(rt2x00dev, 50, 0x86); ++ ++ rt2800_rfcsr_read(rt2x00dev, 51, &rfcsr); ++ if (rf->channel <= 14) ++ rt2800_rfcsr_write(rt2x00dev, 51, 0x75); ++ else ++ rt2800_rfcsr_write(rt2x00dev, 51, 0x51); ++ ++ rt2800_rfcsr_read(rt2x00dev, 52, &rfcsr); ++ if (rf->channel <= 14) ++ rt2800_rfcsr_write(rt2x00dev, 52, 0x45); ++ else ++ rt2800_rfcsr_write(rt2x00dev, 52, 0x05); ++ ++ if (rf->channel <= 14) { ++ pwr1 = info->default_power1 & 0x1f; ++ pwr2 = info->default_power2 & 0x1f; ++ pwr3 = info->default_power3 & 0x1f; ++ } else { ++ pwr1 = 0x48 | ((info->default_power1 & 0x18) << 1) | ++ (info->default_power1 & 0x7); ++ pwr2 = 0x48 | ((info->default_power2 & 0x18) << 1) | ++ (info->default_power2 & 0x7); ++ pwr3 = 0x48 | ((info->default_power3 & 0x18) << 1) | ++ (info->default_power3 & 0x7); ++ } ++ ++ rt2800_rfcsr_write(rt2x00dev, 53, pwr1); ++ rt2800_rfcsr_write(rt2x00dev, 54, pwr2); ++ rt2800_rfcsr_write(rt2x00dev, 55, pwr3); ++ ++ rt2x00_dbg(rt2x00dev, "Channel:%d, pwr1:%02x, pwr2:%02x, pwr3:%02x\n", ++ rf->channel, pwr1, pwr2, pwr3); ++ ++ bbp = (info->default_power1 >> 5) | ++ ((info->default_power2 & 0xe0) >> 1); ++ rt2800_bbp_write(rt2x00dev, 109, bbp); ++ ++ rt2800_bbp_read(rt2x00dev, 110, &bbp); ++ bbp &= 0x0f; ++ bbp |= (info->default_power3 & 0xe0) >> 1; ++ rt2800_bbp_write(rt2x00dev, 110, bbp); ++ ++ rt2800_rfcsr_read(rt2x00dev, 57, &rfcsr); ++ if (rf->channel <= 14) ++ rt2800_rfcsr_write(rt2x00dev, 57, 0x6e); ++ else ++ rt2800_rfcsr_write(rt2x00dev, 57, 0x3e); ++ ++ /* Enable RF tuning */ ++ rt2800_rfcsr_read(rt2x00dev, 3, &rfcsr); ++ rt2x00_set_field8(&rfcsr, RFCSR3_VCOCAL_EN, 1); ++ rt2800_rfcsr_write(rt2x00dev, 3, rfcsr); ++ ++ udelay(2000); ++ ++ rt2800_bbp_read(rt2x00dev, 49, &bbp); ++ /* clear update flag */ ++ rt2800_bbp_write(rt2x00dev, 49, bbp & 0xfe); ++ rt2800_bbp_write(rt2x00dev, 49, bbp); ++ ++ /* TODO: add calibration for TxBF */ ++} ++ + #define POWER_BOUND 0x27 + #define POWER_BOUND_5G 0x2b + +@@ -3203,6 +3408,9 @@ static void rt2800_config_channel(struct + case RF3322: + rt2800_config_channel_rf3322(rt2x00dev, conf, rf, info); + break; ++ case RF3853: ++ rt2800_config_channel_rf3853(rt2x00dev, conf, rf, info); ++ break; + case RF3070: + case RF5350: + case RF5360: diff --git a/package/kernel/mac80211/patches/600-06-rt2x00-rt2800lib-enable-RF3853-support.patch b/package/kernel/mac80211/patches/600-06-rt2x00-rt2800lib-enable-RF3853-support.patch new file mode 100644 index 0000000000..2d65119fd0 --- /dev/null +++ b/package/kernel/mac80211/patches/600-06-rt2x00-rt2800lib-enable-RF3853-support.patch @@ -0,0 +1,20 @@ +From afd38ae82226551bf879b6c7c4b620c271fee9d2 Mon Sep 17 00:00:00 2001 +From: Gabor Juhos +Date: Thu, 1 Aug 2013 14:42:05 +0200 +Subject: [PATCH] rt2x00: rt2800lib: enable RF3853 support + +Signed-off-by: Gabor Juhos +--- + drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c +@@ -7483,6 +7483,7 @@ static int rt2800_init_eeprom(struct rt2 + case RF3290: + case RF3320: + case RF3322: ++ case RF3853: + case RF5350: + case RF5360: + case RF5362: diff --git a/package/kernel/mac80211/patches/600-07-rt2x00-rt2800lib-add-MAC-register-initialization-for.patch b/package/kernel/mac80211/patches/600-07-rt2x00-rt2800lib-add-MAC-register-initialization-for.patch new file mode 100644 index 0000000000..d073c01697 --- /dev/null +++ b/package/kernel/mac80211/patches/600-07-rt2x00-rt2800lib-add-MAC-register-initialization-for.patch @@ -0,0 +1,62 @@ +From 0094872a5e8e4664c6ea1b2dfa487063d39ae363 Mon Sep 17 00:00:00 2001 +From: Gabor Juhos +Date: Sun, 24 Mar 2013 19:26:26 +0100 +Subject: [PATCH] rt2x00: rt2800lib: add MAC register initialization for + RT3883 + +Signed-off-by: Gabor Juhos +--- + drivers/net/wireless/ralink/rt2x00/rt2800.h | 14 ++++++++++++++ + drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 19 ++++++++++++++++--- + 2 files changed, 30 insertions(+), 3 deletions(-) + +--- a/drivers/net/wireless/ralink/rt2x00/rt2800.h ++++ b/drivers/net/wireless/ralink/rt2x00/rt2800.h +@@ -1574,6 +1574,20 @@ + #define TX_PWR_CFG_9_STBC7_CH2 FIELD32(0x00000f00) + + /* ++ * TX_TXBF_CFG: ++ */ ++#define TX_TXBF_CFG_0 0x138c ++#define TX_TXBF_CFG_1 0x13a4 ++#define TX_TXBF_CFG_2 0x13a8 ++#define TX_TXBF_CFG_3 0x13ac ++ ++/* ++ * TX_FBK_CFG_3S: ++ */ ++#define TX_FBK_CFG_3S_0 0x13c4 ++#define TX_FBK_CFG_3S_1 0x13c8 ++ ++/* + * RX_FILTER_CFG: RX configuration register. + */ + #define RX_FILTER_CFG 0x1400 +--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c +@@ -4946,6 +4946,12 @@ static int rt2800_init_registers(struct + rt2800_register_write(rt2x00dev, TX_SW_CFG2, + 0x00000000); + } ++ } else if (rt2x00_rt(rt2x00dev, RT3883)) { ++ rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000402); ++ rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00000000); ++ rt2800_register_write(rt2x00dev, TX_SW_CFG2, 0x00040000); ++ rt2800_register_write(rt2x00dev, TX_TXBF_CFG_0, 0x8000fc21); ++ rt2800_register_write(rt2x00dev, TX_TXBF_CFG_3, 0x00009c40); + } else if (rt2x00_rt(rt2x00dev, RT5390) || + rt2x00_rt(rt2x00dev, RT5392)) { + rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000404); +@@ -5140,6 +5146,11 @@ static int rt2800_init_registers(struct + reg = rt2x00_rt(rt2x00dev, RT5592) ? 0x00000082 : 0x00000002; + rt2800_register_write(rt2x00dev, TXOP_HLDR_ET, reg); + ++ if (rt2x00_rt(rt2x00dev, RT3883)) { ++ rt2800_register_write(rt2x00dev, TX_FBK_CFG_3S_0, 0x12111008); ++ rt2800_register_write(rt2x00dev, TX_FBK_CFG_3S_1, 0x16151413); ++ } ++ + rt2800_register_read(rt2x00dev, TX_RTS_CFG, ®); + rt2x00_set_field32(®, TX_RTS_CFG_AUTO_RTS_RETRY_LIMIT, 7); + rt2x00_set_field32(®, TX_RTS_CFG_RTS_THRES, diff --git a/package/kernel/mac80211/patches/600-08-rt2x00-rt2800soc-fix-rt2800soc_disable_radio-for-RT3.patch b/package/kernel/mac80211/patches/600-08-rt2x00-rt2800soc-fix-rt2800soc_disable_radio-for-RT3.patch new file mode 100644 index 0000000000..d68ad50447 --- /dev/null +++ b/package/kernel/mac80211/patches/600-08-rt2x00-rt2800soc-fix-rt2800soc_disable_radio-for-RT3.patch @@ -0,0 +1,30 @@ +From 6c2d32478159fffff0b85abb6817a21bb2338231 Mon Sep 17 00:00:00 2001 +From: Gabor Juhos +Date: Sun, 24 Mar 2013 19:26:27 +0100 +Subject: [PATCH] rt2x00: rt2800soc: fix rt2800soc_disable_radio for RT3883 + +Signed-off-by: Gabor Juhos +--- + drivers/net/wireless/ralink/rt2x00/rt2800soc.c | 9 ++++++++- + 1 file changed, 8 insertions(+), 1 deletion(-) + +--- a/drivers/net/wireless/ralink/rt2x00/rt2800soc.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2800soc.c +@@ -51,9 +51,16 @@ static bool rt2800soc_hwcrypt_disabled(s + + static void rt2800soc_disable_radio(struct rt2x00_dev *rt2x00dev) + { ++ u32 reg; ++ + rt2800_disable_radio(rt2x00dev); + rt2x00mmio_register_write(rt2x00dev, PWR_PIN_CFG, 0); +- rt2x00mmio_register_write(rt2x00dev, TX_PIN_CFG, 0); ++ ++ reg = 0; ++ if (rt2x00_rt(rt2x00dev, RT3883)) ++ rt2x00_set_field32(®, TX_PIN_CFG_RFTR_EN, 1); ++ ++ rt2x00mmio_register_write(rt2x00dev, TX_PIN_CFG, reg); + } + + static int rt2800soc_set_device_state(struct rt2x00_dev *rt2x00dev, diff --git a/package/kernel/mac80211/patches/600-09-rt2x00-rt2800lib-add-BBP-register-initialization-for.patch b/package/kernel/mac80211/patches/600-09-rt2x00-rt2800lib-add-BBP-register-initialization-for.patch new file mode 100644 index 0000000000..41ed4d3de9 --- /dev/null +++ b/package/kernel/mac80211/patches/600-09-rt2x00-rt2800lib-add-BBP-register-initialization-for.patch @@ -0,0 +1,71 @@ +From 84833056aa7dd25f5b097e31c78f2a0914c5160c Mon Sep 17 00:00:00 2001 +From: Gabor Juhos +Date: Sun, 24 Mar 2013 19:26:26 +0100 +Subject: [PATCH] rt2x00: rt2800lib: add BBP register initialization for + RT3883 + +Signed-off-by: Gabor Juhos +--- + drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 44 +++++++++++++++++++++++++++++++ + 1 file changed, 44 insertions(+) + +--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c +@@ -5767,6 +5767,47 @@ static void rt2800_init_bbp_3593(struct + rt2800_bbp_write(rt2x00dev, 103, 0xc0); + } + ++static void rt2800_init_bbp_3883(struct rt2x00_dev *rt2x00dev) ++{ ++ rt2800_init_bbp_early(rt2x00dev); ++ ++ rt2800_bbp_write(rt2x00dev, 4, 0x50); ++ rt2800_bbp_write(rt2x00dev, 47, 0x48); ++ ++ rt2800_bbp_write(rt2x00dev, 86, 0x46); ++ rt2800_bbp_write(rt2x00dev, 88, 0x90); ++ ++ rt2800_bbp_write(rt2x00dev, 92, 0x02); ++ ++ rt2800_bbp_write(rt2x00dev, 103, 0xc0); ++ rt2800_bbp_write(rt2x00dev, 104, 0x92); ++ rt2800_bbp_write(rt2x00dev, 105, 0x34); ++ rt2800_bbp_write(rt2x00dev, 106, 0x12); ++ rt2800_bbp_write(rt2x00dev, 120, 0x50); ++ rt2800_bbp_write(rt2x00dev, 137, 0x0f); ++ rt2800_bbp_write(rt2x00dev, 163, 0x9d); ++ ++ /* Set ITxBF timeout to 0x9C40=1000msec */ ++ rt2800_bbp_write(rt2x00dev, 179, 0x02); ++ rt2800_bbp_write(rt2x00dev, 180, 0x00); ++ rt2800_bbp_write(rt2x00dev, 182, 0x40); ++ rt2800_bbp_write(rt2x00dev, 180, 0x01); ++ rt2800_bbp_write(rt2x00dev, 182, 0x9c); ++ ++ rt2800_bbp_write(rt2x00dev, 179, 0x00); ++ ++ /* Reprogram the inband interface to put right values in RXWI */ ++ rt2800_bbp_write(rt2x00dev, 142, 0x04); ++ rt2800_bbp_write(rt2x00dev, 143, 0x3b); ++ rt2800_bbp_write(rt2x00dev, 142, 0x06); ++ rt2800_bbp_write(rt2x00dev, 143, 0xa0); ++ rt2800_bbp_write(rt2x00dev, 142, 0x07); ++ rt2800_bbp_write(rt2x00dev, 143, 0xa1); ++ rt2800_bbp_write(rt2x00dev, 142, 0x08); ++ rt2800_bbp_write(rt2x00dev, 143, 0xa2); ++ rt2800_bbp_write(rt2x00dev, 148, 0xc8); ++} ++ + static void rt2800_init_bbp_53xx(struct rt2x00_dev *rt2x00dev) + { + int ant, div_mode; +@@ -5986,6 +6027,9 @@ static void rt2800_init_bbp(struct rt2x0 + case RT3593: + rt2800_init_bbp_3593(rt2x00dev); + return; ++ case RT3883: ++ rt2800_init_bbp_3883(rt2x00dev); ++ return; + case RT5390: + case RT5392: + rt2800_init_bbp_53xx(rt2x00dev); diff --git a/package/kernel/mac80211/patches/600-10-rt2x00-rt2800lib-add-RFCSR-initialization-for-RT3883.patch b/package/kernel/mac80211/patches/600-10-rt2x00-rt2800lib-add-RFCSR-initialization-for-RT3883.patch new file mode 100644 index 0000000000..7e772ec676 --- /dev/null +++ b/package/kernel/mac80211/patches/600-10-rt2x00-rt2800lib-add-RFCSR-initialization-for-RT3883.patch @@ -0,0 +1,178 @@ +From 99c659cf345640fd0f733cbcaf4583cc2c868ec0 Mon Sep 17 00:00:00 2001 +From: Gabor Juhos +Date: Mon, 29 Apr 2013 13:21:48 +0200 +Subject: [PATCH] rt2x00: rt2800lib: add RFCSR initialization for RT3883 + +Signed-off-by: Gabor Juhos +--- + drivers/net/wireless/ralink/rt2x00/rt2800.h | 1 + + drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 141 +++++++++++++++++++++++++++++++ + 2 files changed, 142 insertions(+) + +--- a/drivers/net/wireless/ralink/rt2x00/rt2800.h ++++ b/drivers/net/wireless/ralink/rt2x00/rt2800.h +@@ -2155,6 +2155,7 @@ struct mac_iveiv_entry { + /* + * RFCSR 2: + */ ++#define RFCSR2_RESCAL_BP FIELD8(0x40) + #define RFCSR2_RESCAL_EN FIELD8(0x80) + + /* +--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c +@@ -6899,6 +6899,144 @@ static void rt2800_init_rfcsr_5350(struc + rt2800_rfcsr_write(rt2x00dev, 63, 0x00); + } + ++static void rt2800_init_rfcsr_3883(struct rt2x00_dev *rt2x00dev) ++{ ++ u8 rfcsr; ++ ++ /* TODO: get the actual ECO value from the SoC */ ++ const unsigned int eco = 5; ++ ++ rt2800_rf_init_calibration(rt2x00dev, 2); ++ ++ rt2800_rfcsr_write(rt2x00dev, 0, 0xe0); ++ rt2800_rfcsr_write(rt2x00dev, 1, 0x03); ++ rt2800_rfcsr_write(rt2x00dev, 2, 0x50); ++ rt2800_rfcsr_write(rt2x00dev, 3, 0x20); ++ rt2800_rfcsr_write(rt2x00dev, 4, 0x00); ++ rt2800_rfcsr_write(rt2x00dev, 5, 0x00); ++ rt2800_rfcsr_write(rt2x00dev, 6, 0x40); ++ rt2800_rfcsr_write(rt2x00dev, 7, 0x00); ++ rt2800_rfcsr_write(rt2x00dev, 8, 0x5b); ++ rt2800_rfcsr_write(rt2x00dev, 9, 0x08); ++ rt2800_rfcsr_write(rt2x00dev, 10, 0xd3); ++ rt2800_rfcsr_write(rt2x00dev, 11, 0x48); ++ rt2800_rfcsr_write(rt2x00dev, 12, 0x1a); ++ rt2800_rfcsr_write(rt2x00dev, 13, 0x12); ++ rt2800_rfcsr_write(rt2x00dev, 14, 0x00); ++ rt2800_rfcsr_write(rt2x00dev, 15, 0x00); ++ rt2800_rfcsr_write(rt2x00dev, 16, 0x00); ++ ++ /* RFCSR 17 will be initialized later based on the ++ * frequency offset stored in the EEPROM ++ */ ++ ++ rt2800_rfcsr_write(rt2x00dev, 18, 0x40); ++ rt2800_rfcsr_write(rt2x00dev, 19, 0x00); ++ rt2800_rfcsr_write(rt2x00dev, 20, 0x00); ++ rt2800_rfcsr_write(rt2x00dev, 21, 0x00); ++ rt2800_rfcsr_write(rt2x00dev, 22, 0x20); ++ rt2800_rfcsr_write(rt2x00dev, 23, 0xc0); ++ rt2800_rfcsr_write(rt2x00dev, 24, 0x00); ++ rt2800_rfcsr_write(rt2x00dev, 25, 0x00); ++ rt2800_rfcsr_write(rt2x00dev, 26, 0x00); ++ rt2800_rfcsr_write(rt2x00dev, 27, 0x00); ++ rt2800_rfcsr_write(rt2x00dev, 28, 0x00); ++ rt2800_rfcsr_write(rt2x00dev, 29, 0x00); ++ rt2800_rfcsr_write(rt2x00dev, 30, 0x10); ++ rt2800_rfcsr_write(rt2x00dev, 31, 0x80); ++ rt2800_rfcsr_write(rt2x00dev, 32, 0x80); ++ rt2800_rfcsr_write(rt2x00dev, 33, 0x00); ++ rt2800_rfcsr_write(rt2x00dev, 34, 0x20); ++ rt2800_rfcsr_write(rt2x00dev, 35, 0x00); ++ rt2800_rfcsr_write(rt2x00dev, 36, 0x00); ++ rt2800_rfcsr_write(rt2x00dev, 37, 0x00); ++ rt2800_rfcsr_write(rt2x00dev, 38, 0x86); ++ rt2800_rfcsr_write(rt2x00dev, 39, 0x23); ++ rt2800_rfcsr_write(rt2x00dev, 40, 0x00); ++ rt2800_rfcsr_write(rt2x00dev, 41, 0x00); ++ rt2800_rfcsr_write(rt2x00dev, 42, 0x00); ++ rt2800_rfcsr_write(rt2x00dev, 43, 0x00); ++ rt2800_rfcsr_write(rt2x00dev, 44, 0x93); ++ rt2800_rfcsr_write(rt2x00dev, 45, 0xbb); ++ rt2800_rfcsr_write(rt2x00dev, 46, 0x60); ++ rt2800_rfcsr_write(rt2x00dev, 47, 0x00); ++ rt2800_rfcsr_write(rt2x00dev, 48, 0x00); ++ rt2800_rfcsr_write(rt2x00dev, 49, 0x8e); ++ rt2800_rfcsr_write(rt2x00dev, 50, 0x86); ++ rt2800_rfcsr_write(rt2x00dev, 51, 0x51); ++ rt2800_rfcsr_write(rt2x00dev, 52, 0x05); ++ rt2800_rfcsr_write(rt2x00dev, 53, 0x76); ++ rt2800_rfcsr_write(rt2x00dev, 54, 0x76); ++ rt2800_rfcsr_write(rt2x00dev, 55, 0x76); ++ rt2800_rfcsr_write(rt2x00dev, 56, 0xdb); ++ rt2800_rfcsr_write(rt2x00dev, 57, 0x3e); ++ rt2800_rfcsr_write(rt2x00dev, 58, 0x00); ++ rt2800_rfcsr_write(rt2x00dev, 59, 0x00); ++ rt2800_rfcsr_write(rt2x00dev, 60, 0x00); ++ rt2800_rfcsr_write(rt2x00dev, 61, 0x00); ++ rt2800_rfcsr_write(rt2x00dev, 62, 0x00); ++ rt2800_rfcsr_write(rt2x00dev, 63, 0x00); ++ ++ /* TODO: rx filter calibration? */ ++ ++ rt2800_bbp_write(rt2x00dev, 137, 0x0f); ++ ++ rt2800_bbp_write(rt2x00dev, 163, 0x9d); ++ ++ rt2800_bbp_write(rt2x00dev, 105, 0x05); ++ ++ rt2800_bbp_write(rt2x00dev, 179, 0x02); ++ rt2800_bbp_write(rt2x00dev, 180, 0x00); ++ rt2800_bbp_write(rt2x00dev, 182, 0x40); ++ rt2800_bbp_write(rt2x00dev, 180, 0x01); ++ rt2800_bbp_write(rt2x00dev, 182, 0x9c); ++ ++ rt2800_bbp_write(rt2x00dev, 179, 0x00); ++ ++ rt2800_bbp_write(rt2x00dev, 142, 0x04); ++ rt2800_bbp_write(rt2x00dev, 143, 0x3b); ++ rt2800_bbp_write(rt2x00dev, 142, 0x06); ++ rt2800_bbp_write(rt2x00dev, 143, 0xa0); ++ rt2800_bbp_write(rt2x00dev, 142, 0x07); ++ rt2800_bbp_write(rt2x00dev, 143, 0xa1); ++ rt2800_bbp_write(rt2x00dev, 142, 0x08); ++ rt2800_bbp_write(rt2x00dev, 143, 0xa2); ++ rt2800_bbp_write(rt2x00dev, 148, 0xc8); ++ ++ if (eco == 5) { ++ rt2800_rfcsr_write(rt2x00dev, 32, 0xd8); ++ rt2800_rfcsr_write(rt2x00dev, 33, 0x32); ++ } ++ ++ rt2800_rfcsr_read(rt2x00dev, 2, &rfcsr); ++ rt2x00_set_field8(&rfcsr, RFCSR2_RESCAL_BP, 0); ++ rt2x00_set_field8(&rfcsr, RFCSR2_RESCAL_EN, 1); ++ rt2800_rfcsr_write(rt2x00dev, 2, rfcsr); ++ msleep(1); ++ rt2x00_set_field8(&rfcsr, RFCSR2_RESCAL_EN, 0); ++ rt2800_rfcsr_write(rt2x00dev, 2, rfcsr); ++ ++ rt2800_rfcsr_read(rt2x00dev, 1, &rfcsr); ++ rt2x00_set_field8(&rfcsr, RFCSR1_RF_BLOCK_EN, 1); ++ rt2800_rfcsr_write(rt2x00dev, 1, rfcsr); ++ ++ rt2800_rfcsr_read(rt2x00dev, 6, &rfcsr); ++ rfcsr |= 0xc0; ++ rt2800_rfcsr_write(rt2x00dev, 6, rfcsr); ++ ++ rt2800_rfcsr_read(rt2x00dev, 22, &rfcsr); ++ rfcsr |= 0x20; ++ rt2800_rfcsr_write(rt2x00dev, 22, rfcsr); ++ ++ rt2800_rfcsr_read(rt2x00dev, 46, &rfcsr); ++ rfcsr |= 0x20; ++ rt2800_rfcsr_write(rt2x00dev, 46, rfcsr); ++ ++ rt2800_rfcsr_read(rt2x00dev, 20, &rfcsr); ++ rfcsr &= ~0xee; ++ rt2800_rfcsr_write(rt2x00dev, 20, rfcsr); ++} ++ + static void rt2800_init_rfcsr_5390(struct rt2x00_dev *rt2x00dev) + { + rt2800_rf_init_calibration(rt2x00dev, 2); +@@ -7130,6 +7268,9 @@ static void rt2800_init_rfcsr(struct rt2 + case RT3390: + rt2800_init_rfcsr_3390(rt2x00dev); + break; ++ case RT3883: ++ rt2800_init_rfcsr_3883(rt2x00dev); ++ break; + case RT3572: + rt2800_init_rfcsr_3572(rt2x00dev); + break; diff --git a/package/kernel/mac80211/patches/600-11-rt2x00-rt2800lib-use-the-extended-EEPROM-map-for-RT3.patch b/package/kernel/mac80211/patches/600-11-rt2x00-rt2800lib-use-the-extended-EEPROM-map-for-RT3.patch new file mode 100644 index 0000000000..00e00b959f --- /dev/null +++ b/package/kernel/mac80211/patches/600-11-rt2x00-rt2800lib-use-the-extended-EEPROM-map-for-RT3.patch @@ -0,0 +1,22 @@ +From 86022438ffeb1b87dfcd018bf477fdbb43076691 Mon Sep 17 00:00:00 2001 +From: Gabor Juhos +Date: Wed, 8 May 2013 19:35:33 +0200 +Subject: [PATCH] rt2x00: rt2800lib: use the extended EEPROM map for RT3883 + +Signed-off-by: Gabor Juhos +--- + drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c +@@ -309,7 +309,8 @@ static unsigned int rt2800_eeprom_word_i + wiphy_name(rt2x00dev->hw->wiphy), word)) + return 0; + +- if (rt2x00_rt(rt2x00dev, RT3593)) ++ if (rt2x00_rt(rt2x00dev, RT3593) || ++ rt2x00_rt(rt2x00dev, RT3883)) + map = rt2800_eeprom_map_ext; + else + map = rt2800_eeprom_map; diff --git a/package/kernel/mac80211/patches/600-12-rt2x00-rt2800lib-force-rf-type-to-RF3853-on-RT3883.patch b/package/kernel/mac80211/patches/600-12-rt2x00-rt2800lib-force-rf-type-to-RF3853-on-RT3883.patch new file mode 100644 index 0000000000..11d3c8ccec --- /dev/null +++ b/package/kernel/mac80211/patches/600-12-rt2x00-rt2800lib-force-rf-type-to-RF3853-on-RT3883.patch @@ -0,0 +1,21 @@ +From 4cf5403f02fa65dc2207f61d223cffa9ae50e907 Mon Sep 17 00:00:00 2001 +From: Gabor Juhos +Date: Thu, 1 Aug 2013 14:48:21 +0200 +Subject: [PATCH] rt2x00: rt2800lib: force rf type to RF3853 on RT3883 + +Signed-off-by: Gabor Juhos +--- + drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c +@@ -7660,6 +7660,8 @@ static int rt2800_init_eeprom(struct rt2 + rt2800_eeprom_read(rt2x00dev, EEPROM_CHIP_ID, &rf); + else if (rt2x00_rt(rt2x00dev, RT3352)) + rf = RF3322; ++ else if (rt2x00_rt(rt2x00dev, RT3883)) ++ rf = RF3853; + else if (rt2x00_rt(rt2x00dev, RT5350)) + rf = RF5350; + else diff --git a/package/kernel/mac80211/patches/600-13-rt2x00-rt2800lib-add-channel-configuration-code-for-.patch b/package/kernel/mac80211/patches/600-13-rt2x00-rt2800lib-add-channel-configuration-code-for-.patch new file mode 100644 index 0000000000..beebe90d36 --- /dev/null +++ b/package/kernel/mac80211/patches/600-13-rt2x00-rt2800lib-add-channel-configuration-code-for-.patch @@ -0,0 +1,136 @@ +From 269f19c848a2380db03a3f207cafb88e28d71c53 Mon Sep 17 00:00:00 2001 +From: Gabor Juhos +Date: Sun, 24 Mar 2013 19:26:28 +0100 +Subject: [PATCH] rt2x00: rt2800lib: add channel configuration code for RT3883 + +Signed-off-by: Gabor Juhos +--- + drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 72 +++++++++++++++++++++++++++++-- + 1 file changed, 69 insertions(+), 3 deletions(-) + +--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c +@@ -3371,6 +3371,36 @@ static char rt2800_txpower_to_dev(struct + return clamp_t(char, txpower, MIN_A_TXPOWER, MAX_A_TXPOWER); + } + ++static void rt3883_bbp_adjust(struct rt2x00_dev *rt2x00dev, ++ struct rf_channel *rf) ++{ ++ u8 bbp; ++ ++ bbp = (rf->channel > 14) ? 0x48 : 0x38; ++ rt2800_bbp_write_with_rx_chain(rt2x00dev, 66, bbp); ++ ++ rt2800_bbp_write(rt2x00dev, 69, 0x12); ++ ++ if (rf->channel <= 14) { ++ rt2800_bbp_write(rt2x00dev, 70, 0x0a); ++ } else { ++ /* Disable CCK packet detection */ ++ rt2800_bbp_write(rt2x00dev, 70, 0x00); ++ } ++ ++ rt2800_bbp_write(rt2x00dev, 73, 0x10); ++ ++ if (rf->channel > 14) { ++ rt2800_bbp_write(rt2x00dev, 62, 0x1d); ++ rt2800_bbp_write(rt2x00dev, 63, 0x1d); ++ rt2800_bbp_write(rt2x00dev, 64, 0x1d); ++ } else { ++ rt2800_bbp_write(rt2x00dev, 62, 0x2d); ++ rt2800_bbp_write(rt2x00dev, 63, 0x2d); ++ rt2800_bbp_write(rt2x00dev, 64, 0x2d); ++ } ++} ++ + static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev, + struct ieee80211_conf *conf, + struct rf_channel *rf, +@@ -3389,6 +3419,12 @@ static void rt2800_config_channel(struct + rt2800_txpower_to_dev(rt2x00dev, rf->channel, + info->default_power3); + ++ switch (rt2x00dev->chip.rt) { ++ case RT3883: ++ rt3883_bbp_adjust(rt2x00dev, rf); ++ break; ++ } ++ + switch (rt2x00dev->chip.rf) { + case RF2020: + case RF3020: +@@ -3490,6 +3526,15 @@ static void rt2800_config_channel(struct + rt2800_bbp_write(rt2x00dev, 63, 0x37 - rt2x00dev->lna_gain); + rt2800_bbp_write(rt2x00dev, 64, 0x37 - rt2x00dev->lna_gain); + rt2800_bbp_write(rt2x00dev, 77, 0x98); ++ } else if (rt2x00_rt(rt2x00dev, RT3883)) { ++ rt2800_bbp_write(rt2x00dev, 62, 0x37 - rt2x00dev->lna_gain); ++ rt2800_bbp_write(rt2x00dev, 63, 0x37 - rt2x00dev->lna_gain); ++ rt2800_bbp_write(rt2x00dev, 64, 0x37 - rt2x00dev->lna_gain); ++ ++ if (rt2x00dev->default_ant.rx_chain_num > 1) ++ rt2800_bbp_write(rt2x00dev, 86, 0x46); ++ else ++ rt2800_bbp_write(rt2x00dev, 86, 0); + } else { + rt2800_bbp_write(rt2x00dev, 62, 0x37 - rt2x00dev->lna_gain); + rt2800_bbp_write(rt2x00dev, 63, 0x37 - rt2x00dev->lna_gain); +@@ -3502,6 +3547,7 @@ static void rt2800_config_channel(struct + !rt2x00_rt(rt2x00dev, RT5392)) { + if (rt2x00_has_cap_external_lna_bg(rt2x00dev)) { + rt2800_bbp_write(rt2x00dev, 82, 0x62); ++ rt2800_bbp_write(rt2x00dev, 82, 0x62); + rt2800_bbp_write(rt2x00dev, 75, 0x46); + } else { + if (rt2x00_rt(rt2x00dev, RT3593)) +@@ -3510,19 +3556,22 @@ static void rt2800_config_channel(struct + rt2800_bbp_write(rt2x00dev, 82, 0x84); + rt2800_bbp_write(rt2x00dev, 75, 0x50); + } +- if (rt2x00_rt(rt2x00dev, RT3593)) ++ if (rt2x00_rt(rt2x00dev, RT3593) || ++ rt2x00_rt(rt2x00dev, RT3883)) + rt2800_bbp_write(rt2x00dev, 83, 0x8a); + } + + } else { + if (rt2x00_rt(rt2x00dev, RT3572)) + rt2800_bbp_write(rt2x00dev, 82, 0x94); +- else if (rt2x00_rt(rt2x00dev, RT3593)) ++ else if (rt2x00_rt(rt2x00dev, RT3593) || ++ rt2x00_rt(rt2x00dev, RT3883)) + rt2800_bbp_write(rt2x00dev, 82, 0x82); + else + rt2800_bbp_write(rt2x00dev, 82, 0xf2); + +- if (rt2x00_rt(rt2x00dev, RT3593)) ++ if (rt2x00_rt(rt2x00dev, RT3593) || ++ rt2x00_rt(rt2x00dev, RT3883)) + rt2800_bbp_write(rt2x00dev, 83, 0x9a); + + if (rt2x00_has_cap_external_lna_a(rt2x00dev)) +@@ -3644,6 +3693,23 @@ static void rt2800_config_channel(struct + + rt2800_bbp_write_with_rx_chain(rt2x00dev, 66, reg); + ++ usleep_range(1000, 1500); ++ } ++ ++ if (rt2x00_rt(rt2x00dev, RT3883)) { ++ if (!conf_is_ht40(conf)) ++ rt2800_bbp_write(rt2x00dev, 105, 0x34); ++ else ++ rt2800_bbp_write(rt2x00dev, 105, 0x04); ++ ++ /* AGC init */ ++ if (rf->channel <= 14) ++ reg = 0x2e + rt2x00dev->lna_gain; ++ else ++ reg = 0x20 + ((rt2x00dev->lna_gain * 5) / 3); ++ ++ rt2800_bbp_write_with_rx_chain(rt2x00dev, 66, reg); ++ + usleep_range(1000, 1500); + } + diff --git a/package/kernel/mac80211/patches/600-14-rt2x00-rt2800lib-fix-txpower_to_dev-function-for-RT3.patch b/package/kernel/mac80211/patches/600-14-rt2x00-rt2800lib-fix-txpower_to_dev-function-for-RT3.patch new file mode 100644 index 0000000000..f18f9d5714 --- /dev/null +++ b/package/kernel/mac80211/patches/600-14-rt2x00-rt2800lib-fix-txpower_to_dev-function-for-RT3.patch @@ -0,0 +1,30 @@ +From e37d93abaabe3ab72b0332a18092acc162307274 Mon Sep 17 00:00:00 2001 +From: Gabor Juhos +Date: Mon, 30 Sep 2013 13:57:26 +0200 +Subject: [PATCH] rt2x00: rt2800lib: fix txpower_to_dev function for RT3883 + +Signed-off-by: Gabor Juhos +--- + drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c +@@ -3358,13 +3358,15 @@ static char rt2800_txpower_to_dev(struct + unsigned int channel, + char txpower) + { +- if (rt2x00_rt(rt2x00dev, RT3593)) ++ if (rt2x00_rt(rt2x00dev, RT3593) || ++ rt2x00_rt(rt2x00dev, RT3883)) + txpower = rt2x00_get_field8(txpower, EEPROM_TXPOWER_ALC); + + if (channel <= 14) + return clamp_t(char, txpower, MIN_G_TXPOWER, MAX_G_TXPOWER); + +- if (rt2x00_rt(rt2x00dev, RT3593)) ++ if (rt2x00_rt(rt2x00dev, RT3593) || ++ rt2x00_rt(rt2x00dev, RT3883)) + return clamp_t(char, txpower, MIN_A_TXPOWER_3593, + MAX_A_TXPOWER_3593); + else diff --git a/package/kernel/mac80211/patches/600-15-rt2x00-rt2800lib-use-correct-txpower-calculation-fun.patch b/package/kernel/mac80211/patches/600-15-rt2x00-rt2800lib-use-correct-txpower-calculation-fun.patch new file mode 100644 index 0000000000..0acdf2af79 --- /dev/null +++ b/package/kernel/mac80211/patches/600-15-rt2x00-rt2800lib-use-correct-txpower-calculation-fun.patch @@ -0,0 +1,23 @@ +From c4d79e344bd580d85821390d49f92dced7d8e125 Mon Sep 17 00:00:00 2001 +From: Gabor Juhos +Date: Sun, 24 Mar 2013 19:26:29 +0100 +Subject: [PATCH] rt2x00: rt2800lib: use correct txpower calculation function + for RT3883 + +Signed-off-by: Gabor Juhos +--- + drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c +@@ -4596,7 +4596,8 @@ static void rt2800_config_txpower(struct + struct ieee80211_channel *chan, + int power_level) + { +- if (rt2x00_rt(rt2x00dev, RT3593)) ++ if (rt2x00_rt(rt2x00dev, RT3593) || ++ rt2x00_rt(rt2x00dev, RT3883)) + rt2800_config_txpower_rt3593(rt2x00dev, chan, power_level); + else + rt2800_config_txpower_rt28xx(rt2x00dev, chan, power_level); diff --git a/package/kernel/mac80211/patches/600-16-rt2x00-rt2800lib-hardcode-txmixer-gain-values-to-zer.patch b/package/kernel/mac80211/patches/600-16-rt2x00-rt2800lib-hardcode-txmixer-gain-values-to-zer.patch new file mode 100644 index 0000000000..5877a32bd8 --- /dev/null +++ b/package/kernel/mac80211/patches/600-16-rt2x00-rt2800lib-hardcode-txmixer-gain-values-to-zer.patch @@ -0,0 +1,33 @@ +From caea0671cd8fd9ade4f5969cbe0ee545e94ae105 Mon Sep 17 00:00:00 2001 +From: Gabor Juhos +Date: Sat, 24 Aug 2013 11:49:55 +0200 +Subject: [PATCH] rt2x00: rt2800lib: hardcode txmixer gain values to zero for + RT3883 + +Signed-off-by: Gabor Juhos +--- + drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c +@@ -7543,7 +7543,8 @@ static u8 rt2800_get_txmixer_gain_24g(st + { + u16 word; + +- if (rt2x00_rt(rt2x00dev, RT3593)) ++ if (rt2x00_rt(rt2x00dev, RT3593) || ++ rt2x00_rt(rt2x00dev, RT3883)) + return 0; + + rt2800_eeprom_read(rt2x00dev, EEPROM_TXMIXER_GAIN_BG, &word); +@@ -7557,7 +7558,8 @@ static u8 rt2800_get_txmixer_gain_5g(str + { + u16 word; + +- if (rt2x00_rt(rt2x00dev, RT3593)) ++ if (rt2x00_rt(rt2x00dev, RT3593) || ++ rt2x00_rt(rt2x00dev, RT3883)) + return 0; + + rt2800_eeprom_read(rt2x00dev, EEPROM_TXMIXER_GAIN_A, &word); diff --git a/package/kernel/mac80211/patches/600-17-rt2x00-rt2800lib-use-correct-RT-XWI-size-for-RT3883.patch b/package/kernel/mac80211/patches/600-17-rt2x00-rt2800lib-use-correct-RT-XWI-size-for-RT3883.patch new file mode 100644 index 0000000000..abc6eb4414 --- /dev/null +++ b/package/kernel/mac80211/patches/600-17-rt2x00-rt2800lib-use-correct-RT-XWI-size-for-RT3883.patch @@ -0,0 +1,20 @@ +From 11c40fb47c4a4dd6ad060c2ae127ced89ffb9fe1 Mon Sep 17 00:00:00 2001 +From: Gabor Juhos +Date: Thu, 18 Apr 2013 14:33:33 +0200 +Subject: [PATCH] rt2x00: rt2800lib: use correct [RT]XWI size for RT3883 + +Signed-off-by: Gabor Juhos +--- + drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c +@@ -520,6 +520,7 @@ void rt2800_get_txwi_rxwi_size(struct rt + { + switch (rt2x00dev->chip.rt) { + case RT3593: ++ case RT3883: + *txwi_size = TXWI_DESC_SIZE_4WORDS; + *rxwi_size = RXWI_DESC_SIZE_5WORDS; + break; diff --git a/package/kernel/mac80211/patches/600-18-rt2x00-rt2800lib-fix-antenna-configuration-for-RT388.patch b/package/kernel/mac80211/patches/600-18-rt2x00-rt2800lib-fix-antenna-configuration-for-RT388.patch new file mode 100644 index 0000000000..c1e41bb84e --- /dev/null +++ b/package/kernel/mac80211/patches/600-18-rt2x00-rt2800lib-fix-antenna-configuration-for-RT388.patch @@ -0,0 +1,22 @@ +From fa5ad9c025610c22048add2f0ad03f62b6ca1e74 Mon Sep 17 00:00:00 2001 +From: Gabor Juhos +Date: Mon, 30 Sep 2013 16:53:33 +0200 +Subject: [PATCH] rt2x00: rt2800lib: fix antenna configuration for RT3883 + +Signed-off-by: Gabor Juhos +--- + drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c +@@ -1888,7 +1888,8 @@ void rt2800_config_ant(struct rt2x00_dev + rt2800_bbp_write(rt2x00dev, 3, r3); + rt2800_bbp_write(rt2x00dev, 1, r1); + +- if (rt2x00_rt(rt2x00dev, RT3593)) { ++ if (rt2x00_rt(rt2x00dev, RT3593) || ++ rt2x00_rt(rt2x00dev, RT3883)) { + if (ant->rx_chain_num == 1) + rt2800_bbp_write(rt2x00dev, 86, 0x00); + else diff --git a/package/kernel/mac80211/patches/600-19-rt2x00-rt2800lib-fix-LNA-gain-configuration-for-RT38.patch b/package/kernel/mac80211/patches/600-19-rt2x00-rt2800lib-fix-LNA-gain-configuration-for-RT38.patch new file mode 100644 index 0000000000..645b3c54e9 --- /dev/null +++ b/package/kernel/mac80211/patches/600-19-rt2x00-rt2800lib-fix-LNA-gain-configuration-for-RT38.patch @@ -0,0 +1,32 @@ +From 6d668fef3a1baa60bdd715ee062ddb6333d2647c Mon Sep 17 00:00:00 2001 +From: Gabor Juhos +Date: Mon, 30 Sep 2013 16:58:23 +0200 +Subject: [PATCH] rt2x00: rt2800lib: fix LNA gain configuration for RT3883 + +Signed-off-by: Gabor Juhos +--- + drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c +@@ -1911,7 +1911,8 @@ static void rt2800_config_lna_gain(struc + rt2800_eeprom_read(rt2x00dev, EEPROM_LNA, &eeprom); + lna_gain = rt2x00_get_field16(eeprom, EEPROM_LNA_A0); + } else if (libconf->rf.channel <= 128) { +- if (rt2x00_rt(rt2x00dev, RT3593)) { ++ if (rt2x00_rt(rt2x00dev, RT3593) || ++ rt2x00_rt(rt2x00dev, RT3883)) { + rt2800_eeprom_read(rt2x00dev, EEPROM_EXT_LNA2, &eeprom); + lna_gain = rt2x00_get_field16(eeprom, + EEPROM_EXT_LNA2_A1); +@@ -1921,7 +1922,8 @@ static void rt2800_config_lna_gain(struc + EEPROM_RSSI_BG2_LNA_A1); + } + } else { +- if (rt2x00_rt(rt2x00dev, RT3593)) { ++ if (rt2x00_rt(rt2x00dev, RT3593) || ++ rt2x00_rt(rt2x00dev, RT3883)) { + rt2800_eeprom_read(rt2x00dev, EEPROM_EXT_LNA2, &eeprom); + lna_gain = rt2x00_get_field16(eeprom, + EEPROM_EXT_LNA2_A2); diff --git a/package/kernel/mac80211/patches/600-20-rt2x00-rt2800lib-fix-VGC-setup-for-RT3883.patch b/package/kernel/mac80211/patches/600-20-rt2x00-rt2800lib-fix-VGC-setup-for-RT3883.patch new file mode 100644 index 0000000000..57ea80ea0f --- /dev/null +++ b/package/kernel/mac80211/patches/600-20-rt2x00-rt2800lib-fix-VGC-setup-for-RT3883.patch @@ -0,0 +1,44 @@ +From c49b2d829aa1c816a46a577cdec6d2ff14d9f06e Mon Sep 17 00:00:00 2001 +From: Gabor Juhos +Date: Tue, 1 Oct 2013 15:40:08 +0200 +Subject: [PATCH] rt2x00: rt2800lib: fix VGC setup for RT3883 + +Signed-off-by: Gabor Juhos +--- + drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 11 +++++++++-- + 1 file changed, 9 insertions(+), 2 deletions(-) + +--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c +@@ -4799,7 +4799,8 @@ static u8 rt2800_get_default_vgc(struct + else + vgc = 0x2e + rt2x00dev->lna_gain; + } else { /* 5GHZ band */ +- if (rt2x00_rt(rt2x00dev, RT3593)) ++ if (rt2x00_rt(rt2x00dev, RT3593) || ++ rt2x00_rt(rt2x00dev, RT3883)) + vgc = 0x20 + (rt2x00dev->lna_gain * 5) / 3; + else if (rt2x00_rt(rt2x00dev, RT5592)) + vgc = 0x24 + (2 * rt2x00dev->lna_gain); +@@ -4819,7 +4820,8 @@ static inline void rt2800_set_vgc(struct + { + if (qual->vgc_level != vgc_level) { + if (rt2x00_rt(rt2x00dev, RT3572) || +- rt2x00_rt(rt2x00dev, RT3593)) { ++ rt2x00_rt(rt2x00dev, RT3593) || ++ rt2x00_rt(rt2x00dev, RT3883)) { + rt2800_bbp_write_with_rx_chain(rt2x00dev, 66, + vgc_level); + } else if (rt2x00_rt(rt2x00dev, RT5592)) { +@@ -4866,6 +4868,11 @@ void rt2800_link_tuner(struct rt2x00_dev + } + break; + ++ case RT3883: ++ if (qual->rssi > -65) ++ vgc += 0x10; ++ break; ++ + case RT5592: + if (qual->rssi > -65) + vgc += 0x20; diff --git a/package/kernel/mac80211/patches/600-21-rt2x00-rt2800lib-fix-EEPROM-LNA-validation-for-RT388.patch b/package/kernel/mac80211/patches/600-21-rt2x00-rt2800lib-fix-EEPROM-LNA-validation-for-RT388.patch new file mode 100644 index 0000000000..bb6f4fd684 --- /dev/null +++ b/package/kernel/mac80211/patches/600-21-rt2x00-rt2800lib-fix-EEPROM-LNA-validation-for-RT388.patch @@ -0,0 +1,42 @@ +From 1616650aea676541d4dc8adc6f4219856d193c8b Mon Sep 17 00:00:00 2001 +From: Gabor Juhos +Date: Tue, 1 Oct 2013 17:27:57 +0200 +Subject: [PATCH] rt2x00: rt2800lib: fix EEPROM LNA validation for RT3883 + +Signed-off-by: Gabor Juhos +--- + drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 9 ++++++--- + 1 file changed, 6 insertions(+), 3 deletions(-) + +--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c +@@ -7676,7 +7676,8 @@ static int rt2800_validate_eeprom(struct + rt2800_eeprom_read(rt2x00dev, EEPROM_RSSI_BG2, &word); + if (abs(rt2x00_get_field16(word, EEPROM_RSSI_BG2_OFFSET2)) > 10) + rt2x00_set_field16(&word, EEPROM_RSSI_BG2_OFFSET2, 0); +- if (!rt2x00_rt(rt2x00dev, RT3593)) { ++ if (!rt2x00_rt(rt2x00dev, RT3593) && ++ !rt2x00_rt(rt2x00dev, RT3883)) { + if (rt2x00_get_field16(word, EEPROM_RSSI_BG2_LNA_A1) == 0x00 || + rt2x00_get_field16(word, EEPROM_RSSI_BG2_LNA_A1) == 0xff) + rt2x00_set_field16(&word, EEPROM_RSSI_BG2_LNA_A1, +@@ -7696,7 +7697,8 @@ static int rt2800_validate_eeprom(struct + rt2800_eeprom_read(rt2x00dev, EEPROM_RSSI_A2, &word); + if (abs(rt2x00_get_field16(word, EEPROM_RSSI_A2_OFFSET2)) > 10) + rt2x00_set_field16(&word, EEPROM_RSSI_A2_OFFSET2, 0); +- if (!rt2x00_rt(rt2x00dev, RT3593)) { ++ if (!rt2x00_rt(rt2x00dev, RT3593) && ++ !rt2x00_rt(rt2x00dev, RT3883)) { + if (rt2x00_get_field16(word, EEPROM_RSSI_A2_LNA_A2) == 0x00 || + rt2x00_get_field16(word, EEPROM_RSSI_A2_LNA_A2) == 0xff) + rt2x00_set_field16(&word, EEPROM_RSSI_A2_LNA_A2, +@@ -7704,7 +7706,8 @@ static int rt2800_validate_eeprom(struct + } + rt2800_eeprom_write(rt2x00dev, EEPROM_RSSI_A2, word); + +- if (rt2x00_rt(rt2x00dev, RT3593)) { ++ if (rt2x00_rt(rt2x00dev, RT3593) || ++ rt2x00_rt(rt2x00dev, RT3883)) { + rt2800_eeprom_read(rt2x00dev, EEPROM_EXT_LNA2, &word); + if (rt2x00_get_field16(word, EEPROM_EXT_LNA2_A1) == 0x00 || + rt2x00_get_field16(word, EEPROM_EXT_LNA2_A1) == 0xff) diff --git a/package/kernel/mac80211/patches/600-22-rt2x00-rt2800lib-fix-txpower-compensation-for-RT3883.patch b/package/kernel/mac80211/patches/600-22-rt2x00-rt2800lib-fix-txpower-compensation-for-RT3883.patch new file mode 100644 index 0000000000..b4872b5108 --- /dev/null +++ b/package/kernel/mac80211/patches/600-22-rt2x00-rt2800lib-fix-txpower-compensation-for-RT3883.patch @@ -0,0 +1,22 @@ +From e3871034a0e7c8a95152dc3eafbcc4535398cbdc Mon Sep 17 00:00:00 2001 +From: Gabor Juhos +Date: Wed, 2 Oct 2013 10:11:59 +0200 +Subject: [PATCH] rt2x00: rt2800lib: fix txpower compensation for RT3883 + +Signed-off-by: Gabor Juhos +--- + drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c +@@ -3965,6 +3965,9 @@ static u8 rt2800_compensate_txpower(stru + if (rt2x00_rt(rt2x00dev, RT3593)) + return min_t(u8, txpower, 0xc); + ++ if (rt2x00_rt(rt2x00dev, RT3883)) ++ return min_t(u8, txpower, 0xf); ++ + if (rt2x00_has_cap_power_limit(rt2x00dev)) { + /* + * Check if eirp txpower exceed txpower_limit. diff --git a/package/kernel/mac80211/patches/600-23-rt2x00-rt2800mmio-add-a-workaround-for-spurious-TX_F.patch b/package/kernel/mac80211/patches/600-23-rt2x00-rt2800mmio-add-a-workaround-for-spurious-TX_F.patch new file mode 100644 index 0000000000..a6dc6a6afb --- /dev/null +++ b/package/kernel/mac80211/patches/600-23-rt2x00-rt2800mmio-add-a-workaround-for-spurious-TX_F.patch @@ -0,0 +1,136 @@ +From 5e67d4f8a46d19748b501c2ef86de3f50d3cfd51 Mon Sep 17 00:00:00 2001 +From: Gabor Juhos +Date: Sun, 24 Mar 2013 19:26:27 +0100 +Subject: [PATCH] rt2x00: rt2800mmio: add a workaround for spurious + TX_FIFO_STATUS interrupts + +Signed-off-by: Gabor Juhos +--- + drivers/net/wireless/ralink/rt2x00/rt2800mmio.c | 72 +++++++++++++++++++++++++----- + drivers/net/wireless/ralink/rt2x00/rt2x00.h | 5 +++ + 2 files changed, 65 insertions(+), 12 deletions(-) + +--- a/drivers/net/wireless/ralink/rt2x00/rt2800mmio.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2800mmio.c +@@ -415,9 +415,9 @@ void rt2800mmio_autowake_tasklet(unsigne + } + EXPORT_SYMBOL_GPL(rt2800mmio_autowake_tasklet); + +-static void rt2800mmio_txstatus_interrupt(struct rt2x00_dev *rt2x00dev) ++static void rt2800mmio_txstatus_interrupt(struct rt2x00_dev *rt2x00dev, ++ u32 status) + { +- u32 status; + int i; + + /* +@@ -438,29 +438,77 @@ static void rt2800mmio_txstatus_interrup + * Since we have only one producer and one consumer we don't + * need to lock the kfifo. + */ +- for (i = 0; i < rt2x00dev->tx->limit; i++) { +- rt2x00mmio_register_read(rt2x00dev, TX_STA_FIFO, &status); +- +- if (!rt2x00_get_field32(status, TX_STA_FIFO_VALID)) +- break; +- ++ i = 0; ++ do { + if (!kfifo_put(&rt2x00dev->txstatus_fifo, status)) { +- rt2x00_warn(rt2x00dev, "TX status FIFO overrun, drop tx status report\n"); ++ rt2x00_warn(rt2x00dev, ++ "TX status FIFO overrun, drop TX status report\n"); + break; + } +- } ++ ++ if (++i >= rt2x00dev->tx->limit) ++ break; ++ ++ rt2x00mmio_register_read(rt2x00dev, TX_STA_FIFO, &status); ++ } while (rt2x00_get_field32(status, TX_STA_FIFO_VALID)); + + /* Schedule the tasklet for processing the tx status. */ + tasklet_schedule(&rt2x00dev->txstatus_tasklet); + } + ++#define RT2800MMIO_TXSTATUS_IRQ_MAX_RETRIES 4 ++ ++static bool rt2800mmio_txstatus_is_spurious(struct rt2x00_dev *rt2x00dev, ++ u32 txstatus) ++{ ++ if (likely(rt2x00_get_field32(txstatus, TX_STA_FIFO_VALID))) { ++ rt2x00dev->txstatus_irq_retries = 0; ++ return false; ++ } ++ ++ rt2x00dev->txstatus_irq_retries++; ++ ++ /* Ensure that we don't go into an infinite IRQ loop. */ ++ if (rt2x00dev->txstatus_irq_retries >= ++ RT2800MMIO_TXSTATUS_IRQ_MAX_RETRIES) { ++ rt2x00_warn(rt2x00dev, ++ "%u spurious TX_FIFO_STATUS interrupt(s)\n", ++ rt2x00dev->txstatus_irq_retries); ++ rt2x00dev->txstatus_irq_retries = 0; ++ return false; ++ } ++ ++ return true; ++} ++ + irqreturn_t rt2800mmio_interrupt(int irq, void *dev_instance) + { + struct rt2x00_dev *rt2x00dev = dev_instance; + u32 reg, mask; ++ u32 txstatus = 0; + +- /* Read status and ACK all interrupts */ ++ /* Read status */ + rt2x00mmio_register_read(rt2x00dev, INT_SOURCE_CSR, ®); ++ ++ if (rt2x00_get_field32(reg, INT_SOURCE_CSR_TX_FIFO_STATUS)) { ++ /* Due to unknown reason the hardware generates a ++ * TX_FIFO_STATUS interrupt before the TX_STA_FIFO ++ * register contain valid data. Read the TX status ++ * here to see if we have to process the actual ++ * request. ++ */ ++ rt2x00mmio_register_read(rt2x00dev, TX_STA_FIFO, &txstatus); ++ if (rt2800mmio_txstatus_is_spurious(rt2x00dev, txstatus)) { ++ /* Remove the TX_FIFO_STATUS bit so it won't be ++ * processed in this turn. The hardware will ++ * generate another IRQ for us. ++ */ ++ rt2x00_set_field32(®, ++ INT_SOURCE_CSR_TX_FIFO_STATUS, 0); ++ } ++ } ++ ++ /* ACK interrupts */ + rt2x00mmio_register_write(rt2x00dev, INT_SOURCE_CSR, reg); + + if (!reg) +@@ -477,7 +525,7 @@ irqreturn_t rt2800mmio_interrupt(int irq + mask = ~reg; + + if (rt2x00_get_field32(reg, INT_SOURCE_CSR_TX_FIFO_STATUS)) { +- rt2800mmio_txstatus_interrupt(rt2x00dev); ++ rt2800mmio_txstatus_interrupt(rt2x00dev, txstatus); + /* + * Never disable the TX_FIFO_STATUS interrupt. + */ +--- a/drivers/net/wireless/ralink/rt2x00/rt2x00.h ++++ b/drivers/net/wireless/ralink/rt2x00/rt2x00.h +@@ -999,6 +999,11 @@ struct rt2x00_dev { + int rf_channel; + + /* ++ * Counter for tx status irq retries (rt2800pci). ++ */ ++ unsigned int txstatus_irq_retries; ++ ++ /* + * Protect the interrupt mask register. + */ + spinlock_t irqmask_lock; diff --git a/package/kernel/mac80211/patches/601-rt2x00-introduce-rt2x00_platform_h.patch b/package/kernel/mac80211/patches/601-rt2x00-introduce-rt2x00_platform_h.patch new file mode 100644 index 0000000000..9d47076ff6 --- /dev/null +++ b/package/kernel/mac80211/patches/601-rt2x00-introduce-rt2x00_platform_h.patch @@ -0,0 +1,32 @@ +--- /dev/null ++++ b/include/linux/rt2x00_platform.h +@@ -0,0 +1,19 @@ ++/* ++ * Platform data definition for the rt2x00 driver ++ * ++ * Copyright (C) 2011 Gabor Juhos ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 as published ++ * by the Free Software Foundation. ++ * ++ */ ++ ++#ifndef _RT2X00_PLATFORM_H ++#define _RT2X00_PLATFORM_H ++ ++struct rt2x00_platform_data { ++ char *eeprom_file_name; ++}; ++ ++#endif /* _RT2X00_PLATFORM_H */ +--- a/drivers/net/wireless/ralink/rt2x00/rt2x00.h ++++ b/drivers/net/wireless/ralink/rt2x00/rt2x00.h +@@ -40,6 +40,7 @@ + #include + #include + #include ++#include + + #include + diff --git a/package/kernel/mac80211/patches/601-rt2x00-set_pci_mwi.patch b/package/kernel/mac80211/patches/601-rt2x00-set_pci_mwi.patch deleted file mode 100644 index a40716163f..0000000000 --- a/package/kernel/mac80211/patches/601-rt2x00-set_pci_mwi.patch +++ /dev/null @@ -1,13 +0,0 @@ ---- a/drivers/net/wireless/ralink/rt2x00/rt2x00pci.c -+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00pci.c -@@ -94,8 +94,10 @@ int rt2x00pci_probe(struct pci_dev *pci_ - - pci_set_master(pci_dev); - -+#ifdef CONFIG_PCI_SET_MWI - if (pci_set_mwi(pci_dev)) - rt2x00_probe_err("MWI not available\n"); -+#endif - - if (dma_set_mask(&pci_dev->dev, DMA_BIT_MASK(32))) { - rt2x00_probe_err("PCI DMA not supported\n"); diff --git a/package/kernel/mac80211/patches/602-rt2x00-introduce-rt2x00_platform_h.patch b/package/kernel/mac80211/patches/602-rt2x00-introduce-rt2x00_platform_h.patch deleted file mode 100644 index daa5dc61f9..0000000000 --- a/package/kernel/mac80211/patches/602-rt2x00-introduce-rt2x00_platform_h.patch +++ /dev/null @@ -1,32 +0,0 @@ ---- /dev/null -+++ b/include/linux/rt2x00_platform.h -@@ -0,0 +1,19 @@ -+/* -+ * Platform data definition for the rt2x00 driver -+ * -+ * Copyright (C) 2011 Gabor Juhos -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ * -+ */ -+ -+#ifndef _RT2X00_PLATFORM_H -+#define _RT2X00_PLATFORM_H -+ -+struct rt2x00_platform_data { -+ char *eeprom_file_name; -+}; -+ -+#endif /* _RT2X00_PLATFORM_H */ ---- a/drivers/net/wireless/ralink/rt2x00/rt2x00.h -+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00.h -@@ -39,6 +39,7 @@ - #include - #include - #include -+#include - - #include - diff --git a/package/kernel/mac80211/patches/602-rt2x00-introduce-rt2x00eeprom.patch b/package/kernel/mac80211/patches/602-rt2x00-introduce-rt2x00eeprom.patch new file mode 100644 index 0000000000..65711ae330 --- /dev/null +++ b/package/kernel/mac80211/patches/602-rt2x00-introduce-rt2x00eeprom.patch @@ -0,0 +1,295 @@ +--- a/.local-symbols ++++ b/.local-symbols +@@ -336,6 +336,7 @@ RT2X00_LIB_FIRMWARE= + RT2X00_LIB_CRYPTO= + RT2X00_LIB_LEDS= + RT2X00_LIB_DEBUGFS= ++RT2X00_LIB_EEPROM= + RT2X00_DEBUG= + WLAN_VENDOR_REALTEK= + RTL8180= +--- a/drivers/net/wireless/ralink/rt2x00/Kconfig ++++ b/drivers/net/wireless/ralink/rt2x00/Kconfig +@@ -69,6 +69,7 @@ config RT2800PCI + select RT2X00_LIB_MMIO + select RT2X00_LIB_PCI + select RT2X00_LIB_FIRMWARE ++ select RT2X00_LIB_EEPROM + select RT2X00_LIB_CRYPTO + depends on CRC_CCITT + depends on EEPROM_93CX6 +@@ -215,6 +216,7 @@ config RT2800SOC + select RT2X00_LIB_MMIO + select RT2X00_LIB_CRYPTO + select RT2X00_LIB_FIRMWARE ++ select RT2X00_LIB_EEPROM + select RT2800_LIB + select RT2800_LIB_MMIO + ---help--- +@@ -265,6 +267,9 @@ config RT2X00_LIB_FIRMWARE + config RT2X00_LIB_CRYPTO + bool + ++config RT2X00_LIB_EEPROM ++ boolean ++ + config RT2X00_LIB_LEDS + bool + default y if (RT2X00_LIB=y && LEDS_CLASS=y) || (RT2X00_LIB=m && LEDS_CLASS!=n) +--- a/drivers/net/wireless/ralink/rt2x00/Makefile ++++ b/drivers/net/wireless/ralink/rt2x00/Makefile +@@ -7,6 +7,7 @@ rt2x00lib-$(CPTCFG_RT2X00_LIB_DEBUGFS) + + rt2x00lib-$(CPTCFG_RT2X00_LIB_CRYPTO) += rt2x00crypto.o + rt2x00lib-$(CPTCFG_RT2X00_LIB_FIRMWARE) += rt2x00firmware.o + rt2x00lib-$(CPTCFG_RT2X00_LIB_LEDS) += rt2x00leds.o ++rt2x00lib-$(CPTCFG_RT2X00_LIB_EEPROM) += rt2x00eeprom.o + + obj-$(CPTCFG_RT2X00_LIB) += rt2x00lib.o + obj-$(CPTCFG_RT2X00_LIB_MMIO) += rt2x00mmio.o +--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.h ++++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.h +@@ -20,6 +20,8 @@ + #ifndef RT2800LIB_H + #define RT2800LIB_H + ++#include "rt2800.h" ++ + struct rt2800_ops { + void (*register_read)(struct rt2x00_dev *rt2x00dev, + const unsigned int offset, u32 *value); +@@ -119,6 +121,15 @@ static inline int rt2800_read_eeprom(str + { + const struct rt2800_ops *rt2800ops = rt2x00dev->ops->drv; + ++ if (rt2x00dev->eeprom_file) { ++ memcpy(rt2x00dev->eeprom, rt2x00dev->eeprom_file->data, ++ EEPROM_SIZE); ++ return 0; ++ } ++ ++ if (!rt2800ops->read_eeprom) ++ return -EINVAL; ++ + return rt2800ops->read_eeprom(rt2x00dev); + } + +--- a/drivers/net/wireless/ralink/rt2x00/rt2800soc.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2800soc.c +@@ -102,19 +102,6 @@ static int rt2800soc_set_device_state(st + return retval; + } + +-static int rt2800soc_read_eeprom(struct rt2x00_dev *rt2x00dev) +-{ +- void __iomem *base_addr = ioremap(0x1F040000, EEPROM_SIZE); +- +- if (!base_addr) +- return -ENOMEM; +- +- memcpy_fromio(rt2x00dev->eeprom, base_addr, EEPROM_SIZE); +- +- iounmap(base_addr); +- return 0; +-} +- + /* Firmware functions */ + static char *rt2800soc_get_firmware_name(struct rt2x00_dev *rt2x00dev) + { +@@ -178,7 +165,6 @@ static const struct rt2800_ops rt2800soc + .register_multiread = rt2x00mmio_register_multiread, + .register_multiwrite = rt2x00mmio_register_multiwrite, + .regbusy_read = rt2x00mmio_regbusy_read, +- .read_eeprom = rt2800soc_read_eeprom, + .hwcrypt_disabled = rt2800soc_hwcrypt_disabled, + .drv_write_firmware = rt2800soc_write_firmware, + .drv_init_registers = rt2800mmio_init_registers, +--- a/drivers/net/wireless/ralink/rt2x00/rt2x00.h ++++ b/drivers/net/wireless/ralink/rt2x00/rt2x00.h +@@ -701,6 +701,7 @@ enum rt2x00_capability_flags { + REQUIRE_HT_TX_DESC, + REQUIRE_PS_AUTOWAKE, + REQUIRE_DELAYED_RFKILL, ++ REQUIRE_EEPROM_FILE, + + /* + * Capabilities +@@ -976,6 +977,11 @@ struct rt2x00_dev { + const struct firmware *fw; + + /* ++ * EEPROM image. ++ */ ++ const struct firmware *eeprom_file; ++ ++ /* + * FIFO for storing tx status reports between isr and tasklet. + */ + DECLARE_KFIFO_PTR(txstatus_fifo, u32); +--- a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c +@@ -1346,6 +1346,10 @@ int rt2x00lib_probe_dev(struct rt2x00_de + INIT_DELAYED_WORK(&rt2x00dev->autowakeup_work, rt2x00lib_autowakeup); + INIT_WORK(&rt2x00dev->sleep_work, rt2x00lib_sleep); + ++ retval = rt2x00lib_load_eeprom_file(rt2x00dev); ++ if (retval) ++ goto exit; ++ + /* + * Let the driver probe the device to detect the capabilities. + */ +@@ -1484,6 +1488,11 @@ void rt2x00lib_remove_dev(struct rt2x00_ + * Free the driver data. + */ + kfree(rt2x00dev->drv_data); ++ ++ /* ++ * Free EEPROM image. ++ */ ++ rt2x00lib_free_eeprom_file(rt2x00dev); + } + EXPORT_SYMBOL_GPL(rt2x00lib_remove_dev); + +--- /dev/null ++++ b/drivers/net/wireless/ralink/rt2x00/rt2x00eeprom.c +@@ -0,0 +1,105 @@ ++/* ++ Copyright (C) 2004 - 2009 Ivo van Doorn ++ Copyright (C) 2004 - 2009 Gertjan van Wingerde ++ ++ ++ This program is free software; you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation; either version 2 of the License, or ++ (at your option) any later version. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with this program; if not, write to the ++ Free Software Foundation, Inc., ++ 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ++ */ ++ ++/* ++ Module: rt2x00lib ++ Abstract: rt2x00 eeprom file loading routines. ++ */ ++ ++#include ++#include ++ ++#include "rt2x00.h" ++#include "rt2x00lib.h" ++ ++static const char * ++rt2x00lib_get_eeprom_file_name(struct rt2x00_dev *rt2x00dev) ++{ ++ struct rt2x00_platform_data *pdata = rt2x00dev->dev->platform_data; ++ ++ if (pdata && pdata->eeprom_file_name) ++ return pdata->eeprom_file_name; ++ ++ return NULL ++} ++ ++static int rt2x00lib_request_eeprom_file(struct rt2x00_dev *rt2x00dev) ++{ ++ const struct firmware *ee; ++ const char *ee_name; ++ int retval; ++ ++ ee_name = rt2x00lib_get_eeprom_file_name(rt2x00dev); ++ if (!ee_name && test_bit(REQUIRE_EEPROM_FILE, &rt2x00dev->cap_flags)) { ++ rt2x00_err(rt2x00dev, "Required EEPROM name is missing."); ++ return -EINVAL; ++ } ++ ++ if (!ee_name) ++ return 0; ++ ++ rt2x00_info(rt2x00dev, "Loading EEPROM data from '%s'.\n", ee_name); ++ ++ retval = request_firmware(&ee, ee_name, rt2x00dev->dev); ++ if (retval) { ++ rt2x00_err(rt2x00dev, "Failed to request EEPROM.\n"); ++ return retval; ++ } ++ ++ if (!ee || !ee->size || !ee->data) { ++ rt2x00_err(rt2x00dev, "Failed to read EEPROM file.\n"); ++ retval = -ENOENT; ++ goto err_exit; ++ } ++ ++ if (ee->size != rt2x00dev->ops->eeprom_size) { ++ rt2x00_err(rt2x00dev, ++ "EEPROM file size is invalid, it should be %d bytes\n", ++ rt2x00dev->ops->eeprom_size); ++ retval = -EINVAL; ++ goto err_release_ee; ++ } ++ ++ rt2x00dev->eeprom_file = ee; ++ return 0; ++ ++err_release_ee: ++ release_firmware(ee); ++err_exit: ++ return retval; ++} ++ ++int rt2x00lib_load_eeprom_file(struct rt2x00_dev *rt2x00dev) ++{ ++ int retval; ++ ++ retval = rt2x00lib_request_eeprom_file(rt2x00dev); ++ if (retval) ++ return retval; ++ ++ return 0; ++} ++ ++void rt2x00lib_free_eeprom_file(struct rt2x00_dev *rt2x00dev) ++{ ++ release_firmware(rt2x00dev->eeprom_file); ++ rt2x00dev->eeprom_file = NULL; ++} +--- a/drivers/net/wireless/ralink/rt2x00/rt2x00lib.h ++++ b/drivers/net/wireless/ralink/rt2x00/rt2x00lib.h +@@ -297,6 +297,22 @@ static inline void rt2x00lib_free_firmwa + #endif /* CPTCFG_RT2X00_LIB_FIRMWARE */ + + /* ++ * EEPROM file handlers. ++ */ ++#ifdef CPTCFG_RT2X00_LIB_EEPROM ++int rt2x00lib_load_eeprom_file(struct rt2x00_dev *rt2x00dev); ++void rt2x00lib_free_eeprom_file(struct rt2x00_dev *rt2x00dev); ++#else ++static inline int rt2x00lib_load_eeprom_file(struct rt2x00_dev *rt2x00dev) ++{ ++ return 0; ++} ++static inline void rt2x00lib_free_eeprom_file(struct rt2x00_dev *rt2x00dev) ++{ ++} ++#endif /* CPTCFG_RT2X00_LIB_EEPROM */ ++ ++/* + * Debugfs handlers. + */ + #ifdef CPTCFG_RT2X00_LIB_DEBUGFS +--- a/drivers/net/wireless/ralink/rt2x00/rt2x00soc.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2x00soc.c +@@ -97,6 +97,7 @@ int rt2x00soc_probe(struct platform_devi + if (IS_ERR(rt2x00dev->clk)) + rt2x00dev->clk = NULL; + ++ set_bit(REQUIRE_EEPROM_FILE, &rt2x00dev->cap_flags); + rt2x00_set_chip_intf(rt2x00dev, RT2X00_CHIP_INTF_SOC); + + retval = rt2x00soc_alloc_reg(rt2x00dev); diff --git a/package/kernel/mac80211/patches/603-rt2x00-introduce-rt2x00eeprom.patch b/package/kernel/mac80211/patches/603-rt2x00-introduce-rt2x00eeprom.patch deleted file mode 100644 index 2313bf1567..0000000000 --- a/package/kernel/mac80211/patches/603-rt2x00-introduce-rt2x00eeprom.patch +++ /dev/null @@ -1,295 +0,0 @@ ---- a/.local-symbols -+++ b/.local-symbols -@@ -332,6 +332,7 @@ RT2X00_LIB_FIRMWARE= - RT2X00_LIB_CRYPTO= - RT2X00_LIB_LEDS= - RT2X00_LIB_DEBUGFS= -+RT2X00_LIB_EEPROM= - RT2X00_DEBUG= - WLAN_VENDOR_REALTEK= - RTL8180= ---- a/drivers/net/wireless/ralink/rt2x00/Kconfig -+++ b/drivers/net/wireless/ralink/rt2x00/Kconfig -@@ -69,6 +69,7 @@ config RT2800PCI - select RT2X00_LIB_MMIO - select RT2X00_LIB_PCI - select RT2X00_LIB_FIRMWARE -+ select RT2X00_LIB_EEPROM - select RT2X00_LIB_CRYPTO - depends on CRC_CCITT - depends on EEPROM_93CX6 -@@ -215,6 +216,7 @@ config RT2800SOC - select RT2X00_LIB_MMIO - select RT2X00_LIB_CRYPTO - select RT2X00_LIB_FIRMWARE -+ select RT2X00_LIB_EEPROM - select RT2800_LIB - select RT2800_LIB_MMIO - ---help--- -@@ -265,6 +267,9 @@ config RT2X00_LIB_FIRMWARE - config RT2X00_LIB_CRYPTO - bool - -+config RT2X00_LIB_EEPROM -+ boolean -+ - config RT2X00_LIB_LEDS - bool - default y if (RT2X00_LIB=y && LEDS_CLASS=y) || (RT2X00_LIB=m && LEDS_CLASS!=n) ---- a/drivers/net/wireless/ralink/rt2x00/Makefile -+++ b/drivers/net/wireless/ralink/rt2x00/Makefile -@@ -7,6 +7,7 @@ rt2x00lib-$(CPTCFG_RT2X00_LIB_DEBUGFS) + - rt2x00lib-$(CPTCFG_RT2X00_LIB_CRYPTO) += rt2x00crypto.o - rt2x00lib-$(CPTCFG_RT2X00_LIB_FIRMWARE) += rt2x00firmware.o - rt2x00lib-$(CPTCFG_RT2X00_LIB_LEDS) += rt2x00leds.o -+rt2x00lib-$(CPTCFG_RT2X00_LIB_EEPROM) += rt2x00eeprom.o - - obj-$(CPTCFG_RT2X00_LIB) += rt2x00lib.o - obj-$(CPTCFG_RT2X00_LIB_MMIO) += rt2x00mmio.o ---- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.h -+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.h -@@ -46,6 +46,8 @@ struct rt2800_drv_data { - } shmem_lock; - }; - -+#include "rt2800.h" -+ - struct rt2800_ops { - void (*register_read)(struct rt2x00_dev *rt2x00dev, - const unsigned int offset, u32 *value); -@@ -179,6 +181,15 @@ static inline int rt2800_read_eeprom(str - { - const struct rt2800_ops *rt2800ops = rt2x00dev->ops->drv; - -+ if (rt2x00dev->eeprom_file) { -+ memcpy(rt2x00dev->eeprom, rt2x00dev->eeprom_file->data, -+ EEPROM_SIZE); -+ return 0; -+ } -+ -+ if (!rt2800ops->read_eeprom) -+ return -EINVAL; -+ - return rt2800ops->read_eeprom(rt2x00dev); - } - ---- a/drivers/net/wireless/ralink/rt2x00/rt2800soc.c -+++ b/drivers/net/wireless/ralink/rt2x00/rt2800soc.c -@@ -102,19 +102,6 @@ static int rt2800soc_set_device_state(st - return retval; - } - --static int rt2800soc_read_eeprom(struct rt2x00_dev *rt2x00dev) --{ -- void __iomem *base_addr = ioremap(0x1F040000, EEPROM_SIZE); -- -- if (!base_addr) -- return -ENOMEM; -- -- memcpy_fromio(rt2x00dev->eeprom, base_addr, EEPROM_SIZE); -- -- iounmap(base_addr); -- return 0; --} -- - /* Firmware functions */ - static char *rt2800soc_get_firmware_name(struct rt2x00_dev *rt2x00dev) - { -@@ -178,7 +165,6 @@ static const struct rt2800_ops rt2800soc - .register_multiread = rt2x00mmio_register_multiread, - .register_multiwrite = rt2x00mmio_register_multiwrite, - .regbusy_read = rt2x00mmio_regbusy_read, -- .read_eeprom = rt2800soc_read_eeprom, - .hwcrypt_disabled = rt2800soc_hwcrypt_disabled, - .drv_write_firmware = rt2800soc_write_firmware, - .drv_init_registers = rt2800mmio_init_registers, ---- a/drivers/net/wireless/ralink/rt2x00/rt2x00.h -+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00.h -@@ -699,6 +699,7 @@ enum rt2x00_capability_flags { - REQUIRE_HT_TX_DESC, - REQUIRE_PS_AUTOWAKE, - REQUIRE_DELAYED_RFKILL, -+ REQUIRE_EEPROM_FILE, - - /* - * Capabilities -@@ -968,6 +969,11 @@ struct rt2x00_dev { - const struct firmware *fw; - - /* -+ * EEPROM image. -+ */ -+ const struct firmware *eeprom_file; -+ -+ /* - * FIFO for storing tx status reports between isr and tasklet. - */ - DECLARE_KFIFO_PTR(txstatus_fifo, u32); ---- a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c -+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c -@@ -1334,6 +1334,10 @@ int rt2x00lib_probe_dev(struct rt2x00_de - INIT_DELAYED_WORK(&rt2x00dev->autowakeup_work, rt2x00lib_autowakeup); - INIT_WORK(&rt2x00dev->sleep_work, rt2x00lib_sleep); - -+ retval = rt2x00lib_load_eeprom_file(rt2x00dev); -+ if (retval) -+ goto exit; -+ - /* - * Let the driver probe the device to detect the capabilities. - */ -@@ -1477,6 +1481,11 @@ void rt2x00lib_remove_dev(struct rt2x00_ - * Free the driver data. - */ - kfree(rt2x00dev->drv_data); -+ -+ /* -+ * Free EEPROM image. -+ */ -+ rt2x00lib_free_eeprom_file(rt2x00dev); - } - EXPORT_SYMBOL_GPL(rt2x00lib_remove_dev); - ---- /dev/null -+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00eeprom.c -@@ -0,0 +1,105 @@ -+/* -+ Copyright (C) 2004 - 2009 Ivo van Doorn -+ Copyright (C) 2004 - 2009 Gertjan van Wingerde -+ -+ -+ This program is free software; you can redistribute it and/or modify -+ it under the terms of the GNU General Public License as published by -+ the Free Software Foundation; either version 2 of the License, or -+ (at your option) any later version. -+ -+ This program is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ GNU General Public License for more details. -+ -+ You should have received a copy of the GNU General Public License -+ along with this program; if not, write to the -+ Free Software Foundation, Inc., -+ 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -+ */ -+ -+/* -+ Module: rt2x00lib -+ Abstract: rt2x00 eeprom file loading routines. -+ */ -+ -+#include -+#include -+ -+#include "rt2x00.h" -+#include "rt2x00lib.h" -+ -+static const char * -+rt2x00lib_get_eeprom_file_name(struct rt2x00_dev *rt2x00dev) -+{ -+ struct rt2x00_platform_data *pdata = rt2x00dev->dev->platform_data; -+ -+ if (pdata && pdata->eeprom_file_name) -+ return pdata->eeprom_file_name; -+ -+ return NULL -+} -+ -+static int rt2x00lib_request_eeprom_file(struct rt2x00_dev *rt2x00dev) -+{ -+ const struct firmware *ee; -+ const char *ee_name; -+ int retval; -+ -+ ee_name = rt2x00lib_get_eeprom_file_name(rt2x00dev); -+ if (!ee_name && test_bit(REQUIRE_EEPROM_FILE, &rt2x00dev->cap_flags)) { -+ rt2x00_err(rt2x00dev, "Required EEPROM name is missing."); -+ return -EINVAL; -+ } -+ -+ if (!ee_name) -+ return 0; -+ -+ rt2x00_info(rt2x00dev, "Loading EEPROM data from '%s'.\n", ee_name); -+ -+ retval = request_firmware(&ee, ee_name, rt2x00dev->dev); -+ if (retval) { -+ rt2x00_err(rt2x00dev, "Failed to request EEPROM.\n"); -+ return retval; -+ } -+ -+ if (!ee || !ee->size || !ee->data) { -+ rt2x00_err(rt2x00dev, "Failed to read EEPROM file.\n"); -+ retval = -ENOENT; -+ goto err_exit; -+ } -+ -+ if (ee->size != rt2x00dev->ops->eeprom_size) { -+ rt2x00_err(rt2x00dev, -+ "EEPROM file size is invalid, it should be %d bytes\n", -+ rt2x00dev->ops->eeprom_size); -+ retval = -EINVAL; -+ goto err_release_ee; -+ } -+ -+ rt2x00dev->eeprom_file = ee; -+ return 0; -+ -+err_release_ee: -+ release_firmware(ee); -+err_exit: -+ return retval; -+} -+ -+int rt2x00lib_load_eeprom_file(struct rt2x00_dev *rt2x00dev) -+{ -+ int retval; -+ -+ retval = rt2x00lib_request_eeprom_file(rt2x00dev); -+ if (retval) -+ return retval; -+ -+ return 0; -+} -+ -+void rt2x00lib_free_eeprom_file(struct rt2x00_dev *rt2x00dev) -+{ -+ release_firmware(rt2x00dev->eeprom_file); -+ rt2x00dev->eeprom_file = NULL; -+} ---- a/drivers/net/wireless/ralink/rt2x00/rt2x00lib.h -+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00lib.h -@@ -320,6 +320,22 @@ static inline void rt2x00lib_free_firmwa - #endif /* CPTCFG_RT2X00_LIB_FIRMWARE */ - - /* -+ * EEPROM file handlers. -+ */ -+#ifdef CPTCFG_RT2X00_LIB_EEPROM -+int rt2x00lib_load_eeprom_file(struct rt2x00_dev *rt2x00dev); -+void rt2x00lib_free_eeprom_file(struct rt2x00_dev *rt2x00dev); -+#else -+static inline int rt2x00lib_load_eeprom_file(struct rt2x00_dev *rt2x00dev) -+{ -+ return 0; -+} -+static inline void rt2x00lib_free_eeprom_file(struct rt2x00_dev *rt2x00dev) -+{ -+} -+#endif /* CPTCFG_RT2X00_LIB_EEPROM */ -+ -+/* - * Debugfs handlers. - */ - #ifdef CPTCFG_RT2X00_LIB_DEBUGFS ---- a/drivers/net/wireless/ralink/rt2x00/rt2x00soc.c -+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00soc.c -@@ -92,6 +92,7 @@ int rt2x00soc_probe(struct platform_devi - rt2x00dev->hw = hw; - rt2x00dev->irq = platform_get_irq(pdev, 0); - rt2x00dev->name = pdev->dev.driver->name; -+ set_bit(REQUIRE_EEPROM_FILE, &rt2x00dev->cap_flags); - - rt2x00_set_chip_intf(rt2x00dev, RT2X00_CHIP_INTF_SOC); - diff --git a/package/kernel/mac80211/patches/603-rt2x00-of_load_eeprom_filename.patch b/package/kernel/mac80211/patches/603-rt2x00-of_load_eeprom_filename.patch new file mode 100644 index 0000000000..9dffef1812 --- /dev/null +++ b/package/kernel/mac80211/patches/603-rt2x00-of_load_eeprom_filename.patch @@ -0,0 +1,33 @@ +--- a/drivers/net/wireless/ralink/rt2x00/rt2x00eeprom.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2x00eeprom.c +@@ -26,6 +26,7 @@ + + #include + #include ++#include + + #include "rt2x00.h" + #include "rt2x00lib.h" +@@ -34,11 +35,21 @@ static const char * + rt2x00lib_get_eeprom_file_name(struct rt2x00_dev *rt2x00dev) + { + struct rt2x00_platform_data *pdata = rt2x00dev->dev->platform_data; ++#ifdef CONFIG_OF ++ struct device_node *np; ++ const char *eep; ++#endif + + if (pdata && pdata->eeprom_file_name) + return pdata->eeprom_file_name; + +- return NULL ++#ifdef CONFIG_OF ++ np = rt2x00dev->dev->of_node; ++ if (np && of_property_read_string(np, "ralink,eeprom", &eep) == 0) ++ return eep; ++#endif ++ ++ return NULL; + } + + static int rt2x00lib_request_eeprom_file(struct rt2x00_dev *rt2x00dev) diff --git a/package/kernel/mac80211/patches/604-rt2x00-load-eeprom-on-SoC-from-a-mtd-device-defines-.patch b/package/kernel/mac80211/patches/604-rt2x00-load-eeprom-on-SoC-from-a-mtd-device-defines-.patch new file mode 100644 index 0000000000..a98b49c541 --- /dev/null +++ b/package/kernel/mac80211/patches/604-rt2x00-load-eeprom-on-SoC-from-a-mtd-device-defines-.patch @@ -0,0 +1,108 @@ +From 339fe73f340161a624cc08e738d2244814852c3e Mon Sep 17 00:00:00 2001 +From: John Crispin +Date: Sun, 17 Mar 2013 00:55:04 +0100 +Subject: [PATCH] rt2x00: load eeprom on SoC from a mtd device defines inside + OF + +Signed-off-by: John Crispin +--- + drivers/net/wireless/ralink/rt2x00/Kconfig | 1 + + drivers/net/wireless/ralink/rt2x00/rt2x00eeprom.c | 65 +++++++++++++++++++++++ + 2 files changed, 66 insertions(+) + +--- a/drivers/net/wireless/ralink/rt2x00/Kconfig ++++ b/drivers/net/wireless/ralink/rt2x00/Kconfig +@@ -219,6 +219,7 @@ config RT2800SOC + select RT2X00_LIB_EEPROM + select RT2800_LIB + select RT2800_LIB_MMIO ++ select MTD if SOC_RT288X || SOC_RT305X + ---help--- + This adds support for Ralink WiSoC devices. + Supported chips: RT2880, RT3050, RT3052, RT3350, RT3352. +--- a/drivers/net/wireless/ralink/rt2x00/rt2x00eeprom.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2x00eeprom.c +@@ -26,11 +26,73 @@ + + #include + #include ++#include ++#include + #include + + #include "rt2x00.h" + #include "rt2x00lib.h" + ++static int rt2800lib_read_eeprom_mtd(struct rt2x00_dev *rt2x00dev) ++{ ++ int ret = -EINVAL; ++#ifdef CONFIG_OF ++ static struct firmware mtd_fw; ++ struct device_node *np = rt2x00dev->dev->of_node, *mtd_np = NULL; ++ size_t retlen, len = rt2x00dev->ops->eeprom_size; ++ int i, size, offset = 0; ++ struct mtd_info *mtd; ++ const char *part; ++ const __be32 *list; ++ phandle phandle; ++ ++ list = of_get_property(np, "ralink,mtd-eeprom", &size); ++ if (!list) ++ return -ENOENT; ++ ++ phandle = be32_to_cpup(list++); ++ if (phandle) ++ mtd_np = of_find_node_by_phandle(phandle); ++ if (!mtd_np) { ++ dev_err(rt2x00dev->dev, "failed to load mtd phandle\n"); ++ return -EINVAL; ++ } ++ ++ part = of_get_property(mtd_np, "label", NULL); ++ if (!part) ++ part = mtd_np->name; ++ ++ mtd = get_mtd_device_nm(part); ++ if (IS_ERR(mtd)) { ++ dev_err(rt2x00dev->dev, "failed to get mtd device \"%s\"\n", part); ++ return PTR_ERR(mtd); ++ } ++ ++ if (size > sizeof(*list)) ++ offset = be32_to_cpup(list); ++ ++ ret = mtd_read(mtd, offset, len, &retlen, (u_char *) rt2x00dev->eeprom); ++ put_mtd_device(mtd); ++ ++ if ((retlen != rt2x00dev->ops->eeprom_size) || ret) { ++ dev_err(rt2x00dev->dev, "failed to load eeprom from device \"%s\"\n", part); ++ return ret; ++ } ++ ++ if (of_find_property(np, "ralink,mtd-eeprom-swap", NULL)) ++ for (i = 0; i < len/sizeof(u16); i++) ++ rt2x00dev->eeprom[i] = swab16(rt2x00dev->eeprom[i]); ++ ++ rt2x00dev->eeprom_file = &mtd_fw; ++ mtd_fw.size = len; ++ mtd_fw.data = (const u8 *) rt2x00dev->eeprom; ++ ++ dev_info(rt2x00dev->dev, "loaded eeprom from mtd device \"%s\"\n", part); ++#endif ++ ++ return ret; ++} ++ + static const char * + rt2x00lib_get_eeprom_file_name(struct rt2x00_dev *rt2x00dev) + { +@@ -58,6 +120,9 @@ static int rt2x00lib_request_eeprom_file + const char *ee_name; + int retval; + ++ if (!rt2800lib_read_eeprom_mtd(rt2x00dev)) ++ return 0; ++ + ee_name = rt2x00lib_get_eeprom_file_name(rt2x00dev); + if (!ee_name && test_bit(REQUIRE_EEPROM_FILE, &rt2x00dev->cap_flags)) { + rt2x00_err(rt2x00dev, "Required EEPROM name is missing."); diff --git a/package/kernel/mac80211/patches/604-rt2x00-of_load_eeprom_filename.patch b/package/kernel/mac80211/patches/604-rt2x00-of_load_eeprom_filename.patch deleted file mode 100644 index 9dffef1812..0000000000 --- a/package/kernel/mac80211/patches/604-rt2x00-of_load_eeprom_filename.patch +++ /dev/null @@ -1,33 +0,0 @@ ---- a/drivers/net/wireless/ralink/rt2x00/rt2x00eeprom.c -+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00eeprom.c -@@ -26,6 +26,7 @@ - - #include - #include -+#include - - #include "rt2x00.h" - #include "rt2x00lib.h" -@@ -34,11 +35,21 @@ static const char * - rt2x00lib_get_eeprom_file_name(struct rt2x00_dev *rt2x00dev) - { - struct rt2x00_platform_data *pdata = rt2x00dev->dev->platform_data; -+#ifdef CONFIG_OF -+ struct device_node *np; -+ const char *eep; -+#endif - - if (pdata && pdata->eeprom_file_name) - return pdata->eeprom_file_name; - -- return NULL -+#ifdef CONFIG_OF -+ np = rt2x00dev->dev->of_node; -+ if (np && of_property_read_string(np, "ralink,eeprom", &eep) == 0) -+ return eep; -+#endif -+ -+ return NULL; - } - - static int rt2x00lib_request_eeprom_file(struct rt2x00_dev *rt2x00dev) diff --git a/package/kernel/mac80211/patches/605-rt2x00-load-eeprom-on-SoC-from-a-mtd-device-defines-.patch b/package/kernel/mac80211/patches/605-rt2x00-load-eeprom-on-SoC-from-a-mtd-device-defines-.patch deleted file mode 100644 index a98b49c541..0000000000 --- a/package/kernel/mac80211/patches/605-rt2x00-load-eeprom-on-SoC-from-a-mtd-device-defines-.patch +++ /dev/null @@ -1,108 +0,0 @@ -From 339fe73f340161a624cc08e738d2244814852c3e Mon Sep 17 00:00:00 2001 -From: John Crispin -Date: Sun, 17 Mar 2013 00:55:04 +0100 -Subject: [PATCH] rt2x00: load eeprom on SoC from a mtd device defines inside - OF - -Signed-off-by: John Crispin ---- - drivers/net/wireless/ralink/rt2x00/Kconfig | 1 + - drivers/net/wireless/ralink/rt2x00/rt2x00eeprom.c | 65 +++++++++++++++++++++++ - 2 files changed, 66 insertions(+) - ---- a/drivers/net/wireless/ralink/rt2x00/Kconfig -+++ b/drivers/net/wireless/ralink/rt2x00/Kconfig -@@ -219,6 +219,7 @@ config RT2800SOC - select RT2X00_LIB_EEPROM - select RT2800_LIB - select RT2800_LIB_MMIO -+ select MTD if SOC_RT288X || SOC_RT305X - ---help--- - This adds support for Ralink WiSoC devices. - Supported chips: RT2880, RT3050, RT3052, RT3350, RT3352. ---- a/drivers/net/wireless/ralink/rt2x00/rt2x00eeprom.c -+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00eeprom.c -@@ -26,11 +26,73 @@ - - #include - #include -+#include -+#include - #include - - #include "rt2x00.h" - #include "rt2x00lib.h" - -+static int rt2800lib_read_eeprom_mtd(struct rt2x00_dev *rt2x00dev) -+{ -+ int ret = -EINVAL; -+#ifdef CONFIG_OF -+ static struct firmware mtd_fw; -+ struct device_node *np = rt2x00dev->dev->of_node, *mtd_np = NULL; -+ size_t retlen, len = rt2x00dev->ops->eeprom_size; -+ int i, size, offset = 0; -+ struct mtd_info *mtd; -+ const char *part; -+ const __be32 *list; -+ phandle phandle; -+ -+ list = of_get_property(np, "ralink,mtd-eeprom", &size); -+ if (!list) -+ return -ENOENT; -+ -+ phandle = be32_to_cpup(list++); -+ if (phandle) -+ mtd_np = of_find_node_by_phandle(phandle); -+ if (!mtd_np) { -+ dev_err(rt2x00dev->dev, "failed to load mtd phandle\n"); -+ return -EINVAL; -+ } -+ -+ part = of_get_property(mtd_np, "label", NULL); -+ if (!part) -+ part = mtd_np->name; -+ -+ mtd = get_mtd_device_nm(part); -+ if (IS_ERR(mtd)) { -+ dev_err(rt2x00dev->dev, "failed to get mtd device \"%s\"\n", part); -+ return PTR_ERR(mtd); -+ } -+ -+ if (size > sizeof(*list)) -+ offset = be32_to_cpup(list); -+ -+ ret = mtd_read(mtd, offset, len, &retlen, (u_char *) rt2x00dev->eeprom); -+ put_mtd_device(mtd); -+ -+ if ((retlen != rt2x00dev->ops->eeprom_size) || ret) { -+ dev_err(rt2x00dev->dev, "failed to load eeprom from device \"%s\"\n", part); -+ return ret; -+ } -+ -+ if (of_find_property(np, "ralink,mtd-eeprom-swap", NULL)) -+ for (i = 0; i < len/sizeof(u16); i++) -+ rt2x00dev->eeprom[i] = swab16(rt2x00dev->eeprom[i]); -+ -+ rt2x00dev->eeprom_file = &mtd_fw; -+ mtd_fw.size = len; -+ mtd_fw.data = (const u8 *) rt2x00dev->eeprom; -+ -+ dev_info(rt2x00dev->dev, "loaded eeprom from mtd device \"%s\"\n", part); -+#endif -+ -+ return ret; -+} -+ - static const char * - rt2x00lib_get_eeprom_file_name(struct rt2x00_dev *rt2x00dev) - { -@@ -58,6 +120,9 @@ static int rt2x00lib_request_eeprom_file - const char *ee_name; - int retval; - -+ if (!rt2800lib_read_eeprom_mtd(rt2x00dev)) -+ return 0; -+ - ee_name = rt2x00lib_get_eeprom_file_name(rt2x00dev); - if (!ee_name && test_bit(REQUIRE_EEPROM_FILE, &rt2x00dev->cap_flags)) { - rt2x00_err(rt2x00dev, "Required EEPROM name is missing."); diff --git a/package/kernel/mac80211/patches/606-rt2x00-allow_disabling_bands_through_platform_data.patch b/package/kernel/mac80211/patches/606-rt2x00-allow_disabling_bands_through_platform_data.patch new file mode 100644 index 0000000000..522670ece7 --- /dev/null +++ b/package/kernel/mac80211/patches/606-rt2x00-allow_disabling_bands_through_platform_data.patch @@ -0,0 +1,47 @@ +--- a/include/linux/rt2x00_platform.h ++++ b/include/linux/rt2x00_platform.h +@@ -14,6 +14,9 @@ + + struct rt2x00_platform_data { + char *eeprom_file_name; ++ ++ int disable_2ghz; ++ int disable_5ghz; + }; + + #endif /* _RT2X00_PLATFORM_H */ +--- a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c +@@ -951,6 +951,22 @@ static int rt2x00lib_probe_hw_modes(stru + unsigned int num_rates; + unsigned int i; + ++ if (rt2x00dev->dev->platform_data) { ++ struct rt2x00_platform_data *pdata; ++ ++ pdata = rt2x00dev->dev->platform_data; ++ if (pdata->disable_2ghz) ++ spec->supported_bands &= ~SUPPORT_BAND_2GHZ; ++ if (pdata->disable_5ghz) ++ spec->supported_bands &= ~SUPPORT_BAND_5GHZ; ++ } ++ ++ if ((spec->supported_bands & SUPPORT_BAND_BOTH) == 0) { ++ rt2x00_err(rt2x00dev, "No supported bands\n"); ++ return -EINVAL; ++ } ++ ++ + num_rates = 0; + if (spec->supported_rates & SUPPORT_RATE_CCK) + num_rates += 4; +--- a/drivers/net/wireless/ralink/rt2x00/rt2x00.h ++++ b/drivers/net/wireless/ralink/rt2x00/rt2x00.h +@@ -408,6 +408,7 @@ struct hw_mode_spec { + unsigned int supported_bands; + #define SUPPORT_BAND_2GHZ 0x00000001 + #define SUPPORT_BAND_5GHZ 0x00000002 ++#define SUPPORT_BAND_BOTH (SUPPORT_BAND_2GHZ | SUPPORT_BAND_5GHZ) + + unsigned int supported_rates; + #define SUPPORT_RATE_CCK 0x00000001 diff --git a/package/kernel/mac80211/patches/607-rt2x00-add_platform_data_mac_addr.patch b/package/kernel/mac80211/patches/607-rt2x00-add_platform_data_mac_addr.patch new file mode 100644 index 0000000000..5a3f858090 --- /dev/null +++ b/package/kernel/mac80211/patches/607-rt2x00-add_platform_data_mac_addr.patch @@ -0,0 +1,26 @@ +--- a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c +@@ -929,8 +929,13 @@ static void rt2x00lib_rate(struct ieee80 + + void rt2x00lib_set_mac_address(struct rt2x00_dev *rt2x00dev, u8 *eeprom_mac_addr) + { ++ struct rt2x00_platform_data *pdata; + const char *mac_addr; + ++ pdata = rt2x00dev->dev->platform_data; ++ if (pdata && pdata->mac_address) ++ ether_addr_copy(eeprom_mac_addr, pdata->mac_address); ++ + mac_addr = of_get_mac_address(rt2x00dev->dev->of_node); + if (mac_addr) + ether_addr_copy(eeprom_mac_addr, mac_addr); +--- a/include/linux/rt2x00_platform.h ++++ b/include/linux/rt2x00_platform.h +@@ -14,6 +14,7 @@ + + struct rt2x00_platform_data { + char *eeprom_file_name; ++ const u8 *mac_address; + + int disable_2ghz; + int disable_5ghz; diff --git a/package/kernel/mac80211/patches/607-rt2x00-allow_disabling_bands_through_platform_data.patch b/package/kernel/mac80211/patches/607-rt2x00-allow_disabling_bands_through_platform_data.patch deleted file mode 100644 index a2e1faf9c3..0000000000 --- a/package/kernel/mac80211/patches/607-rt2x00-allow_disabling_bands_through_platform_data.patch +++ /dev/null @@ -1,47 +0,0 @@ ---- a/include/linux/rt2x00_platform.h -+++ b/include/linux/rt2x00_platform.h -@@ -14,6 +14,9 @@ - - struct rt2x00_platform_data { - char *eeprom_file_name; -+ -+ int disable_2ghz; -+ int disable_5ghz; - }; - - #endif /* _RT2X00_PLATFORM_H */ ---- a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c -+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c -@@ -940,6 +940,22 @@ static int rt2x00lib_probe_hw_modes(stru - unsigned int num_rates; - unsigned int i; - -+ if (rt2x00dev->dev->platform_data) { -+ struct rt2x00_platform_data *pdata; -+ -+ pdata = rt2x00dev->dev->platform_data; -+ if (pdata->disable_2ghz) -+ spec->supported_bands &= ~SUPPORT_BAND_2GHZ; -+ if (pdata->disable_5ghz) -+ spec->supported_bands &= ~SUPPORT_BAND_5GHZ; -+ } -+ -+ if ((spec->supported_bands & SUPPORT_BAND_BOTH) == 0) { -+ rt2x00_err(rt2x00dev, "No supported bands\n"); -+ return -EINVAL; -+ } -+ -+ - num_rates = 0; - if (spec->supported_rates & SUPPORT_RATE_CCK) - num_rates += 4; ---- a/drivers/net/wireless/ralink/rt2x00/rt2x00.h -+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00.h -@@ -406,6 +406,7 @@ struct hw_mode_spec { - unsigned int supported_bands; - #define SUPPORT_BAND_2GHZ 0x00000001 - #define SUPPORT_BAND_5GHZ 0x00000002 -+#define SUPPORT_BAND_BOTH (SUPPORT_BAND_2GHZ | SUPPORT_BAND_5GHZ) - - unsigned int supported_rates; - #define SUPPORT_RATE_CCK 0x00000001 diff --git a/package/kernel/mac80211/patches/608-00-rt2x00-get-mac-from-device-tree.patch b/package/kernel/mac80211/patches/608-00-rt2x00-get-mac-from-device-tree.patch deleted file mode 100644 index 290f2480b0..0000000000 --- a/package/kernel/mac80211/patches/608-00-rt2x00-get-mac-from-device-tree.patch +++ /dev/null @@ -1,152 +0,0 @@ -From 0e31738ef78a814fcd2a55f2d57a21d322794da1 Mon Sep 17 00:00:00 2001 -From: Mathias Kresin -Date: Fri, 26 Aug 2016 09:16:53 +0200 -Subject: rt2x00: add support for mac addr from device tree - -On some devices the EEPROMs of Ralink Wi-Fi chips have a default Ralink -MAC address set (RT3062F: 00:0C:43:30:62:00, RT3060F: -00:0C:43:30:60:00). Using multiple of these devices in the same network -can cause nasty issues. - -Allow to override the MAC in the EEPROM with (a known good) one set in -the device tree to bypass the issue. - -Signed-off-by: Mathias Kresin ---- - drivers/net/wireless/ralink/rt2x00/rt2400pci.c | 5 +---- - drivers/net/wireless/ralink/rt2x00/rt2500pci.c | 5 +---- - drivers/net/wireless/ralink/rt2x00/rt2500usb.c | 5 +---- - drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 5 +---- - drivers/net/wireless/ralink/rt2x00/rt2x00.h | 1 + - drivers/net/wireless/ralink/rt2x00/rt2x00dev.c | 16 ++++++++++++++++ - drivers/net/wireless/ralink/rt2x00/rt61pci.c | 5 +---- - drivers/net/wireless/ralink/rt2x00/rt73usb.c | 5 +---- - 8 files changed, 23 insertions(+), 24 deletions(-) - ---- a/drivers/net/wireless/ralink/rt2x00/rt2400pci.c -+++ b/drivers/net/wireless/ralink/rt2x00/rt2400pci.c -@@ -1459,10 +1459,7 @@ static int rt2400pci_validate_eeprom(str - * Start validation of the data that has been read. - */ - mac = rt2x00_eeprom_addr(rt2x00dev, EEPROM_MAC_ADDR_0); -- if (!is_valid_ether_addr(mac)) { -- eth_random_addr(mac); -- rt2x00_eeprom_dbg(rt2x00dev, "MAC: %pM\n", mac); -- } -+ rt2x00lib_set_mac_address(rt2x00dev, mac); - - rt2x00_eeprom_read(rt2x00dev, EEPROM_ANTENNA, &word); - if (word == 0xffff) { ---- a/drivers/net/wireless/ralink/rt2x00/rt2500pci.c -+++ b/drivers/net/wireless/ralink/rt2x00/rt2500pci.c -@@ -1585,10 +1585,7 @@ static int rt2500pci_validate_eeprom(str - * Start validation of the data that has been read. - */ - mac = rt2x00_eeprom_addr(rt2x00dev, EEPROM_MAC_ADDR_0); -- if (!is_valid_ether_addr(mac)) { -- eth_random_addr(mac); -- rt2x00_eeprom_dbg(rt2x00dev, "MAC: %pM\n", mac); -- } -+ rt2x00lib_set_mac_address(rt2x00dev, mac); - - rt2x00_eeprom_read(rt2x00dev, EEPROM_ANTENNA, &word); - if (word == 0xffff) { ---- a/drivers/net/wireless/ralink/rt2x00/rt2500usb.c -+++ b/drivers/net/wireless/ralink/rt2x00/rt2500usb.c -@@ -1349,10 +1349,7 @@ static int rt2500usb_validate_eeprom(str - * Start validation of the data that has been read. - */ - mac = rt2x00_eeprom_addr(rt2x00dev, EEPROM_MAC_ADDR_0); -- if (!is_valid_ether_addr(mac)) { -- eth_random_addr(mac); -- rt2x00_eeprom_dbg(rt2x00dev, "MAC: %pM\n", mac); -- } -+ rt2x00lib_set_mac_address(rt2x00dev, mac); - - rt2x00_eeprom_read(rt2x00dev, EEPROM_ANTENNA, &word); - if (word == 0xffff) { ---- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c -+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c -@@ -7531,10 +7531,7 @@ static int rt2800_validate_eeprom(struct - * Start validation of the data that has been read. - */ - mac = rt2800_eeprom_addr(rt2x00dev, EEPROM_MAC_ADDR_0); -- if (!is_valid_ether_addr(mac)) { -- eth_random_addr(mac); -- rt2x00_eeprom_dbg(rt2x00dev, "MAC: %pM\n", mac); -- } -+ rt2x00lib_set_mac_address(rt2x00dev, mac); - - rt2800_eeprom_read(rt2x00dev, EEPROM_NIC_CONF0, &word); - if (word == 0xffff) { ---- a/drivers/net/wireless/ralink/rt2x00/rt2x00.h -+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00.h -@@ -1416,6 +1416,7 @@ static inline void rt2x00debug_dump_fram - */ - u32 rt2x00lib_get_bssidx(struct rt2x00_dev *rt2x00dev, - struct ieee80211_vif *vif); -+void rt2x00lib_set_mac_address(struct rt2x00_dev *rt2x00dev, u8 *eeprom_mac_addr); - - /* - * Interrupt context handlers. ---- a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c -+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c -@@ -26,6 +26,8 @@ - #include - #include - #include -+#include -+#include - - #include "rt2x00.h" - #include "rt2x00lib.h" -@@ -931,6 +933,21 @@ static void rt2x00lib_rate(struct ieee80 - entry->flags |= IEEE80211_RATE_SHORT_PREAMBLE; - } - -+void rt2x00lib_set_mac_address(struct rt2x00_dev *rt2x00dev, u8 *eeprom_mac_addr) -+{ -+ const char *mac_addr; -+ -+ mac_addr = of_get_mac_address(rt2x00dev->dev->of_node); -+ if (mac_addr) -+ ether_addr_copy(eeprom_mac_addr, mac_addr); -+ -+ if (!is_valid_ether_addr(eeprom_mac_addr)) { -+ eth_random_addr(eeprom_mac_addr); -+ rt2x00_eeprom_dbg(rt2x00dev, "MAC: %pM\n", eeprom_mac_addr); -+ } -+} -+EXPORT_SYMBOL_GPL(rt2x00lib_set_mac_address); -+ - static int rt2x00lib_probe_hw_modes(struct rt2x00_dev *rt2x00dev, - struct hw_mode_spec *spec) - { ---- a/drivers/net/wireless/ralink/rt2x00/rt61pci.c -+++ b/drivers/net/wireless/ralink/rt2x00/rt61pci.c -@@ -2413,10 +2413,7 @@ static int rt61pci_validate_eeprom(struc - * Start validation of the data that has been read. - */ - mac = rt2x00_eeprom_addr(rt2x00dev, EEPROM_MAC_ADDR_0); -- if (!is_valid_ether_addr(mac)) { -- eth_random_addr(mac); -- rt2x00_eeprom_dbg(rt2x00dev, "MAC: %pM\n", mac); -- } -+ rt2x00lib_set_mac_address(rt2x00dev, mac); - - rt2x00_eeprom_read(rt2x00dev, EEPROM_ANTENNA, &word); - if (word == 0xffff) { ---- a/drivers/net/wireless/ralink/rt2x00/rt73usb.c -+++ b/drivers/net/wireless/ralink/rt2x00/rt73usb.c -@@ -1766,10 +1766,7 @@ static int rt73usb_validate_eeprom(struc - * Start validation of the data that has been read. - */ - mac = rt2x00_eeprom_addr(rt2x00dev, EEPROM_MAC_ADDR_0); -- if (!is_valid_ether_addr(mac)) { -- eth_random_addr(mac); -- rt2x00_eeprom_dbg(rt2x00dev, "MAC: %pM\n", mac); -- } -+ rt2x00lib_set_mac_address(rt2x00dev, mac); - - rt2x00_eeprom_read(rt2x00dev, EEPROM_ANTENNA, &word); - if (word == 0xffff) { diff --git a/package/kernel/mac80211/patches/608-01-rt2x00-add_platform_data_mac_addr.patch b/package/kernel/mac80211/patches/608-01-rt2x00-add_platform_data_mac_addr.patch deleted file mode 100644 index 1cb81017c5..0000000000 --- a/package/kernel/mac80211/patches/608-01-rt2x00-add_platform_data_mac_addr.patch +++ /dev/null @@ -1,26 +0,0 @@ ---- a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c -+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c -@@ -936,7 +936,12 @@ static void rt2x00lib_rate(struct ieee80 - void rt2x00lib_set_mac_address(struct rt2x00_dev *rt2x00dev, u8 *eeprom_mac_addr) - { - const char *mac_addr; -- -+ struct rt2x00_platform_data *pdata; -+ -+ pdata = rt2x00dev->dev->platform_data; -+ if (pdata) -+ ether_addr_copy(pdata->mac_address, eeprom_mac_addr); -+ - mac_addr = of_get_mac_address(rt2x00dev->dev->of_node); - if (mac_addr) - ether_addr_copy(eeprom_mac_addr, mac_addr); ---- a/include/linux/rt2x00_platform.h -+++ b/include/linux/rt2x00_platform.h -@@ -14,6 +14,7 @@ - - struct rt2x00_platform_data { - char *eeprom_file_name; -+ const u8 *mac_address; - - int disable_2ghz; - int disable_5ghz; diff --git a/package/kernel/mac80211/patches/608-rt2x00-allow_disabling_bands_through_dts.patch b/package/kernel/mac80211/patches/608-rt2x00-allow_disabling_bands_through_dts.patch new file mode 100644 index 0000000000..e312c1dc8a --- /dev/null +++ b/package/kernel/mac80211/patches/608-rt2x00-allow_disabling_bands_through_dts.patch @@ -0,0 +1,19 @@ +--- a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c +@@ -955,6 +955,16 @@ static int rt2x00lib_probe_hw_modes(stru + struct ieee80211_rate *rates; + unsigned int num_rates; + unsigned int i; ++#ifdef CONFIG_OF ++ struct device_node *np = rt2x00dev->dev->of_node; ++ unsigned int enabled; ++ if (!of_property_read_u32(np, "ralink,2ghz", ++ &enabled) && !enabled) ++ spec->supported_bands &= ~SUPPORT_BAND_2GHZ; ++ if (!of_property_read_u32(np, "ralink,5ghz", ++ &enabled) && !enabled) ++ spec->supported_bands &= ~SUPPORT_BAND_5GHZ; ++#endif /* CONFIG_OF */ + + if (rt2x00dev->dev->platform_data) { + struct rt2x00_platform_data *pdata; diff --git a/package/kernel/mac80211/patches/609-rt2x00-allow_disabling_bands_through_dts.patch b/package/kernel/mac80211/patches/609-rt2x00-allow_disabling_bands_through_dts.patch deleted file mode 100644 index c27a2f44de..0000000000 --- a/package/kernel/mac80211/patches/609-rt2x00-allow_disabling_bands_through_dts.patch +++ /dev/null @@ -1,19 +0,0 @@ ---- a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c -+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c -@@ -961,6 +961,16 @@ static int rt2x00lib_probe_hw_modes(stru - struct ieee80211_rate *rates; - unsigned int num_rates; - unsigned int i; -+#ifdef CONFIG_OF -+ struct device_node *np = rt2x00dev->dev->of_node; -+ unsigned int enabled; -+ if (!of_property_read_u32(np, "ralink,2ghz", -+ &enabled) && !enabled) -+ spec->supported_bands &= ~SUPPORT_BAND_2GHZ; -+ if (!of_property_read_u32(np, "ralink,5ghz", -+ &enabled) && !enabled) -+ spec->supported_bands &= ~SUPPORT_BAND_5GHZ; -+#endif /* CONFIG_OF */ - - if (rt2x00dev->dev->platform_data) { - struct rt2x00_platform_data *pdata; diff --git a/package/kernel/mac80211/patches/609-rt2x00-make-wmac-loadable-via-OF-on-rt288x-305x-SoC.patch b/package/kernel/mac80211/patches/609-rt2x00-make-wmac-loadable-via-OF-on-rt288x-305x-SoC.patch new file mode 100644 index 0000000000..02b66e3bc0 --- /dev/null +++ b/package/kernel/mac80211/patches/609-rt2x00-make-wmac-loadable-via-OF-on-rt288x-305x-SoC.patch @@ -0,0 +1,33 @@ +From 04dbd87265f6ba4a373b211ba324b437d224fb2d Mon Sep 17 00:00:00 2001 +From: John Crispin +Date: Sun, 17 Mar 2013 00:03:31 +0100 +Subject: [PATCH 21/38] rt2x00: make wmac loadable via OF on rt288x/305x SoC + +This patch ads the match table to allow loading the wmac support from a +devicetree. + +Signed-off-by: John Crispin +--- + drivers/net/wireless/ralink/rt2x00/rt2800pci.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +--- a/drivers/net/wireless/ralink/rt2x00/rt2800soc.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2800soc.c +@@ -234,10 +234,17 @@ static int rt2800soc_probe(struct platfo + return rt2x00soc_probe(pdev, &rt2800soc_ops); + } + ++static const struct of_device_id rt2880_wmac_match[] = { ++ { .compatible = "ralink,rt2880-wmac" }, ++ {}, ++}; ++MODULE_DEVICE_TABLE(of, rt2880_wmac_match); ++ + static struct platform_driver rt2800soc_driver = { + .driver = { + .name = "rt2800_wmac", + .mod_name = KBUILD_MODNAME, ++ .of_match_table = rt2880_wmac_match, + }, + .probe = rt2800soc_probe, + .remove = rt2x00soc_remove, diff --git a/package/kernel/mac80211/patches/610-rt2x00-change-led-polarity-from-OF.patch b/package/kernel/mac80211/patches/610-rt2x00-change-led-polarity-from-OF.patch new file mode 100644 index 0000000000..89fc706100 --- /dev/null +++ b/package/kernel/mac80211/patches/610-rt2x00-change-led-polarity-from-OF.patch @@ -0,0 +1,40 @@ +--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c +@@ -36,6 +36,7 @@ + #include + #include + #include ++#include + + #include "rt2x00.h" + #include "rt2800lib.h" +@@ -7861,6 +7862,17 @@ static int rt2800_init_eeprom(struct rt2 + rt2800_init_led(rt2x00dev, &rt2x00dev->led_assoc, LED_TYPE_ASSOC); + rt2800_init_led(rt2x00dev, &rt2x00dev->led_qual, LED_TYPE_QUALITY); + ++ { ++ struct device_node *np = rt2x00dev->dev->of_node; ++ unsigned int led_polarity; ++ ++ /* Allow overriding polarity from OF */ ++ if (!of_property_read_u32(np, "ralink,led-polarity", ++ &led_polarity)) ++ rt2x00_set_field16(&eeprom, EEPROM_FREQ_LED_POLARITY, ++ led_polarity); ++ } ++ + rt2x00dev->led_mcu_reg = eeprom; + #endif /* CPTCFG_RT2X00_LIB_LEDS */ + +--- a/drivers/net/wireless/ralink/rt2x00/rt2x00leds.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2x00leds.c +@@ -109,6 +109,9 @@ static int rt2x00leds_register_led(struc + led->led_dev.name = name; + led->led_dev.brightness = LED_OFF; + ++ if (rt2x00_is_soc(rt2x00dev)) ++ led->led_dev.brightness_set(&led->led_dev, LED_OFF); ++ + retval = led_classdev_register(device, &led->led_dev); + if (retval) { + rt2x00_err(rt2x00dev, "Failed to register led handler\n"); diff --git a/package/kernel/mac80211/patches/610-rt2x00-fix-rt3352-ext-pa.patch b/package/kernel/mac80211/patches/610-rt2x00-fix-rt3352-ext-pa.patch deleted file mode 100644 index 22d5b0240e..0000000000 --- a/package/kernel/mac80211/patches/610-rt2x00-fix-rt3352-ext-pa.patch +++ /dev/null @@ -1,211 +0,0 @@ ---- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c -+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c -@@ -3529,11 +3529,18 @@ static void rt2800_config_channel(struct - /* - * Change BBP settings - */ -+ - if (rt2x00_rt(rt2x00dev, RT3352)) { -+ rt2800_bbp_write(rt2x00dev, 62, 0x37 - rt2x00dev->lna_gain); -+ rt2800_bbp_write(rt2x00dev, 63, 0x37 - rt2x00dev->lna_gain); -+ rt2800_bbp_write(rt2x00dev, 64, 0x37 - rt2x00dev->lna_gain); -+ - rt2800_bbp_write(rt2x00dev, 27, 0x0); - rt2800_bbp_write(rt2x00dev, 66, 0x26 + rt2x00dev->lna_gain); - rt2800_bbp_write(rt2x00dev, 27, 0x20); - rt2800_bbp_write(rt2x00dev, 66, 0x26 + rt2x00dev->lna_gain); -+ rt2800_bbp_write(rt2x00dev, 86, 0x38); -+ rt2800_bbp_write(rt2x00dev, 83, 0x6a); - } else if (rt2x00_rt(rt2x00dev, RT3593)) { - if (rf->channel > 14) { - /* Disable CCK Packet detection on 5GHz */ -@@ -6595,6 +6602,12 @@ static void rt2800_init_rfcsr_3290(struc - - static void rt2800_init_rfcsr_3352(struct rt2x00_dev *rt2x00dev) - { -+ int tx0_int_pa = test_bit(CAPABILITY_INTERNAL_PA_TX0, -+ &rt2x00dev->cap_flags); -+ int tx1_int_pa = test_bit(CAPABILITY_INTERNAL_PA_TX1, -+ &rt2x00dev->cap_flags); -+ u8 rfcsr; -+ - rt2800_rf_init_calibration(rt2x00dev, 30); - - rt2800_rfcsr_write(rt2x00dev, 0, 0xf0); -@@ -6630,15 +6643,30 @@ static void rt2800_init_rfcsr_3352(struc - rt2800_rfcsr_write(rt2x00dev, 31, 0x80); - rt2800_rfcsr_write(rt2x00dev, 32, 0x80); - rt2800_rfcsr_write(rt2x00dev, 33, 0x00); -- rt2800_rfcsr_write(rt2x00dev, 34, 0x01); -+ rfcsr = 0x01; -+ if (!tx0_int_pa) -+ rt2x00_set_field8(&rfcsr, RFCSR34_TX0_EXT_PA, 1); -+ if (!tx1_int_pa) -+ rt2x00_set_field8(&rfcsr, RFCSR34_TX1_EXT_PA, 1); -+ rt2800_rfcsr_write(rt2x00dev, 34, rfcsr); - rt2800_rfcsr_write(rt2x00dev, 35, 0x03); - rt2800_rfcsr_write(rt2x00dev, 36, 0xbd); - rt2800_rfcsr_write(rt2x00dev, 37, 0x3c); - rt2800_rfcsr_write(rt2x00dev, 38, 0x5f); - rt2800_rfcsr_write(rt2x00dev, 39, 0xc5); - rt2800_rfcsr_write(rt2x00dev, 40, 0x33); -- rt2800_rfcsr_write(rt2x00dev, 41, 0x5b); -- rt2800_rfcsr_write(rt2x00dev, 42, 0x5b); -+ rfcsr = 0x52; -+ if (tx0_int_pa) { -+ rt2x00_set_field8(&rfcsr, RFCSR41_BIT1, 1); -+ rt2x00_set_field8(&rfcsr, RFCSR41_BIT4, 1); -+ } -+ rt2800_rfcsr_write(rt2x00dev, 41, rfcsr); -+ rfcsr = 0x52; -+ if (tx1_int_pa) { -+ rt2x00_set_field8(&rfcsr, RFCSR42_BIT1, 1); -+ rt2x00_set_field8(&rfcsr, RFCSR42_BIT4, 1); -+ } -+ rt2800_rfcsr_write(rt2x00dev, 42, rfcsr); - rt2800_rfcsr_write(rt2x00dev, 43, 0xdb); - rt2800_rfcsr_write(rt2x00dev, 44, 0xdb); - rt2800_rfcsr_write(rt2x00dev, 45, 0xdb); -@@ -6646,15 +6674,20 @@ static void rt2800_init_rfcsr_3352(struc - rt2800_rfcsr_write(rt2x00dev, 47, 0x0d); - rt2800_rfcsr_write(rt2x00dev, 48, 0x14); - rt2800_rfcsr_write(rt2x00dev, 49, 0x00); -- rt2800_rfcsr_write(rt2x00dev, 50, 0x2d); -- rt2800_rfcsr_write(rt2x00dev, 51, 0x7f); -- rt2800_rfcsr_write(rt2x00dev, 52, 0x00); -- rt2800_rfcsr_write(rt2x00dev, 53, 0x52); -- rt2800_rfcsr_write(rt2x00dev, 54, 0x1b); -- rt2800_rfcsr_write(rt2x00dev, 55, 0x7f); -- rt2800_rfcsr_write(rt2x00dev, 56, 0x00); -- rt2800_rfcsr_write(rt2x00dev, 57, 0x52); -- rt2800_rfcsr_write(rt2x00dev, 58, 0x1b); -+ rfcsr = 0x2d; -+ if (!tx0_int_pa) -+ rt2x00_set_field8(&rfcsr, RFCSR50_TX0_EXT_PA, 1); -+ if (!tx1_int_pa) -+ rt2x00_set_field8(&rfcsr, RFCSR50_TX1_EXT_PA, 1); -+ rt2800_rfcsr_write(rt2x00dev, 50, rfcsr); -+ rt2800_rfcsr_write(rt2x00dev, 51, (tx0_int_pa ? 0x7f : 0x52)); -+ rt2800_rfcsr_write(rt2x00dev, 52, (tx0_int_pa ? 0x00 : 0xc0)); -+ rt2800_rfcsr_write(rt2x00dev, 53, (tx0_int_pa ? 0x52 : 0xd2)); -+ rt2800_rfcsr_write(rt2x00dev, 54, (tx0_int_pa ? 0x1b : 0xc0)); -+ rt2800_rfcsr_write(rt2x00dev, 55, (tx1_int_pa ? 0x7f : 0x52)); -+ rt2800_rfcsr_write(rt2x00dev, 56, (tx1_int_pa ? 0x00 : 0xc0)); -+ rt2800_rfcsr_write(rt2x00dev, 57, (tx0_int_pa ? 0x52 : 0x49)); -+ rt2800_rfcsr_write(rt2x00dev, 58, (tx1_int_pa ? 0x1b : 0xc0)); - rt2800_rfcsr_write(rt2x00dev, 59, 0x00); - rt2800_rfcsr_write(rt2x00dev, 60, 0x00); - rt2800_rfcsr_write(rt2x00dev, 61, 0x00); -@@ -7672,6 +7705,7 @@ static int rt2800_init_eeprom(struct rt2 - * RT53xx: defined in "EEPROM_CHIP_ID" field - */ - if (rt2x00_rt(rt2x00dev, RT3290) || -+ rt2x00_rt(rt2x00dev, RT3352) || - rt2x00_rt(rt2x00dev, RT5390) || - rt2x00_rt(rt2x00dev, RT5392)) - rt2800_eeprom_read(rt2x00dev, EEPROM_CHIP_ID, &rf); -@@ -7767,7 +7801,8 @@ static int rt2800_init_eeprom(struct rt2 - /* - * Detect if this device has Bluetooth co-existence. - */ -- if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF1_BT_COEXIST)) -+ if (!rt2x00_rt(rt2x00dev, RT3352) && -+ rt2x00_get_field16(eeprom, EEPROM_NIC_CONF1_BT_COEXIST)) - __set_bit(CAPABILITY_BT_COEXIST, &rt2x00dev->cap_flags); - - /* -@@ -7796,6 +7831,22 @@ static int rt2800_init_eeprom(struct rt2 - EIRP_MAX_TX_POWER_LIMIT) - __set_bit(CAPABILITY_POWER_LIMIT, &rt2x00dev->cap_flags); - -+ /* -+ * Detect if device uses internal or external PA -+ */ -+ rt2800_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1, &eeprom); -+ -+ if (rt2x00_rt(rt2x00dev, RT3352)) { -+ if (!rt2x00_get_field16(eeprom, -+ EEPROM_NIC_CONF1_EXTERNAL_TX0_PA_3352)) -+ __set_bit(CAPABILITY_INTERNAL_PA_TX0, -+ &rt2x00dev->cap_flags); -+ if (!rt2x00_get_field16(eeprom, -+ EEPROM_NIC_CONF1_EXTERNAL_TX1_PA_3352)) -+ __set_bit(CAPABILITY_INTERNAL_PA_TX1, -+ &rt2x00dev->cap_flags); -+ } -+ - return 0; - } - ---- a/drivers/net/wireless/ralink/rt2x00/rt2800.h -+++ b/drivers/net/wireless/ralink/rt2x00/rt2800.h -@@ -2335,6 +2335,12 @@ struct mac_iveiv_entry { - #define RFCSR36_RF_BS FIELD8(0x80) - - /* -+ * RFCSR 34: -+ */ -+#define RFCSR34_TX0_EXT_PA FIELD8(0x04) -+#define RFCSR34_TX1_EXT_PA FIELD8(0x08) -+ -+/* - * RFCSR 38: - */ - #define RFCSR38_RX_LO1_EN FIELD8(0x20) -@@ -2346,6 +2352,18 @@ struct mac_iveiv_entry { - #define RFCSR39_RX_LO2_EN FIELD8(0x80) - - /* -+ * RFCSR 41: -+ */ -+#define RFCSR41_BIT1 FIELD8(0x01) -+#define RFCSR41_BIT4 FIELD8(0x08) -+ -+/* -+ * RFCSR 42: -+ */ -+#define RFCSR42_BIT1 FIELD8(0x01) -+#define RFCSR42_BIT4 FIELD8(0x08) -+ -+/* - * RFCSR 49: - */ - #define RFCSR49_TX FIELD8(0x3f) -@@ -2358,6 +2376,8 @@ struct mac_iveiv_entry { - * RFCSR 50: - */ - #define RFCSR50_TX FIELD8(0x3f) -+#define RFCSR50_TX0_EXT_PA FIELD8(0x02) -+#define RFCSR50_TX1_EXT_PA FIELD8(0x10) - #define RFCSR50_EP FIELD8(0xc0) - /* bits for RT3593 */ - #define RFCSR50_TX_LO1_EN FIELD8(0x20) -@@ -2505,6 +2525,8 @@ enum rt2800_eeprom_word { - * INTERNAL_TX_ALC: 0: disable, 1: enable - * BT_COEXIST: 0: disable, 1: enable - * DAC_TEST: 0: disable, 1: enable -+ * EXTERNAL_TX0_PA: 0: disable, 1: enable (only on RT3352) -+ * EXTERNAL_TX1_PA: 0: disable, 1: enable (only on RT3352) - */ - #define EEPROM_NIC_CONF1_HW_RADIO FIELD16(0x0001) - #define EEPROM_NIC_CONF1_EXTERNAL_TX_ALC FIELD16(0x0002) -@@ -2521,6 +2543,8 @@ enum rt2800_eeprom_word { - #define EEPROM_NIC_CONF1_INTERNAL_TX_ALC FIELD16(0x2000) - #define EEPROM_NIC_CONF1_BT_COEXIST FIELD16(0x4000) - #define EEPROM_NIC_CONF1_DAC_TEST FIELD16(0x8000) -+#define EEPROM_NIC_CONF1_EXTERNAL_TX0_PA_3352 FIELD16(0x4000) -+#define EEPROM_NIC_CONF1_EXTERNAL_TX1_PA_3352 FIELD16(0x8000) - - /* - * EEPROM frequency ---- a/drivers/net/wireless/ralink/rt2x00/rt2x00.h -+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00.h -@@ -719,6 +719,8 @@ enum rt2x00_capability_flags { - CAPABILITY_DOUBLE_ANTENNA, - CAPABILITY_BT_COEXIST, - CAPABILITY_VCO_RECALIBRATION, -+ CAPABILITY_INTERNAL_PA_TX0, -+ CAPABILITY_INTERNAL_PA_TX1, - }; - - /* diff --git a/package/kernel/mac80211/patches/611-rt2x00-add-AP+STA-support.patch b/package/kernel/mac80211/patches/611-rt2x00-add-AP+STA-support.patch new file mode 100644 index 0000000000..2dac89566a --- /dev/null +++ b/package/kernel/mac80211/patches/611-rt2x00-add-AP+STA-support.patch @@ -0,0 +1,11 @@ +--- a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c +@@ -1286,7 +1286,7 @@ static inline void rt2x00lib_set_if_comb + */ + if_limit = &rt2x00dev->if_limits_ap; + if_limit->max = rt2x00dev->ops->max_ap_intf; +- if_limit->types = BIT(NL80211_IFTYPE_AP); ++ if_limit->types = BIT(NL80211_IFTYPE_AP) | BIT(NL80211_IFTYPE_STATION); + #ifdef CPTCFG_MAC80211_MESH + if_limit->types |= BIT(NL80211_IFTYPE_MESH_POINT); + #endif diff --git a/package/kernel/mac80211/patches/611-rt2x00-rf_vals-rt3352-xtal20.patch b/package/kernel/mac80211/patches/611-rt2x00-rf_vals-rt3352-xtal20.patch deleted file mode 100644 index 124b952515..0000000000 --- a/package/kernel/mac80211/patches/611-rt2x00-rf_vals-rt3352-xtal20.patch +++ /dev/null @@ -1,105 +0,0 @@ ---- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c -+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c -@@ -36,6 +36,7 @@ - #include - #include - #include -+#include - - #include "rt2x00.h" - #include "rt2800lib.h" -@@ -8183,6 +8184,27 @@ static const struct rf_channel rf_vals_5 - {196, 83, 0, 12, 1}, - }; - -+/* -+ * RF value list for rt3xxx with Xtal20MHz -+ * Supports: 2.4 GHz (all) (RF3322) -+ */ -+static const struct rf_channel rf_vals_xtal20mhz_3x[] = { -+ {1, 0xE2, 2, 0x14}, -+ {2, 0xE3, 2, 0x14}, -+ {3, 0xE4, 2, 0x14}, -+ {4, 0xE5, 2, 0x14}, -+ {5, 0xE6, 2, 0x14}, -+ {6, 0xE7, 2, 0x14}, -+ {7, 0xE8, 2, 0x14}, -+ {8, 0xE9, 2, 0x14}, -+ {9, 0xEA, 2, 0x14}, -+ {10, 0xEB, 2, 0x14}, -+ {11, 0xEC, 2, 0x14}, -+ {12, 0xED, 2, 0x14}, -+ {13, 0xEE, 2, 0x14}, -+ {14, 0xF0, 2, 0x18}, -+}; -+ - static int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev) - { - struct hw_mode_spec *spec = &rt2x00dev->spec; -@@ -8273,7 +8295,10 @@ static int rt2800_probe_hw_mode(struct r - case RF5390: - case RF5392: - spec->num_channels = 14; -- spec->channels = rf_vals_3x; -+ if (spec->clk_is_20mhz) -+ spec->channels = rf_vals_xtal20mhz_3x; -+ else -+ spec->channels = rf_vals_3x; - break; - - case RF3052: -@@ -8457,6 +8482,20 @@ static int rt2800_probe_rt(struct rt2x00 - return 0; - } - -+int rt2800_probe_clk(struct rt2x00_dev *rt2x00dev) -+{ -+ struct hw_mode_spec *spec = &rt2x00dev->spec; -+ struct clk *clk = clk_get(rt2x00dev->dev, NULL); -+ -+ if (IS_ERR(clk)) -+ return PTR_ERR(clk); -+ -+ if (clk_get_rate(clk) == 20000000) -+ spec->clk_is_20mhz = 1; -+ -+ return 0; -+} -+ - int rt2800_probe_hw(struct rt2x00_dev *rt2x00dev) - { - struct rt2800_drv_data *drv_data = rt2x00dev->drv_data; -@@ -8499,6 +8538,15 @@ int rt2800_probe_hw(struct rt2x00_dev *r - rt2800_register_write(rt2x00dev, GPIO_CTRL, reg); - - /* -+ * Probe SoC clock. -+ */ -+ if (rt2x00_is_soc(rt2x00dev)) { -+ retval = rt2800_probe_clk(rt2x00dev); -+ if (retval) -+ return retval; -+ } -+ -+ /* - * Initialize hw specifications. - */ - retval = rt2800_probe_hw_mode(rt2x00dev); ---- a/drivers/net/wireless/ralink/rt2x00/rt2x00.h -+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00.h -@@ -401,6 +401,7 @@ static inline struct rt2x00_intf* vif_to - * @channels: Device/chipset specific channel values (See &struct rf_channel). - * @channels_info: Additional information for channels (See &struct channel_info). - * @ht: Driver HT Capabilities (See &ieee80211_sta_ht_cap). -+ * @clk_is_20mhz: External crystal of WiSoC is 20MHz instead of 40MHz - */ - struct hw_mode_spec { - unsigned int supported_bands; -@@ -417,6 +418,7 @@ struct hw_mode_spec { - const struct channel_info *channels_info; - - struct ieee80211_sta_ht_cap ht; -+ int clk_is_20mhz; - }; - - /* diff --git a/package/kernel/mac80211/patches/612-rt2x00-make-wmac-loadable-via-OF-on-rt288x-305x-SoC.patch b/package/kernel/mac80211/patches/612-rt2x00-make-wmac-loadable-via-OF-on-rt288x-305x-SoC.patch deleted file mode 100644 index e4b028b1a9..0000000000 --- a/package/kernel/mac80211/patches/612-rt2x00-make-wmac-loadable-via-OF-on-rt288x-305x-SoC.patch +++ /dev/null @@ -1,33 +0,0 @@ -From 04dbd87265f6ba4a373b211ba324b437d224fb2d Mon Sep 17 00:00:00 2001 -From: John Crispin -Date: Sun, 17 Mar 2013 00:03:31 +0100 -Subject: [PATCH 21/38] rt2x00: make wmac loadable via OF on rt288x/305x SoC - -This patch ads the match table to allow loading the wmac support from a -devicetree. - -Signed-off-by: John Crispin ---- - drivers/net/wireless/ralink/rt2x00/rt2800pci.c | 7 +++++++ - 1 file changed, 7 insertions(+) - ---- a/drivers/net/wireless/ralink/rt2x00/rt2800soc.c -+++ b/drivers/net/wireless/ralink/rt2x00/rt2800soc.c -@@ -237,10 +237,17 @@ static int rt2800soc_probe(struct platfo - return rt2x00soc_probe(pdev, &rt2800soc_ops); - } - -+static const struct of_device_id rt2880_wmac_match[] = { -+ { .compatible = "ralink,rt2880-wmac" }, -+ {}, -+}; -+MODULE_DEVICE_TABLE(of, rt2880_wmac_match); -+ - static struct platform_driver rt2800soc_driver = { - .driver = { - .name = "rt2800_wmac", - .mod_name = KBUILD_MODNAME, -+ .of_match_table = rt2880_wmac_match, - }, - .probe = rt2800soc_probe, - .remove = rt2x00soc_remove, diff --git a/package/kernel/mac80211/patches/616-rt2x00-support-rt5350.patch b/package/kernel/mac80211/patches/616-rt2x00-support-rt5350.patch deleted file mode 100644 index a5007ddb4a..0000000000 --- a/package/kernel/mac80211/patches/616-rt2x00-support-rt5350.patch +++ /dev/null @@ -1,276 +0,0 @@ ---- a/drivers/net/wireless/ralink/rt2x00/rt2800.h -+++ b/drivers/net/wireless/ralink/rt2x00/rt2800.h -@@ -74,6 +74,7 @@ - #define RF3070 0x3070 - #define RF3290 0x3290 - #define RF3853 0x3853 -+#define RF5350 0x5350 - #define RF5360 0x5360 - #define RF5362 0x5362 - #define RF5370 0x5370 ---- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c -+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c -@@ -3015,6 +3015,13 @@ static void rt2800_config_channel_rf53xx - - rt2800_rfcsr_write(rt2x00dev, 59, - r59_non_bt[idx]); -+ } else if (rt2x00_rt(rt2x00dev, RT5350)) { -+ static const char r59_non_bt[] = {0x0b, 0x0b, -+ 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0a, -+ 0x0a, 0x09, 0x08, 0x07, 0x07, 0x06}; -+ -+ rt2800_rfcsr_write(rt2x00dev, 59, -+ r59_non_bt[idx]); - } - } - } -@@ -3493,6 +3500,7 @@ static void rt2800_config_channel(struct - rt2800_config_channel_rf3853(rt2x00dev, conf, rf, info); - break; - case RF3070: -+ case RF5350: - case RF5360: - case RF5362: - case RF5370: -@@ -3511,6 +3519,7 @@ static void rt2800_config_channel(struct - if (rt2x00_rf(rt2x00dev, RF3070) || - rt2x00_rf(rt2x00dev, RF3290) || - rt2x00_rf(rt2x00dev, RF3322) || -+ rt2x00_rf(rt2x00dev, RF5350) || - rt2x00_rf(rt2x00dev, RF5360) || - rt2x00_rf(rt2x00dev, RF5362) || - rt2x00_rf(rt2x00dev, RF5370) || -@@ -3789,7 +3798,8 @@ static void rt2800_config_channel(struct - /* - * Clear update flag - */ -- if (rt2x00_rt(rt2x00dev, RT3352)) { -+ if (rt2x00_rt(rt2x00dev, RT3352) || -+ rt2x00_rt(rt2x00dev, RT5350)) { - rt2800_bbp_read(rt2x00dev, 49, &bbp); - rt2x00_set_field8(&bbp, BBP49_UPDATE_FLAG, 0); - rt2800_bbp_write(rt2x00dev, 49, bbp); -@@ -4675,6 +4685,7 @@ void rt2800_vco_calibration(struct rt2x0 - case RF3070: - case RF3290: - case RF3853: -+ case RF5350: - case RF5360: - case RF5362: - case RF5370: -@@ -5088,6 +5099,8 @@ static int rt2800_init_registers(struct - rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000404); - rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00080606); - rt2800_register_write(rt2x00dev, TX_SW_CFG2, 0x00000000); -+ } else if (rt2x00_rt(rt2x00dev, RT5350)) { -+ rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000404); - } else { - rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000000); - rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00080606); -@@ -5743,9 +5756,13 @@ static void rt2800_init_bbp_3352(struct - - rt2800_bbp_write(rt2x00dev, 82, 0x62); - -- rt2800_bbp_write(rt2x00dev, 83, 0x6a); -- -- rt2800_bbp_write(rt2x00dev, 84, 0x99); -+ if (rt2x00_rt(rt2x00dev, RT5350)) { -+ rt2800_bbp_write(rt2x00dev, 83, 0x7a); -+ rt2800_bbp_write(rt2x00dev, 84, 0x9a); -+ } else { -+ rt2800_bbp_write(rt2x00dev, 83, 0x6a); -+ rt2800_bbp_write(rt2x00dev, 84, 0x99); -+ } - - rt2800_bbp_write(rt2x00dev, 86, 0x38); - -@@ -5759,9 +5776,13 @@ static void rt2800_init_bbp_3352(struct - - rt2800_bbp_write(rt2x00dev, 104, 0x92); - -- rt2800_bbp_write(rt2x00dev, 105, 0x34); -- -- rt2800_bbp_write(rt2x00dev, 106, 0x05); -+ if (rt2x00_rt(rt2x00dev, RT5350)) { -+ rt2800_bbp_write(rt2x00dev, 105, 0x3c); -+ rt2800_bbp_write(rt2x00dev, 106, 0x03); -+ } else { -+ rt2800_bbp_write(rt2x00dev, 105, 0x34); -+ rt2800_bbp_write(rt2x00dev, 106, 0x05); -+ } - - rt2800_bbp_write(rt2x00dev, 120, 0x50); - -@@ -5786,6 +5807,13 @@ static void rt2800_init_bbp_3352(struct - rt2800_bbp_write(rt2x00dev, 143, 0xa2); - - rt2800_bbp_write(rt2x00dev, 148, 0xc8); -+ -+ if (rt2x00_rt(rt2x00dev, RT5350)) { -+ rt2800_bbp_write(rt2x00dev, 150, 0x40); /* Antenna Software OFDM */ -+ rt2800_bbp_write(rt2x00dev, 151, 0x30); /* Antenna Software CCK */ -+ rt2800_bbp_write(rt2x00dev, 152, 0xa3); -+ rt2800_bbp_write(rt2x00dev, 154, 0); /* Clear previously selected antenna */ -+ } - } - - static void rt2800_init_bbp_3390(struct rt2x00_dev *rt2x00dev) -@@ -6127,6 +6155,7 @@ static void rt2800_init_bbp(struct rt2x0 - rt2800_init_bbp_3290(rt2x00dev); - break; - case RT3352: -+ case RT5350: - rt2800_init_bbp_3352(rt2x00dev); - break; - case RT3390: -@@ -7078,6 +7107,76 @@ static void rt2800_init_rfcsr_3883(struc - rt2800_rfcsr_write(rt2x00dev, 20, rfcsr); - } - -+static void rt2800_init_rfcsr_5350(struct rt2x00_dev *rt2x00dev) -+{ -+ rt2800_rfcsr_write(rt2x00dev, 0, 0xf0); -+ rt2800_rfcsr_write(rt2x00dev, 1, 0x23); -+ rt2800_rfcsr_write(rt2x00dev, 2, 0x50); -+ rt2800_rfcsr_write(rt2x00dev, 3, 0x08); -+ rt2800_rfcsr_write(rt2x00dev, 4, 0x49); -+ rt2800_rfcsr_write(rt2x00dev, 5, 0x10); -+ rt2800_rfcsr_write(rt2x00dev, 6, 0xe0); -+ rt2800_rfcsr_write(rt2x00dev, 7, 0x00); -+ rt2800_rfcsr_write(rt2x00dev, 8, 0xf1); -+ rt2800_rfcsr_write(rt2x00dev, 9, 0x02); -+ rt2800_rfcsr_write(rt2x00dev, 10, 0x53); -+ rt2800_rfcsr_write(rt2x00dev, 11, 0x4a); -+ rt2800_rfcsr_write(rt2x00dev, 12, 0x46); -+ if(rt2x00dev->spec.clk_is_20mhz) -+ rt2800_rfcsr_write(rt2x00dev, 13, 0x1f); -+ else -+ rt2800_rfcsr_write(rt2x00dev, 13, 0x9f); -+ rt2800_rfcsr_write(rt2x00dev, 14, 0x00); -+ rt2800_rfcsr_write(rt2x00dev, 15, 0x00); -+ rt2800_rfcsr_write(rt2x00dev, 16, 0xc0); -+ rt2800_rfcsr_write(rt2x00dev, 18, 0x03); -+ rt2800_rfcsr_write(rt2x00dev, 19, 0x00); -+ rt2800_rfcsr_write(rt2x00dev, 20, 0x00); -+ rt2800_rfcsr_write(rt2x00dev, 21, 0x00); -+ rt2800_rfcsr_write(rt2x00dev, 22, 0x20); -+ rt2800_rfcsr_write(rt2x00dev, 23, 0x00); -+ rt2800_rfcsr_write(rt2x00dev, 24, 0x00); -+ rt2800_rfcsr_write(rt2x00dev, 25, 0x80); -+ rt2800_rfcsr_write(rt2x00dev, 26, 0x00); -+ rt2800_rfcsr_write(rt2x00dev, 27, 0x03); -+ rt2800_rfcsr_write(rt2x00dev, 28, 0x00); -+ rt2800_rfcsr_write(rt2x00dev, 29, 0xd0); -+ rt2800_rfcsr_write(rt2x00dev, 30, 0x10); -+ rt2800_rfcsr_write(rt2x00dev, 31, 0x80); -+ rt2800_rfcsr_write(rt2x00dev, 32, 0x80); -+ rt2800_rfcsr_write(rt2x00dev, 33, 0x00); -+ rt2800_rfcsr_write(rt2x00dev, 34, 0x07); -+ rt2800_rfcsr_write(rt2x00dev, 35, 0x12); -+ rt2800_rfcsr_write(rt2x00dev, 36, 0x00); -+ rt2800_rfcsr_write(rt2x00dev, 37, 0x08); -+ rt2800_rfcsr_write(rt2x00dev, 38, 0x85); -+ rt2800_rfcsr_write(rt2x00dev, 39, 0x1b); -+ rt2800_rfcsr_write(rt2x00dev, 40, 0x0b); -+ rt2800_rfcsr_write(rt2x00dev, 41, 0xbb); -+ rt2800_rfcsr_write(rt2x00dev, 42, 0xd5); -+ rt2800_rfcsr_write(rt2x00dev, 43, 0x9b); -+ rt2800_rfcsr_write(rt2x00dev, 44, 0x0c); -+ rt2800_rfcsr_write(rt2x00dev, 45, 0xa6); -+ rt2800_rfcsr_write(rt2x00dev, 46, 0x73); -+ rt2800_rfcsr_write(rt2x00dev, 47, 0x00); -+ rt2800_rfcsr_write(rt2x00dev, 48, 0x10); -+ rt2800_rfcsr_write(rt2x00dev, 49, 0x80); -+ rt2800_rfcsr_write(rt2x00dev, 50, 0x00); -+ rt2800_rfcsr_write(rt2x00dev, 51, 0x00); -+ rt2800_rfcsr_write(rt2x00dev, 52, 0x38); -+ rt2800_rfcsr_write(rt2x00dev, 53, 0x00); -+ rt2800_rfcsr_write(rt2x00dev, 54, 0x38); -+ rt2800_rfcsr_write(rt2x00dev, 55, 0x43); -+ rt2800_rfcsr_write(rt2x00dev, 56, 0x82); -+ rt2800_rfcsr_write(rt2x00dev, 57, 0x00); -+ rt2800_rfcsr_write(rt2x00dev, 58, 0x39); -+ rt2800_rfcsr_write(rt2x00dev, 59, 0x0b); -+ rt2800_rfcsr_write(rt2x00dev, 60, 0x45); -+ rt2800_rfcsr_write(rt2x00dev, 61, 0xd1); -+ rt2800_rfcsr_write(rt2x00dev, 62, 0x00); -+ rt2800_rfcsr_write(rt2x00dev, 63, 0x00); -+} -+ - static void rt2800_init_rfcsr_5390(struct rt2x00_dev *rt2x00dev) - { - rt2800_rf_init_calibration(rt2x00dev, 2); -@@ -7318,6 +7417,9 @@ static void rt2800_init_rfcsr(struct rt2 - case RT3593: - rt2800_init_rfcsr_3593(rt2x00dev); - break; -+ case RT5350: -+ rt2800_init_rfcsr_5350(rt2x00dev); -+ break; - case RT5390: - rt2800_init_rfcsr_5390(rt2x00dev); - break; -@@ -7574,6 +7676,12 @@ static int rt2800_validate_eeprom(struct - rt2x00_set_field16(&word, EEPROM_NIC_CONF0_RF_TYPE, RF2820); - rt2800_eeprom_write(rt2x00dev, EEPROM_NIC_CONF0, word); - rt2x00_eeprom_dbg(rt2x00dev, "Antenna: 0x%04x\n", word); -+ } else if (rt2x00_rt(rt2x00dev, RT5350)) { -+ rt2x00_set_field16(&word, EEPROM_NIC_CONF0_RXPATH, 1); -+ rt2x00_set_field16(&word, EEPROM_NIC_CONF0_TXPATH, 1); -+ rt2x00_set_field16(&word, EEPROM_NIC_CONF0_RF_TYPE, RF3320); -+ rt2x00_eeprom_write(rt2x00dev, EEPROM_NIC_CONF0, word); -+ rt2x00_eeprom_dbg(rt2x00dev, "Antenna: 0x%04x\n", word); - } else if (rt2x00_rt(rt2x00dev, RT2860) || - rt2x00_rt(rt2x00dev, RT2872)) { - /* -@@ -7712,6 +7820,8 @@ static int rt2800_init_eeprom(struct rt2 - rt2800_eeprom_read(rt2x00dev, EEPROM_CHIP_ID, &rf); - else if (rt2x00_rt(rt2x00dev, RT3883)) - rf = RF3853; -+ else if (rt2x00_rt(rt2x00dev, RT5350)) -+ rf = RF5350; - else - rf = rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_RF_TYPE); - -@@ -7731,6 +7841,7 @@ static int rt2800_init_eeprom(struct rt2 - case RF3320: - case RF3322: - case RF3853: -+ case RF5350: - case RF5360: - case RF5362: - case RF5370: -@@ -8288,6 +8399,7 @@ static int rt2800_probe_hw_mode(struct r - case RF3290: - case RF3320: - case RF3322: -+ case RF5350: - case RF5360: - case RF5362: - case RF5370: -@@ -8427,6 +8539,7 @@ static int rt2800_probe_hw_mode(struct r - case RF3070: - case RF3290: - case RF3853: -+ case RF5350: - case RF5360: - case RF5362: - case RF5370: -@@ -8467,6 +8580,7 @@ static int rt2800_probe_rt(struct rt2x00 - case RT3572: - case RT3593: - case RT3883: -+ case RT5350: - case RT5390: - case RT5392: - case RT5592: ---- a/drivers/net/wireless/ralink/rt2x00/rt2x00.h -+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00.h -@@ -170,6 +170,7 @@ struct rt2x00_chip { - #define RT3572 0x3572 - #define RT3593 0x3593 - #define RT3883 0x3883 /* WSOC */ -+#define RT5350 0x5350 /* WSOC 2.4GHz */ - #define RT5390 0x5390 /* 2.4GHz */ - #define RT5392 0x5392 /* 2.4GHz */ - #define RT5592 0x5592 diff --git a/package/kernel/mac80211/patches/619-rt2x00-change-led-polarity-from-OF.patch b/package/kernel/mac80211/patches/619-rt2x00-change-led-polarity-from-OF.patch deleted file mode 100644 index c173bc0ca3..0000000000 --- a/package/kernel/mac80211/patches/619-rt2x00-change-led-polarity-from-OF.patch +++ /dev/null @@ -1,40 +0,0 @@ ---- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c -+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c -@@ -37,6 +37,7 @@ - #include - #include - #include -+#include - - #include "rt2x00.h" - #include "rt2800lib.h" -@@ -7931,6 +7932,17 @@ static int rt2800_init_eeprom(struct rt2 - rt2800_init_led(rt2x00dev, &rt2x00dev->led_assoc, LED_TYPE_ASSOC); - rt2800_init_led(rt2x00dev, &rt2x00dev->led_qual, LED_TYPE_QUALITY); - -+ { -+ struct device_node *np = rt2x00dev->dev->of_node; -+ unsigned int led_polarity; -+ -+ /* Allow overriding polarity from OF */ -+ if (!of_property_read_u32(np, "ralink,led-polarity", -+ &led_polarity)) -+ rt2x00_set_field16(&eeprom, EEPROM_FREQ_LED_POLARITY, -+ led_polarity); -+ } -+ - rt2x00dev->led_mcu_reg = eeprom; - #endif /* CPTCFG_RT2X00_LIB_LEDS */ - ---- a/drivers/net/wireless/ralink/rt2x00/rt2x00leds.c -+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00leds.c -@@ -109,6 +109,9 @@ static int rt2x00leds_register_led(struc - led->led_dev.name = name; - led->led_dev.brightness = LED_OFF; - -+ if (rt2x00_is_soc(rt2x00dev)) -+ led->led_dev.brightness_set(&led->led_dev, LED_OFF); -+ - retval = led_classdev_register(device, &led->led_dev); - if (retval) { - rt2x00_err(rt2x00dev, "Failed to register led handler\n"); diff --git a/package/kernel/mac80211/patches/620-rt2x00-add-AP+STA-support.patch b/package/kernel/mac80211/patches/620-rt2x00-add-AP+STA-support.patch deleted file mode 100644 index 2fe5c7e1cc..0000000000 --- a/package/kernel/mac80211/patches/620-rt2x00-add-AP+STA-support.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c -+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c -@@ -1292,7 +1292,7 @@ static inline void rt2x00lib_set_if_comb - */ - if_limit = &rt2x00dev->if_limits_ap; - if_limit->max = rt2x00dev->ops->max_ap_intf; -- if_limit->types = BIT(NL80211_IFTYPE_AP); -+ if_limit->types = BIT(NL80211_IFTYPE_AP) | BIT(NL80211_IFTYPE_STATION); - #ifdef CPTCFG_MAC80211_MESH - if_limit->types |= BIT(NL80211_IFTYPE_MESH_POINT); - #endif diff --git a/package/kernel/mac80211/patches/620-rt2x00-enable-rt2800soc-for-mt7620.patch b/package/kernel/mac80211/patches/620-rt2x00-enable-rt2800soc-for-mt7620.patch new file mode 100644 index 0000000000..bc9f799520 --- /dev/null +++ b/package/kernel/mac80211/patches/620-rt2x00-enable-rt2800soc-for-mt7620.patch @@ -0,0 +1,20 @@ +--- a/drivers/net/wireless/ralink/rt2x00/Kconfig ++++ b/drivers/net/wireless/ralink/rt2x00/Kconfig +@@ -211,7 +211,7 @@ endif + config RT2800SOC + tristate "Ralink WiSoC support" + depends on m +- depends on SOC_RT288X || SOC_RT305X || SOC_RT3883 ++ depends on SOC_RT288X || SOC_RT305X || SOC_RT3883 || SOC_MT7620 + select RT2X00_LIB_SOC + select RT2X00_LIB_MMIO + select RT2X00_LIB_CRYPTO +@@ -248,7 +248,7 @@ config RT2X00_LIB_PCI + + config RT2X00_LIB_SOC + tristate "RT2x00 SoC support" +- depends on SOC_RT288X || SOC_RT305X || SOC_RT3883 ++ depends on SOC_RT288X || SOC_RT305X || SOC_RT3883 || SOC_MT7620 + depends on m + select RT2X00_LIB + diff --git a/package/kernel/mac80211/patches/620-rt2x00-rt3352-rf-id.patch b/package/kernel/mac80211/patches/620-rt2x00-rt3352-rf-id.patch deleted file mode 100644 index 1a6e728d59..0000000000 --- a/package/kernel/mac80211/patches/620-rt2x00-rt3352-rf-id.patch +++ /dev/null @@ -1,15 +0,0 @@ ---- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c -+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c -@@ -7815,10 +7815,11 @@ static int rt2800_init_eeprom(struct rt2 - * RT53xx: defined in "EEPROM_CHIP_ID" field - */ - if (rt2x00_rt(rt2x00dev, RT3290) || -- rt2x00_rt(rt2x00dev, RT3352) || - rt2x00_rt(rt2x00dev, RT5390) || - rt2x00_rt(rt2x00dev, RT5392)) - rt2800_eeprom_read(rt2x00dev, EEPROM_CHIP_ID, &rf); -+ else if (rt2x00_rt(rt2x00dev, RT3352)) -+ rf = RF3322; - else if (rt2x00_rt(rt2x00dev, RT3883)) - rf = RF3853; - else if (rt2x00_rt(rt2x00dev, RT5350)) diff --git a/package/kernel/mac80211/patches/621-rt2x00-add-support-for-mt7620.patch b/package/kernel/mac80211/patches/621-rt2x00-add-support-for-mt7620.patch new file mode 100644 index 0000000000..ecb046b9f1 --- /dev/null +++ b/package/kernel/mac80211/patches/621-rt2x00-add-support-for-mt7620.patch @@ -0,0 +1,1185 @@ +--- a/drivers/net/wireless/ralink/rt2x00/rt2800.h ++++ b/drivers/net/wireless/ralink/rt2x00/rt2800.h +@@ -81,6 +81,7 @@ + #define RF5372 0x5372 + #define RF5390 0x5390 + #define RF5392 0x5392 ++#define RF7620 0x7620 + + /* + * Chipset revisions. +@@ -641,6 +642,14 @@ + #define RF_CSR_CFG_BUSY FIELD32(0x00020000) + + /* ++ * mt7620 RF registers (reversed order) ++ */ ++#define RF_CSR_CFG_DATA_MT7620 FIELD32(0x0000ff00) ++#define RF_CSR_CFG_REGNUM_MT7620 FIELD32(0x03ff0000) ++#define RF_CSR_CFG_WRITE_MT7620 FIELD32(0x00000010) ++#define RF_CSR_CFG_BUSY_MT7620 FIELD32(0x00000001) ++ ++/* + * EFUSE_CSR: RT30x0 EEPROM + */ + #define EFUSE_CTRL 0x0580 +@@ -1024,6 +1033,11 @@ + #define AUTOWAKEUP_CFG_AUTOWAKE FIELD32(0x00008000) + + /* ++ * mt7620 ++ */ ++#define MIMO_PS_CFG 0x1210 ++ ++/* + * EDCA_AC0_CFG: + */ + #define EDCA_AC0_CFG 0x1300 +@@ -1203,6 +1217,8 @@ + #define TX_PIN_CFG_RFTR_POL FIELD32(0x00020000) + #define TX_PIN_CFG_TRSW_EN FIELD32(0x00040000) + #define TX_PIN_CFG_TRSW_POL FIELD32(0x00080000) ++#define TX_PIN_CFG_RFRX_EN FIELD32(0x00100000) /* mt7620 */ ++#define TX_PIN_CFG_RFRX_POL FIELD32(0x00200000) /* mt7620 */ + #define TX_PIN_CFG_PA_PE_A2_EN FIELD32(0x01000000) + #define TX_PIN_CFG_PA_PE_G2_EN FIELD32(0x02000000) + #define TX_PIN_CFG_PA_PE_A2_POL FIELD32(0x04000000) +@@ -1549,6 +1565,17 @@ + #define TX_PWR_CFG_4_EXT_STBC4_CH2 FIELD32(0x0000000f) + #define TX_PWR_CFG_4_EXT_STBC6_CH2 FIELD32(0x00000f00) + ++/* mt7620 */ ++#define TX0_RF_GAIN_CORRECT 0x13a0 ++#define TX1_RF_GAIN_CORRECT 0x13a4 ++#define TX0_RF_GAIN_ATTEN 0x13a8 ++#define TX1_RF_GAIN_ATTEN 0x13ac ++#define TX_ALG_CFG_0 0x13b0 ++#define TX_ALG_CFG_1 0x13b4 ++#define TX0_BB_GAIN_ATTEN 0x13c0 ++#define TX1_BB_GAIN_ATTEN 0x13c4 ++#define TX_ALC_VGA3 0x13c8 ++ + /* TX_PWR_CFG_7 */ + #define TX_PWR_CFG_7 0x13d4 + #define TX_PWR_CFG_7_OFDM54_CH0 FIELD32(0x0000000f) +--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c +@@ -60,6 +60,8 @@ + rt2800_regbusy_read((__dev), BBP_CSR_CFG, BBP_CSR_CFG_BUSY, (__reg)) + #define WAIT_FOR_RFCSR(__dev, __reg) \ + rt2800_regbusy_read((__dev), RF_CSR_CFG, RF_CSR_CFG_BUSY, (__reg)) ++#define WAIT_FOR_RFCSR_MT7620(__dev, __reg) \ ++ rt2800_regbusy_read((__dev), RF_CSR_CFG, RF_CSR_CFG_BUSY_MT7620, (__reg)) + #define WAIT_FOR_RF(__dev, __reg) \ + rt2800_regbusy_read((__dev), RF_CSR_CFG0, RF_CSR_CFG0_BUSY, (__reg)) + #define WAIT_FOR_MCU(__dev, __reg) \ +@@ -151,19 +153,55 @@ static void rt2800_rfcsr_write(struct rt + * Wait until the RFCSR becomes available, afterwards we + * can safely write the new data into the register. + */ +- if (WAIT_FOR_RFCSR(rt2x00dev, ®)) { +- reg = 0; +- rt2x00_set_field32(®, RF_CSR_CFG_DATA, value); +- rt2x00_set_field32(®, RF_CSR_CFG_REGNUM, word); +- rt2x00_set_field32(®, RF_CSR_CFG_WRITE, 1); +- rt2x00_set_field32(®, RF_CSR_CFG_BUSY, 1); ++ switch (rt2x00dev->chip.rf) { ++ case RF7620: ++ if (WAIT_FOR_RFCSR_MT7620(rt2x00dev, ®)) { ++ reg = 0; ++ rt2x00_set_field32(®, RF_CSR_CFG_DATA_MT7620, value); ++ rt2x00_set_field32(®, RF_CSR_CFG_REGNUM_MT7620, word); ++ rt2x00_set_field32(®, RF_CSR_CFG_WRITE_MT7620, 1); ++ rt2x00_set_field32(®, RF_CSR_CFG_BUSY_MT7620, 1); + +- rt2800_register_write_lock(rt2x00dev, RF_CSR_CFG, reg); ++ rt2800_register_write_lock(rt2x00dev, RF_CSR_CFG, reg); ++ } ++ break; ++ ++ default: ++ if (WAIT_FOR_RFCSR(rt2x00dev, ®)) { ++ reg = 0; ++ rt2x00_set_field32(®, RF_CSR_CFG_DATA, value); ++ rt2x00_set_field32(®, RF_CSR_CFG_REGNUM, word); ++ rt2x00_set_field32(®, RF_CSR_CFG_WRITE, 1); ++ rt2x00_set_field32(®, RF_CSR_CFG_BUSY, 1); ++ ++ rt2800_register_write_lock(rt2x00dev, RF_CSR_CFG, reg); ++ } ++ break; + } + + mutex_unlock(&rt2x00dev->csr_mutex); + } + ++static void rt2800_rfcsr_write_bank(struct rt2x00_dev *rt2x00dev, const u8 bank, ++ const unsigned int reg, const u8 value) ++{ ++ rt2800_rfcsr_write(rt2x00dev, (reg | (bank << 6)), value); ++} ++ ++static void rt2800_rfcsr_write_chanreg(struct rt2x00_dev *rt2x00dev, ++ const unsigned int reg, const u8 value) ++{ ++ rt2800_rfcsr_write_bank(rt2x00dev, 4, reg, value); ++ rt2800_rfcsr_write_bank(rt2x00dev, 6, reg, value); ++} ++ ++static void rt2800_rfcsr_write_dccal(struct rt2x00_dev *rt2x00dev, ++ const unsigned int reg, const u8 value) ++{ ++ rt2800_rfcsr_write_bank(rt2x00dev, 5, reg, value); ++ rt2800_rfcsr_write_bank(rt2x00dev, 7, reg, value); ++} ++ + static void rt2800_rfcsr_read(struct rt2x00_dev *rt2x00dev, + const unsigned int word, u8 *value) + { +@@ -179,22 +217,47 @@ static void rt2800_rfcsr_read(struct rt2 + * doesn't become available in time, reg will be 0xffffffff + * which means we return 0xff to the caller. + */ +- if (WAIT_FOR_RFCSR(rt2x00dev, ®)) { +- reg = 0; +- rt2x00_set_field32(®, RF_CSR_CFG_REGNUM, word); +- rt2x00_set_field32(®, RF_CSR_CFG_WRITE, 0); +- rt2x00_set_field32(®, RF_CSR_CFG_BUSY, 1); ++ switch (rt2x00dev->chip.rf) { ++ case RF7620: ++ if (WAIT_FOR_RFCSR_MT7620(rt2x00dev, ®)) { ++ reg = 0; ++ rt2x00_set_field32(®, RF_CSR_CFG_REGNUM_MT7620, word); ++ rt2x00_set_field32(®, RF_CSR_CFG_WRITE_MT7620, 0); ++ rt2x00_set_field32(®, RF_CSR_CFG_BUSY_MT7620, 1); + +- rt2800_register_write_lock(rt2x00dev, RF_CSR_CFG, reg); ++ rt2800_register_write_lock(rt2x00dev, RF_CSR_CFG, reg); + +- WAIT_FOR_RFCSR(rt2x00dev, ®); +- } ++ WAIT_FOR_RFCSR_MT7620(rt2x00dev, ®); ++ } + +- *value = rt2x00_get_field32(reg, RF_CSR_CFG_DATA); ++ *value = rt2x00_get_field32(reg, RF_CSR_CFG_DATA_MT7620); ++ break; ++ ++ default: ++ if (WAIT_FOR_RFCSR(rt2x00dev, ®)) { ++ reg = 0; ++ rt2x00_set_field32(®, RF_CSR_CFG_REGNUM, word); ++ rt2x00_set_field32(®, RF_CSR_CFG_WRITE, 0); ++ rt2x00_set_field32(®, RF_CSR_CFG_BUSY, 1); ++ ++ rt2800_register_write_lock(rt2x00dev, RF_CSR_CFG, reg); ++ ++ WAIT_FOR_RFCSR(rt2x00dev, ®); ++ } ++ ++ *value = rt2x00_get_field32(reg, RF_CSR_CFG_DATA); ++ break; ++ } + + mutex_unlock(&rt2x00dev->csr_mutex); + } + ++static void rt2800_rfcsr_read_bank(struct rt2x00_dev *rt2x00dev, const u8 bank, ++ const unsigned int reg, u8 *value) ++{ ++ rt2800_rfcsr_read(rt2x00dev, (reg | (bank << 6)), value); ++} ++ + static void rt2800_rf_write(struct rt2x00_dev *rt2x00dev, + const unsigned int word, const u32 value) + { +@@ -526,6 +589,16 @@ void rt2800_get_txwi_rxwi_size(struct rt + *rxwi_size = RXWI_DESC_SIZE_5WORDS; + break; + ++ case RT5390: ++ if ( rt2x00dev->chip.rf == RF7620 ) { ++ *txwi_size = TXWI_DESC_SIZE_5WORDS; ++ *rxwi_size = RXWI_DESC_SIZE_6WORDS; ++ } else { ++ *txwi_size = TXWI_DESC_SIZE_4WORDS; ++ *rxwi_size = RXWI_DESC_SIZE_4WORDS; ++ } ++ break; ++ + case RT5592: + *txwi_size = TXWI_DESC_SIZE_5WORDS; + *rxwi_size = RXWI_DESC_SIZE_6WORDS; +@@ -3258,6 +3331,317 @@ static void rt2800_config_channel_rf55xx + rt2800_bbp_write(rt2x00dev, 196, (rf->channel <= 14) ? 0x19 : 0x7F); + } + ++typedef struct mt7620_freqconfig { ++ u8 Channel; ++ u8 Rdiv; ++ u16 N; ++ u8 K; ++ u8 D; ++ u32 Ksd; ++} mt7620_freqconfig; ++ ++mt7620_freqconfig mt7620_chanconfig[] = ++{ ++ /* 2.4 to 2.483 GHz ++ * CH Rdiv N K D Ksd */ ++ { 0, 0, 0, 0, 0, 0 }, ++ { 1, 3, 0x50, 0, 0, 0x19999 }, ++ { 2, 3, 0x50, 0, 0, 0x24444 }, ++ { 3, 3, 0x50, 0, 0, 0x2EEEE }, ++ { 4, 3, 0x50, 0, 0, 0x39999 }, ++ { 5, 3, 0x51, 0, 0, 0x04444 }, ++ { 6, 3, 0x51, 0, 0, 0x0EEEE }, ++ { 7, 3, 0x51, 0, 0, 0x19999 }, ++ { 8, 3, 0x51, 0, 0, 0x24444 }, ++ { 9, 3, 0x51, 0, 0, 0x2EEEE }, ++ { 10, 3, 0x51, 0, 0, 0x39999 }, ++ { 11, 3, 0x52, 0, 0, 0x04444 }, ++ { 12, 3, 0x52, 0, 0, 0x0EEEE }, ++ { 13, 3, 0x52, 0, 0, 0x19999 }, ++ { 14, 3, 0x52, 0, 0, 0x33333 }, ++}; ++ ++static void rt2800_config_channel_rf7620(struct rt2x00_dev *rt2x00dev, ++ struct ieee80211_conf *conf, ++ struct rf_channel *rf, ++ struct channel_info *info) ++{ ++ struct rt2800_drv_data *drv_data = rt2x00dev->drv_data; ++ u32 mac_sys_ctrl, mac_status; ++ u16 eeprom, target_power; ++ u32 tx_pin = 0x00150F0F; ++ u8 txrx_agc_fc; ++ u8 rfcsr; ++ u32 reg; ++ u8 bbp; ++ int i; ++ ++ /* Frequeny plan setting */ ++ /* ++ * Rdiv setting ++ * R13[1:0] ++ */ ++ rt2800_rfcsr_read(rt2x00dev, 13, &rfcsr); ++ rfcsr = rfcsr & (~0x03); ++ if (rt2800_clk_is_20mhz(rt2x00dev)) ++ rfcsr |= (mt7620_chanconfig[rf->channel].Rdiv & 0x3); ++ rt2800_rfcsr_write(rt2x00dev, 13, rfcsr); ++ ++ /* ++ * N setting ++ * R21[0], R20[7:0] ++ */ ++ rt2800_rfcsr_read(rt2x00dev, 20, &rfcsr); ++ rfcsr = (mt7620_chanconfig[rf->channel].N & 0x00ff); ++ rt2800_rfcsr_write(rt2x00dev, 20, rfcsr); ++ ++ rt2800_rfcsr_read(rt2x00dev, 21, &rfcsr); ++ rfcsr = rfcsr & (~0x01); ++ rfcsr |= ((mt7620_chanconfig[rf->channel].N & 0x0100) >> 8); ++ rt2800_rfcsr_write(rt2x00dev, 21, rfcsr); ++ ++ /* ++ * K setting ++ * R16[3:0] (RF PLL freq selection) ++ */ ++ rt2800_rfcsr_read(rt2x00dev, 16, &rfcsr); ++ rfcsr = rfcsr & (~0x0f); ++ rfcsr |= (mt7620_chanconfig[rf->channel].K & 0x0f); ++ rt2800_rfcsr_write(rt2x00dev, 16, rfcsr); ++ ++ /* ++ * D setting ++ * R22[2:0] (D=15, R22[2:0]=<111>) ++ */ ++ rt2800_rfcsr_read(rt2x00dev, 22, &rfcsr); ++ rfcsr = rfcsr & (~0x07); ++ rfcsr |= (mt7620_chanconfig[rf->channel].D & 0x07); ++ rt2800_rfcsr_write(rt2x00dev, 22, rfcsr); ++ ++ /* ++ * Ksd setting ++ * Ksd: R19<1:0>,R18<7:0>,R17<7:0> ++ */ ++ rt2800_rfcsr_read(rt2x00dev, 17, &rfcsr); ++ rfcsr = (mt7620_chanconfig[rf->channel].Ksd & 0x000000ff); ++ rt2800_rfcsr_write(rt2x00dev, 17, rfcsr); ++ ++ rt2800_rfcsr_read(rt2x00dev, 18, &rfcsr); ++ rfcsr = ((mt7620_chanconfig[rf->channel].Ksd & 0x0000ff00) >> 8); ++ rt2800_rfcsr_write(rt2x00dev, 18, rfcsr); ++ ++ rt2800_rfcsr_read(rt2x00dev, 19, &rfcsr); ++ rfcsr = rfcsr & (~0x03); ++ rfcsr |= ((mt7620_chanconfig[rf->channel].Ksd & 0x00030000) >> 16); ++ rt2800_rfcsr_write(rt2x00dev, 19, rfcsr); ++ ++ /* Default: XO=20MHz , SDM mode */ ++ rt2800_rfcsr_read(rt2x00dev, 16, &rfcsr); ++ rfcsr = rfcsr & (~0xE0); ++ rfcsr |= 0x80; ++ rt2800_rfcsr_write(rt2x00dev, 16, rfcsr); ++ ++ rt2800_rfcsr_read(rt2x00dev, 21, &rfcsr); ++ rfcsr |= 0x80; ++ rt2800_rfcsr_write(rt2x00dev, 21, rfcsr); ++ ++ rt2800_rfcsr_read(rt2x00dev, 1, &rfcsr); ++ if (rt2x00dev->default_ant.tx_chain_num == 1) ++ rfcsr &= (~0x2); ++ else ++ rfcsr |= 0x2; ++ rt2800_rfcsr_write(rt2x00dev, 1, rfcsr); ++ ++ rt2800_rfcsr_read(rt2x00dev, 2, &rfcsr); ++ if (rt2x00dev->default_ant.tx_chain_num == 1) ++ rfcsr &= (~0x20); ++ else ++ rfcsr |= 0x20; ++ if (rt2x00dev->default_ant.rx_chain_num == 1) ++ rfcsr &= (~0x02); ++ else ++ rfcsr |= 0x02; ++ rt2800_rfcsr_write(rt2x00dev, 2, rfcsr); ++ ++ rt2800_rfcsr_read(rt2x00dev, 42, &rfcsr); ++ if (rt2x00dev->default_ant.tx_chain_num == 1) ++ rfcsr &= (~0x40); ++ else ++ rfcsr |= 0x40; ++ rt2800_rfcsr_write(rt2x00dev, 42, rfcsr); ++ ++ /* RF for DC Cal BW */ ++ if (conf_is_ht40(conf)) { ++ rt2800_rfcsr_write_dccal(rt2x00dev, 6, 0x10); ++ rt2800_rfcsr_write_dccal(rt2x00dev, 7, 0x10); ++ rt2800_rfcsr_write_dccal(rt2x00dev, 8, 0x04); ++ rt2800_rfcsr_write_dccal(rt2x00dev, 58, 0x10); ++ rt2800_rfcsr_write_dccal(rt2x00dev, 59, 0x10); ++ } else { ++ rt2800_rfcsr_write_dccal(rt2x00dev, 6, 0x20); ++ rt2800_rfcsr_write_dccal(rt2x00dev, 7, 0x20); ++ rt2800_rfcsr_write_dccal(rt2x00dev, 8, 0x00); ++ rt2800_rfcsr_write_dccal(rt2x00dev, 58, 0x20); ++ rt2800_rfcsr_write_dccal(rt2x00dev, 59, 0x20); ++ } ++ ++ if (conf_is_ht40(conf)) { ++ rt2800_rfcsr_write_dccal(rt2x00dev, 58, 0x08); ++ rt2800_rfcsr_write_dccal(rt2x00dev, 59, 0x08); ++ } else { ++ rt2800_rfcsr_write_dccal(rt2x00dev, 58, 0x28); ++ rt2800_rfcsr_write_dccal(rt2x00dev, 59, 0x28); ++ } ++ ++ rt2800_rfcsr_read(rt2x00dev, 28, &rfcsr); ++ if (conf_is_ht40(conf) && (rf->channel == 11)) ++ rfcsr |= 0x4; ++ else ++ rfcsr &= (~0x4); ++ rt2800_rfcsr_write(rt2x00dev, 28, rfcsr); ++ ++ /*if (bScan == FALSE)*/ ++ if (conf_is_ht40(conf)) { ++ txrx_agc_fc = rt2x00_get_field8(drv_data->calibration_bw40, ++ RFCSR24_TX_AGC_FC); ++ } else { ++ txrx_agc_fc = rt2x00_get_field8(drv_data->calibration_bw20, ++ RFCSR24_TX_AGC_FC); ++ } ++ rt2800_rfcsr_read_bank(rt2x00dev, 5, 6, &rfcsr); ++ rfcsr &= (~0x3F); ++ rfcsr |= txrx_agc_fc; ++ rt2800_rfcsr_write_bank(rt2x00dev, 5, 6, rfcsr); ++ rt2800_rfcsr_read_bank(rt2x00dev, 5, 7, &rfcsr); ++ rfcsr &= (~0x3F); ++ rfcsr |= txrx_agc_fc; ++ rt2800_rfcsr_write_bank(rt2x00dev, 5, 7, rfcsr); ++ rt2800_rfcsr_read_bank(rt2x00dev, 7, 6, &rfcsr); ++ rfcsr &= (~0x3F); ++ rfcsr |= txrx_agc_fc; ++ rt2800_rfcsr_write_bank(rt2x00dev, 7, 6, rfcsr); ++ rt2800_rfcsr_read_bank(rt2x00dev, 7, 7, &rfcsr); ++ rfcsr &= (~0x3F); ++ rfcsr |= txrx_agc_fc; ++ rt2800_rfcsr_write_bank(rt2x00dev, 7, 7, rfcsr); ++ ++ rt2800_rfcsr_read_bank(rt2x00dev, 5, 58, &rfcsr); ++ rfcsr &= (~0x3F); ++ rfcsr |= txrx_agc_fc; ++ rt2800_rfcsr_write_bank(rt2x00dev, 5, 58, rfcsr); ++ rt2800_rfcsr_read_bank(rt2x00dev, 5, 59, &rfcsr); ++ rfcsr &= (~0x3F); ++ rfcsr |= txrx_agc_fc; ++ rt2800_rfcsr_write_bank(rt2x00dev, 5, 59, rfcsr); ++ rt2800_rfcsr_read_bank(rt2x00dev, 7, 58, &rfcsr); ++ rfcsr &= (~0x3F); ++ rfcsr |= txrx_agc_fc; ++ rt2800_rfcsr_write_bank(rt2x00dev, 7, 58, rfcsr); ++ rt2800_rfcsr_read_bank(rt2x00dev, 7, 59, &rfcsr); ++ rfcsr &= (~0x3F); ++ rfcsr |= txrx_agc_fc; ++ rt2800_rfcsr_write_bank(rt2x00dev, 7, 59, rfcsr); ++ ++ rt2800_register_read(rt2x00dev, TX_ALG_CFG_0, ®); ++ reg = reg & (~0x3F3F); ++ reg |= info->default_power1; ++ reg |= (info->default_power2 << 8); ++ reg |= (0x2F << 16); ++ reg |= (0x2F << 24); ++ ++ rt2800_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1, &eeprom); ++ if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF1_INTERNAL_TX_ALC)) { ++ /* init base power by e2p target power */ ++ rt2800_eeprom_read(rt2x00dev, 0xD0, &target_power); ++ target_power &= 0x3F; ++ reg = reg & (~0x3F3F); ++ reg |= target_power; ++ reg |= (target_power << 8); ++ } ++ rt2800_register_write(rt2x00dev, TX_ALG_CFG_0, reg); ++ ++ rt2800_register_read(rt2x00dev, TX_ALG_CFG_1, ®); ++ reg = reg & (~0x3F); ++ rt2800_register_write(rt2x00dev, TX_ALG_CFG_1, reg); ++ ++ /*if (bScan == FALSE)*/ ++ /* Save MAC SYS CTRL registers */ ++ rt2800_register_read(rt2x00dev, MAC_SYS_CTRL, &mac_sys_ctrl); ++ /* Disable Tx/Rx */ ++ rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, 0); ++ /* Check MAC Tx/Rx idle */ ++ for (i = 0; i < 10000; i++) { ++ rt2800_register_read(rt2x00dev, MAC_STATUS_CFG, &mac_status); ++ if (mac_status & 0x3) ++ udelay(50); ++ else ++ break; ++ } ++ ++ if (i == 10000) ++ rt2x00_warn(rt2x00dev, "Wait MAC Status to MAX !!!\n"); ++ ++ if (rf->channel > 10) { ++ rt2800_bbp_read(rt2x00dev, 30, &bbp); ++ bbp = 0x40; ++ rt2800_bbp_write(rt2x00dev, 30, bbp); ++ rt2800_rfcsr_write(rt2x00dev, 39, 0); ++ if (rt2x00_has_cap_external_lna_bg(rt2x00dev)) ++ rt2800_rfcsr_write(rt2x00dev, 42, 0xfb); ++ else ++ rt2800_rfcsr_write(rt2x00dev, 42, 0x7b); ++ } else { ++ rt2800_bbp_read(rt2x00dev, 30, &bbp); ++ bbp = 0x1f; ++ rt2800_bbp_write(rt2x00dev, 30, bbp); ++ rt2800_rfcsr_write(rt2x00dev, 39, 0x80); ++ if (rt2x00_has_cap_external_lna_bg(rt2x00dev)) ++ rt2800_rfcsr_write(rt2x00dev, 42, 0xdb); ++ else ++ rt2800_rfcsr_write(rt2x00dev, 42, 0x5b); ++ } ++ ++ rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, mac_sys_ctrl); ++ ++ rt2800_rfcsr_write(rt2x00dev, 5, 0x40); ++ rt2800_rfcsr_write(rt2x00dev, 4, 0x0C); ++ ++ /* vcocal_en (initiate VCO calibration (reset after completion)) */ ++ rt2800_rfcsr_read(rt2x00dev, 4, &rfcsr); ++ rfcsr = ((rfcsr & ~0x80) | 0x80); ++ rt2800_rfcsr_write(rt2x00dev, 4, rfcsr); ++ mdelay(2); ++ ++ rt2800_register_write(rt2x00dev, TX_PIN_CFG, tx_pin); ++ ++ if (rt2x00dev->default_ant.tx_chain_num == 1) { ++ rt2800_bbp_write(rt2x00dev, 91, 0x07); ++ rt2800_bbp_write(rt2x00dev, 95, 0x1A); ++ rt2800_bbp_write(rt2x00dev, 195, 128); ++ rt2800_bbp_write(rt2x00dev, 196, 0xA0); ++ rt2800_bbp_write(rt2x00dev, 195, 170); ++ rt2800_bbp_write(rt2x00dev, 196, 0x12); ++ rt2800_bbp_write(rt2x00dev, 195, 171); ++ rt2800_bbp_write(rt2x00dev, 196, 0x10); ++ } else { ++ rt2800_bbp_write(rt2x00dev, 91, 0x06); ++ rt2800_bbp_write(rt2x00dev, 95, 0x9A); ++ rt2800_bbp_write(rt2x00dev, 195, 128); ++ rt2800_bbp_write(rt2x00dev, 196, 0xE0); ++ rt2800_bbp_write(rt2x00dev, 195, 170); ++ rt2800_bbp_write(rt2x00dev, 196, 0x30); ++ rt2800_bbp_write(rt2x00dev, 195, 171); ++ rt2800_bbp_write(rt2x00dev, 196, 0x30); ++ } ++ ++ /* On 11A, We should delay and wait RF/BBP to be stable*/ ++ /* and the appropriate time should be 1000 micro seconds */ ++ /* 2005/06/05 - On 11G, We also need this delay time. ++ * Otherwise it's difficult to pass the WHQL.*/ ++ udelay(1000); ++} ++ ++ + static void rt2800_bbp_write_with_rx_chain(struct rt2x00_dev *rt2x00dev, + const unsigned int word, + const u8 value) +@@ -3414,7 +3798,7 @@ static void rt2800_config_channel(struct + struct channel_info *info) + { + u32 reg; +- unsigned int tx_pin; ++ u32 tx_pin; + u8 bbp, rfcsr; + + info->default_power1 = rt2800_txpower_to_dev(rt2x00dev, rf->channel, +@@ -3468,6 +3852,9 @@ static void rt2800_config_channel(struct + case RF5592: + rt2800_config_channel_rf55xx(rt2x00dev, conf, rf, info); + break; ++ case RF7620: ++ rt2800_config_channel_rf7620(rt2x00dev, conf, rf, info); ++ break; + default: + rt2800_config_channel_rf2xxx(rt2x00dev, conf, rf, info); + } +@@ -3574,7 +3961,7 @@ static void rt2800_config_channel(struct + else if (rt2x00_rt(rt2x00dev, RT3593) || + rt2x00_rt(rt2x00dev, RT3883)) + rt2800_bbp_write(rt2x00dev, 82, 0x82); +- else ++ else if (rt2x00dev->chip.rf != RF7620) + rt2800_bbp_write(rt2x00dev, 82, 0xf2); + + if (rt2x00_rt(rt2x00dev, RT3593) || +@@ -3596,7 +3983,7 @@ static void rt2800_config_channel(struct + if (rt2x00_rt(rt2x00dev, RT3572)) + rt2800_rfcsr_write(rt2x00dev, 8, 0); + +- tx_pin = 0; ++ rt2800_register_read(rt2x00dev, TX_PIN_CFG, &tx_pin); + + switch (rt2x00dev->default_ant.tx_chain_num) { + case 3: +@@ -3645,6 +4032,7 @@ static void rt2800_config_channel(struct + + rt2x00_set_field32(&tx_pin, TX_PIN_CFG_RFTR_EN, 1); + rt2x00_set_field32(&tx_pin, TX_PIN_CFG_TRSW_EN, 1); ++ rt2x00_set_field32(&tx_pin, TX_PIN_CFG_RFRX_EN, 1); /* mt7620 */ + + rt2800_register_write(rt2x00dev, TX_PIN_CFG, tx_pin); + +@@ -4662,6 +5050,14 @@ void rt2800_vco_calibration(struct rt2x0 + rt2x00_set_field8(&rfcsr, RFCSR3_VCOCAL_EN, 1); + rt2800_rfcsr_write(rt2x00dev, 3, rfcsr); + break; ++ case RF7620: ++ rt2800_rfcsr_read(rt2x00dev, 4, &rfcsr); ++ /* vcocal_en (initiate VCO calibration (reset after completion)) ++ * It should be at the end of RF configuration. */ ++ rfcsr = ((rfcsr & ~0x80) | 0x80); ++ rt2800_rfcsr_write(rt2x00dev, 4, rfcsr); ++ mdelay(1); ++ break; + default: + WARN_ONCE(1, "Not supported RF chipet %x for VCO recalibration", + rt2x00dev->chip.rf); +@@ -5037,6 +5433,24 @@ static int rt2800_init_registers(struct + rt2800_register_write(rt2x00dev, TX_SW_CFG2, 0x00040000); + rt2800_register_write(rt2x00dev, TX_TXBF_CFG_0, 0x8000fc21); + rt2800_register_write(rt2x00dev, TX_TXBF_CFG_3, 0x00009c40); ++ } else if (rt2x00_rf(rt2x00dev, RF7620)) { ++ rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000401); ++ rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x000C0000); ++ rt2800_register_write(rt2x00dev, TX_SW_CFG2, 0x00000000); ++ rt2800_register_write(rt2x00dev, MIMO_PS_CFG, 0x00000002); ++ rt2800_register_write(rt2x00dev, TX_PIN_CFG, 0x00150F0F); ++ rt2800_register_write(rt2x00dev, TX_ALC_VGA3, 0x06060606); ++ rt2800_register_write(rt2x00dev, TX0_BB_GAIN_ATTEN, 0x0); ++ rt2800_register_write(rt2x00dev, TX1_BB_GAIN_ATTEN, 0x0); ++ rt2800_register_write(rt2x00dev, TX0_RF_GAIN_ATTEN, 0x6C6C666C); ++ rt2800_register_write(rt2x00dev, TX1_RF_GAIN_ATTEN, 0x6C6C666C); ++ rt2800_register_write(rt2x00dev, TX0_RF_GAIN_CORRECT, ++ 0x3630363A); ++ rt2800_register_write(rt2x00dev, TX1_RF_GAIN_CORRECT, ++ 0x3630363A); ++ rt2800_register_read(rt2x00dev, TX_ALG_CFG_1, ®); ++ reg = reg & (~0x80000000); ++ rt2800_register_write(rt2x00dev, TX_ALG_CFG_1, reg); + } else if (rt2x00_rt(rt2x00dev, RT5390) || + rt2x00_rt(rt2x00dev, RT5392)) { + rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000404); +@@ -6075,6 +6489,225 @@ static void rt2800_init_bbp_5592(struct + rt2800_bbp_write(rt2x00dev, 103, 0xc0); + } + ++static void rt2800_bbp_glrt_write(struct rt2x00_dev *rt2x00dev, ++ const u8 reg, const u8 value) ++{ ++ rt2800_bbp_write(rt2x00dev, 195, reg); ++ rt2800_bbp_write(rt2x00dev, 196, value); ++} ++ ++static void rt2800_bbp_dcoc_write(struct rt2x00_dev *rt2x00dev, ++ const u8 reg, const u8 value) ++{ ++ rt2800_bbp_write(rt2x00dev, 158, reg); ++ rt2800_bbp_write(rt2x00dev, 159, value); ++} ++ ++static void rt2800_init_bbp_7620(struct rt2x00_dev *rt2x00dev) ++{ ++ u8 bbp; ++ ++ /* Apply Maximum Likelihood Detection (MLD) for 2 stream case */ ++ rt2800_bbp_read(rt2x00dev, 105, &bbp); ++ rt2x00_set_field8(&bbp, BBP105_MLD, ++ rt2x00dev->default_ant.rx_chain_num == 2); ++ rt2800_bbp_write(rt2x00dev, 105, bbp); ++ ++ /* Avoid data loss and CRC errors */ ++ /* MAC interface control (MAC_IF_80M, 1: 80 MHz) */ ++ rt2800_bbp4_mac_if_ctrl(rt2x00dev); ++ ++ /* Fix I/Q swap issue */ ++ rt2800_bbp_read(rt2x00dev, 1, &bbp); ++ bbp |= 0x04; ++ rt2800_bbp_write(rt2x00dev, 1, bbp); ++ ++ /* BBP for G band */ ++ rt2800_bbp_write(rt2x00dev, 3, 0x08); ++ rt2800_bbp_write(rt2x00dev, 4, 0x00); /* rt2800_bbp4_mac_if_ctrl? */ ++ rt2800_bbp_write(rt2x00dev, 6, 0x08); ++ rt2800_bbp_write(rt2x00dev, 14, 0x09); ++ rt2800_bbp_write(rt2x00dev, 15, 0xFF); ++ rt2800_bbp_write(rt2x00dev, 16, 0x01); ++ rt2800_bbp_write(rt2x00dev, 20, 0x06); ++ rt2800_bbp_write(rt2x00dev, 21, 0x00); ++ rt2800_bbp_write(rt2x00dev, 22, 0x00); ++ rt2800_bbp_write(rt2x00dev, 27, 0x00); ++ rt2800_bbp_write(rt2x00dev, 28, 0x00); ++ rt2800_bbp_write(rt2x00dev, 30, 0x00); ++ rt2800_bbp_write(rt2x00dev, 31, 0x48); ++ rt2800_bbp_write(rt2x00dev, 47, 0x40); ++ rt2800_bbp_write(rt2x00dev, 62, 0x00); ++ rt2800_bbp_write(rt2x00dev, 63, 0x00); ++ rt2800_bbp_write(rt2x00dev, 64, 0x00); ++ rt2800_bbp_write(rt2x00dev, 65, 0x2C); ++ rt2800_bbp_write(rt2x00dev, 66, 0x1C); ++ rt2800_bbp_write(rt2x00dev, 67, 0x20); ++ rt2800_bbp_write(rt2x00dev, 68, 0xDD); ++ rt2800_bbp_write(rt2x00dev, 69, 0x10); ++ rt2800_bbp_write(rt2x00dev, 70, 0x05); ++ rt2800_bbp_write(rt2x00dev, 73, 0x18); ++ rt2800_bbp_write(rt2x00dev, 74, 0x0F); ++ rt2800_bbp_write(rt2x00dev, 75, 0x60); ++ rt2800_bbp_write(rt2x00dev, 76, 0x44); ++ rt2800_bbp_write(rt2x00dev, 77, 0x59); ++ rt2800_bbp_write(rt2x00dev, 78, 0x1E); ++ rt2800_bbp_write(rt2x00dev, 79, 0x1C); ++ rt2800_bbp_write(rt2x00dev, 80, 0x0C); ++ rt2800_bbp_write(rt2x00dev, 81, 0x3A); ++ rt2800_bbp_write(rt2x00dev, 82, 0xB6); ++ rt2800_bbp_write(rt2x00dev, 83, 0x9A); ++ rt2800_bbp_write(rt2x00dev, 84, 0x9A); ++ rt2800_bbp_write(rt2x00dev, 86, 0x38); ++ rt2800_bbp_write(rt2x00dev, 88, 0x90); ++ rt2800_bbp_write(rt2x00dev, 91, 0x04); ++ rt2800_bbp_write(rt2x00dev, 92, 0x02); ++ rt2800_bbp_write(rt2x00dev, 95, 0x9A); ++ rt2800_bbp_write(rt2x00dev, 96, 0x00); ++ rt2800_bbp_write(rt2x00dev, 103, 0xC0); ++ rt2800_bbp_write(rt2x00dev, 104, 0x92); ++ /* FIXME BBP105 owerwrite */ ++ rt2800_bbp_write(rt2x00dev, 105, 0x3C); ++ rt2800_bbp_write(rt2x00dev, 106, 0x12); ++ rt2800_bbp_write(rt2x00dev, 109, 0x00); ++ rt2800_bbp_write(rt2x00dev, 134, 0x10); ++ rt2800_bbp_write(rt2x00dev, 135, 0xA6); ++ rt2800_bbp_write(rt2x00dev, 137, 0x04); ++ rt2800_bbp_write(rt2x00dev, 142, 0x30); ++ rt2800_bbp_write(rt2x00dev, 143, 0xF7); ++ rt2800_bbp_write(rt2x00dev, 160, 0xEC); ++ rt2800_bbp_write(rt2x00dev, 161, 0xC4); ++ rt2800_bbp_write(rt2x00dev, 162, 0x77); ++ rt2800_bbp_write(rt2x00dev, 163, 0xF9); ++ rt2800_bbp_write(rt2x00dev, 164, 0x00); ++ rt2800_bbp_write(rt2x00dev, 165, 0x00); ++ rt2800_bbp_write(rt2x00dev, 186, 0x00); ++ rt2800_bbp_write(rt2x00dev, 187, 0x00); ++ rt2800_bbp_write(rt2x00dev, 188, 0x00); ++ rt2800_bbp_write(rt2x00dev, 186, 0x00); ++ rt2800_bbp_write(rt2x00dev, 187, 0x01); ++ rt2800_bbp_write(rt2x00dev, 188, 0x00); ++ rt2800_bbp_write(rt2x00dev, 189, 0x00); ++ ++ rt2800_bbp_write(rt2x00dev, 91, 0x06); ++ rt2800_bbp_write(rt2x00dev, 92, 0x04); ++ rt2800_bbp_write(rt2x00dev, 93, 0x54); ++ rt2800_bbp_write(rt2x00dev, 99, 0x50); ++ rt2800_bbp_write(rt2x00dev, 148, 0x84); ++ rt2800_bbp_write(rt2x00dev, 167, 0x80); ++ rt2800_bbp_write(rt2x00dev, 178, 0xFF); ++ rt2800_bbp_write(rt2x00dev, 106, 0x13); ++ ++ /* BBP for G band GLRT function (BBP_128 ~ BBP_221) */ ++ rt2800_bbp_glrt_write(rt2x00dev, 0, 0x00); ++ rt2800_bbp_glrt_write(rt2x00dev, 1, 0x14); /* ? see above */ ++ rt2800_bbp_glrt_write(rt2x00dev, 2, 0x20); ++ rt2800_bbp_glrt_write(rt2x00dev, 3, 0x0A); ++ rt2800_bbp_glrt_write(rt2x00dev, 10, 0x16); ++ rt2800_bbp_glrt_write(rt2x00dev, 11, 0x06); ++ rt2800_bbp_glrt_write(rt2x00dev, 12, 0x02); ++ rt2800_bbp_glrt_write(rt2x00dev, 13, 0x07); ++ rt2800_bbp_glrt_write(rt2x00dev, 14, 0x05); ++ rt2800_bbp_glrt_write(rt2x00dev, 15, 0x09); ++ rt2800_bbp_glrt_write(rt2x00dev, 16, 0x20); ++ rt2800_bbp_glrt_write(rt2x00dev, 17, 0x08); ++ rt2800_bbp_glrt_write(rt2x00dev, 18, 0x4A); ++ rt2800_bbp_glrt_write(rt2x00dev, 19, 0x00); ++ rt2800_bbp_glrt_write(rt2x00dev, 20, 0x00); ++ rt2800_bbp_glrt_write(rt2x00dev, 128, 0xE0); ++ rt2800_bbp_glrt_write(rt2x00dev, 129, 0x1F); ++ rt2800_bbp_glrt_write(rt2x00dev, 130, 0x4F); ++ rt2800_bbp_glrt_write(rt2x00dev, 131, 0x32); ++ rt2800_bbp_glrt_write(rt2x00dev, 132, 0x08); ++ rt2800_bbp_glrt_write(rt2x00dev, 133, 0x28); ++ rt2800_bbp_glrt_write(rt2x00dev, 134, 0x19); ++ rt2800_bbp_glrt_write(rt2x00dev, 135, 0x0A); ++ rt2800_bbp_glrt_write(rt2x00dev, 138, 0x16); ++ rt2800_bbp_glrt_write(rt2x00dev, 139, 0x10); ++ rt2800_bbp_glrt_write(rt2x00dev, 140, 0x10); ++ rt2800_bbp_glrt_write(rt2x00dev, 141, 0x1A); ++ rt2800_bbp_glrt_write(rt2x00dev, 142, 0x36); ++ rt2800_bbp_glrt_write(rt2x00dev, 143, 0x2C); ++ rt2800_bbp_glrt_write(rt2x00dev, 144, 0x26); ++ rt2800_bbp_glrt_write(rt2x00dev, 145, 0x24); ++ rt2800_bbp_glrt_write(rt2x00dev, 146, 0x42); ++ rt2800_bbp_glrt_write(rt2x00dev, 147, 0x40); ++ rt2800_bbp_glrt_write(rt2x00dev, 148, 0x30); ++ rt2800_bbp_glrt_write(rt2x00dev, 149, 0x29); ++ rt2800_bbp_glrt_write(rt2x00dev, 150, 0x4C); ++ rt2800_bbp_glrt_write(rt2x00dev, 151, 0x46); ++ rt2800_bbp_glrt_write(rt2x00dev, 152, 0x3D); ++ rt2800_bbp_glrt_write(rt2x00dev, 153, 0x40); ++ rt2800_bbp_glrt_write(rt2x00dev, 154, 0x3E); ++ rt2800_bbp_glrt_write(rt2x00dev, 155, 0x38); ++ rt2800_bbp_glrt_write(rt2x00dev, 156, 0x3D); ++ rt2800_bbp_glrt_write(rt2x00dev, 157, 0x2F); ++ rt2800_bbp_glrt_write(rt2x00dev, 158, 0x3C); ++ rt2800_bbp_glrt_write(rt2x00dev, 159, 0x34); ++ rt2800_bbp_glrt_write(rt2x00dev, 160, 0x2C); ++ rt2800_bbp_glrt_write(rt2x00dev, 161, 0x2F); ++ rt2800_bbp_glrt_write(rt2x00dev, 162, 0x3C); ++ rt2800_bbp_glrt_write(rt2x00dev, 163, 0x35); ++ rt2800_bbp_glrt_write(rt2x00dev, 164, 0x2E); ++ rt2800_bbp_glrt_write(rt2x00dev, 165, 0x2F); ++ rt2800_bbp_glrt_write(rt2x00dev, 166, 0x49); ++ rt2800_bbp_glrt_write(rt2x00dev, 167, 0x41); ++ rt2800_bbp_glrt_write(rt2x00dev, 168, 0x36); ++ rt2800_bbp_glrt_write(rt2x00dev, 169, 0x39); ++ rt2800_bbp_glrt_write(rt2x00dev, 170, 0x30); ++ rt2800_bbp_glrt_write(rt2x00dev, 171, 0x30); ++ rt2800_bbp_glrt_write(rt2x00dev, 172, 0x0E); ++ rt2800_bbp_glrt_write(rt2x00dev, 173, 0x0D); ++ rt2800_bbp_glrt_write(rt2x00dev, 174, 0x28); ++ rt2800_bbp_glrt_write(rt2x00dev, 175, 0x21); ++ rt2800_bbp_glrt_write(rt2x00dev, 176, 0x1C); ++ rt2800_bbp_glrt_write(rt2x00dev, 177, 0x16); ++ rt2800_bbp_glrt_write(rt2x00dev, 178, 0x50); ++ rt2800_bbp_glrt_write(rt2x00dev, 179, 0x4A); ++ rt2800_bbp_glrt_write(rt2x00dev, 180, 0x43); ++ rt2800_bbp_glrt_write(rt2x00dev, 181, 0x50); ++ rt2800_bbp_glrt_write(rt2x00dev, 182, 0x10); ++ rt2800_bbp_glrt_write(rt2x00dev, 183, 0x10); ++ rt2800_bbp_glrt_write(rt2x00dev, 184, 0x10); ++ rt2800_bbp_glrt_write(rt2x00dev, 185, 0x10); ++ rt2800_bbp_glrt_write(rt2x00dev, 200, 0x7D); ++ rt2800_bbp_glrt_write(rt2x00dev, 201, 0x14); ++ rt2800_bbp_glrt_write(rt2x00dev, 202, 0x32); ++ rt2800_bbp_glrt_write(rt2x00dev, 203, 0x2C); ++ rt2800_bbp_glrt_write(rt2x00dev, 204, 0x36); ++ rt2800_bbp_glrt_write(rt2x00dev, 205, 0x4C); ++ rt2800_bbp_glrt_write(rt2x00dev, 206, 0x43); ++ rt2800_bbp_glrt_write(rt2x00dev, 207, 0x2C); ++ rt2800_bbp_glrt_write(rt2x00dev, 208, 0x2E); ++ rt2800_bbp_glrt_write(rt2x00dev, 209, 0x36); ++ rt2800_bbp_glrt_write(rt2x00dev, 210, 0x30); ++ rt2800_bbp_glrt_write(rt2x00dev, 211, 0x6E); ++ ++ /* BBP for G band DCOC function */ ++ rt2800_bbp_dcoc_write(rt2x00dev, 140, 0x0C); ++ rt2800_bbp_dcoc_write(rt2x00dev, 141, 0x00); ++ rt2800_bbp_dcoc_write(rt2x00dev, 142, 0x10); ++ rt2800_bbp_dcoc_write(rt2x00dev, 143, 0x10); ++ rt2800_bbp_dcoc_write(rt2x00dev, 144, 0x10); ++ rt2800_bbp_dcoc_write(rt2x00dev, 145, 0x10); ++ rt2800_bbp_dcoc_write(rt2x00dev, 146, 0x08); ++ rt2800_bbp_dcoc_write(rt2x00dev, 147, 0x40); ++ rt2800_bbp_dcoc_write(rt2x00dev, 148, 0x04); ++ rt2800_bbp_dcoc_write(rt2x00dev, 149, 0x04); ++ rt2800_bbp_dcoc_write(rt2x00dev, 150, 0x08); ++ rt2800_bbp_dcoc_write(rt2x00dev, 151, 0x08); ++ rt2800_bbp_dcoc_write(rt2x00dev, 152, 0x03); ++ rt2800_bbp_dcoc_write(rt2x00dev, 153, 0x03); ++ rt2800_bbp_dcoc_write(rt2x00dev, 154, 0x03); ++ rt2800_bbp_dcoc_write(rt2x00dev, 155, 0x02); ++ rt2800_bbp_dcoc_write(rt2x00dev, 156, 0x40); ++ rt2800_bbp_dcoc_write(rt2x00dev, 157, 0x40); ++ rt2800_bbp_dcoc_write(rt2x00dev, 158, 0x64); ++ rt2800_bbp_dcoc_write(rt2x00dev, 159, 0x64); ++ ++ rt2800_bbp4_mac_if_ctrl(rt2x00dev); ++} ++ + static void rt2800_init_bbp(struct rt2x00_dev *rt2x00dev) + { + unsigned int i; +@@ -6117,7 +6750,10 @@ static void rt2800_init_bbp(struct rt2x0 + return; + case RT5390: + case RT5392: +- rt2800_init_bbp_53xx(rt2x00dev); ++ if (rt2x00dev->chip.rf == RF7620) ++ rt2800_init_bbp_7620(rt2x00dev); ++ else ++ rt2800_init_bbp_53xx(rt2x00dev); + break; + case RT5592: + rt2800_init_bbp_5592(rt2x00dev); +@@ -7331,6 +7967,295 @@ static void rt2800_init_rfcsr_5592(struc + rt2800_led_open_drain_enable(rt2x00dev); + } + ++static void rt2800_init_rfcsr_7620(struct rt2x00_dev *rt2x00dev) ++{ ++ u8 rfvalue; ++ u16 freq; ++ ++ /* Initialize RF central register to default value */ ++ rt2800_rfcsr_write(rt2x00dev, 0, 0x02); ++ rt2800_rfcsr_write(rt2x00dev, 1, 0x03); ++ rt2800_rfcsr_write(rt2x00dev, 2, 0x33); ++ rt2800_rfcsr_write(rt2x00dev, 3, 0xFF); ++ rt2800_rfcsr_write(rt2x00dev, 4, 0x0C); ++ rt2800_rfcsr_write(rt2x00dev, 5, 0x40); /* Read only */ ++ rt2800_rfcsr_write(rt2x00dev, 6, 0x00); ++ rt2800_rfcsr_write(rt2x00dev, 7, 0x00); ++ rt2800_rfcsr_write(rt2x00dev, 8, 0x00); ++ rt2800_rfcsr_write(rt2x00dev, 9, 0x00); ++ rt2800_rfcsr_write(rt2x00dev, 10, 0x00); ++ rt2800_rfcsr_write(rt2x00dev, 11, 0x00); ++ /* rt2800_rfcsr_write(rt2x00dev, 12, 0x43); *//* EEPROM */ ++ rt2800_rfcsr_write(rt2x00dev, 13, 0x00); ++ rt2800_rfcsr_write(rt2x00dev, 14, 0x40); ++ rt2800_rfcsr_write(rt2x00dev, 15, 0x22); ++ rt2800_rfcsr_write(rt2x00dev, 16, 0x4C); ++ rt2800_rfcsr_write(rt2x00dev, 17, 0x00); ++ rt2800_rfcsr_write(rt2x00dev, 18, 0x00); ++ rt2800_rfcsr_write(rt2x00dev, 19, 0x00); ++ rt2800_rfcsr_write(rt2x00dev, 20, 0xA0); ++ rt2800_rfcsr_write(rt2x00dev, 21, 0x12); ++ rt2800_rfcsr_write(rt2x00dev, 22, 0x07); ++ rt2800_rfcsr_write(rt2x00dev, 23, 0x13); ++ rt2800_rfcsr_write(rt2x00dev, 24, 0xFE); ++ rt2800_rfcsr_write(rt2x00dev, 25, 0x24); ++ rt2800_rfcsr_write(rt2x00dev, 26, 0x7A); ++ rt2800_rfcsr_write(rt2x00dev, 27, 0x00); ++ rt2800_rfcsr_write(rt2x00dev, 28, 0x00); ++ rt2800_rfcsr_write(rt2x00dev, 29, 0x05); ++ rt2800_rfcsr_write(rt2x00dev, 30, 0x00); ++ rt2800_rfcsr_write(rt2x00dev, 31, 0x00); ++ rt2800_rfcsr_write(rt2x00dev, 32, 0x00); ++ rt2800_rfcsr_write(rt2x00dev, 33, 0x00); ++ rt2800_rfcsr_write(rt2x00dev, 34, 0x00); ++ rt2800_rfcsr_write(rt2x00dev, 35, 0x00); ++ rt2800_rfcsr_write(rt2x00dev, 36, 0x00); ++ rt2800_rfcsr_write(rt2x00dev, 37, 0x00); ++ rt2800_rfcsr_write(rt2x00dev, 38, 0x00); ++ rt2800_rfcsr_write(rt2x00dev, 39, 0x00); ++ rt2800_rfcsr_write(rt2x00dev, 40, 0x00); ++ rt2800_rfcsr_write(rt2x00dev, 41, 0xD0); ++ rt2800_rfcsr_write(rt2x00dev, 42, 0x5B); ++ rt2800_rfcsr_write(rt2x00dev, 43, 0x00); ++ ++ rt2800_rfcsr_write(rt2x00dev, 11, 0x21); ++ if (rt2800_clk_is_20mhz(rt2x00dev)) ++ rt2800_rfcsr_write(rt2x00dev, 13, 0x03); ++ else ++ rt2800_rfcsr_write(rt2x00dev, 13, 0x00); ++ rt2800_rfcsr_write(rt2x00dev, 14, 0x7C); ++ rt2800_rfcsr_write(rt2x00dev, 16, 0x80); ++ rt2800_rfcsr_write(rt2x00dev, 17, 0x99); ++ rt2800_rfcsr_write(rt2x00dev, 18, 0x99); ++ rt2800_rfcsr_write(rt2x00dev, 19, 0x09); ++ rt2800_rfcsr_write(rt2x00dev, 20, 0x50); ++ rt2800_rfcsr_write(rt2x00dev, 21, 0xB0); ++ rt2800_rfcsr_write(rt2x00dev, 22, 0x00); ++ rt2800_rfcsr_write(rt2x00dev, 23, 0x06); ++ rt2800_rfcsr_write(rt2x00dev, 24, 0x00); ++ rt2800_rfcsr_write(rt2x00dev, 25, 0x00); ++ rt2800_rfcsr_write(rt2x00dev, 26, 0x5D); ++ rt2800_rfcsr_write(rt2x00dev, 27, 0x00); ++ rt2800_rfcsr_write(rt2x00dev, 28, 0x61); ++ rt2800_rfcsr_write(rt2x00dev, 29, 0xB5); ++ rt2800_rfcsr_write(rt2x00dev, 43, 0x02); ++ ++ rt2800_rfcsr_write(rt2x00dev, 28, 0x62); ++ rt2800_rfcsr_write(rt2x00dev, 29, 0xAD); ++ rt2800_rfcsr_write(rt2x00dev, 39, 0x80); ++ /* RTMP_TEMPERATURE_CALIBRATION */ ++ /* rt2800_rfcsr_write(rt2x00dev, 34, 0x23); */ ++ /* rt2800_rfcsr_write(rt2x00dev, 35, 0x01); */ ++ ++ /* use rt2800_adjust_freq_offset ? */ ++ rt2800_eeprom_read(rt2x00dev, EEPROM_FREQ, &freq); ++ rfvalue = freq & 0xff; ++ rt2800_rfcsr_write(rt2x00dev, 12, rfvalue); ++ ++ /* Initialize RF channel register to default value */ ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 0, 0x03); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 1, 0x00); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 2, 0x00); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 3, 0x00); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 4, 0x00); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 5, 0x08); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 6, 0x00); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 7, 0x51); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 8, 0x53); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 9, 0x16); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 10, 0x61); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 11, 0x53); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 12, 0x22); ++ /* rt2800_rfcsr_write_chanreg(rt2x00dev, 13, 0x3D); */ /* fails */ ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 14, 0x06); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 15, 0x13); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 16, 0x22); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 17, 0x27); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 18, 0x02); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 19, 0xA7); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 20, 0x01); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 21, 0x52); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 22, 0x80); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 23, 0xB3); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 24, 0x00); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 25, 0x00); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 26, 0x00); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 27, 0x00); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 28, 0x5C); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 29, 0x6B); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 30, 0x6B); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 31, 0x31); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 32, 0x5D); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 33, 0x00); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 34, 0xE6); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 35, 0x55); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 36, 0x00); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 37, 0xBB); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 38, 0xB3); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 39, 0xB3); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 40, 0x03); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 41, 0x00); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 42, 0x00); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 43, 0xB3); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 44, 0xD3); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 45, 0xD5); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 46, 0x07); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 47, 0x68); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 48, 0xEF); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 49, 0x1C); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 54, 0x07); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 55, 0xA8); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 56, 0x85); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 57, 0x10); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 58, 0x07); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 59, 0x6A); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 60, 0x85); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 61, 0x10); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 62, 0x1C); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 63, 0x00); ++ ++ rt2800_rfcsr_write_bank(rt2x00dev, 6, 45, 0xC5); ++ ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 9, 0x47); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 10, 0x71); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 11, 0x33); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 14, 0x0E); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 17, 0x23); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 19, 0xA4); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 20, 0x02); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 21, 0x12); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 28, 0x1C); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 29, 0xEB); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 32, 0x7D); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 34, 0xD6); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 36, 0x08); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 38, 0xB4); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 43, 0xD3); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 44, 0xB3); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 45, 0xD5); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 46, 0x27); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 47, 0x69); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 48, 0xFF); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 54, 0x20); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 55, 0x66); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 56, 0xFF); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 57, 0x1C); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 58, 0x20); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 59, 0x6B); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 60, 0xF7); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 61, 0x09); ++ ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 10, 0x51); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 14, 0x06); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 19, 0xA7); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 28, 0x2C); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 55, 0x64); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 8, 0x51); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 9, 0x36); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 11, 0x53); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 14, 0x16); ++ ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 47, 0x6C); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 48, 0xFC); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 49, 0x1F); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 54, 0x27); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 55, 0x66); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 59, 0x6B); ++ ++ /* Initialize RF channel register for DRQFN */ ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 43, 0xD3); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 44, 0xE3); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 45, 0xE5); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 47, 0x28); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 55, 0x68); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 56, 0xF7); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 58, 0x02); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 60, 0xC7); ++ ++ /* reduce power consumption */ ++/* rt2800_rfcsr_write_chanreg(rt2x00dev, 43, 0x53); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 44, 0x53); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 45, 0x53); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 47, 0x64); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 48, 0x4F); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 49, 0x02); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 55, 0x64); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 56, 0x4F); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 57, 0x02); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 58, 0x27); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 59, 0x64); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 60, 0x4F); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 61, 0x02); ++*/ ++ /* Initialize RF DC calibration register to default value */ ++ rt2800_rfcsr_write_dccal(rt2x00dev, 0, 0x47); ++ rt2800_rfcsr_write_dccal(rt2x00dev, 1, 0x00); ++ rt2800_rfcsr_write_dccal(rt2x00dev, 2, 0x00); ++ rt2800_rfcsr_write_dccal(rt2x00dev, 3, 0x00); ++ rt2800_rfcsr_write_dccal(rt2x00dev, 4, 0x00); ++ rt2800_rfcsr_write_dccal(rt2x00dev, 5, 0x00); ++ rt2800_rfcsr_write_dccal(rt2x00dev, 6, 0x10); ++ rt2800_rfcsr_write_dccal(rt2x00dev, 7, 0x10); ++ rt2800_rfcsr_write_dccal(rt2x00dev, 8, 0x04); ++ rt2800_rfcsr_write_dccal(rt2x00dev, 9, 0x00); ++ rt2800_rfcsr_write_dccal(rt2x00dev, 10, 0x07); ++ rt2800_rfcsr_write_dccal(rt2x00dev, 11, 0x01); ++ rt2800_rfcsr_write_dccal(rt2x00dev, 12, 0x07); ++ rt2800_rfcsr_write_dccal(rt2x00dev, 13, 0x07); ++ rt2800_rfcsr_write_dccal(rt2x00dev, 14, 0x07); ++ rt2800_rfcsr_write_dccal(rt2x00dev, 15, 0x20); ++ rt2800_rfcsr_write_dccal(rt2x00dev, 16, 0x22); ++ rt2800_rfcsr_write_dccal(rt2x00dev, 17, 0x00); ++ rt2800_rfcsr_write_dccal(rt2x00dev, 18, 0x00); ++ rt2800_rfcsr_write_dccal(rt2x00dev, 19, 0x00); ++ rt2800_rfcsr_write_dccal(rt2x00dev, 20, 0x00); ++ rt2800_rfcsr_write_dccal(rt2x00dev, 21, 0xF1); ++ rt2800_rfcsr_write_dccal(rt2x00dev, 22, 0x11); ++ rt2800_rfcsr_write_dccal(rt2x00dev, 23, 0x02); ++ rt2800_rfcsr_write_dccal(rt2x00dev, 24, 0x41); ++ rt2800_rfcsr_write_dccal(rt2x00dev, 25, 0x20); ++ rt2800_rfcsr_write_dccal(rt2x00dev, 26, 0x00); ++ rt2800_rfcsr_write_dccal(rt2x00dev, 27, 0xD7); ++ rt2800_rfcsr_write_dccal(rt2x00dev, 28, 0xA2); ++ rt2800_rfcsr_write_dccal(rt2x00dev, 29, 0x20); ++ rt2800_rfcsr_write_dccal(rt2x00dev, 30, 0x49); ++ rt2800_rfcsr_write_dccal(rt2x00dev, 31, 0x20); ++ rt2800_rfcsr_write_dccal(rt2x00dev, 32, 0x04); ++ rt2800_rfcsr_write_dccal(rt2x00dev, 33, 0xF1); ++ rt2800_rfcsr_write_dccal(rt2x00dev, 34, 0xA1); ++ rt2800_rfcsr_write_dccal(rt2x00dev, 35, 0x01); ++ rt2800_rfcsr_write_dccal(rt2x00dev, 41, 0x00); ++ rt2800_rfcsr_write_dccal(rt2x00dev, 42, 0x00); ++ rt2800_rfcsr_write_dccal(rt2x00dev, 43, 0x00); ++ rt2800_rfcsr_write_dccal(rt2x00dev, 44, 0x00); ++ rt2800_rfcsr_write_dccal(rt2x00dev, 45, 0x00); ++ rt2800_rfcsr_write_dccal(rt2x00dev, 46, 0x00); ++ rt2800_rfcsr_write_dccal(rt2x00dev, 47, 0x3E); ++ rt2800_rfcsr_write_dccal(rt2x00dev, 48, 0x3D); ++ rt2800_rfcsr_write_dccal(rt2x00dev, 49, 0x3E); ++ rt2800_rfcsr_write_dccal(rt2x00dev, 50, 0x3D); ++ rt2800_rfcsr_write_dccal(rt2x00dev, 51, 0x3E); ++ rt2800_rfcsr_write_dccal(rt2x00dev, 52, 0x3D); ++ rt2800_rfcsr_write_dccal(rt2x00dev, 53, 0x00); ++ rt2800_rfcsr_write_dccal(rt2x00dev, 54, 0x00); ++ rt2800_rfcsr_write_dccal(rt2x00dev, 55, 0x00); ++ rt2800_rfcsr_write_dccal(rt2x00dev, 56, 0x00); ++ rt2800_rfcsr_write_dccal(rt2x00dev, 57, 0x00); ++ rt2800_rfcsr_write_dccal(rt2x00dev, 58, 0x10); ++ rt2800_rfcsr_write_dccal(rt2x00dev, 59, 0x10); ++ rt2800_rfcsr_write_dccal(rt2x00dev, 60, 0x0A); ++ rt2800_rfcsr_write_dccal(rt2x00dev, 61, 0x00); ++ rt2800_rfcsr_write_dccal(rt2x00dev, 62, 0x00); ++ rt2800_rfcsr_write_dccal(rt2x00dev, 63, 0x00); ++ ++ rt2800_rfcsr_write_dccal(rt2x00dev, 3, 0x08); ++ rt2800_rfcsr_write_dccal(rt2x00dev, 4, 0x04); ++ rt2800_rfcsr_write_dccal(rt2x00dev, 5, 0x20); ++ ++ rt2800_rfcsr_write_dccal(rt2x00dev, 5, 0x00); ++ rt2800_rfcsr_write_dccal(rt2x00dev, 17, 0x7C); ++} ++ + static void rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev) + { + if (rt2800_is_305x_soc(rt2x00dev)) { +@@ -7366,7 +8291,10 @@ static void rt2800_init_rfcsr(struct rt2 + rt2800_init_rfcsr_5350(rt2x00dev); + break; + case RT5390: +- rt2800_init_rfcsr_5390(rt2x00dev); ++ if (rt2x00dev->chip.rf == RF7620) ++ rt2800_init_rfcsr_7620(rt2x00dev); ++ else ++ rt2800_init_rfcsr_5390(rt2x00dev); + break; + case RT5392: + rt2800_init_rfcsr_5392(rt2x00dev); +@@ -7780,6 +8708,7 @@ static int rt2800_init_eeprom(struct rt2 + case RF5390: + case RF5392: + case RF5592: ++ case RF7620: + break; + default: + rt2x00_err(rt2x00dev, "Invalid RF chipset 0x%04x detected\n", +@@ -8354,6 +9283,7 @@ static int rt2800_probe_hw_mode(struct r + case RF5372: + case RF5390: + case RF5392: ++ case RF7620: + spec->num_channels = 14; + if (rt2800_clk_is_20mhz(rt2x00dev)) + spec->channels = rf_vals_3x_xtal20; +@@ -8498,6 +9428,7 @@ static int rt2800_probe_hw_mode(struct r + case RF5390: + case RF5392: + case RF5592: ++ case RF7620: + __set_bit(CAPABILITY_VCO_RECALIBRATION, &rt2x00dev->cap_flags); + break; + } diff --git a/package/kernel/mac80211/patches/621-rt2x00-ht20_40_fix.patch b/package/kernel/mac80211/patches/621-rt2x00-ht20_40_fix.patch deleted file mode 100644 index e3e4c98efc..0000000000 --- a/package/kernel/mac80211/patches/621-rt2x00-ht20_40_fix.patch +++ /dev/null @@ -1,29 +0,0 @@ ---- a/drivers/net/wireless/ralink/rt2x00/rt2800.h -+++ b/drivers/net/wireless/ralink/rt2x00/rt2800.h -@@ -2321,6 +2321,8 @@ struct mac_iveiv_entry { - #define RFCSR30_RX_H20M FIELD8(0x04) - #define RFCSR30_RX_VCM FIELD8(0x18) - #define RFCSR30_RF_CALIBRATION FIELD8(0x80) -+#define RF3322_RFCSR30_TX_H20M FIELD8(0x01) -+#define RF3322_RFCSR30_RX_H20M FIELD8(0x02) - - /* - * RFCSR 31: ---- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c -+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c -@@ -3528,8 +3528,13 @@ static void rt2800_config_channel(struct - rt2x00_rf(rt2x00dev, RF5390) || - rt2x00_rf(rt2x00dev, RF5392)) { - rt2800_rfcsr_read(rt2x00dev, 30, &rfcsr); -- rt2x00_set_field8(&rfcsr, RFCSR30_TX_H20M, 0); -- rt2x00_set_field8(&rfcsr, RFCSR30_RX_H20M, 0); -+ if(rt2x00_rf(rt2x00dev, RF3322)) { -+ rt2x00_set_field8(&rfcsr, RF3322_RFCSR30_TX_H20M, conf_is_ht40(conf)); -+ rt2x00_set_field8(&rfcsr, RF3322_RFCSR30_RX_H20M, conf_is_ht40(conf)); -+ } else { -+ rt2x00_set_field8(&rfcsr, RFCSR30_TX_H20M, conf_is_ht40(conf)); -+ rt2x00_set_field8(&rfcsr, RFCSR30_RX_H20M, conf_is_ht40(conf)); -+ } - rt2800_rfcsr_write(rt2x00dev, 30, rfcsr); - - rt2800_rfcsr_read(rt2x00dev, 3, &rfcsr); diff --git a/package/kernel/mac80211/patches/622-rt2x00-fix-beacon-bit-balance.patch b/package/kernel/mac80211/patches/622-rt2x00-fix-beacon-bit-balance.patch deleted file mode 100644 index 58e57fed3d..0000000000 --- a/package/kernel/mac80211/patches/622-rt2x00-fix-beacon-bit-balance.patch +++ /dev/null @@ -1,47 +0,0 @@ ---- a/drivers/net/wireless/ralink/rt2x00/rt2x00mac.c -+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00mac.c -@@ -627,12 +627,8 @@ void rt2x00mac_bss_info_changed(struct i - } else if (bss_conf->enable_beacon && !intf->enable_beacon) { - rt2x00dev->intf_beaconing++; - intf->enable_beacon = true; -- /* -- * Upload beacon to the H/W. This is only required on -- * USB devices. PCI devices fetch beacons periodically. -- */ -- if (rt2x00_is_usb(rt2x00dev)) -- rt2x00queue_update_beacon(rt2x00dev, vif); -+ -+ rt2x00queue_update_beacon(rt2x00dev, vif); - - if (rt2x00dev->intf_beaconing == 1) { - /* ---- a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c -+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c -@@ -145,7 +145,8 @@ static void rt2x00lib_intf_scheduled_ite - - if (test_and_clear_bit(DELAYED_UPDATE_BEACON, &intf->delayed_flags)) { - mutex_lock(&intf->beacon_skb_mutex); -- rt2x00queue_update_beacon(rt2x00dev, vif); -+ if (intf->enable_beacon) -+ rt2x00queue_update_beacon(rt2x00dev, vif); - mutex_unlock(&intf->beacon_skb_mutex); - } - } -@@ -208,6 +209,7 @@ static void rt2x00lib_beaconupdate_iter( - struct ieee80211_vif *vif) - { - struct rt2x00_dev *rt2x00dev = data; -+ struct rt2x00_intf *intf = vif_to_intf(vif); - - if (vif->type != NL80211_IFTYPE_AP && - vif->type != NL80211_IFTYPE_ADHOC && -@@ -221,7 +223,8 @@ static void rt2x00lib_beaconupdate_iter( - * never be called for USB devices. - */ - WARN_ON(rt2x00_is_usb(rt2x00dev)); -- rt2x00queue_update_beacon(rt2x00dev, vif); -+ if (intf->enable_beacon) -+ rt2x00queue_update_beacon(rt2x00dev, vif); - } - - void rt2x00lib_beacondone(struct rt2x00_dev *rt2x00dev) diff --git a/package/kernel/mac80211/patches/650-0001-rtl8xxxu-Fix-memory-leak-in-handling-rxdesc16-packet.patch b/package/kernel/mac80211/patches/650-0001-rtl8xxxu-Fix-memory-leak-in-handling-rxdesc16-packet.patch deleted file mode 100644 index 31604b6264..0000000000 --- a/package/kernel/mac80211/patches/650-0001-rtl8xxxu-Fix-memory-leak-in-handling-rxdesc16-packet.patch +++ /dev/null @@ -1,34 +0,0 @@ -From 51be39337a10a8bf9d8ec65419e78b76bf5adf60 Mon Sep 17 00:00:00 2001 -From: Jes Sorensen -Date: Wed, 28 Sep 2016 14:48:51 -0400 -Subject: [PATCH] rtl8xxxu: Fix memory leak in handling rxdesc16 packets - -A device running without RX package aggregation could return more data -in the USB packet than the actual network packet. In this case the -could would clone the skb but then determine that that there was no -packet to handle and exit without freeing the cloned skb first. - -This has so far only been observed with 8188eu devices, but could -affect others. - -Signed-off-by: Jes Sorensen ---- - drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c | 7 ++++++- - 1 file changed, 6 insertions(+), 1 deletion(-) - ---- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c -+++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c -@@ -5197,7 +5197,12 @@ int rtl8xxxu_parse_rxdesc16(struct rtl8x - pkt_offset = roundup(pkt_len + drvinfo_sz + desc_shift + - sizeof(struct rtl8xxxu_rxdesc16), 128); - -- if (pkt_cnt > 1) -+ /* -+ * Only clone the skb if there's enough data at the end to -+ * at least cover the rx descriptor -+ */ -+ if (pkt_cnt > 1 && -+ urb_len > (pkt_offset + sizeof(struct rtl8xxxu_rxdesc16))) - next_skb = skb_clone(skb, GFP_ATOMIC); - - rx_status = IEEE80211_SKB_RXCB(skb); diff --git a/package/kernel/mac80211/patches/650-0002-rtl8xxxu-Fix-big-endian-problem-reporting-mactime.patch b/package/kernel/mac80211/patches/650-0002-rtl8xxxu-Fix-big-endian-problem-reporting-mactime.patch deleted file mode 100644 index 7531d510b8..0000000000 --- a/package/kernel/mac80211/patches/650-0002-rtl8xxxu-Fix-big-endian-problem-reporting-mactime.patch +++ /dev/null @@ -1,54 +0,0 @@ -From 8d829444c8a860ba69ca8c51b9b609e29eaa4596 Mon Sep 17 00:00:00 2001 -From: Jes Sorensen -Date: Wed, 28 Sep 2016 15:43:42 -0400 -Subject: [PATCH] rtl8xxxu: Fix big-endian problem reporting mactime - -The full RX descriptor is converted so converting tsfl again would -return it to it's original endian value. - -Signed-off-by: Jes Sorensen ---- - drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h | 4 ++-- - drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c | 4 ++-- - 2 files changed, 4 insertions(+), 4 deletions(-) - ---- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h -+++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h -@@ -238,7 +238,7 @@ struct rtl8xxxu_rxdesc16 { - u32 pattern1match:1; - u32 pattern0match:1; - #endif -- __le32 tsfl; -+ u32 tsfl; - #if 0 - u32 bassn:12; - u32 bavld:1; -@@ -368,7 +368,7 @@ struct rtl8xxxu_rxdesc24 { - u32 ldcp:1; - u32 splcp:1; - #endif -- __le32 tsfl; -+ u32 tsfl; - }; - - struct rtl8xxxu_txdesc32 { ---- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c -+++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c -@@ -5220,7 +5220,7 @@ int rtl8xxxu_parse_rxdesc16(struct rtl8x - rtl8xxxu_rx_parse_phystats(priv, rx_status, phy_stats, - rx_desc->rxmcs); - -- rx_status->mactime = le32_to_cpu(rx_desc->tsfl); -+ rx_status->mactime = rx_desc->tsfl; - rx_status->flag |= RX_FLAG_MACTIME_START; - - if (!rx_desc->swdec) -@@ -5290,7 +5290,7 @@ int rtl8xxxu_parse_rxdesc24(struct rtl8x - rtl8xxxu_rx_parse_phystats(priv, rx_status, phy_stats, - rx_desc->rxmcs); - -- rx_status->mactime = le32_to_cpu(rx_desc->tsfl); -+ rx_status->mactime = rx_desc->tsfl; - rx_status->flag |= RX_FLAG_MACTIME_START; - - if (!rx_desc->swdec) diff --git a/package/kernel/mac80211/patches/651-0001-rtl8xxxu-Fix-rtl8723bu-driver-reload-issue.patch b/package/kernel/mac80211/patches/651-0001-rtl8xxxu-Fix-rtl8723bu-driver-reload-issue.patch deleted file mode 100644 index 600317c493..0000000000 --- a/package/kernel/mac80211/patches/651-0001-rtl8xxxu-Fix-rtl8723bu-driver-reload-issue.patch +++ /dev/null @@ -1,30 +0,0 @@ -From ee286f4b57536ec4a7c1b52d0a3476f8e52594d5 Mon Sep 17 00:00:00 2001 -From: Jes Sorensen -Date: Fri, 30 Sep 2016 16:39:39 -0400 -Subject: [PATCH] rtl8xxxu: Fix rtl8723bu driver reload issue - -The generic disable_rf() function clears bits 22 and 23 in -REG_RX_WAIT_CCA, however we did not re-enable them again in -rtl8723b_enable_rf() - -This resolves the problem for me with 8723bu devices not working again -after reloading the driver. - -Signed-off-by: Jes Sorensen ---- - drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8723b.c | 4 ++++ - 1 file changed, 4 insertions(+) - ---- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8723b.c -+++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8723b.c -@@ -1498,6 +1498,10 @@ static void rtl8723b_enable_rf(struct rt - u32 val32; - u8 val8; - -+ val32 = rtl8xxxu_read32(priv, REG_RX_WAIT_CCA); -+ val32 |= (BIT(22) | BIT(23)); -+ rtl8xxxu_write32(priv, REG_RX_WAIT_CCA, val32); -+ - /* - * No indication anywhere as to what 0x0790 does. The 2 antenna - * vendor code preserves bits 6-7 here. diff --git a/package/kernel/mac80211/patches/651-0002-rtl8xxxu-Fix-rtl8192eu-driver-reload-issue.patch b/package/kernel/mac80211/patches/651-0002-rtl8xxxu-Fix-rtl8192eu-driver-reload-issue.patch deleted file mode 100644 index ba7477b3d3..0000000000 --- a/package/kernel/mac80211/patches/651-0002-rtl8xxxu-Fix-rtl8192eu-driver-reload-issue.patch +++ /dev/null @@ -1,46 +0,0 @@ -From 93064d0ae3e9d97c03a3aabd71e6048e1ac82f46 Mon Sep 17 00:00:00 2001 -From: Jes Sorensen -Date: Fri, 30 Sep 2016 19:18:34 -0400 -Subject: [PATCH] rtl8xxxu: Fix rtl8192eu driver reload issue - -The 8192eu suffered from two issues when reloading the driver. - -The same problems as with the 8723bu where REG_RX_WAIT_CCA bits 22 and -23 didn't get set in rtl8192e_enable_rf(). - -In addition it also seems prone to issues when setting REG_RF_CTRL to -0 intead of just disabling the RF_ENABLE bit. Similar to what was -causing issues with the 8188eu. - -With this patch I can successfully reload the driver and reassociate -to an APi with an 8192eu dongle. - -Signed-off-by: Jes Sorensen ---- - drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8192e.c | 8 +++++++- - 1 file changed, 7 insertions(+), 1 deletion(-) - ---- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8192e.c -+++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8192e.c -@@ -1461,7 +1461,9 @@ static int rtl8192eu_active_to_emu(struc - int count, ret = 0; - - /* Turn off RF */ -- rtl8xxxu_write8(priv, REG_RF_CTRL, 0); -+ val8 = rtl8xxxu_read8(priv, REG_RF_CTRL); -+ val8 &= ~RF_ENABLE; -+ rtl8xxxu_write8(priv, REG_RF_CTRL, val8); - - /* Switch DPDT_SEL_P output from register 0x65[2] */ - val8 = rtl8xxxu_read8(priv, REG_LEDCFG2); -@@ -1593,6 +1595,10 @@ static void rtl8192e_enable_rf(struct rt - u32 val32; - u8 val8; - -+ val32 = rtl8xxxu_read32(priv, REG_RX_WAIT_CCA); -+ val32 |= (BIT(22) | BIT(23)); -+ rtl8xxxu_write32(priv, REG_RX_WAIT_CCA, val32); -+ - val8 = rtl8xxxu_read8(priv, REG_GPIO_MUXCFG); - val8 |= BIT(5); - rtl8xxxu_write8(priv, REG_GPIO_MUXCFG, val8); diff --git a/package/kernel/mac80211/patches/652-0001-rtl8xxxu-Obtain-RTS-rates-from-mac80211.patch b/package/kernel/mac80211/patches/652-0001-rtl8xxxu-Obtain-RTS-rates-from-mac80211.patch deleted file mode 100644 index 3ebc685f6a..0000000000 --- a/package/kernel/mac80211/patches/652-0001-rtl8xxxu-Obtain-RTS-rates-from-mac80211.patch +++ /dev/null @@ -1,138 +0,0 @@ -From 3d1d6d96f14881c421860973b4eb4b2fff7cb812 Mon Sep 17 00:00:00 2001 -From: Jes Sorensen -Date: Wed, 5 Oct 2016 16:04:54 -0400 -Subject: [PATCH] rtl8xxxu: Obtain RTS rates from mac80211 - -Use the mac80211 provided rate for RTS rather than the hard coded -24Mbps as suggested by the vendor drivers. - -Reported-by: Andrea Merello -Signed-off-by: Jes Sorensen ---- - drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h | 6 +-- - .../net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c | 46 ++++++++++++++-------- - 2 files changed, 32 insertions(+), 20 deletions(-) - ---- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h -+++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h -@@ -1340,7 +1340,7 @@ struct rtl8xxxu_fileops { - void (*fill_txdesc) (struct ieee80211_hdr *hdr, - struct rtl8xxxu_txdesc32 *tx_desc, u32 rate, - u16 rate_flag, bool sgi, bool short_preamble, -- bool ampdu_enable); -+ bool ampdu_enable, u32 rts_rate); - int writeN_block_size; - int rx_agg_buf_size; - char tx_desc_size; -@@ -1437,11 +1437,11 @@ bool rtl8xxxu_gen2_simularity_compare(st - void rtl8xxxu_fill_txdesc_v1(struct ieee80211_hdr *hdr, - struct rtl8xxxu_txdesc32 *tx_desc, u32 rate, - u16 rate_flag, bool sgi, bool short_preamble, -- bool ampdu_enable); -+ bool ampdu_enable, u32 rts_rate); - void rtl8xxxu_fill_txdesc_v2(struct ieee80211_hdr *hdr, - struct rtl8xxxu_txdesc32 *tx_desc32, u32 rate, - u16 rate_flag, bool sgi, bool short_preamble, -- bool ampdu_enable); -+ bool ampdu_enable, u32 rts_rate); - - extern struct rtl8xxxu_fileops rtl8192cu_fops; - extern struct rtl8xxxu_fileops rtl8192eu_fops; ---- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c -+++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c -@@ -4762,7 +4762,7 @@ void - rtl8xxxu_fill_txdesc_v1(struct ieee80211_hdr *hdr, - struct rtl8xxxu_txdesc32 *tx_desc, u32 rate, - u16 rate_flag, bool sgi, bool short_preamble, -- bool ampdu_enable) -+ bool ampdu_enable, u32 rts_rate) - { - u16 seq_number; - -@@ -4796,15 +4796,16 @@ rtl8xxxu_fill_txdesc_v1(struct ieee80211 - if (sgi) - tx_desc->txdw5 |= cpu_to_le32(TXDESC32_SHORT_GI); - -+ /* -+ * rts_rate is zero if RTS/CTS or CTS to SELF are not enabled -+ */ -+ tx_desc->txdw4 |= cpu_to_le32(rts_rate << TXDESC32_RTS_RATE_SHIFT); - if (rate_flag & IEEE80211_TX_RC_USE_RTS_CTS) { -- /* -- * Use RTS rate 24M - does the mac80211 tell -- * us which to use? -- */ -- tx_desc->txdw4 |= cpu_to_le32(DESC_RATE_24M << -- TXDESC32_RTS_RATE_SHIFT); - tx_desc->txdw4 |= cpu_to_le32(TXDESC32_RTS_CTS_ENABLE); - tx_desc->txdw4 |= cpu_to_le32(TXDESC32_HW_RTS_ENABLE); -+ } else if (rate_flag & IEEE80211_TX_RC_USE_CTS_PROTECT) { -+ tx_desc->txdw4 |= cpu_to_le32(TXDESC32_CTS_SELF_ENABLE); -+ tx_desc->txdw4 |= cpu_to_le32(TXDESC32_HW_RTS_ENABLE); - } - } - -@@ -4816,7 +4817,7 @@ void - rtl8xxxu_fill_txdesc_v2(struct ieee80211_hdr *hdr, - struct rtl8xxxu_txdesc32 *tx_desc32, u32 rate, - u16 rate_flag, bool sgi, bool short_preamble, -- bool ampdu_enable) -+ bool ampdu_enable, u32 rts_rate) - { - struct rtl8xxxu_txdesc40 *tx_desc40; - u16 seq_number; -@@ -4849,15 +4850,19 @@ rtl8xxxu_fill_txdesc_v2(struct ieee80211 - if (short_preamble) - tx_desc40->txdw5 |= cpu_to_le32(TXDESC40_SHORT_PREAMBLE); - -+ tx_desc40->txdw4 |= cpu_to_le32(rts_rate << TXDESC40_RTS_RATE_SHIFT); -+ /* -+ * rts_rate is zero if RTS/CTS or CTS to SELF are not enabled -+ */ - if (rate_flag & IEEE80211_TX_RC_USE_RTS_CTS) { -- /* -- * Use RTS rate 24M - does the mac80211 tell -- * us which to use? -- */ -- tx_desc40->txdw4 |= cpu_to_le32(DESC_RATE_24M << -- TXDESC40_RTS_RATE_SHIFT); - tx_desc40->txdw3 |= cpu_to_le32(TXDESC40_RTS_CTS_ENABLE); - tx_desc40->txdw3 |= cpu_to_le32(TXDESC40_HW_RTS_ENABLE); -+ } else if (rate_flag & IEEE80211_TX_RC_USE_CTS_PROTECT) { -+ /* -+ * For some reason the vendor driver doesn't set -+ * TXDESC40_HW_RTS_ENABLE for CTS to SELF -+ */ -+ tx_desc40->txdw3 |= cpu_to_le32(TXDESC40_CTS_SELF_ENABLE); - } - } - -@@ -4874,7 +4879,7 @@ static void rtl8xxxu_tx(struct ieee80211 - struct ieee80211_sta *sta = NULL; - struct ieee80211_vif *vif = tx_info->control.vif; - struct device *dev = &priv->udev->dev; -- u32 queue, rate; -+ u32 queue, rate, rts_rate; - u16 pktlen = skb->len; - u16 seq_number; - u16 rate_flag = tx_info->control.rates[0].flags; -@@ -4974,10 +4979,17 @@ static void rtl8xxxu_tx(struct ieee80211 - (sta && vif && vif->bss_conf.use_short_preamble)) - short_preamble = true; - -+ if (rate_flag & IEEE80211_TX_RC_USE_RTS_CTS) -+ rts_rate = ieee80211_get_rts_cts_rate(hw, tx_info)->hw_value; -+ else if (rate_flag & IEEE80211_TX_RC_USE_CTS_PROTECT) -+ rts_rate = ieee80211_get_rts_cts_rate(hw, tx_info)->hw_value; -+ else -+ rts_rate = 0; -+ - seq_number = IEEE80211_SEQ_TO_SN(le16_to_cpu(hdr->seq_ctrl)); - -- priv->fops->fill_txdesc(hdr, tx_desc, rate, rate_flag, -- sgi, short_preamble, ampdu_enable); -+ priv->fops->fill_txdesc(hdr, tx_desc, rate, rate_flag, sgi, -+ short_preamble, ampdu_enable, rts_rate); - - rtl8xxxu_calc_tx_desc_csum(tx_desc); - diff --git a/package/kernel/mac80211/patches/652-0002-rtl8xxxu-Pass-tx_info-to-fill_txdesc-in-order-to-hav.patch b/package/kernel/mac80211/patches/652-0002-rtl8xxxu-Pass-tx_info-to-fill_txdesc-in-order-to-hav.patch deleted file mode 100644 index 4b81a9d422..0000000000 --- a/package/kernel/mac80211/patches/652-0002-rtl8xxxu-Pass-tx_info-to-fill_txdesc-in-order-to-hav.patch +++ /dev/null @@ -1,213 +0,0 @@ -From f958b1e0806c045830d78c4287fbcddf9e5fd9d0 Mon Sep 17 00:00:00 2001 -From: Jes Sorensen -Date: Thu, 6 Oct 2016 21:08:53 -0400 -Subject: [PATCH] rtl8xxxu: Pass tx_info to fill_txdesc in order to have access - to retry count - -In order to obtain retry count for a given rate we need to pass the -full struct ieee80211_tx_info to the function setting the rate in he -TX descriptor. - -This uncovered a huge bug where the old code would use struct -ieee80211_rate.flags to test for rate parameters, which is always -zero, instead of the flags value from struct ieee80211_tx_rate. - -Time to find a brown paper bag :( - -Signed-off-by: Jes Sorensen ---- - drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h | 27 ++++---- - .../net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c | 71 ++++++++++++++-------- - 2 files changed, 60 insertions(+), 38 deletions(-) - ---- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h -+++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h -@@ -1337,10 +1337,11 @@ struct rtl8xxxu_fileops { - u32 ramask, int sgi); - void (*report_connect) (struct rtl8xxxu_priv *priv, - u8 macid, bool connect); -- void (*fill_txdesc) (struct ieee80211_hdr *hdr, -- struct rtl8xxxu_txdesc32 *tx_desc, u32 rate, -- u16 rate_flag, bool sgi, bool short_preamble, -- bool ampdu_enable, u32 rts_rate); -+ void (*fill_txdesc) (struct ieee80211_hw *hw, struct ieee80211_hdr *hdr, -+ struct ieee80211_tx_info *tx_info, -+ struct rtl8xxxu_txdesc32 *tx_desc, bool sgi, -+ bool short_preamble, bool ampdu_enable, -+ u32 rts_rate); - int writeN_block_size; - int rx_agg_buf_size; - char tx_desc_size; -@@ -1434,14 +1435,16 @@ int rtl8xxxu_parse_rxdesc24(struct rtl8x - int rtl8xxxu_gen2_channel_to_group(int channel); - bool rtl8xxxu_gen2_simularity_compare(struct rtl8xxxu_priv *priv, - int result[][8], int c1, int c2); --void rtl8xxxu_fill_txdesc_v1(struct ieee80211_hdr *hdr, -- struct rtl8xxxu_txdesc32 *tx_desc, u32 rate, -- u16 rate_flag, bool sgi, bool short_preamble, -- bool ampdu_enable, u32 rts_rate); --void rtl8xxxu_fill_txdesc_v2(struct ieee80211_hdr *hdr, -- struct rtl8xxxu_txdesc32 *tx_desc32, u32 rate, -- u16 rate_flag, bool sgi, bool short_preamble, -- bool ampdu_enable, u32 rts_rate); -+void rtl8xxxu_fill_txdesc_v1(struct ieee80211_hw *hw, struct ieee80211_hdr *hdr, -+ struct ieee80211_tx_info *tx_info, -+ struct rtl8xxxu_txdesc32 *tx_desc, bool sgi, -+ bool short_preamble, bool ampdu_enable, -+ u32 rts_rate); -+void rtl8xxxu_fill_txdesc_v2(struct ieee80211_hw *hw, struct ieee80211_hdr *hdr, -+ struct ieee80211_tx_info *tx_info, -+ struct rtl8xxxu_txdesc32 *tx_desc32, bool sgi, -+ bool short_preamble, bool ampdu_enable, -+ u32 rts_rate); - - extern struct rtl8xxxu_fileops rtl8192cu_fops; - extern struct rtl8xxxu_fileops rtl8192eu_fops; ---- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c -+++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c -@@ -4759,13 +4759,28 @@ static void rtl8xxxu_dump_action(struct - * This format is used on 8188cu/8192cu/8723au - */ - void --rtl8xxxu_fill_txdesc_v1(struct ieee80211_hdr *hdr, -- struct rtl8xxxu_txdesc32 *tx_desc, u32 rate, -- u16 rate_flag, bool sgi, bool short_preamble, -- bool ampdu_enable, u32 rts_rate) -+rtl8xxxu_fill_txdesc_v1(struct ieee80211_hw *hw, struct ieee80211_hdr *hdr, -+ struct ieee80211_tx_info *tx_info, -+ struct rtl8xxxu_txdesc32 *tx_desc, bool sgi, -+ bool short_preamble, bool ampdu_enable, u32 rts_rate) - { -+ struct ieee80211_rate *tx_rate = ieee80211_get_tx_rate(hw, tx_info); -+ struct rtl8xxxu_priv *priv = hw->priv; -+ struct device *dev = &priv->udev->dev; -+ u32 rate; -+ u16 rate_flags = tx_info->control.rates[0].flags; - u16 seq_number; - -+ if (rate_flags & IEEE80211_TX_RC_MCS && -+ !ieee80211_is_mgmt(hdr->frame_control)) -+ rate = tx_info->control.rates[0].idx + DESC_RATE_MCS0; -+ else -+ rate = tx_rate->hw_value; -+ -+ if (rtl8xxxu_debug & RTL8XXXU_DEBUG_TX) -+ dev_info(dev, "%s: TX rate: %d, pkt size %d\n", -+ __func__, rate, cpu_to_le16(tx_desc->pkt_size)); -+ - seq_number = IEEE80211_SEQ_TO_SN(le16_to_cpu(hdr->seq_ctrl)); - - tx_desc->txdw5 = cpu_to_le32(rate); -@@ -4800,10 +4815,10 @@ rtl8xxxu_fill_txdesc_v1(struct ieee80211 - * rts_rate is zero if RTS/CTS or CTS to SELF are not enabled - */ - tx_desc->txdw4 |= cpu_to_le32(rts_rate << TXDESC32_RTS_RATE_SHIFT); -- if (rate_flag & IEEE80211_TX_RC_USE_RTS_CTS) { -+ if (rate_flags & IEEE80211_TX_RC_USE_RTS_CTS) { - tx_desc->txdw4 |= cpu_to_le32(TXDESC32_RTS_CTS_ENABLE); - tx_desc->txdw4 |= cpu_to_le32(TXDESC32_HW_RTS_ENABLE); -- } else if (rate_flag & IEEE80211_TX_RC_USE_CTS_PROTECT) { -+ } else if (rate_flags & IEEE80211_TX_RC_USE_CTS_PROTECT) { - tx_desc->txdw4 |= cpu_to_le32(TXDESC32_CTS_SELF_ENABLE); - tx_desc->txdw4 |= cpu_to_le32(TXDESC32_HW_RTS_ENABLE); - } -@@ -4814,16 +4829,31 @@ rtl8xxxu_fill_txdesc_v1(struct ieee80211 - * This format is used on 8192eu/8723bu - */ - void --rtl8xxxu_fill_txdesc_v2(struct ieee80211_hdr *hdr, -- struct rtl8xxxu_txdesc32 *tx_desc32, u32 rate, -- u16 rate_flag, bool sgi, bool short_preamble, -- bool ampdu_enable, u32 rts_rate) -+rtl8xxxu_fill_txdesc_v2(struct ieee80211_hw *hw, struct ieee80211_hdr *hdr, -+ struct ieee80211_tx_info *tx_info, -+ struct rtl8xxxu_txdesc32 *tx_desc32, bool sgi, -+ bool short_preamble, bool ampdu_enable, u32 rts_rate) - { -+ struct ieee80211_rate *tx_rate = ieee80211_get_tx_rate(hw, tx_info); -+ struct rtl8xxxu_priv *priv = hw->priv; -+ struct device *dev = &priv->udev->dev; - struct rtl8xxxu_txdesc40 *tx_desc40; -+ u32 rate; -+ u16 rate_flags = tx_info->control.rates[0].flags; - u16 seq_number; - - tx_desc40 = (struct rtl8xxxu_txdesc40 *)tx_desc32; - -+ if (rtl8xxxu_debug & RTL8XXXU_DEBUG_TX) -+ dev_info(dev, "%s: TX rate: %d, pkt size %d\n", -+ __func__, rate, cpu_to_le16(tx_desc40->pkt_size)); -+ -+ if (rate_flags & IEEE80211_TX_RC_MCS && -+ !ieee80211_is_mgmt(hdr->frame_control)) -+ rate = tx_info->control.rates[0].idx + DESC_RATE_MCS0; -+ else -+ rate = tx_rate->hw_value; -+ - seq_number = IEEE80211_SEQ_TO_SN(le16_to_cpu(hdr->seq_ctrl)); - - tx_desc40->txdw4 = cpu_to_le32(rate); -@@ -4854,10 +4884,10 @@ rtl8xxxu_fill_txdesc_v2(struct ieee80211 - /* - * rts_rate is zero if RTS/CTS or CTS to SELF are not enabled - */ -- if (rate_flag & IEEE80211_TX_RC_USE_RTS_CTS) { -+ if (rate_flags & IEEE80211_TX_RC_USE_RTS_CTS) { - tx_desc40->txdw3 |= cpu_to_le32(TXDESC40_RTS_CTS_ENABLE); - tx_desc40->txdw3 |= cpu_to_le32(TXDESC40_HW_RTS_ENABLE); -- } else if (rate_flag & IEEE80211_TX_RC_USE_CTS_PROTECT) { -+ } else if (rate_flags & IEEE80211_TX_RC_USE_CTS_PROTECT) { - /* - * For some reason the vendor driver doesn't set - * TXDESC40_HW_RTS_ENABLE for CTS to SELF -@@ -4872,14 +4902,13 @@ static void rtl8xxxu_tx(struct ieee80211 - { - struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; - struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); -- struct ieee80211_rate *tx_rate = ieee80211_get_tx_rate(hw, tx_info); - struct rtl8xxxu_priv *priv = hw->priv; - struct rtl8xxxu_txdesc32 *tx_desc; - struct rtl8xxxu_tx_urb *tx_urb; - struct ieee80211_sta *sta = NULL; - struct ieee80211_vif *vif = tx_info->control.vif; - struct device *dev = &priv->udev->dev; -- u32 queue, rate, rts_rate; -+ u32 queue, rts_rate; - u16 pktlen = skb->len; - u16 seq_number; - u16 rate_flag = tx_info->control.rates[0].flags; -@@ -4906,10 +4935,6 @@ static void rtl8xxxu_tx(struct ieee80211 - goto error; - } - -- if (rtl8xxxu_debug & RTL8XXXU_DEBUG_TX) -- dev_info(dev, "%s: TX rate: %d (%d), pkt size %d\n", -- __func__, tx_rate->bitrate, tx_rate->hw_value, pktlen); -- - if (ieee80211_is_action(hdr->frame_control)) - rtl8xxxu_dump_action(dev, hdr); - -@@ -4963,12 +4988,6 @@ static void rtl8xxxu_tx(struct ieee80211 - } - } - -- if (rate_flag & IEEE80211_TX_RC_MCS && -- !ieee80211_is_mgmt(hdr->frame_control)) -- rate = tx_info->control.rates[0].idx + DESC_RATE_MCS0; -- else -- rate = tx_rate->hw_value; -- - if (rate_flag & IEEE80211_TX_RC_SHORT_GI || - (ieee80211_is_data_qos(hdr->frame_control) && - sta && sta->ht_cap.cap & -@@ -4988,8 +5007,8 @@ static void rtl8xxxu_tx(struct ieee80211 - - seq_number = IEEE80211_SEQ_TO_SN(le16_to_cpu(hdr->seq_ctrl)); - -- priv->fops->fill_txdesc(hdr, tx_desc, rate, rate_flag, sgi, -- short_preamble, ampdu_enable, rts_rate); -+ priv->fops->fill_txdesc(hw, hdr, tx_info, tx_desc, sgi, short_preamble, -+ ampdu_enable, rts_rate); - - rtl8xxxu_calc_tx_desc_csum(tx_desc); - diff --git a/package/kernel/mac80211/patches/653-0002-rtl8xxxu-Add-initial-code-to-detect-8188eu-devices.patch b/package/kernel/mac80211/patches/653-0002-rtl8xxxu-Add-initial-code-to-detect-8188eu-devices.patch index ebd35fcb29..f90ce492f0 100644 --- a/package/kernel/mac80211/patches/653-0002-rtl8xxxu-Add-initial-code-to-detect-8188eu-devices.patch +++ b/package/kernel/mac80211/patches/653-0002-rtl8xxxu-Add-initial-code-to-detect-8188eu-devices.patch @@ -110,7 +110,7 @@ Signed-off-by: Jes Sorensen MODULE_FIRMWARE("rtlwifi/rtl8192cufw_A.bin"); MODULE_FIRMWARE("rtlwifi/rtl8192cufw_B.bin"); MODULE_FIRMWARE("rtlwifi/rtl8192cufw_TMSC.bin"); -@@ -6195,6 +6196,8 @@ static struct usb_device_id dev_table[] +@@ -6210,6 +6211,8 @@ static struct usb_device_id dev_table[] {USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_REALTEK, 0xb720, 0xff, 0xff, 0xff), .driver_info = (unsigned long)&rtl8723bu_fops}, #ifdef CPTCFG_RTL8XXXU_UNTESTED diff --git a/package/kernel/mac80211/patches/653-0035-rtl8xxxu-Implement-rtl8xxxu_fill_txdesc_v3-for-8188e.patch b/package/kernel/mac80211/patches/653-0035-rtl8xxxu-Implement-rtl8xxxu_fill_txdesc_v3-for-8188e.patch index 8ad4c70109..7ceaccb3f8 100644 --- a/package/kernel/mac80211/patches/653-0035-rtl8xxxu-Implement-rtl8xxxu_fill_txdesc_v3-for-8188e.patch +++ b/package/kernel/mac80211/patches/653-0035-rtl8xxxu-Implement-rtl8xxxu_fill_txdesc_v3-for-8188e.patch @@ -58,7 +58,7 @@ Signed-off-by: Jes Sorensen .tx_desc_size = sizeof(struct rtl8xxxu_txdesc32), --- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c +++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c -@@ -4923,6 +4923,84 @@ rtl8xxxu_fill_txdesc_v2(struct ieee80211 +@@ -4931,6 +4931,84 @@ rtl8xxxu_fill_txdesc_v2(struct ieee80211 } } diff --git a/package/kernel/mac80211/patches/653-0041-rtl8xxxu-8188eu-set-REG_OFDM0_XA_AGC_CORE1-to-match-.patch b/package/kernel/mac80211/patches/653-0041-rtl8xxxu-8188eu-set-REG_OFDM0_XA_AGC_CORE1-to-match-.patch index 0370693e46..e11260eb8a 100644 --- a/package/kernel/mac80211/patches/653-0041-rtl8xxxu-8188eu-set-REG_OFDM0_XA_AGC_CORE1-to-match-.patch +++ b/package/kernel/mac80211/patches/653-0041-rtl8xxxu-8188eu-set-REG_OFDM0_XA_AGC_CORE1-to-match-.patch @@ -14,7 +14,7 @@ Signed-off-by: Jes Sorensen --- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c +++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c -@@ -5937,7 +5937,10 @@ exit: +@@ -5945,7 +5945,10 @@ exit: rtl8xxxu_write16(priv, REG_RXFLTMAP2, 0xffff); rtl8xxxu_write16(priv, REG_RXFLTMAP0, 0xffff); diff --git a/package/kernel/mac80211/patches/653-0045-rtl8xxxu-Add-rtl8188etv-to-USB-device-list.patch b/package/kernel/mac80211/patches/653-0045-rtl8xxxu-Add-rtl8188etv-to-USB-device-list.patch index 6bc507797c..31c4b6535b 100644 --- a/package/kernel/mac80211/patches/653-0045-rtl8xxxu-Add-rtl8188etv-to-USB-device-list.patch +++ b/package/kernel/mac80211/patches/653-0045-rtl8xxxu-Add-rtl8188etv-to-USB-device-list.patch @@ -13,7 +13,7 @@ Signed-off-by: Jes Sorensen --- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c +++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c -@@ -6309,6 +6309,9 @@ static struct usb_device_id dev_table[] +@@ -6324,6 +6324,9 @@ static struct usb_device_id dev_table[] #ifdef CPTCFG_RTL8XXXU_UNTESTED {USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_REALTEK, 0x8179, 0xff, 0xff, 0xff), .driver_info = (unsigned long)&rtl8188eu_fops}, diff --git a/package/kernel/mac80211/patches/653-0046-rtl8xxxu-Add-sitecom-dongle-to-USB-device-list.patch b/package/kernel/mac80211/patches/653-0046-rtl8xxxu-Add-sitecom-dongle-to-USB-device-list.patch index 3797206359..fa8ad28d97 100644 --- a/package/kernel/mac80211/patches/653-0046-rtl8xxxu-Add-sitecom-dongle-to-USB-device-list.patch +++ b/package/kernel/mac80211/patches/653-0046-rtl8xxxu-Add-sitecom-dongle-to-USB-device-list.patch @@ -11,7 +11,7 @@ Signed-off-by: Jes Sorensen --- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c +++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c -@@ -6312,6 +6312,9 @@ static struct usb_device_id dev_table[] +@@ -6327,6 +6327,9 @@ static struct usb_device_id dev_table[] /* Tested by Hans de Goede - rtl8188etv */ {USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_REALTEK, 0x0179, 0xff, 0xff, 0xff), .driver_info = (unsigned long)&rtl8188eu_fops}, diff --git a/package/kernel/mac80211/patches/653-0049-rtl8xxxu-Add-rtl8188eu-USB-ID-for-D-Link-USB-GO-N150.patch b/package/kernel/mac80211/patches/653-0049-rtl8xxxu-Add-rtl8188eu-USB-ID-for-D-Link-USB-GO-N150.patch index 1c3df95796..05c45ca24d 100644 --- a/package/kernel/mac80211/patches/653-0049-rtl8xxxu-Add-rtl8188eu-USB-ID-for-D-Link-USB-GO-N150.patch +++ b/package/kernel/mac80211/patches/653-0049-rtl8xxxu-Add-rtl8188eu-USB-ID-for-D-Link-USB-GO-N150.patch @@ -13,7 +13,7 @@ Signed-off-by: Jes Sorensen --- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c +++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c -@@ -6315,6 +6315,9 @@ static struct usb_device_id dev_table[] +@@ -6330,6 +6330,9 @@ static struct usb_device_id dev_table[] /* Sitecom rtl8188eus */ {USB_DEVICE_AND_INTERFACE_INFO(0x0df6, 0x0076, 0xff, 0xff, 0xff), .driver_info = (unsigned long)&rtl8188eu_fops}, diff --git a/package/kernel/mac80211/patches/801-libertas-configure-sysfs-links.patch b/package/kernel/mac80211/patches/801-libertas-configure-sysfs-links.patch index 40e1f9f30c..106ef706b8 100644 --- a/package/kernel/mac80211/patches/801-libertas-configure-sysfs-links.patch +++ b/package/kernel/mac80211/patches/801-libertas-configure-sysfs-links.patch @@ -11,7 +11,7 @@ --- a/drivers/net/wireless/marvell/libertas/main.c +++ b/drivers/net/wireless/marvell/libertas/main.c -@@ -987,6 +987,7 @@ struct lbs_private *lbs_add_card(void *c +@@ -986,6 +986,7 @@ struct lbs_private *lbs_add_card(void *c goto err_adapter; } diff --git a/package/kernel/mac80211/patches/812-b43-add-antenna-control.patch b/package/kernel/mac80211/patches/812-b43-add-antenna-control.patch index f8f555f3e6..33c9402f18 100644 --- a/package/kernel/mac80211/patches/812-b43-add-antenna-control.patch +++ b/package/kernel/mac80211/patches/812-b43-add-antenna-control.patch @@ -108,7 +108,7 @@ wldev->use_pio = b43_modparam_pio; wldev->dev = dev; wldev->wl = wl; -@@ -5603,6 +5645,9 @@ static struct b43_wl *b43_wireless_init( +@@ -5605,6 +5647,9 @@ static struct b43_wl *b43_wireless_init( hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN; diff --git a/package/kernel/mac80211/patches/840-brcmfmac-use-wiphy_read_of_freq_limits.patch b/package/kernel/mac80211/patches/840-brcmfmac-use-wiphy_read_of_freq_limits.patch new file mode 100644 index 0000000000..a9d77caece --- /dev/null +++ b/package/kernel/mac80211/patches/840-brcmfmac-use-wiphy_read_of_freq_limits.patch @@ -0,0 +1,31 @@ +From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= +Subject: [PATCH] brcmfmac: use wiphy_read_of_freq_limits +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Rafał Miłecki +--- + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +@@ -5908,6 +5908,9 @@ static int brcmf_construct_chaninfo(stru + continue; + } + ++ if (channel->orig_flags & IEEE80211_CHAN_DISABLED) ++ continue; ++ + /* assuming the chanspecs order is HT20, + * HT40 upper, HT40 lower, and VHT80. + */ +@@ -6509,6 +6512,9 @@ static int brcmf_setup_wiphy(struct wiph + wiphy->bands[NL80211_BAND_5GHZ] = band; + } + } ++ ++ wiphy_read_of_freq_limits(wiphy); ++ + return 0; + } + diff --git a/package/kernel/mac80211/patches/841-brcmfmac-use-wiphy_read_of_freq_limits.patch b/package/kernel/mac80211/patches/841-brcmfmac-use-wiphy_read_of_freq_limits.patch deleted file mode 100644 index 614399f831..0000000000 --- a/package/kernel/mac80211/patches/841-brcmfmac-use-wiphy_read_of_freq_limits.patch +++ /dev/null @@ -1,31 +0,0 @@ -From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= -Subject: [PATCH] brcmfmac: use wiphy_read_of_freq_limits -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Signed-off-by: Rafał Miłecki ---- - ---- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c -+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c -@@ -5882,6 +5882,9 @@ static int brcmf_construct_chaninfo(stru - continue; - } - -+ if (channel->orig_flags & IEEE80211_CHAN_DISABLED) -+ continue; -+ - /* assuming the chanspecs order is HT20, - * HT40 upper, HT40 lower, and VHT80. - */ -@@ -6483,6 +6486,9 @@ static int brcmf_setup_wiphy(struct wiph - wiphy->bands[NL80211_BAND_5GHZ] = band; - } - } -+ -+ wiphy_read_of_freq_limits(wiphy); -+ - return 0; - } - diff --git a/package/kernel/mac80211/patches/861-brcmfmac-workaround-bug-with-some-inconsistent-BSSes.patch b/package/kernel/mac80211/patches/861-brcmfmac-workaround-bug-with-some-inconsistent-BSSes.patch index c7b13892a4..774b333402 100644 --- a/package/kernel/mac80211/patches/861-brcmfmac-workaround-bug-with-some-inconsistent-BSSes.patch +++ b/package/kernel/mac80211/patches/861-brcmfmac-workaround-bug-with-some-inconsistent-BSSes.patch @@ -10,7 +10,7 @@ Signed-off-by: Rafał Miłecki --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c -@@ -654,9 +654,37 @@ static struct wireless_dev *brcmf_cfg802 +@@ -656,9 +656,37 @@ static struct wireless_dev *brcmf_cfg802 u32 *flags, struct vif_params *params) { diff --git a/package/kernel/mac80211/patches/862-brcmfmac-Disable-power-management.patch b/package/kernel/mac80211/patches/862-brcmfmac-Disable-power-management.patch index 83bc7fe1fd..41b0f64f09 100644 --- a/package/kernel/mac80211/patches/862-brcmfmac-Disable-power-management.patch +++ b/package/kernel/mac80211/patches/862-brcmfmac-Disable-power-management.patch @@ -14,7 +14,7 @@ Signed-off-by: Phil Elwell --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c -@@ -2773,6 +2773,10 @@ brcmf_cfg80211_set_power_mgmt(struct wip +@@ -2775,6 +2775,10 @@ brcmf_cfg80211_set_power_mgmt(struct wip * preference in cfg struct to apply this to * FW later while initializing the dongle */ diff --git a/package/kernel/mac80211/patches/910-00-rt2x00-enable-rt2800soc-for-mt7620.patch b/package/kernel/mac80211/patches/910-00-rt2x00-enable-rt2800soc-for-mt7620.patch deleted file mode 100644 index bc9f799520..0000000000 --- a/package/kernel/mac80211/patches/910-00-rt2x00-enable-rt2800soc-for-mt7620.patch +++ /dev/null @@ -1,20 +0,0 @@ ---- a/drivers/net/wireless/ralink/rt2x00/Kconfig -+++ b/drivers/net/wireless/ralink/rt2x00/Kconfig -@@ -211,7 +211,7 @@ endif - config RT2800SOC - tristate "Ralink WiSoC support" - depends on m -- depends on SOC_RT288X || SOC_RT305X || SOC_RT3883 -+ depends on SOC_RT288X || SOC_RT305X || SOC_RT3883 || SOC_MT7620 - select RT2X00_LIB_SOC - select RT2X00_LIB_MMIO - select RT2X00_LIB_CRYPTO -@@ -248,7 +248,7 @@ config RT2X00_LIB_PCI - - config RT2X00_LIB_SOC - tristate "RT2x00 SoC support" -- depends on SOC_RT288X || SOC_RT305X || SOC_RT3883 -+ depends on SOC_RT288X || SOC_RT305X || SOC_RT3883 || SOC_MT7620 - depends on m - select RT2X00_LIB - diff --git a/package/kernel/mac80211/patches/910-01-add-support-for-mt7620.patch b/package/kernel/mac80211/patches/910-01-add-support-for-mt7620.patch deleted file mode 100644 index 4273936971..0000000000 --- a/package/kernel/mac80211/patches/910-01-add-support-for-mt7620.patch +++ /dev/null @@ -1,1208 +0,0 @@ ---- a/drivers/net/wireless/ralink/rt2x00/rt2800.h -+++ b/drivers/net/wireless/ralink/rt2x00/rt2800.h -@@ -81,6 +81,7 @@ - #define RF5372 0x5372 - #define RF5390 0x5390 - #define RF5392 0x5392 -+#define RF7620 0x7620 - - /* - * Chipset revisions. -@@ -656,6 +657,14 @@ - #define RF_CSR_CFG_BUSY FIELD32(0x00020000) - - /* -+ * mt7620 RF registers (reversed order) -+ */ -+#define RF_CSR_CFG_DATA_MT7620 FIELD32(0x0000ff00) -+#define RF_CSR_CFG_REGNUM_MT7620 FIELD32(0x03ff0000) -+#define RF_CSR_CFG_WRITE_MT7620 FIELD32(0x00000010) -+#define RF_CSR_CFG_BUSY_MT7620 FIELD32(0x00000001) -+ -+/* - * EFUSE_CSR: RT30x0 EEPROM - */ - #define EFUSE_CTRL 0x0580 -@@ -1039,6 +1048,11 @@ - #define AUTOWAKEUP_CFG_AUTOWAKE FIELD32(0x00008000) - - /* -+ * mt7620 -+ */ -+#define MIMO_PS_CFG 0x1210 -+ -+/* - * EDCA_AC0_CFG: - */ - #define EDCA_AC0_CFG 0x1300 -@@ -1218,6 +1232,8 @@ - #define TX_PIN_CFG_RFTR_POL FIELD32(0x00020000) - #define TX_PIN_CFG_TRSW_EN FIELD32(0x00040000) - #define TX_PIN_CFG_TRSW_POL FIELD32(0x00080000) -+#define TX_PIN_CFG_RFRX_EN FIELD32(0x00100000) /* mt7620 */ -+#define TX_PIN_CFG_RFRX_POL FIELD32(0x00200000) /* mt7620 */ - #define TX_PIN_CFG_PA_PE_A2_EN FIELD32(0x01000000) - #define TX_PIN_CFG_PA_PE_G2_EN FIELD32(0x02000000) - #define TX_PIN_CFG_PA_PE_A2_POL FIELD32(0x04000000) -@@ -1564,6 +1580,17 @@ - #define TX_PWR_CFG_4_EXT_STBC4_CH2 FIELD32(0x0000000f) - #define TX_PWR_CFG_4_EXT_STBC6_CH2 FIELD32(0x00000f00) - -+/* mt7620 */ -+#define TX0_RF_GAIN_CORRECT 0x13a0 -+#define TX1_RF_GAIN_CORRECT 0x13a4 -+#define TX0_RF_GAIN_ATTEN 0x13a8 -+#define TX1_RF_GAIN_ATTEN 0x13ac -+#define TX_ALG_CFG_0 0x13b0 -+#define TX_ALG_CFG_1 0x13b4 -+#define TX0_BB_GAIN_ATTEN 0x13c0 -+#define TX1_BB_GAIN_ATTEN 0x13c4 -+#define TX_ALC_VGA3 0x13c8 -+ - /* TX_PWR_CFG_7 */ - #define TX_PWR_CFG_7 0x13d4 - #define TX_PWR_CFG_7_OFDM54_CH0 FIELD32(0x0000000f) ---- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c -+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c -@@ -61,6 +61,8 @@ - rt2800_regbusy_read((__dev), BBP_CSR_CFG, BBP_CSR_CFG_BUSY, (__reg)) - #define WAIT_FOR_RFCSR(__dev, __reg) \ - rt2800_regbusy_read((__dev), RF_CSR_CFG, RF_CSR_CFG_BUSY, (__reg)) -+#define WAIT_FOR_RFCSR_MT7620(__dev, __reg) \ -+ rt2800_regbusy_read((__dev), RF_CSR_CFG, RF_CSR_CFG_BUSY_MT7620, (__reg)) - #define WAIT_FOR_RF(__dev, __reg) \ - rt2800_regbusy_read((__dev), RF_CSR_CFG0, RF_CSR_CFG0_BUSY, (__reg)) - #define WAIT_FOR_MCU(__dev, __reg) \ -@@ -186,19 +188,55 @@ static void rt2800_rfcsr_write(struct rt - * Wait until the RFCSR becomes available, afterwards we - * can safely write the new data into the register. - */ -- if (WAIT_FOR_RFCSR(rt2x00dev, ®)) { -- reg = 0; -- rt2x00_set_field32(®, RF_CSR_CFG_DATA, value); -- rt2x00_set_field32(®, RF_CSR_CFG_REGNUM, word); -- rt2x00_set_field32(®, RF_CSR_CFG_WRITE, 1); -- rt2x00_set_field32(®, RF_CSR_CFG_BUSY, 1); -+ switch (rt2x00dev->chip.rf) { -+ case RF7620: -+ if (WAIT_FOR_RFCSR_MT7620(rt2x00dev, ®)) { -+ reg = 0; -+ rt2x00_set_field32(®, RF_CSR_CFG_DATA_MT7620, value); -+ rt2x00_set_field32(®, RF_CSR_CFG_REGNUM_MT7620, word); -+ rt2x00_set_field32(®, RF_CSR_CFG_WRITE_MT7620, 1); -+ rt2x00_set_field32(®, RF_CSR_CFG_BUSY_MT7620, 1); - -- rt2800_register_write_lock(rt2x00dev, RF_CSR_CFG, reg); -+ rt2800_register_write_lock(rt2x00dev, RF_CSR_CFG, reg); -+ } -+ break; -+ -+ default: -+ if (WAIT_FOR_RFCSR(rt2x00dev, ®)) { -+ reg = 0; -+ rt2x00_set_field32(®, RF_CSR_CFG_DATA, value); -+ rt2x00_set_field32(®, RF_CSR_CFG_REGNUM, word); -+ rt2x00_set_field32(®, RF_CSR_CFG_WRITE, 1); -+ rt2x00_set_field32(®, RF_CSR_CFG_BUSY, 1); -+ -+ rt2800_register_write_lock(rt2x00dev, RF_CSR_CFG, reg); -+ } -+ break; - } - - mutex_unlock(&rt2x00dev->csr_mutex); - } - -+static void rt2800_rfcsr_write_bank(struct rt2x00_dev *rt2x00dev, const u8 bank, -+ const unsigned int reg, const u8 value) -+{ -+ rt2800_rfcsr_write(rt2x00dev, (reg | (bank << 6)), value); -+} -+ -+static void rt2800_rfcsr_write_chanreg(struct rt2x00_dev *rt2x00dev, -+ const unsigned int reg, const u8 value) -+{ -+ rt2800_rfcsr_write_bank(rt2x00dev, 4, reg, value); -+ rt2800_rfcsr_write_bank(rt2x00dev, 6, reg, value); -+} -+ -+static void rt2800_rfcsr_write_dccal(struct rt2x00_dev *rt2x00dev, -+ const unsigned int reg, const u8 value) -+{ -+ rt2800_rfcsr_write_bank(rt2x00dev, 5, reg, value); -+ rt2800_rfcsr_write_bank(rt2x00dev, 7, reg, value); -+} -+ - static void rt2800_rfcsr_read(struct rt2x00_dev *rt2x00dev, - const unsigned int word, u8 *value) - { -@@ -214,22 +252,47 @@ static void rt2800_rfcsr_read(struct rt2 - * doesn't become available in time, reg will be 0xffffffff - * which means we return 0xff to the caller. - */ -- if (WAIT_FOR_RFCSR(rt2x00dev, ®)) { -- reg = 0; -- rt2x00_set_field32(®, RF_CSR_CFG_REGNUM, word); -- rt2x00_set_field32(®, RF_CSR_CFG_WRITE, 0); -- rt2x00_set_field32(®, RF_CSR_CFG_BUSY, 1); -+ switch (rt2x00dev->chip.rf) { -+ case RF7620: -+ if (WAIT_FOR_RFCSR_MT7620(rt2x00dev, ®)) { -+ reg = 0; -+ rt2x00_set_field32(®, RF_CSR_CFG_REGNUM_MT7620, word); -+ rt2x00_set_field32(®, RF_CSR_CFG_WRITE_MT7620, 0); -+ rt2x00_set_field32(®, RF_CSR_CFG_BUSY_MT7620, 1); - -- rt2800_register_write_lock(rt2x00dev, RF_CSR_CFG, reg); -+ rt2800_register_write_lock(rt2x00dev, RF_CSR_CFG, reg); - -- WAIT_FOR_RFCSR(rt2x00dev, ®); -- } -+ WAIT_FOR_RFCSR_MT7620(rt2x00dev, ®); -+ } - -- *value = rt2x00_get_field32(reg, RF_CSR_CFG_DATA); -+ *value = rt2x00_get_field32(reg, RF_CSR_CFG_DATA_MT7620); -+ break; -+ -+ default: -+ if (WAIT_FOR_RFCSR(rt2x00dev, ®)) { -+ reg = 0; -+ rt2x00_set_field32(®, RF_CSR_CFG_REGNUM, word); -+ rt2x00_set_field32(®, RF_CSR_CFG_WRITE, 0); -+ rt2x00_set_field32(®, RF_CSR_CFG_BUSY, 1); -+ -+ rt2800_register_write_lock(rt2x00dev, RF_CSR_CFG, reg); -+ -+ WAIT_FOR_RFCSR(rt2x00dev, ®); -+ } -+ -+ *value = rt2x00_get_field32(reg, RF_CSR_CFG_DATA); -+ break; -+ } - - mutex_unlock(&rt2x00dev->csr_mutex); - } - -+static void rt2800_rfcsr_read_bank(struct rt2x00_dev *rt2x00dev, const u8 bank, -+ const unsigned int reg, u8 *value) -+{ -+ rt2800_rfcsr_read(rt2x00dev, (reg | (bank << 6)), value); -+} -+ - static void rt2800_rf_write(struct rt2x00_dev *rt2x00dev, - const unsigned int word, const u32 value) - { -@@ -566,6 +629,16 @@ void rt2800_get_txwi_rxwi_size(struct rt - *rxwi_size = RXWI_DESC_SIZE_5WORDS; - break; - -+ case RT5390: -+ if ( rt2x00dev->chip.rf == RF7620 ) { -+ *txwi_size = TXWI_DESC_SIZE_5WORDS; -+ *rxwi_size = RXWI_DESC_SIZE_6WORDS; -+ } else { -+ *txwi_size = TXWI_DESC_SIZE_4WORDS; -+ *rxwi_size = RXWI_DESC_SIZE_4WORDS; -+ } -+ break; -+ - case RT5592: - *txwi_size = TXWI_DESC_SIZE_5WORDS; - *rxwi_size = RXWI_DESC_SIZE_6WORDS; -@@ -3303,6 +3376,318 @@ static void rt2800_config_channel_rf55xx - rt2800_bbp_write(rt2x00dev, 196, (rf->channel <= 14) ? 0x19 : 0x7F); - } - -+typedef struct mt7620_freqconfig { -+ u8 Channel; -+ u8 Rdiv; -+ u16 N; -+ u8 K; -+ u8 D; -+ u32 Ksd; -+} mt7620_freqconfig; -+ -+mt7620_freqconfig mt7620_chanconfig[] = -+{ -+ /* 2.4 to 2.483 GHz -+ * CH Rdiv N K D Ksd */ -+ { 0, 0, 0, 0, 0, 0 }, -+ { 1, 3, 0x50, 0, 0, 0x19999 }, -+ { 2, 3, 0x50, 0, 0, 0x24444 }, -+ { 3, 3, 0x50, 0, 0, 0x2EEEE }, -+ { 4, 3, 0x50, 0, 0, 0x39999 }, -+ { 5, 3, 0x51, 0, 0, 0x04444 }, -+ { 6, 3, 0x51, 0, 0, 0x0EEEE }, -+ { 7, 3, 0x51, 0, 0, 0x19999 }, -+ { 8, 3, 0x51, 0, 0, 0x24444 }, -+ { 9, 3, 0x51, 0, 0, 0x2EEEE }, -+ { 10, 3, 0x51, 0, 0, 0x39999 }, -+ { 11, 3, 0x52, 0, 0, 0x04444 }, -+ { 12, 3, 0x52, 0, 0, 0x0EEEE }, -+ { 13, 3, 0x52, 0, 0, 0x19999 }, -+ { 14, 3, 0x52, 0, 0, 0x33333 }, -+}; -+ -+static void rt2800_config_channel_rf7620(struct rt2x00_dev *rt2x00dev, -+ struct ieee80211_conf *conf, -+ struct rf_channel *rf, -+ struct channel_info *info) -+{ -+ int i; -+ u8 bbp; -+ u8 rfcsr; -+ u8 txrx_agc_fc; -+ u32 reg; -+ u16 eeprom, target_power; -+ u32 mac_sys_ctrl, mac_status; -+ u32 tx_pin = 0x00150F0F; -+ struct hw_mode_spec *spec = &rt2x00dev->spec; -+ struct rt2800_drv_data *drv_data = rt2x00dev->drv_data; -+ -+ /* Frequeny plan setting */ -+ /* -+ * Rdiv setting -+ * R13[1:0] -+ */ -+ rt2800_rfcsr_read(rt2x00dev, 13, &rfcsr); -+ rfcsr = rfcsr & (~0x03); -+ if (spec->clk_is_20mhz) -+ rfcsr |= (mt7620_chanconfig[rf->channel].Rdiv & 0x3); -+ rt2800_rfcsr_write(rt2x00dev, 13, rfcsr); -+ -+ /* -+ * N setting -+ * R21[0], R20[7:0] -+ */ -+ rt2800_rfcsr_read(rt2x00dev, 20, &rfcsr); -+ rfcsr = (mt7620_chanconfig[rf->channel].N & 0x00ff); -+ rt2800_rfcsr_write(rt2x00dev, 20, rfcsr); -+ -+ rt2800_rfcsr_read(rt2x00dev, 21, &rfcsr); -+ rfcsr = rfcsr & (~0x01); -+ rfcsr |= ((mt7620_chanconfig[rf->channel].N & 0x0100) >> 8); -+ rt2800_rfcsr_write(rt2x00dev, 21, rfcsr); -+ -+ /* -+ * K setting -+ * R16[3:0] (RF PLL freq selection) -+ */ -+ rt2800_rfcsr_read(rt2x00dev, 16, &rfcsr); -+ rfcsr = rfcsr & (~0x0f); -+ rfcsr |= (mt7620_chanconfig[rf->channel].K & 0x0f); -+ rt2800_rfcsr_write(rt2x00dev, 16, rfcsr); -+ -+ /* -+ * D setting -+ * R22[2:0] (D=15, R22[2:0]=<111>) -+ */ -+ rt2800_rfcsr_read(rt2x00dev, 22, &rfcsr); -+ rfcsr = rfcsr & (~0x07); -+ rfcsr |= (mt7620_chanconfig[rf->channel].D & 0x07); -+ rt2800_rfcsr_write(rt2x00dev, 22, rfcsr); -+ -+ /* -+ * Ksd setting -+ * Ksd: R19<1:0>,R18<7:0>,R17<7:0> -+ */ -+ rt2800_rfcsr_read(rt2x00dev, 17, &rfcsr); -+ rfcsr = (mt7620_chanconfig[rf->channel].Ksd & 0x000000ff); -+ rt2800_rfcsr_write(rt2x00dev, 17, rfcsr); -+ -+ rt2800_rfcsr_read(rt2x00dev, 18, &rfcsr); -+ rfcsr = ((mt7620_chanconfig[rf->channel].Ksd & 0x0000ff00) >> 8); -+ rt2800_rfcsr_write(rt2x00dev, 18, rfcsr); -+ -+ rt2800_rfcsr_read(rt2x00dev, 19, &rfcsr); -+ rfcsr = rfcsr & (~0x03); -+ rfcsr |= ((mt7620_chanconfig[rf->channel].Ksd & 0x00030000) >> 16); -+ rt2800_rfcsr_write(rt2x00dev, 19, rfcsr); -+ -+ /* Default: XO=20MHz , SDM mode */ -+ rt2800_rfcsr_read(rt2x00dev, 16, &rfcsr); -+ rfcsr = rfcsr & (~0xE0); -+ rfcsr |= 0x80; -+ rt2800_rfcsr_write(rt2x00dev, 16, rfcsr); -+ -+ rt2800_rfcsr_read(rt2x00dev, 21, &rfcsr); -+ rfcsr |= 0x80; -+ rt2800_rfcsr_write(rt2x00dev, 21, rfcsr); -+ -+ rt2800_rfcsr_read(rt2x00dev, 1, &rfcsr); -+ if (rt2x00dev->default_ant.tx_chain_num == 1) -+ rfcsr &= (~0x2); -+ else -+ rfcsr |= 0x2; -+ rt2800_rfcsr_write(rt2x00dev, 1, rfcsr); -+ -+ rt2800_rfcsr_read(rt2x00dev, 2, &rfcsr); -+ if (rt2x00dev->default_ant.tx_chain_num == 1) -+ rfcsr &= (~0x20); -+ else -+ rfcsr |= 0x20; -+ if (rt2x00dev->default_ant.rx_chain_num == 1) -+ rfcsr &= (~0x02); -+ else -+ rfcsr |= 0x02; -+ rt2800_rfcsr_write(rt2x00dev, 2, rfcsr); -+ -+ rt2800_rfcsr_read(rt2x00dev, 42, &rfcsr); -+ if (rt2x00dev->default_ant.tx_chain_num == 1) -+ rfcsr &= (~0x40); -+ else -+ rfcsr |= 0x40; -+ rt2800_rfcsr_write(rt2x00dev, 42, rfcsr); -+ -+ /* RF for DC Cal BW */ -+ if (conf_is_ht40(conf)) { -+ rt2800_rfcsr_write_dccal(rt2x00dev, 6, 0x10); -+ rt2800_rfcsr_write_dccal(rt2x00dev, 7, 0x10); -+ rt2800_rfcsr_write_dccal(rt2x00dev, 8, 0x04); -+ rt2800_rfcsr_write_dccal(rt2x00dev, 58, 0x10); -+ rt2800_rfcsr_write_dccal(rt2x00dev, 59, 0x10); -+ } else { -+ rt2800_rfcsr_write_dccal(rt2x00dev, 6, 0x20); -+ rt2800_rfcsr_write_dccal(rt2x00dev, 7, 0x20); -+ rt2800_rfcsr_write_dccal(rt2x00dev, 8, 0x00); -+ rt2800_rfcsr_write_dccal(rt2x00dev, 58, 0x20); -+ rt2800_rfcsr_write_dccal(rt2x00dev, 59, 0x20); -+ } -+ -+ if (conf_is_ht40(conf)) { -+ rt2800_rfcsr_write_dccal(rt2x00dev, 58, 0x08); -+ rt2800_rfcsr_write_dccal(rt2x00dev, 59, 0x08); -+ } else { -+ rt2800_rfcsr_write_dccal(rt2x00dev, 58, 0x28); -+ rt2800_rfcsr_write_dccal(rt2x00dev, 59, 0x28); -+ } -+ -+ rt2800_rfcsr_read(rt2x00dev, 28, &rfcsr); -+ if (conf_is_ht40(conf) && (rf->channel == 11)) -+ rfcsr |= 0x4; -+ else -+ rfcsr &= (~0x4); -+ rt2800_rfcsr_write(rt2x00dev, 28, rfcsr); -+ -+ /*if (bScan == FALSE)*/ -+ if (conf_is_ht40(conf)) { -+ txrx_agc_fc = rt2x00_get_field8(drv_data->calibration_bw40, -+ RFCSR24_TX_AGC_FC); -+ } else { -+ txrx_agc_fc = rt2x00_get_field8(drv_data->calibration_bw20, -+ RFCSR24_TX_AGC_FC); -+ } -+ rt2800_rfcsr_read_bank(rt2x00dev, 5, 6, &rfcsr); -+ rfcsr &= (~0x3F); -+ rfcsr |= txrx_agc_fc; -+ rt2800_rfcsr_write_bank(rt2x00dev, 5, 6, rfcsr); -+ rt2800_rfcsr_read_bank(rt2x00dev, 5, 7, &rfcsr); -+ rfcsr &= (~0x3F); -+ rfcsr |= txrx_agc_fc; -+ rt2800_rfcsr_write_bank(rt2x00dev, 5, 7, rfcsr); -+ rt2800_rfcsr_read_bank(rt2x00dev, 7, 6, &rfcsr); -+ rfcsr &= (~0x3F); -+ rfcsr |= txrx_agc_fc; -+ rt2800_rfcsr_write_bank(rt2x00dev, 7, 6, rfcsr); -+ rt2800_rfcsr_read_bank(rt2x00dev, 7, 7, &rfcsr); -+ rfcsr &= (~0x3F); -+ rfcsr |= txrx_agc_fc; -+ rt2800_rfcsr_write_bank(rt2x00dev, 7, 7, rfcsr); -+ -+ rt2800_rfcsr_read_bank(rt2x00dev, 5, 58, &rfcsr); -+ rfcsr &= (~0x3F); -+ rfcsr |= txrx_agc_fc; -+ rt2800_rfcsr_write_bank(rt2x00dev, 5, 58, rfcsr); -+ rt2800_rfcsr_read_bank(rt2x00dev, 5, 59, &rfcsr); -+ rfcsr &= (~0x3F); -+ rfcsr |= txrx_agc_fc; -+ rt2800_rfcsr_write_bank(rt2x00dev, 5, 59, rfcsr); -+ rt2800_rfcsr_read_bank(rt2x00dev, 7, 58, &rfcsr); -+ rfcsr &= (~0x3F); -+ rfcsr |= txrx_agc_fc; -+ rt2800_rfcsr_write_bank(rt2x00dev, 7, 58, rfcsr); -+ rt2800_rfcsr_read_bank(rt2x00dev, 7, 59, &rfcsr); -+ rfcsr &= (~0x3F); -+ rfcsr |= txrx_agc_fc; -+ rt2800_rfcsr_write_bank(rt2x00dev, 7, 59, rfcsr); -+ -+ rt2800_register_read(rt2x00dev, TX_ALG_CFG_0, ®); -+ reg = reg & (~0x3F3F); -+ reg |= info->default_power1; -+ reg |= (info->default_power2 << 8); -+ reg |= (0x2F << 16); -+ reg |= (0x2F << 24); -+ -+ rt2800_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1, &eeprom); -+ if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF1_INTERNAL_TX_ALC)) { -+ /* init base power by e2p target power */ -+ rt2800_eeprom_read(rt2x00dev, 0xD0, &target_power); -+ target_power &= 0x3F; -+ reg = reg & (~0x3F3F); -+ reg |= target_power; -+ reg |= (target_power << 8); -+ } -+ rt2800_register_write(rt2x00dev, TX_ALG_CFG_0, reg); -+ -+ rt2800_register_read(rt2x00dev, TX_ALG_CFG_1, ®); -+ reg = reg & (~0x3F); -+ rt2800_register_write(rt2x00dev, TX_ALG_CFG_1, reg); -+ -+ /*if (bScan == FALSE)*/ -+ /* Save MAC SYS CTRL registers */ -+ rt2800_register_read(rt2x00dev, MAC_SYS_CTRL, &mac_sys_ctrl); -+ /* Disable Tx/Rx */ -+ rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, 0); -+ /* Check MAC Tx/Rx idle */ -+ for (i = 0; i < 10000; i++) { -+ rt2800_register_read(rt2x00dev, MAC_STATUS_CFG, &mac_status); -+ if (mac_status & 0x3) -+ udelay(50); -+ else -+ break; -+ } -+ -+ if (i == 10000) -+ rt2x00_warn(rt2x00dev, "Wait MAC Status to MAX !!!\n"); -+ -+ if (rf->channel > 10) { -+ rt2800_bbp_read(rt2x00dev, 30, &bbp); -+ bbp = 0x40; -+ rt2800_bbp_write(rt2x00dev, 30, bbp); -+ rt2800_rfcsr_write(rt2x00dev, 39, 0); -+ if (rt2x00_has_cap_external_lna_bg(rt2x00dev)) -+ rt2800_rfcsr_write(rt2x00dev, 42, 0xfb); -+ else -+ rt2800_rfcsr_write(rt2x00dev, 42, 0x7b); -+ } else { -+ rt2800_bbp_read(rt2x00dev, 30, &bbp); -+ bbp = 0x1f; -+ rt2800_bbp_write(rt2x00dev, 30, bbp); -+ rt2800_rfcsr_write(rt2x00dev, 39, 0x80); -+ if (rt2x00_has_cap_external_lna_bg(rt2x00dev)) -+ rt2800_rfcsr_write(rt2x00dev, 42, 0xdb); -+ else -+ rt2800_rfcsr_write(rt2x00dev, 42, 0x5b); -+ } -+ -+ rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, mac_sys_ctrl); -+ -+ rt2800_rfcsr_write(rt2x00dev, 5, 0x40); -+ rt2800_rfcsr_write(rt2x00dev, 4, 0x0C); -+ -+ /* vcocal_en (initiate VCO calibration (reset after completion)) */ -+ rt2800_rfcsr_read(rt2x00dev, 4, &rfcsr); -+ rfcsr = ((rfcsr & ~0x80) | 0x80); -+ rt2800_rfcsr_write(rt2x00dev, 4, rfcsr); -+ mdelay(2); -+ -+ rt2800_register_write(rt2x00dev, TX_PIN_CFG, tx_pin); -+ -+ if (rt2x00dev->default_ant.tx_chain_num == 1) { -+ rt2800_bbp_write(rt2x00dev, 91, 0x07); -+ rt2800_bbp_write(rt2x00dev, 95, 0x1A); -+ rt2800_bbp_write(rt2x00dev, 195, 128); -+ rt2800_bbp_write(rt2x00dev, 196, 0xA0); -+ rt2800_bbp_write(rt2x00dev, 195, 170); -+ rt2800_bbp_write(rt2x00dev, 196, 0x12); -+ rt2800_bbp_write(rt2x00dev, 195, 171); -+ rt2800_bbp_write(rt2x00dev, 196, 0x10); -+ } else { -+ rt2800_bbp_write(rt2x00dev, 91, 0x06); -+ rt2800_bbp_write(rt2x00dev, 95, 0x9A); -+ rt2800_bbp_write(rt2x00dev, 195, 128); -+ rt2800_bbp_write(rt2x00dev, 196, 0xE0); -+ rt2800_bbp_write(rt2x00dev, 195, 170); -+ rt2800_bbp_write(rt2x00dev, 196, 0x30); -+ rt2800_bbp_write(rt2x00dev, 195, 171); -+ rt2800_bbp_write(rt2x00dev, 196, 0x30); -+ } -+ -+ /* On 11A, We should delay and wait RF/BBP to be stable*/ -+ /* and the appropriate time should be 1000 micro seconds */ -+ /* 2005/06/05 - On 11G, We also need this delay time. -+ * Otherwise it's difficult to pass the WHQL.*/ -+ udelay(1000); -+} -+ -+ - static void rt2800_bbp_write_with_rx_chain(struct rt2x00_dev *rt2x00dev, - const unsigned int word, - const u8 value) -@@ -3459,7 +3844,7 @@ static void rt2800_config_channel(struct - struct channel_info *info) - { - u32 reg; -- unsigned int tx_pin; -+ u32 tx_pin; - u8 bbp, rfcsr; - - info->default_power1 = rt2800_txpower_to_dev(rt2x00dev, rf->channel, -@@ -3513,6 +3898,9 @@ static void rt2800_config_channel(struct - case RF5592: - rt2800_config_channel_rf55xx(rt2x00dev, conf, rf, info); - break; -+ case RF7620: -+ rt2800_config_channel_rf7620(rt2x00dev, conf, rf, info); -+ break; - default: - rt2800_config_channel_rf2xxx(rt2x00dev, conf, rf, info); - } -@@ -3615,7 +4003,7 @@ static void rt2800_config_channel(struct - else if (rt2x00_rt(rt2x00dev, RT3593) || - rt2x00_rt(rt2x00dev, RT3883)) - rt2800_bbp_write(rt2x00dev, 82, 0x82); -- else -+ else if (rt2x00dev->chip.rf != RF7620) - rt2800_bbp_write(rt2x00dev, 82, 0xf2); - - if (rt2x00_rt(rt2x00dev, RT3593) || -@@ -3637,7 +4025,7 @@ static void rt2800_config_channel(struct - if (rt2x00_rt(rt2x00dev, RT3572)) - rt2800_rfcsr_write(rt2x00dev, 8, 0); - -- tx_pin = 0; -+ rt2800_register_read(rt2x00dev, TX_PIN_CFG, &tx_pin); - - switch (rt2x00dev->default_ant.tx_chain_num) { - case 3: -@@ -3686,6 +4074,7 @@ static void rt2800_config_channel(struct - - rt2x00_set_field32(&tx_pin, TX_PIN_CFG_RFTR_EN, 1); - rt2x00_set_field32(&tx_pin, TX_PIN_CFG_TRSW_EN, 1); -+ rt2x00_set_field32(&tx_pin, TX_PIN_CFG_RFRX_EN, 1); /* mt7620 */ - - rt2800_register_write(rt2x00dev, TX_PIN_CFG, tx_pin); - -@@ -4702,6 +5091,14 @@ void rt2800_vco_calibration(struct rt2x0 - rt2x00_set_field8(&rfcsr, RFCSR3_VCOCAL_EN, 1); - rt2800_rfcsr_write(rt2x00dev, 3, rfcsr); - break; -+ case RF7620: -+ rt2800_rfcsr_read(rt2x00dev, 4, &rfcsr); -+ /* vcocal_en (initiate VCO calibration (reset after completion)) -+ * It should be at the end of RF configuration. */ -+ rfcsr = ((rfcsr & ~0x80) | 0x80); -+ rt2800_rfcsr_write(rt2x00dev, 4, rfcsr); -+ mdelay(1); -+ break; - default: - return; - } -@@ -5102,9 +5499,42 @@ static int rt2800_init_registers(struct - } else if (rt2x00_rt(rt2x00dev, RT5390) || - rt2x00_rt(rt2x00dev, RT5392) || - rt2x00_rt(rt2x00dev, RT5592)) { -- rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000404); -- rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00080606); -- rt2800_register_write(rt2x00dev, TX_SW_CFG2, 0x00000000); -+ if (rt2x00dev->chip.rf == RF7620) { -+ rt2800_register_write(rt2x00dev, TX_SW_CFG0, -+ 0x00000401); -+ rt2800_register_write(rt2x00dev, TX_SW_CFG1, -+ 0x000C0000); -+ rt2800_register_write(rt2x00dev, TX_SW_CFG2, -+ 0x00000000); -+ rt2800_register_write(rt2x00dev, MIMO_PS_CFG, -+ 0x00000002); -+ rt2800_register_write(rt2x00dev, TX_PIN_CFG, -+ 0x00150F0F); -+ rt2800_register_write(rt2x00dev, TX_ALC_VGA3, -+ 0x06060606); -+ rt2800_register_write(rt2x00dev, TX0_BB_GAIN_ATTEN, -+ 0x0); -+ rt2800_register_write(rt2x00dev, TX1_BB_GAIN_ATTEN, -+ 0x0); -+ rt2800_register_write(rt2x00dev, TX0_RF_GAIN_ATTEN, -+ 0x6C6C666C); -+ rt2800_register_write(rt2x00dev, TX1_RF_GAIN_ATTEN, -+ 0x6C6C666C); -+ rt2800_register_write(rt2x00dev, TX0_RF_GAIN_CORRECT, -+ 0x3630363A); -+ rt2800_register_write(rt2x00dev, TX1_RF_GAIN_CORRECT, -+ 0x3630363A); -+ rt2800_register_read(rt2x00dev, TX_ALG_CFG_1, ®); -+ reg = reg & (~0x80000000); -+ rt2800_register_write(rt2x00dev, TX_ALG_CFG_1, reg); -+ } else { -+ rt2800_register_write(rt2x00dev, TX_SW_CFG0, -+ 0x00000404); -+ rt2800_register_write(rt2x00dev, TX_SW_CFG1, -+ 0x00080606); -+ rt2800_register_write(rt2x00dev, TX_SW_CFG2, -+ 0x00000000); -+ } - } else if (rt2x00_rt(rt2x00dev, RT5350)) { - rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000404); - } else { -@@ -6136,6 +6566,225 @@ static void rt2800_init_bbp_5592(struct - rt2800_bbp_write(rt2x00dev, 103, 0xc0); - } - -+static void rt2800_bbp_glrt_write(struct rt2x00_dev *rt2x00dev, -+ const u8 reg, const u8 value) -+{ -+ rt2800_bbp_write(rt2x00dev, 195, reg); -+ rt2800_bbp_write(rt2x00dev, 196, value); -+} -+ -+static void rt2800_bbp_dcoc_write(struct rt2x00_dev *rt2x00dev, -+ const u8 reg, const u8 value) -+{ -+ rt2800_bbp_write(rt2x00dev, 158, reg); -+ rt2800_bbp_write(rt2x00dev, 159, value); -+} -+ -+static void rt2800_init_bbp_7620(struct rt2x00_dev *rt2x00dev) -+{ -+ u8 bbp; -+ -+ /* Apply Maximum Likelihood Detection (MLD) for 2 stream case */ -+ rt2800_bbp_read(rt2x00dev, 105, &bbp); -+ rt2x00_set_field8(&bbp, BBP105_MLD, -+ rt2x00dev->default_ant.rx_chain_num == 2); -+ rt2800_bbp_write(rt2x00dev, 105, bbp); -+ -+ /* Avoid data loss and CRC errors */ -+ /* MAC interface control (MAC_IF_80M, 1: 80 MHz) */ -+ rt2800_bbp4_mac_if_ctrl(rt2x00dev); -+ -+ /* Fix I/Q swap issue */ -+ rt2800_bbp_read(rt2x00dev, 1, &bbp); -+ bbp |= 0x04; -+ rt2800_bbp_write(rt2x00dev, 1, bbp); -+ -+ /* BBP for G band */ -+ rt2800_bbp_write(rt2x00dev, 3, 0x08); -+ rt2800_bbp_write(rt2x00dev, 4, 0x00); /* rt2800_bbp4_mac_if_ctrl? */ -+ rt2800_bbp_write(rt2x00dev, 6, 0x08); -+ rt2800_bbp_write(rt2x00dev, 14, 0x09); -+ rt2800_bbp_write(rt2x00dev, 15, 0xFF); -+ rt2800_bbp_write(rt2x00dev, 16, 0x01); -+ rt2800_bbp_write(rt2x00dev, 20, 0x06); -+ rt2800_bbp_write(rt2x00dev, 21, 0x00); -+ rt2800_bbp_write(rt2x00dev, 22, 0x00); -+ rt2800_bbp_write(rt2x00dev, 27, 0x00); -+ rt2800_bbp_write(rt2x00dev, 28, 0x00); -+ rt2800_bbp_write(rt2x00dev, 30, 0x00); -+ rt2800_bbp_write(rt2x00dev, 31, 0x48); -+ rt2800_bbp_write(rt2x00dev, 47, 0x40); -+ rt2800_bbp_write(rt2x00dev, 62, 0x00); -+ rt2800_bbp_write(rt2x00dev, 63, 0x00); -+ rt2800_bbp_write(rt2x00dev, 64, 0x00); -+ rt2800_bbp_write(rt2x00dev, 65, 0x2C); -+ rt2800_bbp_write(rt2x00dev, 66, 0x1C); -+ rt2800_bbp_write(rt2x00dev, 67, 0x20); -+ rt2800_bbp_write(rt2x00dev, 68, 0xDD); -+ rt2800_bbp_write(rt2x00dev, 69, 0x10); -+ rt2800_bbp_write(rt2x00dev, 70, 0x05); -+ rt2800_bbp_write(rt2x00dev, 73, 0x18); -+ rt2800_bbp_write(rt2x00dev, 74, 0x0F); -+ rt2800_bbp_write(rt2x00dev, 75, 0x60); -+ rt2800_bbp_write(rt2x00dev, 76, 0x44); -+ rt2800_bbp_write(rt2x00dev, 77, 0x59); -+ rt2800_bbp_write(rt2x00dev, 78, 0x1E); -+ rt2800_bbp_write(rt2x00dev, 79, 0x1C); -+ rt2800_bbp_write(rt2x00dev, 80, 0x0C); -+ rt2800_bbp_write(rt2x00dev, 81, 0x3A); -+ rt2800_bbp_write(rt2x00dev, 82, 0xB6); -+ rt2800_bbp_write(rt2x00dev, 83, 0x9A); -+ rt2800_bbp_write(rt2x00dev, 84, 0x9A); -+ rt2800_bbp_write(rt2x00dev, 86, 0x38); -+ rt2800_bbp_write(rt2x00dev, 88, 0x90); -+ rt2800_bbp_write(rt2x00dev, 91, 0x04); -+ rt2800_bbp_write(rt2x00dev, 92, 0x02); -+ rt2800_bbp_write(rt2x00dev, 95, 0x9A); -+ rt2800_bbp_write(rt2x00dev, 96, 0x00); -+ rt2800_bbp_write(rt2x00dev, 103, 0xC0); -+ rt2800_bbp_write(rt2x00dev, 104, 0x92); -+ /* FIXME BBP105 owerwrite */ -+ rt2800_bbp_write(rt2x00dev, 105, 0x3C); -+ rt2800_bbp_write(rt2x00dev, 106, 0x12); -+ rt2800_bbp_write(rt2x00dev, 109, 0x00); -+ rt2800_bbp_write(rt2x00dev, 134, 0x10); -+ rt2800_bbp_write(rt2x00dev, 135, 0xA6); -+ rt2800_bbp_write(rt2x00dev, 137, 0x04); -+ rt2800_bbp_write(rt2x00dev, 142, 0x30); -+ rt2800_bbp_write(rt2x00dev, 143, 0xF7); -+ rt2800_bbp_write(rt2x00dev, 160, 0xEC); -+ rt2800_bbp_write(rt2x00dev, 161, 0xC4); -+ rt2800_bbp_write(rt2x00dev, 162, 0x77); -+ rt2800_bbp_write(rt2x00dev, 163, 0xF9); -+ rt2800_bbp_write(rt2x00dev, 164, 0x00); -+ rt2800_bbp_write(rt2x00dev, 165, 0x00); -+ rt2800_bbp_write(rt2x00dev, 186, 0x00); -+ rt2800_bbp_write(rt2x00dev, 187, 0x00); -+ rt2800_bbp_write(rt2x00dev, 188, 0x00); -+ rt2800_bbp_write(rt2x00dev, 186, 0x00); -+ rt2800_bbp_write(rt2x00dev, 187, 0x01); -+ rt2800_bbp_write(rt2x00dev, 188, 0x00); -+ rt2800_bbp_write(rt2x00dev, 189, 0x00); -+ -+ rt2800_bbp_write(rt2x00dev, 91, 0x06); -+ rt2800_bbp_write(rt2x00dev, 92, 0x04); -+ rt2800_bbp_write(rt2x00dev, 93, 0x54); -+ rt2800_bbp_write(rt2x00dev, 99, 0x50); -+ rt2800_bbp_write(rt2x00dev, 148, 0x84); -+ rt2800_bbp_write(rt2x00dev, 167, 0x80); -+ rt2800_bbp_write(rt2x00dev, 178, 0xFF); -+ rt2800_bbp_write(rt2x00dev, 106, 0x13); -+ -+ /* BBP for G band GLRT function (BBP_128 ~ BBP_221) */ -+ rt2800_bbp_glrt_write(rt2x00dev, 0, 0x00); -+ rt2800_bbp_glrt_write(rt2x00dev, 1, 0x14); /* ? see above */ -+ rt2800_bbp_glrt_write(rt2x00dev, 2, 0x20); -+ rt2800_bbp_glrt_write(rt2x00dev, 3, 0x0A); -+ rt2800_bbp_glrt_write(rt2x00dev, 10, 0x16); -+ rt2800_bbp_glrt_write(rt2x00dev, 11, 0x06); -+ rt2800_bbp_glrt_write(rt2x00dev, 12, 0x02); -+ rt2800_bbp_glrt_write(rt2x00dev, 13, 0x07); -+ rt2800_bbp_glrt_write(rt2x00dev, 14, 0x05); -+ rt2800_bbp_glrt_write(rt2x00dev, 15, 0x09); -+ rt2800_bbp_glrt_write(rt2x00dev, 16, 0x20); -+ rt2800_bbp_glrt_write(rt2x00dev, 17, 0x08); -+ rt2800_bbp_glrt_write(rt2x00dev, 18, 0x4A); -+ rt2800_bbp_glrt_write(rt2x00dev, 19, 0x00); -+ rt2800_bbp_glrt_write(rt2x00dev, 20, 0x00); -+ rt2800_bbp_glrt_write(rt2x00dev, 128, 0xE0); -+ rt2800_bbp_glrt_write(rt2x00dev, 129, 0x1F); -+ rt2800_bbp_glrt_write(rt2x00dev, 130, 0x4F); -+ rt2800_bbp_glrt_write(rt2x00dev, 131, 0x32); -+ rt2800_bbp_glrt_write(rt2x00dev, 132, 0x08); -+ rt2800_bbp_glrt_write(rt2x00dev, 133, 0x28); -+ rt2800_bbp_glrt_write(rt2x00dev, 134, 0x19); -+ rt2800_bbp_glrt_write(rt2x00dev, 135, 0x0A); -+ rt2800_bbp_glrt_write(rt2x00dev, 138, 0x16); -+ rt2800_bbp_glrt_write(rt2x00dev, 139, 0x10); -+ rt2800_bbp_glrt_write(rt2x00dev, 140, 0x10); -+ rt2800_bbp_glrt_write(rt2x00dev, 141, 0x1A); -+ rt2800_bbp_glrt_write(rt2x00dev, 142, 0x36); -+ rt2800_bbp_glrt_write(rt2x00dev, 143, 0x2C); -+ rt2800_bbp_glrt_write(rt2x00dev, 144, 0x26); -+ rt2800_bbp_glrt_write(rt2x00dev, 145, 0x24); -+ rt2800_bbp_glrt_write(rt2x00dev, 146, 0x42); -+ rt2800_bbp_glrt_write(rt2x00dev, 147, 0x40); -+ rt2800_bbp_glrt_write(rt2x00dev, 148, 0x30); -+ rt2800_bbp_glrt_write(rt2x00dev, 149, 0x29); -+ rt2800_bbp_glrt_write(rt2x00dev, 150, 0x4C); -+ rt2800_bbp_glrt_write(rt2x00dev, 151, 0x46); -+ rt2800_bbp_glrt_write(rt2x00dev, 152, 0x3D); -+ rt2800_bbp_glrt_write(rt2x00dev, 153, 0x40); -+ rt2800_bbp_glrt_write(rt2x00dev, 154, 0x3E); -+ rt2800_bbp_glrt_write(rt2x00dev, 155, 0x38); -+ rt2800_bbp_glrt_write(rt2x00dev, 156, 0x3D); -+ rt2800_bbp_glrt_write(rt2x00dev, 157, 0x2F); -+ rt2800_bbp_glrt_write(rt2x00dev, 158, 0x3C); -+ rt2800_bbp_glrt_write(rt2x00dev, 159, 0x34); -+ rt2800_bbp_glrt_write(rt2x00dev, 160, 0x2C); -+ rt2800_bbp_glrt_write(rt2x00dev, 161, 0x2F); -+ rt2800_bbp_glrt_write(rt2x00dev, 162, 0x3C); -+ rt2800_bbp_glrt_write(rt2x00dev, 163, 0x35); -+ rt2800_bbp_glrt_write(rt2x00dev, 164, 0x2E); -+ rt2800_bbp_glrt_write(rt2x00dev, 165, 0x2F); -+ rt2800_bbp_glrt_write(rt2x00dev, 166, 0x49); -+ rt2800_bbp_glrt_write(rt2x00dev, 167, 0x41); -+ rt2800_bbp_glrt_write(rt2x00dev, 168, 0x36); -+ rt2800_bbp_glrt_write(rt2x00dev, 169, 0x39); -+ rt2800_bbp_glrt_write(rt2x00dev, 170, 0x30); -+ rt2800_bbp_glrt_write(rt2x00dev, 171, 0x30); -+ rt2800_bbp_glrt_write(rt2x00dev, 172, 0x0E); -+ rt2800_bbp_glrt_write(rt2x00dev, 173, 0x0D); -+ rt2800_bbp_glrt_write(rt2x00dev, 174, 0x28); -+ rt2800_bbp_glrt_write(rt2x00dev, 175, 0x21); -+ rt2800_bbp_glrt_write(rt2x00dev, 176, 0x1C); -+ rt2800_bbp_glrt_write(rt2x00dev, 177, 0x16); -+ rt2800_bbp_glrt_write(rt2x00dev, 178, 0x50); -+ rt2800_bbp_glrt_write(rt2x00dev, 179, 0x4A); -+ rt2800_bbp_glrt_write(rt2x00dev, 180, 0x43); -+ rt2800_bbp_glrt_write(rt2x00dev, 181, 0x50); -+ rt2800_bbp_glrt_write(rt2x00dev, 182, 0x10); -+ rt2800_bbp_glrt_write(rt2x00dev, 183, 0x10); -+ rt2800_bbp_glrt_write(rt2x00dev, 184, 0x10); -+ rt2800_bbp_glrt_write(rt2x00dev, 185, 0x10); -+ rt2800_bbp_glrt_write(rt2x00dev, 200, 0x7D); -+ rt2800_bbp_glrt_write(rt2x00dev, 201, 0x14); -+ rt2800_bbp_glrt_write(rt2x00dev, 202, 0x32); -+ rt2800_bbp_glrt_write(rt2x00dev, 203, 0x2C); -+ rt2800_bbp_glrt_write(rt2x00dev, 204, 0x36); -+ rt2800_bbp_glrt_write(rt2x00dev, 205, 0x4C); -+ rt2800_bbp_glrt_write(rt2x00dev, 206, 0x43); -+ rt2800_bbp_glrt_write(rt2x00dev, 207, 0x2C); -+ rt2800_bbp_glrt_write(rt2x00dev, 208, 0x2E); -+ rt2800_bbp_glrt_write(rt2x00dev, 209, 0x36); -+ rt2800_bbp_glrt_write(rt2x00dev, 210, 0x30); -+ rt2800_bbp_glrt_write(rt2x00dev, 211, 0x6E); -+ -+ /* BBP for G band DCOC function */ -+ rt2800_bbp_dcoc_write(rt2x00dev, 140, 0x0C); -+ rt2800_bbp_dcoc_write(rt2x00dev, 141, 0x00); -+ rt2800_bbp_dcoc_write(rt2x00dev, 142, 0x10); -+ rt2800_bbp_dcoc_write(rt2x00dev, 143, 0x10); -+ rt2800_bbp_dcoc_write(rt2x00dev, 144, 0x10); -+ rt2800_bbp_dcoc_write(rt2x00dev, 145, 0x10); -+ rt2800_bbp_dcoc_write(rt2x00dev, 146, 0x08); -+ rt2800_bbp_dcoc_write(rt2x00dev, 147, 0x40); -+ rt2800_bbp_dcoc_write(rt2x00dev, 148, 0x04); -+ rt2800_bbp_dcoc_write(rt2x00dev, 149, 0x04); -+ rt2800_bbp_dcoc_write(rt2x00dev, 150, 0x08); -+ rt2800_bbp_dcoc_write(rt2x00dev, 151, 0x08); -+ rt2800_bbp_dcoc_write(rt2x00dev, 152, 0x03); -+ rt2800_bbp_dcoc_write(rt2x00dev, 153, 0x03); -+ rt2800_bbp_dcoc_write(rt2x00dev, 154, 0x03); -+ rt2800_bbp_dcoc_write(rt2x00dev, 155, 0x02); -+ rt2800_bbp_dcoc_write(rt2x00dev, 156, 0x40); -+ rt2800_bbp_dcoc_write(rt2x00dev, 157, 0x40); -+ rt2800_bbp_dcoc_write(rt2x00dev, 158, 0x64); -+ rt2800_bbp_dcoc_write(rt2x00dev, 159, 0x64); -+ -+ rt2800_bbp4_mac_if_ctrl(rt2x00dev); -+} -+ - static void rt2800_init_bbp(struct rt2x00_dev *rt2x00dev) - { - unsigned int i; -@@ -6178,7 +6827,10 @@ static void rt2800_init_bbp(struct rt2x0 - return; - case RT5390: - case RT5392: -- rt2800_init_bbp_53xx(rt2x00dev); -+ if (rt2x00dev->chip.rf == RF7620) -+ rt2800_init_bbp_7620(rt2x00dev); -+ else -+ rt2800_init_bbp_53xx(rt2x00dev); - break; - case RT5592: - rt2800_init_bbp_5592(rt2x00dev); -@@ -7392,6 +8044,296 @@ static void rt2800_init_rfcsr_5592(struc - rt2800_led_open_drain_enable(rt2x00dev); - } - -+static void rt2800_init_rfcsr_7620(struct rt2x00_dev *rt2x00dev) -+{ -+ u16 freq; -+ u8 rfvalue; -+ struct hw_mode_spec *spec = &rt2x00dev->spec; -+ -+ /* Initialize RF central register to default value */ -+ rt2800_rfcsr_write(rt2x00dev, 0, 0x02); -+ rt2800_rfcsr_write(rt2x00dev, 1, 0x03); -+ rt2800_rfcsr_write(rt2x00dev, 2, 0x33); -+ rt2800_rfcsr_write(rt2x00dev, 3, 0xFF); -+ rt2800_rfcsr_write(rt2x00dev, 4, 0x0C); -+ rt2800_rfcsr_write(rt2x00dev, 5, 0x40); /* Read only */ -+ rt2800_rfcsr_write(rt2x00dev, 6, 0x00); -+ rt2800_rfcsr_write(rt2x00dev, 7, 0x00); -+ rt2800_rfcsr_write(rt2x00dev, 8, 0x00); -+ rt2800_rfcsr_write(rt2x00dev, 9, 0x00); -+ rt2800_rfcsr_write(rt2x00dev, 10, 0x00); -+ rt2800_rfcsr_write(rt2x00dev, 11, 0x00); -+ /* rt2800_rfcsr_write(rt2x00dev, 12, 0x43); *//* EEPROM */ -+ rt2800_rfcsr_write(rt2x00dev, 13, 0x00); -+ rt2800_rfcsr_write(rt2x00dev, 14, 0x40); -+ rt2800_rfcsr_write(rt2x00dev, 15, 0x22); -+ rt2800_rfcsr_write(rt2x00dev, 16, 0x4C); -+ rt2800_rfcsr_write(rt2x00dev, 17, 0x00); -+ rt2800_rfcsr_write(rt2x00dev, 18, 0x00); -+ rt2800_rfcsr_write(rt2x00dev, 19, 0x00); -+ rt2800_rfcsr_write(rt2x00dev, 20, 0xA0); -+ rt2800_rfcsr_write(rt2x00dev, 21, 0x12); -+ rt2800_rfcsr_write(rt2x00dev, 22, 0x07); -+ rt2800_rfcsr_write(rt2x00dev, 23, 0x13); -+ rt2800_rfcsr_write(rt2x00dev, 24, 0xFE); -+ rt2800_rfcsr_write(rt2x00dev, 25, 0x24); -+ rt2800_rfcsr_write(rt2x00dev, 26, 0x7A); -+ rt2800_rfcsr_write(rt2x00dev, 27, 0x00); -+ rt2800_rfcsr_write(rt2x00dev, 28, 0x00); -+ rt2800_rfcsr_write(rt2x00dev, 29, 0x05); -+ rt2800_rfcsr_write(rt2x00dev, 30, 0x00); -+ rt2800_rfcsr_write(rt2x00dev, 31, 0x00); -+ rt2800_rfcsr_write(rt2x00dev, 32, 0x00); -+ rt2800_rfcsr_write(rt2x00dev, 33, 0x00); -+ rt2800_rfcsr_write(rt2x00dev, 34, 0x00); -+ rt2800_rfcsr_write(rt2x00dev, 35, 0x00); -+ rt2800_rfcsr_write(rt2x00dev, 36, 0x00); -+ rt2800_rfcsr_write(rt2x00dev, 37, 0x00); -+ rt2800_rfcsr_write(rt2x00dev, 38, 0x00); -+ rt2800_rfcsr_write(rt2x00dev, 39, 0x00); -+ rt2800_rfcsr_write(rt2x00dev, 40, 0x00); -+ rt2800_rfcsr_write(rt2x00dev, 41, 0xD0); -+ rt2800_rfcsr_write(rt2x00dev, 42, 0x5B); -+ rt2800_rfcsr_write(rt2x00dev, 43, 0x00); -+ -+ rt2800_rfcsr_write(rt2x00dev, 11, 0x21); -+ if (spec->clk_is_20mhz) -+ rt2800_rfcsr_write(rt2x00dev, 13, 0x03); -+ else -+ rt2800_rfcsr_write(rt2x00dev, 13, 0x00); -+ rt2800_rfcsr_write(rt2x00dev, 14, 0x7C); -+ rt2800_rfcsr_write(rt2x00dev, 16, 0x80); -+ rt2800_rfcsr_write(rt2x00dev, 17, 0x99); -+ rt2800_rfcsr_write(rt2x00dev, 18, 0x99); -+ rt2800_rfcsr_write(rt2x00dev, 19, 0x09); -+ rt2800_rfcsr_write(rt2x00dev, 20, 0x50); -+ rt2800_rfcsr_write(rt2x00dev, 21, 0xB0); -+ rt2800_rfcsr_write(rt2x00dev, 22, 0x00); -+ rt2800_rfcsr_write(rt2x00dev, 23, 0x06); -+ rt2800_rfcsr_write(rt2x00dev, 24, 0x00); -+ rt2800_rfcsr_write(rt2x00dev, 25, 0x00); -+ rt2800_rfcsr_write(rt2x00dev, 26, 0x5D); -+ rt2800_rfcsr_write(rt2x00dev, 27, 0x00); -+ rt2800_rfcsr_write(rt2x00dev, 28, 0x61); -+ rt2800_rfcsr_write(rt2x00dev, 29, 0xB5); -+ rt2800_rfcsr_write(rt2x00dev, 43, 0x02); -+ -+ rt2800_rfcsr_write(rt2x00dev, 28, 0x62); -+ rt2800_rfcsr_write(rt2x00dev, 29, 0xAD); -+ rt2800_rfcsr_write(rt2x00dev, 39, 0x80); -+ /* RTMP_TEMPERATURE_CALIBRATION */ -+ /* rt2800_rfcsr_write(rt2x00dev, 34, 0x23); */ -+ /* rt2800_rfcsr_write(rt2x00dev, 35, 0x01); */ -+ -+ /* use rt2800_adjust_freq_offset ? */ -+ rt2800_eeprom_read(rt2x00dev, EEPROM_FREQ, &freq); -+ rfvalue = freq & 0xff; -+ rt2800_rfcsr_write(rt2x00dev, 12, rfvalue); -+ -+ /* Initialize RF channel register to default value */ -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 0, 0x03); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 1, 0x00); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 2, 0x00); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 3, 0x00); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 4, 0x00); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 5, 0x08); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 6, 0x00); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 7, 0x51); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 8, 0x53); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 9, 0x16); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 10, 0x61); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 11, 0x53); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 12, 0x22); -+ /* rt2800_rfcsr_write_chanreg(rt2x00dev, 13, 0x3D); */ /* fails */ -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 14, 0x06); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 15, 0x13); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 16, 0x22); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 17, 0x27); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 18, 0x02); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 19, 0xA7); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 20, 0x01); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 21, 0x52); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 22, 0x80); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 23, 0xB3); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 24, 0x00); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 25, 0x00); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 26, 0x00); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 27, 0x00); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 28, 0x5C); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 29, 0x6B); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 30, 0x6B); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 31, 0x31); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 32, 0x5D); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 33, 0x00); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 34, 0xE6); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 35, 0x55); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 36, 0x00); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 37, 0xBB); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 38, 0xB3); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 39, 0xB3); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 40, 0x03); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 41, 0x00); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 42, 0x00); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 43, 0xB3); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 44, 0xD3); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 45, 0xD5); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 46, 0x07); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 47, 0x68); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 48, 0xEF); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 49, 0x1C); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 54, 0x07); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 55, 0xA8); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 56, 0x85); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 57, 0x10); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 58, 0x07); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 59, 0x6A); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 60, 0x85); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 61, 0x10); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 62, 0x1C); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 63, 0x00); -+ -+ rt2800_rfcsr_write_bank(rt2x00dev, 6, 45, 0xC5); -+ -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 9, 0x47); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 10, 0x71); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 11, 0x33); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 14, 0x0E); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 17, 0x23); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 19, 0xA4); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 20, 0x02); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 21, 0x12); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 28, 0x1C); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 29, 0xEB); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 32, 0x7D); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 34, 0xD6); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 36, 0x08); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 38, 0xB4); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 43, 0xD3); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 44, 0xB3); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 45, 0xD5); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 46, 0x27); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 47, 0x69); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 48, 0xFF); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 54, 0x20); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 55, 0x66); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 56, 0xFF); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 57, 0x1C); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 58, 0x20); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 59, 0x6B); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 60, 0xF7); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 61, 0x09); -+ -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 10, 0x51); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 14, 0x06); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 19, 0xA7); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 28, 0x2C); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 55, 0x64); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 8, 0x51); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 9, 0x36); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 11, 0x53); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 14, 0x16); -+ -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 47, 0x6C); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 48, 0xFC); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 49, 0x1F); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 54, 0x27); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 55, 0x66); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 59, 0x6B); -+ -+ /* Initialize RF channel register for DRQFN */ -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 43, 0xD3); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 44, 0xE3); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 45, 0xE5); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 47, 0x28); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 55, 0x68); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 56, 0xF7); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 58, 0x02); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 60, 0xC7); -+ -+ /* reduce power consumption */ -+/* rt2800_rfcsr_write_chanreg(rt2x00dev, 43, 0x53); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 44, 0x53); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 45, 0x53); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 47, 0x64); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 48, 0x4F); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 49, 0x02); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 55, 0x64); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 56, 0x4F); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 57, 0x02); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 58, 0x27); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 59, 0x64); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 60, 0x4F); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 61, 0x02); -+*/ -+ /* Initialize RF DC calibration register to default value */ -+ rt2800_rfcsr_write_dccal(rt2x00dev, 0, 0x47); -+ rt2800_rfcsr_write_dccal(rt2x00dev, 1, 0x00); -+ rt2800_rfcsr_write_dccal(rt2x00dev, 2, 0x00); -+ rt2800_rfcsr_write_dccal(rt2x00dev, 3, 0x00); -+ rt2800_rfcsr_write_dccal(rt2x00dev, 4, 0x00); -+ rt2800_rfcsr_write_dccal(rt2x00dev, 5, 0x00); -+ rt2800_rfcsr_write_dccal(rt2x00dev, 6, 0x10); -+ rt2800_rfcsr_write_dccal(rt2x00dev, 7, 0x10); -+ rt2800_rfcsr_write_dccal(rt2x00dev, 8, 0x04); -+ rt2800_rfcsr_write_dccal(rt2x00dev, 9, 0x00); -+ rt2800_rfcsr_write_dccal(rt2x00dev, 10, 0x07); -+ rt2800_rfcsr_write_dccal(rt2x00dev, 11, 0x01); -+ rt2800_rfcsr_write_dccal(rt2x00dev, 12, 0x07); -+ rt2800_rfcsr_write_dccal(rt2x00dev, 13, 0x07); -+ rt2800_rfcsr_write_dccal(rt2x00dev, 14, 0x07); -+ rt2800_rfcsr_write_dccal(rt2x00dev, 15, 0x20); -+ rt2800_rfcsr_write_dccal(rt2x00dev, 16, 0x22); -+ rt2800_rfcsr_write_dccal(rt2x00dev, 17, 0x00); -+ rt2800_rfcsr_write_dccal(rt2x00dev, 18, 0x00); -+ rt2800_rfcsr_write_dccal(rt2x00dev, 19, 0x00); -+ rt2800_rfcsr_write_dccal(rt2x00dev, 20, 0x00); -+ rt2800_rfcsr_write_dccal(rt2x00dev, 21, 0xF1); -+ rt2800_rfcsr_write_dccal(rt2x00dev, 22, 0x11); -+ rt2800_rfcsr_write_dccal(rt2x00dev, 23, 0x02); -+ rt2800_rfcsr_write_dccal(rt2x00dev, 24, 0x41); -+ rt2800_rfcsr_write_dccal(rt2x00dev, 25, 0x20); -+ rt2800_rfcsr_write_dccal(rt2x00dev, 26, 0x00); -+ rt2800_rfcsr_write_dccal(rt2x00dev, 27, 0xD7); -+ rt2800_rfcsr_write_dccal(rt2x00dev, 28, 0xA2); -+ rt2800_rfcsr_write_dccal(rt2x00dev, 29, 0x20); -+ rt2800_rfcsr_write_dccal(rt2x00dev, 30, 0x49); -+ rt2800_rfcsr_write_dccal(rt2x00dev, 31, 0x20); -+ rt2800_rfcsr_write_dccal(rt2x00dev, 32, 0x04); -+ rt2800_rfcsr_write_dccal(rt2x00dev, 33, 0xF1); -+ rt2800_rfcsr_write_dccal(rt2x00dev, 34, 0xA1); -+ rt2800_rfcsr_write_dccal(rt2x00dev, 35, 0x01); -+ rt2800_rfcsr_write_dccal(rt2x00dev, 41, 0x00); -+ rt2800_rfcsr_write_dccal(rt2x00dev, 42, 0x00); -+ rt2800_rfcsr_write_dccal(rt2x00dev, 43, 0x00); -+ rt2800_rfcsr_write_dccal(rt2x00dev, 44, 0x00); -+ rt2800_rfcsr_write_dccal(rt2x00dev, 45, 0x00); -+ rt2800_rfcsr_write_dccal(rt2x00dev, 46, 0x00); -+ rt2800_rfcsr_write_dccal(rt2x00dev, 47, 0x3E); -+ rt2800_rfcsr_write_dccal(rt2x00dev, 48, 0x3D); -+ rt2800_rfcsr_write_dccal(rt2x00dev, 49, 0x3E); -+ rt2800_rfcsr_write_dccal(rt2x00dev, 50, 0x3D); -+ rt2800_rfcsr_write_dccal(rt2x00dev, 51, 0x3E); -+ rt2800_rfcsr_write_dccal(rt2x00dev, 52, 0x3D); -+ rt2800_rfcsr_write_dccal(rt2x00dev, 53, 0x00); -+ rt2800_rfcsr_write_dccal(rt2x00dev, 54, 0x00); -+ rt2800_rfcsr_write_dccal(rt2x00dev, 55, 0x00); -+ rt2800_rfcsr_write_dccal(rt2x00dev, 56, 0x00); -+ rt2800_rfcsr_write_dccal(rt2x00dev, 57, 0x00); -+ rt2800_rfcsr_write_dccal(rt2x00dev, 58, 0x10); -+ rt2800_rfcsr_write_dccal(rt2x00dev, 59, 0x10); -+ rt2800_rfcsr_write_dccal(rt2x00dev, 60, 0x0A); -+ rt2800_rfcsr_write_dccal(rt2x00dev, 61, 0x00); -+ rt2800_rfcsr_write_dccal(rt2x00dev, 62, 0x00); -+ rt2800_rfcsr_write_dccal(rt2x00dev, 63, 0x00); -+ -+ rt2800_rfcsr_write_dccal(rt2x00dev, 3, 0x08); -+ rt2800_rfcsr_write_dccal(rt2x00dev, 4, 0x04); -+ rt2800_rfcsr_write_dccal(rt2x00dev, 5, 0x20); -+ -+ rt2800_rfcsr_write_dccal(rt2x00dev, 5, 0x00); -+ rt2800_rfcsr_write_dccal(rt2x00dev, 17, 0x7C); -+} -+ - static void rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev) - { - if (rt2800_is_305x_soc(rt2x00dev)) { -@@ -7427,7 +8369,10 @@ static void rt2800_init_rfcsr(struct rt2 - rt2800_init_rfcsr_5350(rt2x00dev); - break; - case RT5390: -- rt2800_init_rfcsr_5390(rt2x00dev); -+ if (rt2x00dev->chip.rf == RF7620) -+ rt2800_init_rfcsr_7620(rt2x00dev); -+ else -+ rt2800_init_rfcsr_5390(rt2x00dev); - break; - case RT5392: - rt2800_init_rfcsr_5392(rt2x00dev); -@@ -7856,6 +8801,7 @@ static int rt2800_init_eeprom(struct rt2 - case RF5390: - case RF5392: - case RF5592: -+ case RF7620: - break; - default: - rt2x00_err(rt2x00dev, "Invalid RF chipset 0x%04x detected\n", -@@ -8424,6 +9370,7 @@ static int rt2800_probe_hw_mode(struct r - case RF5372: - case RF5390: - case RF5392: -+ case RF7620: - spec->num_channels = 14; - if (spec->clk_is_20mhz) - spec->channels = rf_vals_xtal20mhz_3x; -@@ -8564,6 +9511,7 @@ static int rt2800_probe_hw_mode(struct r - case RF5372: - case RF5390: - case RF5392: -+ case RF7620: - __set_bit(CAPABILITY_VCO_RECALIBRATION, &rt2x00dev->cap_flags); - break; - } diff --git a/package/kernel/mac80211/patches/921-ath10k_init_devices_synchronously.patch b/package/kernel/mac80211/patches/921-ath10k_init_devices_synchronously.patch index e417eb8ffa..0c34d96847 100644 --- a/package/kernel/mac80211/patches/921-ath10k_init_devices_synchronously.patch +++ b/package/kernel/mac80211/patches/921-ath10k_init_devices_synchronously.patch @@ -14,7 +14,7 @@ Signed-off-by: Sven Eckelmann --- a/drivers/net/wireless/ath/ath10k/core.c +++ b/drivers/net/wireless/ath/ath10k/core.c -@@ -2220,6 +2220,16 @@ int ath10k_core_register(struct ath10k * +@@ -2319,6 +2319,16 @@ int ath10k_core_register(struct ath10k * ar->chip_id = chip_id; queue_work(ar->workqueue, &ar->register_work); diff --git a/package/kernel/mac80211/patches/930-ath10k_add_tpt_led_trigger.patch b/package/kernel/mac80211/patches/930-ath10k_add_tpt_led_trigger.patch index d47e2a6e25..4cf1b9f92a 100644 --- a/package/kernel/mac80211/patches/930-ath10k_add_tpt_led_trigger.patch +++ b/package/kernel/mac80211/patches/930-ath10k_add_tpt_led_trigger.patch @@ -1,7 +1,7 @@ --- a/drivers/net/wireless/ath/ath10k/mac.c +++ b/drivers/net/wireless/ath/ath10k/mac.c -@@ -7812,6 +7812,21 @@ struct ath10k_vif *ath10k_get_arvif(stru - return arvif_iter.arvif; +@@ -8003,6 +8003,21 @@ static int ath10k_mac_init_rd(struct ath + return 0; } +#ifdef CPTCFG_MAC80211_LEDS @@ -22,7 +22,7 @@ int ath10k_mac_register(struct ath10k *ar) { static const u32 cipher_suites[] = { -@@ -8045,6 +8060,12 @@ int ath10k_mac_register(struct ath10k *a +@@ -8248,6 +8263,12 @@ int ath10k_mac_register(struct ath10k *a ar->hw->wiphy->cipher_suites = cipher_suites; ar->hw->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites); diff --git a/package/kernel/mac80211/patches/936-ath10k_skip_otp_check.patch b/package/kernel/mac80211/patches/936-ath10k_skip_otp_check.patch index fbda8d5ac1..057995c55a 100644 --- a/package/kernel/mac80211/patches/936-ath10k_skip_otp_check.patch +++ b/package/kernel/mac80211/patches/936-ath10k_skip_otp_check.patch @@ -1,6 +1,6 @@ --- a/drivers/net/wireless/ath/ath10k/core.c +++ b/drivers/net/wireless/ath/ath10k/core.c -@@ -1282,9 +1282,6 @@ static int ath10k_core_fetch_firmware_fi +@@ -1362,9 +1362,6 @@ static int ath10k_core_fetch_firmware_fi { int ret; @@ -10,7 +10,7 @@ ar->fw_api = 5; ath10k_dbg(ar, ATH10K_DBG_BOOT, "trying fw api %d\n", ar->fw_api); -@@ -2054,7 +2051,7 @@ EXPORT_SYMBOL(ath10k_core_stop); +@@ -2149,7 +2146,7 @@ EXPORT_SYMBOL(ath10k_core_stop); static int ath10k_core_probe_fw(struct ath10k *ar) { struct bmi_target_info target_info; @@ -19,7 +19,7 @@ ret = ath10k_hif_power_up(ar); if (ret) { -@@ -2078,6 +2075,9 @@ static int ath10k_core_probe_fw(struct a +@@ -2173,6 +2170,9 @@ static int ath10k_core_probe_fw(struct a goto err_power_down; } @@ -29,7 +29,7 @@ ret = ath10k_core_fetch_firmware_files(ar); if (ret) { ath10k_err(ar, "could not fetch firmware files (%d)\n", ret); -@@ -2100,11 +2100,14 @@ static int ath10k_core_probe_fw(struct a +@@ -2195,11 +2195,14 @@ static int ath10k_core_probe_fw(struct a "could not load pre cal data: %d\n", ret); } @@ -48,4 +48,4 @@ + } } - ret = ath10k_core_fetch_board_file(ar); + ret = ath10k_core_check_smbios(ar);