diff --git a/patches/openwrt/0018-Backport-mac80211-from-Barrier-Breaker.patch b/patches/openwrt/0018-Backport-mac80211-from-Barrier-Breaker-r40804.patch similarity index 65% rename from patches/openwrt/0018-Backport-mac80211-from-Barrier-Breaker.patch rename to patches/openwrt/0018-Backport-mac80211-from-Barrier-Breaker-r40804.patch index 942ee309..cb273fad 100644 --- a/patches/openwrt/0018-Backport-mac80211-from-Barrier-Breaker.patch +++ b/patches/openwrt/0018-Backport-mac80211-from-Barrier-Breaker-r40804.patch @@ -1,9 +1,9 @@ From: Matthias Schiffer Date: Mon, 19 May 2014 15:59:37 +0200 -Subject: Backport mac80211 from Barrier Breaker +Subject: Backport mac80211 from Barrier Breaker (r40804) diff --git a/package/mac80211/Makefile b/package/mac80211/Makefile -index 9a7093c..e19f30e 100644 +index 9a7093c..7eacf24 100644 --- a/package/mac80211/Makefile +++ b/package/mac80211/Makefile @@ -1,5 +1,5 @@ @@ -18,12 +18,12 @@ index 9a7093c..e19f30e 100644 PKG_NAME:=mac80211 -PKG_VERSION:=2014-01-23.1 -+PKG_VERSION:=2014-03-31 ++PKG_VERSION:=2014-05-19 PKG_RELEASE:=1 PKG_SOURCE_URL:=http://mirror2.openwrt.org/sources PKG_BACKPORT_VERSION:= -PKG_MD5SUM:=8db16edbdaf4abc2e9c2f3b6c86736a6 -+PKG_MD5SUM:=8b5cf82d6defc5867511014af4afc0b6 ++PKG_MD5SUM:=ff5426bf85668c3c36c7f602adeb1e5b PKG_SOURCE:=compat-wireless-$(PKG_VERSION)$(PKG_BACKPORT_VERSION).tar.bz2 PKG_BUILD_DIR:=$(KERNEL_BUILD_DIR)/compat-wireless-$(PKG_VERSION) @@ -51,6 +51,15 @@ index 9a7093c..e19f30e 100644 PKG_ATH10K_LINUX_FIRMWARE_SOURCE:=$(PKG_ATH10K_LINUX_FIRMWARE_NAME)-$(PKG_ATH10K_LINUX_FIRMWARE_VERSION).tar.bz2 PKG_ATH10K_LINUX_FIRMWARE_PROTO:=git PKG_ATH10K_LINUX_FIRMWARE_SOURCE_URL:=https://github.com/kvalo/ath10k-firmware.git +@@ -363,7 +363,7 @@ define KernelPackage/rtl8180 + $(call KernelPackage/rtl818x/Default) + DEPENDS+= @PCI_SUPPORT + TITLE+= (RTL8180 PCI) +- FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/rtl818x/rtl8180/rtl8180.ko ++ FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/rtl818x/rtl8180/rtl818x_pci.ko + AUTOLOAD:=$(call AutoLoad,27,rtl8180) + endef + @@ -606,6 +606,19 @@ Atheros IEEE 802.11ac family of chipsets. For now only PCI is supported. endef @@ -1602,6 +1611,40 @@ index 2badb21..fcab208 100644 + (5250 - 5330 @ 80), (20), DFS + (5490 - 5710 @ 80), (27), DFS +diff --git a/package/mac80211/patches/001-fix_build.patch b/package/mac80211/patches/001-fix_build.patch +index 26b327a..99ef50e 100644 +--- a/package/mac80211/patches/001-fix_build.patch ++++ b/package/mac80211/patches/001-fix_build.patch +@@ -131,7 +131,7 @@ + .PHONY: defconfig-help + --- a/Makefile.real + +++ b/Makefile.real +-@@ -54,7 +54,7 @@ defconfig-%:: ++@@ -59,7 +59,7 @@ defconfig-%:: + + backport-include/backport/autoconf.h: .config Kconfig.versions Kconfig.kernel + @$(MAKE) oldconfig +@@ -140,7 +140,7 @@ + @grep -f .local-symbols .config | ( \ + echo "#ifndef COMPAT_AUTOCONF_INCLUDED" ;\ + echo "#define COMPAT_AUTOCONF_INCLUDED" ;\ +-@@ -75,7 +75,12 @@ backport-include/backport/autoconf.h: .c ++@@ -80,7 +80,12 @@ backport-include/backport/autoconf.h: .c + esac ;\ + done ;\ + echo "#endif /* COMPAT_AUTOCONF_INCLUDED */" ;\ +diff --git a/package/mac80211/patches/003-remove_bogus_modparams.patch b/package/mac80211/patches/003-remove_bogus_modparams.patch +index c969b19..ffb730b 100644 +--- a/package/mac80211/patches/003-remove_bogus_modparams.patch ++++ b/package/mac80211/patches/003-remove_bogus_modparams.patch +@@ -1,6 +1,6 @@ + --- a/compat/main.c + +++ b/compat/main.c +-@@ -21,31 +21,6 @@ MODULE_LICENSE("GPL"); ++@@ -20,31 +20,6 @@ MODULE_LICENSE("GPL"); + #error "You need a BACKPORTS_VERSION" + #endif + diff --git a/package/mac80211/patches/004-backports-add-led_trigger_blink-_oneshot.patch b/package/mac80211/patches/004-backports-add-led_trigger_blink-_oneshot.patch index 584fb05..8d97224 100644 --- a/package/mac80211/patches/004-backports-add-led_trigger_blink-_oneshot.patch @@ -1667,258 +1710,414 @@ index 0000000..55bffbc + flagstr = flagstr $i + split(flagstr, flagarray, ",") + flags = "" +diff --git a/package/mac80211/patches/007-select_queue.patch b/package/mac80211/patches/007-select_queue.patch +new file mode 100644 +index 0000000..0a1d292 +--- /dev/null ++++ b/package/mac80211/patches/007-select_queue.patch +@@ -0,0 +1,11 @@ ++--- a/drivers/net/wireless/mwifiex/main.c +++++ b/drivers/net/wireless/mwifiex/main.c ++@@ -745,7 +745,7 @@ static struct net_device_stats *mwifiex_ ++ return &priv->stats; ++ } ++ ++-#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0) +++#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0) ++ static u16 ++ mwifiex_netdev_select_wmm_queue(struct net_device *dev, struct sk_buff *skb, ++ void *accel_priv, select_queue_fallback_t fallback) +diff --git a/package/mac80211/patches/020-disable_tty_set_termios.patch b/package/mac80211/patches/020-disable_tty_set_termios.patch +deleted file mode 100644 +index e6d4ff6..0000000 +--- a/package/mac80211/patches/020-disable_tty_set_termios.patch ++++ /dev/null +@@ -1,16 +0,0 @@ +---- a/compat/compat-2.6.39.c +-+++ b/compat/compat-2.6.39.c +-@@ -13,6 +13,7 @@ +- #include +- #include +- +-+#ifdef CONFIG_COMPAT_BLUETOOTH +- #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)) +- #ifdef CONFIG_TTY +- /* +-@@ -114,4 +115,4 @@ int tty_set_termios(struct tty_struct *t +- EXPORT_SYMBOL_GPL(tty_set_termios); +- #endif /* CONFIG_TTY */ +- #endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)) */ +-- +-+#endif +diff --git a/package/mac80211/patches/050-lib80211_option.patch b/package/mac80211/patches/050-lib80211_option.patch +index 5372114..168871a 100644 +--- a/package/mac80211/patches/050-lib80211_option.patch ++++ b/package/mac80211/patches/050-lib80211_option.patch +@@ -1,6 +1,6 @@ + --- a/net/wireless/Kconfig + +++ b/net/wireless/Kconfig +-@@ -123,7 +123,7 @@ config CFG80211_WEXT ++@@ -160,7 +160,7 @@ config CFG80211_WEXT + extensions with cfg80211-based drivers. + + config LIB80211 +@@ -9,7 +9,7 @@ + depends on m + default n + help +-@@ -133,15 +133,15 @@ config LIB80211 ++@@ -170,15 +170,15 @@ config LIB80211 + Drivers should select this themselves if needed. + + config LIB80211_CRYPT_WEP diff --git a/package/mac80211/patches/060-no_local_ssb_bcma.patch b/package/mac80211/patches/060-no_local_ssb_bcma.patch -index f4b9470..95f14f4 100644 +index f4b9470..d550bba 100644 --- a/package/mac80211/patches/060-no_local_ssb_bcma.patch +++ b/package/mac80211/patches/060-no_local_ssb_bcma.patch @@ -1,6 +1,6 @@ --- a/.local-symbols +++ b/.local-symbols -@@ -379,42 +379,6 @@ USB_CDC_PHONET= -+@@ -402,42 +402,6 @@ USB_CDC_PHONET= ++@@ -403,42 +403,6 @@ USB_CDC_PHONET= USB_IPHETH= USB_SIERRA_NET= USB_VL600= +@@ -68,7 +68,7 @@ + obj-$(CPTCFG_NFC) += net/nfc/ + --- a/drivers/net/wireless/b43/main.c + +++ b/drivers/net/wireless/b43/main.c +-@@ -2734,7 +2734,7 @@ static struct ssb_device *b43_ssb_gpio_d ++@@ -2723,7 +2723,7 @@ static struct ssb_device *b43_ssb_gpio_d + { + struct ssb_bus *bus = dev->dev->sdev->bus; + +@@ -77,12 +77,12 @@ + return (bus->chipco.dev ? bus->chipco.dev : bus->pcicore.dev); + #else + return bus->chipco.dev; +-@@ -4751,7 +4751,7 @@ static int b43_wireless_core_init(struct ++@@ -4688,7 +4688,7 @@ static int b43_wireless_core_init(struct + } + if (sprom->boardflags_lo & B43_BFL_XTAL_NOSLOW) + hf |= B43_HF_DSCRQ; /* Disable slowclock requests from ucode. */ +--#ifdef CPTCFG_SSB_DRIVER_PCICORE +-+#ifdef CONFIG_SSB_DRIVER_PCICORE ++-#if defined(CPTCFG_B43_SSB) && defined(CPTCFG_SSB_DRIVER_PCICORE) +++#if defined(CPTCFG_B43_SSB) && defined(CONFIG_SSB_DRIVER_PCICORE) + if (dev->dev->bus_type == B43_BUS_SSB && + dev->dev->sdev->bus->bustype == SSB_BUSTYPE_PCI && + dev->dev->sdev->bus->pcicore.dev->id.revision <= 10) diff --git a/package/mac80211/patches/070-add-missing-header.patch b/package/mac80211/patches/070-add-missing-header.patch new file mode 100644 -index 0000000..9307804 +index 0000000..e3ec780 --- /dev/null +++ b/package/mac80211/patches/070-add-missing-header.patch @@ -0,0 +1,10 @@ +--- a/compat/backport-3.15.c ++++ b/compat/backport-3.15.c -+@@ -11,6 +11,7 @@ ++@@ -12,6 +12,7 @@ + #include + #include + #include ++#include ++ #include + -+ /** -+ * devm_kstrdup - Allocate resource managed space and ++ #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0)) diff --git a/package/mac80211/patches/100-revert_aes_ccm_port.patch b/package/mac80211/patches/100-revert_aes_ccm_port.patch -index 4654bc8..ac7d6b3 100644 +index 4654bc8..640d34e 100644 --- a/package/mac80211/patches/100-revert_aes_ccm_port.patch +++ b/package/mac80211/patches/100-revert_aes_ccm_port.patch -@@ -1,3 +1,104 @@ -+--- a/net/mac80211/wpa.c -++++ b/net/mac80211/wpa.c -+@@ -301,15 +301,22 @@ ieee80211_crypto_tkip_decrypt(struct iee -+ } -+ -+ -+-static void ccmp_special_blocks(struct sk_buff *skb, u8 *pn, u8 *b_0, u8 *aad) -++static void ccmp_special_blocks(struct sk_buff *skb, u8 *pn, u8 *scratch, -++ int encrypted) -+ { -+ __le16 mask_fc; -+ int a4_included, mgmt; -+ u8 qos_tid; -+- u16 len_a; -++ u8 *b_0, *aad; -++ u16 data_len, len_a; -+ unsigned int hdrlen; -+ struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; -+ -++ memset(scratch, 0, 6 * AES_BLOCK_SIZE); -++ -++ b_0 = scratch + 3 * AES_BLOCK_SIZE; -++ aad = scratch + 4 * AES_BLOCK_SIZE; -++ -+ /* -+ * Mask FC: zero subtype b4 b5 b6 (if not mgmt) -+ * Retry, PwrMgt, MoreData; set Protected -+@@ -331,21 +338,20 @@ static void ccmp_special_blocks(struct s -+ else -+ qos_tid = 0; -+ -+- /* In CCM, the initial vectors (IV) used for CTR mode encryption and CBC -+- * mode authentication are not allowed to collide, yet both are derived -+- * from this vector b_0. We only set L := 1 here to indicate that the -+- * data size can be represented in (L+1) bytes. The CCM layer will take -+- * care of storing the data length in the top (L+1) bytes and setting -+- * and clearing the other bits as is required to derive the two IVs. -+- */ -+- b_0[0] = 0x1; -++ data_len = skb->len - hdrlen - IEEE80211_CCMP_HDR_LEN; -++ if (encrypted) -++ data_len -= IEEE80211_CCMP_MIC_LEN; -+ -++ /* First block, b_0 */ -++ b_0[0] = 0x59; /* flags: Adata: 1, M: 011, L: 001 */ -+ /* Nonce: Nonce Flags | A2 | PN -+ * Nonce Flags: Priority (b0..b3) | Management (b4) | Reserved (b5..b7) -+ */ -+ b_0[1] = qos_tid | (mgmt << 4); -+ memcpy(&b_0[2], hdr->addr2, ETH_ALEN); -+ memcpy(&b_0[8], pn, IEEE80211_CCMP_PN_LEN); -++ /* l(m) */ -++ put_unaligned_be16(data_len, &b_0[14]); -+ -+ /* AAD (extra authenticate-only data) / masked 802.11 header -+ * FC | A1 | A2 | A3 | SC | [A4] | [QC] */ -+@@ -401,8 +407,7 @@ static int ccmp_encrypt_skb(struct ieee8 -+ u8 *pos; -+ u8 pn[6]; -+ u64 pn64; -+- u8 aad[2 * AES_BLOCK_SIZE]; -+- u8 b_0[AES_BLOCK_SIZE]; -++ u8 scratch[6 * AES_BLOCK_SIZE]; -+ -+ if (info->control.hw_key && -+ !(info->control.hw_key->flags & IEEE80211_KEY_FLAG_GENERATE_IV) && -+@@ -455,9 +460,9 @@ static int ccmp_encrypt_skb(struct ieee8 -+ return 0; -+ -+ pos += IEEE80211_CCMP_HDR_LEN; -+- ccmp_special_blocks(skb, pn, b_0, aad); -+- ieee80211_aes_ccm_encrypt(key->u.ccmp.tfm, b_0, aad, pos, len, -+- skb_put(skb, IEEE80211_CCMP_MIC_LEN)); -++ ccmp_special_blocks(skb, pn, scratch, 0); -++ ieee80211_aes_ccm_encrypt(key->u.ccmp.tfm, scratch, pos, len, -++ pos, skb_put(skb, IEEE80211_CCMP_MIC_LEN)); -+ -+ return 0; -+ } -+@@ -520,16 +525,16 @@ ieee80211_crypto_ccmp_decrypt(struct iee -+ } -+ -+ if (!(status->flag & RX_FLAG_DECRYPTED)) { -+- u8 aad[2 * AES_BLOCK_SIZE]; -+- u8 b_0[AES_BLOCK_SIZE]; -++ u8 scratch[6 * AES_BLOCK_SIZE]; -+ /* hardware didn't decrypt/verify MIC */ -+- ccmp_special_blocks(skb, pn, b_0, aad); -++ ccmp_special_blocks(skb, pn, scratch, 1); -+ -+ if (ieee80211_aes_ccm_decrypt( -+- key->u.ccmp.tfm, b_0, aad, -++ key->u.ccmp.tfm, scratch, -+ skb->data + hdrlen + IEEE80211_CCMP_HDR_LEN, -+ data_len, -+- skb->data + skb->len - IEEE80211_CCMP_MIC_LEN)) -++ skb->data + skb->len - IEEE80211_CCMP_MIC_LEN, -++ skb->data + hdrlen + IEEE80211_CCMP_HDR_LEN)) -+ return RX_DROP_UNUSABLE; -+ } -+ - --- a/net/mac80211/Kconfig - +++ b/net/mac80211/Kconfig - @@ -5,7 +5,6 @@ config MAC80211 -@@ -244,104 +345,3 @@ - u32 replays; /* dot11RSNAStatsCCMPReplays */ - } ccmp; - struct { ----- a/net/mac80211/wpa.c --+++ b/net/mac80211/wpa.c --@@ -301,16 +301,22 @@ ieee80211_crypto_tkip_decrypt(struct iee -- } -- -- ---static void ccmp_special_blocks(struct sk_buff *skb, u8 *pn, u8 *b_0, u8 *aad, --+static void ccmp_special_blocks(struct sk_buff *skb, u8 *pn, u8 *scratch, -- int encrypted) +@@ -4,7 +4,7 @@ + depends on CRYPTO + depends on CRYPTO_ARC4 + depends on CRYPTO_AES +-- depends on CRYPTO_CCM ++- select BACKPORT_CRYPTO_CCM + depends on CRC32 + select BACKPORT_AVERAGE + ---help--- +@@ -19,35 +19,17 @@ + * 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. +-@@ -19,75 +17,134 @@ ++@@ -19,76 +17,134 @@ + #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) + +static void aes_ccm_prepare(struct crypto_cipher *tfm, u8 *scratch, u8 *a) - { -- __le16 mask_fc; -- int a4_included, mgmt; -- u8 qos_tid; --- u16 len_a; --+ u8 *b_0, *aad; --+ u16 data_len, len_a; -- unsigned int hdrlen; -- struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; +-- struct scatterlist assoc, pt, ct[2]; +-- struct { +-- struct aead_request req; +-- u8 priv[crypto_aead_reqsize(tfm)]; +-- } aead_req; +-- +-- memset(&aead_req, 0, sizeof(aead_req)); +-- +-- sg_init_one(&pt, data, data_len); +-- sg_init_one(&assoc, &aad[2], be16_to_cpup((__be16 *)aad)); +-- sg_init_table(ct, 2); +-- sg_set_buf(&ct[0], data, data_len); +-- sg_set_buf(&ct[1], mic, IEEE80211_CCMP_MIC_LEN); +-- +-- aead_request_set_tfm(&aead_req.req, tfm); +-- aead_request_set_assoc(&aead_req.req, &assoc, assoc.length); +-- aead_request_set_crypt(&aead_req.req, &pt, ct, data_len, b_0); +++{ + + int i; + + u8 *b_0, *aad, *b, *s_0; - --+ memset(scratch, 0, 6 * AES_BLOCK_SIZE); --+ --+ b_0 = scratch + 3 * AES_BLOCK_SIZE; --+ aad = scratch + 4 * AES_BLOCK_SIZE; --+ -- /* -- * Mask FC: zero subtype b4 b5 b6 (if not mgmt) -- * Retry, PwrMgt, MoreData; set Protected --@@ -332,21 +338,20 @@ static void ccmp_special_blocks(struct s -- else -- qos_tid = 0; -- --- /* In CCM, the initial vectors (IV) used for CTR mode encryption and CBC --- * mode authentication are not allowed to collide, yet both are derived --- * from this vector b_0. We only set L := 1 here to indicate that the --- * data size can be represented in (L+1) bytes. The CCM layer will take --- * care of storing the data length in the top (L+1) bytes and setting --- * and clearing the other bits as is required to derive the two IVs. --- */ --- b_0[0] = 0x1; --+ data_len = skb->len - hdrlen - IEEE80211_CCMP_HDR_LEN; --+ if (encrypted) --+ data_len -= IEEE80211_CCMP_MIC_LEN; -- --+ /* First block, b_0 */ --+ b_0[0] = 0x59; /* flags: Adata: 1, M: 011, L: 001 */ -- /* Nonce: Nonce Flags | A2 | PN -- * Nonce Flags: Priority (b0..b3) | Management (b4) | Reserved (b5..b7) -- */ -- b_0[1] = qos_tid | (mgmt << 4); -- memcpy(&b_0[2], hdr->addr2, ETH_ALEN); -- memcpy(&b_0[8], pn, IEEE80211_CCMP_PN_LEN); --+ /* l(m) */ --+ put_unaligned_be16(data_len, &b_0[14]); -- -- /* AAD (extra authenticate-only data) / masked 802.11 header -- * FC | A1 | A2 | A3 | SC | [A4] | [QC] */ --@@ -402,8 +407,7 @@ static int ccmp_encrypt_skb(struct ieee8 -- u8 *pos; -- u8 pn[6]; -- u64 pn64; --- u8 aad[2 * AES_BLOCK_SIZE]; --- u8 b_0[AES_BLOCK_SIZE]; --+ u8 scratch[6 * AES_BLOCK_SIZE]; -- -- if (info->control.hw_key && -- !(info->control.hw_key->flags & IEEE80211_KEY_FLAG_GENERATE_IV) && --@@ -456,9 +460,9 @@ static int ccmp_encrypt_skb(struct ieee8 -- return 0; -- -- pos += IEEE80211_CCMP_HDR_LEN; --- ccmp_special_blocks(skb, pn, b_0, aad, 0); --- ieee80211_aes_ccm_encrypt(key->u.ccmp.tfm, b_0, aad, pos, len, --- skb_put(skb, IEEE80211_CCMP_MIC_LEN)); --+ ccmp_special_blocks(skb, pn, scratch, 0); --+ ieee80211_aes_ccm_encrypt(key->u.ccmp.tfm, scratch, pos, len, --+ pos, skb_put(skb, IEEE80211_CCMP_MIC_LEN)); -- -- return 0; +-- crypto_aead_encrypt(&aead_req.req); +++ + + b_0 = scratch + 3 * AES_BLOCK_SIZE; + + aad = scratch + 4 * AES_BLOCK_SIZE; + + b = scratch; +@@ -73,22 +55,23 @@ + + b_0[14] = 0; + + b_0[15] = 0; + + crypto_cipher_encrypt_one(tfm, s_0, b_0); - } +- +--int ieee80211_aes_ccm_decrypt(struct crypto_aead *tfm, u8 *b_0, u8 *aad, +-- u8 *data, size_t data_len, u8 *mic) +++} +++ + + + +void ieee80211_aes_ccm_encrypt(struct crypto_cipher *tfm, u8 *scratch, + + u8 *data, size_t data_len, + + u8 *cdata, u8 *mic) + { + - struct scatterlist assoc, pt, ct[2]; +-- struct { +-- struct aead_request req; +-- u8 priv[crypto_aead_reqsize(tfm)]; +-- } aead_req; +++ int i, j, last_len, num_blocks; +++ u8 *pos, *cpos, *b, *s_0, *e, *b_0; ++ ++- 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; + - +-- memset(&aead_req, 0, sizeof(aead_req)); ++- memset(aead_req, 0, sizeof(aead_req_data)); + - + - sg_init_one(&pt, data, data_len); + - sg_init_one(&assoc, &aad[2], be16_to_cpup((__be16 *)aad)); +@@ -96,13 +79,9 @@ + - sg_set_buf(&ct[0], data, data_len); + - sg_set_buf(&ct[1], mic, IEEE80211_CCMP_MIC_LEN); + - +-- aead_request_set_tfm(&aead_req.req, tfm); +-- aead_request_set_assoc(&aead_req.req, &assoc, assoc.length); +-- aead_request_set_crypt(&aead_req.req, ct, &pt, +-- data_len + IEEE80211_CCMP_MIC_LEN, b_0); +-+ int i, j, last_len, num_blocks; +-+ u8 *pos, *cpos, *b, *s_0, *e, *b_0; +-+ ++- aead_request_set_tfm(aead_req, tfm); ++- aead_request_set_assoc(aead_req, &assoc, assoc.length); ++- aead_request_set_crypt(aead_req, &pt, ct, data_len, b_0); + + b = scratch; + + s_0 = scratch + AES_BLOCK_SIZE; + + e = scratch + 2 * AES_BLOCK_SIZE; +@@ -131,30 +110,38 @@ + + *cpos++ = *pos++ ^ e[i]; + + } + +-- return crypto_aead_decrypt(&aead_req.req); ++- crypto_aead_encrypt(aead_req); + + for (i = 0; i < IEEE80211_CCMP_MIC_LEN; i++) + + mic[i] = b[i] ^ s_0[i]; + } + +--struct crypto_aead *ieee80211_aes_key_setup_encrypt(const u8 key[]) ++-int ieee80211_aes_ccm_decrypt(struct crypto_aead *tfm, u8 *b_0, u8 *aad, ++- u8 *data, size_t data_len, u8 *mic) + + + +int ieee80211_aes_ccm_decrypt(struct crypto_cipher *tfm, u8 *scratch, + + u8 *cdata, size_t data_len, u8 *mic, u8 *data) + { +-- struct crypto_aead *tfm; +-- int err; ++- struct scatterlist assoc, pt, ct[2]; ++- 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; ++- ++- memset(aead_req, 0, sizeof(aead_req_data)); ++- ++- sg_init_one(&pt, data, data_len); ++- sg_init_one(&assoc, &aad[2], be16_to_cpup((__be16 *)aad)); ++- sg_init_table(ct, 2); ++- sg_set_buf(&ct[0], data, data_len); ++- sg_set_buf(&ct[1], mic, IEEE80211_CCMP_MIC_LEN); ++- ++- aead_request_set_tfm(aead_req, tfm); ++- aead_request_set_assoc(aead_req, &assoc, assoc.length); ++- aead_request_set_crypt(aead_req, ct, &pt, ++- data_len + IEEE80211_CCMP_MIC_LEN, b_0); + + int i, j, last_len, num_blocks; + + u8 *pos, *cpos, *b, *s_0, *a, *b_0; +- +-- tfm = crypto_alloc_aead("ccm(aes)", 0, CRYPTO_ALG_ASYNC); +-- if (IS_ERR(tfm)) +-- return tfm; +-- +-- err = crypto_aead_setkey(tfm, key, WLAN_KEY_LEN_CCMP); +-- if (!err) +-- err = crypto_aead_setauthsize(tfm, IEEE80211_CCMP_MIC_LEN); +-- if (!err) +-- return tfm; +++ + + b = scratch; + + s_0 = scratch + AES_BLOCK_SIZE; + + a = scratch + 2 * AES_BLOCK_SIZE; +@@ -187,24 +174,37 @@ + + return -1; + + } + +-- crypto_free_aead(tfm); +-- return ERR_PTR(err); ++- return crypto_aead_decrypt(aead_req); + + return 0; + } + +--void ieee80211_aes_key_free(struct crypto_aead *tfm) ++-struct crypto_aead *ieee80211_aes_key_setup_encrypt(const u8 key[]) + + + +struct crypto_cipher *ieee80211_aes_key_setup_encrypt(const u8 key[]) +-+{ ++ { ++- 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; ++- ++- err = crypto_aead_setkey(tfm, key, WLAN_KEY_LEN_CCMP); ++- if (!err) ++- err = crypto_aead_setauthsize(tfm, IEEE80211_CCMP_MIC_LEN); ++- if (!err) ++- return tfm; + + tfm = crypto_alloc_cipher("aes", 0, CRYPTO_ALG_ASYNC); + + if (!IS_ERR(tfm)) + + crypto_cipher_setkey(tfm, key, WLAN_KEY_LEN_CCMP); +-+ ++ ++- crypto_free_aead(tfm); ++- return ERR_PTR(err); + + return tfm; +-+} +-+ ++ } ++ ++-void ieee80211_aes_key_free(struct crypto_aead *tfm) + + + +void ieee80211_aes_key_free(struct crypto_cipher *tfm) + { +@@ -246,13 +246,13 @@ + struct { + --- a/net/mac80211/wpa.c + +++ b/net/mac80211/wpa.c +-@@ -301,16 +301,22 @@ ieee80211_crypto_tkip_decrypt(struct iee ++@@ -301,15 +301,22 @@ ieee80211_crypto_tkip_decrypt(struct iee + } + + +--static void ccmp_special_blocks(struct sk_buff *skb, u8 *pn, u8 *b_0, u8 *aad, ++-static void ccmp_special_blocks(struct sk_buff *skb, u8 *pn, u8 *b_0, u8 *aad) + +static void ccmp_special_blocks(struct sk_buff *skb, u8 *pn, u8 *scratch, +- int encrypted) +++ int encrypted) + { + __le16 mask_fc; + int a4_included, mgmt; +@@ -271,7 +271,7 @@ + /* + * Mask FC: zero subtype b4 b5 b6 (if not mgmt) + * Retry, PwrMgt, MoreData; set Protected +-@@ -332,21 +338,20 @@ static void ccmp_special_blocks(struct s ++@@ -331,21 +338,20 @@ static void ccmp_special_blocks(struct s + else + qos_tid = 0; + +@@ -300,7 +300,7 @@ + + /* AAD (extra authenticate-only data) / masked 802.11 header + * FC | A1 | A2 | A3 | SC | [A4] | [QC] */ +-@@ -402,8 +407,7 @@ static int ccmp_encrypt_skb(struct ieee8 ++@@ -401,8 +407,7 @@ static int ccmp_encrypt_skb(struct ieee8 + u8 *pos; + u8 pn[6]; + u64 pn64; +@@ -310,11 +310,11 @@ + + if (info->control.hw_key && + !(info->control.hw_key->flags & IEEE80211_KEY_FLAG_GENERATE_IV) && +-@@ -456,9 +460,9 @@ static int ccmp_encrypt_skb(struct ieee8 ++@@ -458,9 +463,9 @@ static int ccmp_encrypt_skb(struct ieee8 + return 0; + + pos += IEEE80211_CCMP_HDR_LEN; +-- ccmp_special_blocks(skb, pn, b_0, aad, 0); ++- ccmp_special_blocks(skb, pn, b_0, aad); + - ieee80211_aes_ccm_encrypt(key->u.ccmp.tfm, b_0, aad, pos, len, + - skb_put(skb, IEEE80211_CCMP_MIC_LEN)); + + ccmp_special_blocks(skb, pn, scratch, 0); +@@ -323,7 +323,7 @@ + + return 0; + } -@@ -521,16 +525,16 @@ ieee80211_crypto_ccmp_decrypt(struct iee -- } -- -- if (!(status->flag & RX_FLAG_DECRYPTED)) { --- u8 aad[2 * AES_BLOCK_SIZE]; --- u8 b_0[AES_BLOCK_SIZE]; --+ u8 scratch[6 * AES_BLOCK_SIZE]; -- /* hardware didn't decrypt/verify MIC */ ++@@ -523,16 +528,16 @@ ieee80211_crypto_ccmp_decrypt(struct iee + } + + if (!(status->flag & RX_FLAG_DECRYPTED)) { +@@ -331,7 +331,7 @@ + - u8 b_0[AES_BLOCK_SIZE]; + + u8 scratch[6 * AES_BLOCK_SIZE]; + /* hardware didn't decrypt/verify MIC */ -- ccmp_special_blocks(skb, pn, b_0, aad, 1); --+ ccmp_special_blocks(skb, pn, scratch, 1); -- -- if (ieee80211_aes_ccm_decrypt( --- key->u.ccmp.tfm, b_0, aad, --+ key->u.ccmp.tfm, scratch, -- skb->data + hdrlen + IEEE80211_CCMP_HDR_LEN, -- data_len, --- skb->data + skb->len - IEEE80211_CCMP_MIC_LEN)) --+ skb->data + skb->len - IEEE80211_CCMP_MIC_LEN, --+ skb->data + hdrlen + IEEE80211_CCMP_HDR_LEN)) -- return RX_DROP_UNUSABLE; -- } -- ++- ccmp_special_blocks(skb, pn, b_0, aad); + + ccmp_special_blocks(skb, pn, scratch, 1); + + if (ieee80211_aes_ccm_decrypt( diff --git a/package/mac80211/patches/150-disable_addr_notifier.patch b/package/mac80211/patches/150-disable_addr_notifier.patch -index 7b50154..3f749e9 100644 +index 7b50154..c80b2bb 100644 --- a/package/mac80211/patches/150-disable_addr_notifier.patch +++ b/package/mac80211/patches/150-disable_addr_notifier.patch +@@ -1,6 +1,6 @@ + --- a/net/mac80211/main.c + +++ b/net/mac80211/main.c +-@@ -287,7 +287,7 @@ void ieee80211_restart_hw(struct ieee802 ++@@ -285,7 +285,7 @@ void ieee80211_restart_hw(struct ieee802 + } + EXPORT_SYMBOL(ieee80211_restart_hw); + +@@ -9,7 +9,7 @@ + static int ieee80211_ifa_changed(struct notifier_block *nb, + unsigned long data, void *arg) + { +-@@ -346,7 +346,7 @@ static int ieee80211_ifa_changed(struct ++@@ -344,7 +344,7 @@ static int ieee80211_ifa_changed(struct + } + #endif + @@ -18,7 +18,7 @@ static int ieee80211_ifa6_changed(struct notifier_block *nb, unsigned long data, void *arg) { -@@ -1031,14 +1031,14 @@ int ieee80211_register_hw(struct ieee802 -+@@ -1036,14 +1036,14 @@ int ieee80211_register_hw(struct ieee802 ++@@ -1034,14 +1034,14 @@ int ieee80211_register_hw(struct ieee802 goto fail_pm_qos; } @@ -1927,7 +2126,7 @@ index 7b50154..3f749e9 100644 result = register_inet6addr_notifier(&local->ifa6_notifier); if (result) -@@ -1047,13 +1047,13 @@ int ieee80211_register_hw(struct ieee802 -+@@ -1052,13 +1052,13 @@ int ieee80211_register_hw(struct ieee802 ++@@ -1050,13 +1050,13 @@ int ieee80211_register_hw(struct ieee802 return 0; @@ -1936,31 +2135,41 @@ index 7b50154..3f749e9 100644 pm_qos_remove_notifier(PM_QOS_NETWORK_LATENCY, &local->network_latency_notifier); -@@ -1086,10 +1086,10 @@ void ieee80211_unregister_hw(struct ieee -+@@ -1103,10 +1103,10 @@ void ieee80211_unregister_hw(struct ieee ++@@ -1101,10 +1101,10 @@ void ieee80211_unregister_hw(struct ieee pm_qos_remove_notifier(PM_QOS_NETWORK_LATENCY, &local->network_latency_notifier); diff --git a/package/mac80211/patches/300-pending_work.patch b/package/mac80211/patches/300-pending_work.patch -index a1af6c2..892f51e 100644 +index a1af6c2..dc1e265 100644 --- a/package/mac80211/patches/300-pending_work.patch +++ b/package/mac80211/patches/300-pending_work.patch -@@ -1,4153 +1,543 @@ +@@ -1,4153 +1,4383 @@ -commit 93f310a38a1d81a4bc8fcd9bf29628bd721cf2ef --Author: Felix Fietkau ++commit ff9655bebd25d35ab13c2515a029723b69949720 + Author: Felix Fietkau -Date: Sun Apr 6 23:35:28 2014 +0200 -- ++Date: Mon May 19 21:20:49 2014 +0200 + - ath9k_hw: reduce ANI firstep range for older chips -- ++ ath9k: avoid passing buffers to the hardware during flush + - Use 0-8 instead of 0-16, which is closer to the old implementation. - Also drop the overwrite of the firstep_low parameter to improve - stability. -- -- Signed-off-by: Felix Fietkau -- ++ The commit "ath9k: fix possible hang on flush" changed the receive code ++ to always link rx descriptors of processed frames, even when flushing. ++ In some cases, this leads to flushed rx buffers being passed to the ++ hardware while rx is already stopped. + + Signed-off-by: Felix Fietkau + -commit 584d297fd29fb39c76af25ae74ff9d5fe74c8a14 -Author: Helmut Schaa -Date: Wed Mar 12 10:37:55 2014 +0100 -- ++commit 46c5d7d207a2a0725066c0928fd19b8c578b7d4f ++Author: Oleksij Rempel ++Date: Tue May 20 00:02:03 2014 +0200 + - ath9k: Fix sequence number assignment for non-data frames - - Since commit 558ff225de80ac95b132d3a115ddadcd64498b4f (ath9k: fix @@ -2012,10 +2221,7 @@ index a1af6c2..892f51e 100644 - old table). - - Signed-off-by: Felix Fietkau -+commit 4c8a3486cb577d40c1ef75f0a8dc9a04773eef83 -+Author: Nickolay Ledovskikh -+Date: Fri Apr 25 22:53:34 2014 +0400 - +- -commit c977493766310a825f406836636ffd66e1447783 -Author: Felix Fietkau -Date: Mon Mar 10 19:52:56 2014 +0100 @@ -2034,74 +2240,45 @@ index a1af6c2..892f51e 100644 -Date: Sun Mar 9 11:25:43 2014 +0100 - - ath9k: clean up and enhance ANI debugfs file -+ ath5k: Fix AR5K_PHY_TXPOWER_RATE_MAX register value setting. - +- - Unify scnprintf calls and include the current OFDM/CCK immunity level. -+ I was reading ath5k power setting code and -+ noticed typing error in ath5k_hw_txpower function. -+ Invalid value was written to AR5K_PHY_TXPOWER_RATE_MAX -+ register. - +- - Signed-off-by: Felix Fietkau -+ Signed-off-by: Nikolay Ledovskikh -+ Acked-by: Nick Kossifidis -+ Signed-off-by: John W. Linville - +- -commit 22e298b5a3a8a49e33805d4e351965123dede35b -Author: Felix Fietkau -Date: Sun Mar 9 10:58:47 2014 +0100 -+commit 4d76248013dbb1948429555208900a585b0f351d -+Author: Janusz Dziedzic -+Date: Tue Apr 8 13:38:43 2014 +0200 - +- - ath9k: fix ready time of the multicast buffer queue - - qi->tqi_readyTime is written directly to registers that expect - microseconds as unit instead of TU. - When setting the CABQ ready time, cur_conf->beacon_interval is in TU, so - convert it to microseconds before passing it to ath9k_hw. -+ ath9k: Enable DFS only when ATH9K_DFS_CERTIFIED - +- - This should hopefully fix some Tx DMA issues with buffered multicast - frames in AP mode. -+ Add DFS interface combination only when -+ CONFIG_ATH9K_DFS_CERTIFIED is set. In other case -+ user can run CAC/beaconing without proper handling -+ of pulse events (without radar detection activated). - +- - Cc: stable@vger.kernel.org - Signed-off-by: Felix Fietkau -+ Reported-by: Cedric Voncken -+ Signed-off-by: Janusz Dziedzic -+ Signed-off-by: John W. Linville - +- -commit fcb064fdd5a27bec8d24099bc0172468f34c97cb -Author: Felix Fietkau -Date: Sun Mar 9 09:43:09 2014 +0100 -+commit c83a4e5156a4b4dd22137d33a5625440982d6d37 -+Author: Rajkumar Manoharan -+Date: Mon Apr 28 21:17:08 2014 +0530 - +- - ath9k_hw: fix unreachable code in baseband hang detection code -+ ath9k_hw: fix worse EVM for 11b rates - +- - The commit "ath9k: reduce baseband hang detection false positive rate" - added a delay in the loop checking the baseband state, however it was - unreachable due to previous 'continue' statements. -+ Adjust FIR filter co-efficients to improve EVM for 11b rates. - +- - Reported-by: Dan Carpenter - Signed-off-by: Felix Fietkau -+ Signed-off-by: Rajkumar Manoharan -+ Signed-off-by: John W. Linville - +- -commit 31959d8df39319e32c6d5ba9c135727be90cfad7 -Author: Michal Kazior -Date: Fri Mar 7 08:09:38 2014 +0100 -+commit 8aab2c7a2f4a957e344db429dfb1190ae59ce8b5 -+Author: Rajkumar Manoharan -+Date: Mon Apr 28 21:17:07 2014 +0530 - +- - mac80211: fix possible NULL dereference - - If chanctx is missing on a given vif then the band @@ -2113,37 +2290,23 @@ index a1af6c2..892f51e 100644 - - [ 4605.207223] BUG: unable to handle kernel NULL pointer dereference at 0000000000000018 - [ 4605.210789] IP: [] ieee80211_parse_bitrates+0x65/0x110 [mac80211] -+ ath9k_hw: update ar9300 initvals - +- - The splat was preceeded by WARN_ON(!chanctx_conf) - in ieee80211_get_sdata_band(). -+ * rfsat gainchange hysteresis of rf_gain stuck with large -+ interference present. - +- - Signed-off-by: Michal Kazior -+ Signed-off-by: Rajkumar Manoharan -+ Signed-off-by: John W. Linville - +- -commit 6c5a3ffa0a2d22c091a2717f427259bacf77ac5e -Author: Michael Braun -Date: Thu Mar 6 15:08:43 2014 +0100 -+commit 8c7ae357cc5b6bd037ad2d666e9f3789cf882925 -+Author: Rajkumar Manoharan -+Date: Wed Apr 23 15:07:57 2014 +0530 - +- - mac80211: fix WPA with VLAN on AP side with ps-sta again -+ ath9k: fix race in setting ATH_OP_INVALID - +- - commit de74a1d9032f4d37ea453ad2a647e1aff4cd2591 - "mac80211: fix WPA with VLAN on AP side with ps-sta" - fixed an issue where queued multicast packets would - be sent out encrypted with the key of an other bss. -+ The commit "ath9k: move sc_flags to ath_common" moved setting -+ ATH_OP_INVALID flag below ieee80211_register_hw. This is causing -+ the flag never being cleared randomly as the drv_start is called -+ prior to setting flag. Fix this by setting the flag prior to -+ register_hw. - +- - commit "7cbf9d017dbb5e3276de7d527925d42d4c11e732" - "mac80211: fix oops on mesh PS broadcast forwarding" - essentially reverted it, because vif.type cannot be AP_VLAN @@ -2160,109 +2323,92 @@ index a1af6c2..892f51e 100644 - Cc: - Cc: - Signed-off-by: Michael Braun -+ Signed-off-by: Rajkumar Manoharan -+ Signed-off-by: John W. Linville ++ ath9k_htc: fix build with disabled debug ++ ++ CC [M] drivers/net/wireless/ath/ath9k/htc_drv_txrx.o ++ drivers/net/wireless/ath/ath9k/htc_drv_txrx.c: In function ‘ath9k_rx_prepare’: ++ drivers/net/wireless/ath/ath9k/htc_drv_txrx.c:1006:2: warning: passing argument 2 of ‘ath9k_htc_err_stat_rx’ from incompatible pointer type [enabled by default] ++ ath9k_htc_err_stat_rx(priv, &rx_stats); ++ ^ ++ In file included from drivers/net/wireless/ath/ath9k/htc_drv_txrx.c:17:0: ++ drivers/net/wireless/ath/ath9k/htc.h:380:20: note: expected ‘struct ath_htc_rx_status *’ but argument is of type ‘struct ath_rx_status *’ ++ static inline void ath9k_htc_err_stat_rx(struct ath9k_htc_priv *priv, ++ ++ Signed-off-by: Oleksij Rempel -commit 9d6ab9bdb9b368a6cf9519f0f92509b5b2c297ec --Author: Johannes Berg ++commit 2d331334e9dc5659fdf9a89326c34c3db5a15279 + Author: Johannes Berg -Date: Mon Mar 3 14:19:08 2014 +0100 -+commit c82552c5b0cb1735dbcbad78b1ffc6d3c212dc56 -+Author: Tim Harvey -+Date: Mon Apr 21 16:14:57 2014 -0700 ++Date: Mon May 19 17:59:50 2014 +0200 - cfg80211: remove racy beacon_interval assignment -+ ath9k: add a recv budget ++ cfg80211: constify wowlan/coalesce mask/pattern pointers - In case of AP mode, the beacon interval is already reset to - zero inside cfg80211_stop_ap(), and in the other modes it - isn't relevant. Remove the assignment to remove a potential - race since the assignment isn't properly locked. -+ Implement a recv budget so that in cases of high traffic we still allow other -+ taskets to get processed. ++ This requires changing the nl80211 parsing code a bit to use ++ intermediate pointers for the allocation, but clarifies the ++ API towards the drivers. - Reported-by: Michal Kazior -- Signed-off-by: Johannes Berg -- + Signed-off-by: Johannes Berg + -commit 1abdeca3c6fb9cf1f84f85e78ed8d1c33bd69db0 -Author: Felix Fietkau -Date: Fri Feb 28 18:52:56 2014 +0100 - - ath9k_hw: tweak noise immunity thresholds for older chipsets -+ Without this, we can encounter a host of issues during high wireless traffic -+ reception depending on system load including rcu stall's detected (ARM), -+ soft lockups, failure to service critical tasks such as watchdog resets, -+ and triggering of the tx stuck tasklet. - +- - Older chipsets are more sensitive to high PHY error counts, and the - current noise immunity thresholds were based on tests run at QCA with - newer chipsets. -+ The same thing was proposed previously by Ben: -+ http://www.spinics.net/lists/linux-wireless/msg112891.html - +- - This patch brings back the values from the old ANI implementation for - old chipsets, and it also disables weak signal detection on an earlier - noise immunity level, to improve overall radio stability on affected - devices. -+ The only difference here is that I make sure only processed packets are counted -+ in the budget by checking at the end of the rx loop. - +- - Signed-off-by: Felix Fietkau -+ Signed-off-by: Tim Harvey -+ Acked-by: Felix Fietkau -+ Signed-off-by: John W. Linville - +- -commit 431e506da5953adc3b65af25f4b90873d528c115 -Author: Felix Fietkau -Date: Fri Feb 28 18:44:13 2014 +0100 -+commit 3a758134e66ca74a9df792616b5288b2fa2cfd7f -+Author: Tim Harvey -+Date: Mon Apr 21 16:14:56 2014 -0700 - +- - ath9k_hw: toggle weak signal detection in AP mode on older chipsets - - The commit 80b4205b "ath9k: Fix OFDM weak signal detection for AP mode" - prevented weak signal detection changes from taking effect in AP mode on - all chipsets, claiming it is "not allowed". -+ ath9k: fix possible hang on flush - +- - The main reason for not disabling weak signal detection in AP mode is - that typically beacon RSSI is used to track whether it is needed to - boost range, and this is unavailable in AP mode for obvious reasons. -+ If a flush is requested, make sure to clear the descriptor once we've -+ processed it. - +- - The problem with not disabling weak signal detection is that older - chipsets are very sensitive to high PHY error counts. When faced with - heavy noise, this can lead to an excessive amount of "Failed to stop - TX DMA" errors in the field. -+ This resolves a hang that will occur if all RX descriptors are full when a -+ flush is requested. - +- - Signed-off-by: Felix Fietkau -+ Signed-off-by: Tim Harvey -+ Acked-by: Felix Fietkau -+ Signed-off-by: John W. Linville - +- -commit 98d1a6c5b14688ed030e81b889f607be308e0df9 -+commit eefb1d6adc4c60d219182b8917e4567484ce07fc - Author: Felix Fietkau +-Author: Felix Fietkau -Date: Mon Feb 24 22:20:32 2014 +0100 -+Date: Mon Apr 28 18:27:41 2014 +0200 - +- - ath9k: fix invalid descriptor discarding - - Only set sc->rx.discard_next to rx_stats->rs_more when actually - discarding the current descriptor. -+ ath9k: remove tid->paused flag - +- - Also, fix a detection of broken descriptors: - First the code checks if the current descriptor is not done. - Then it checks if the next descriptor is done. - Add a check that afterwards checks the first descriptor again, because - it might have been completed in the mean time. -+ There are some corner cases where the driver could get stuck with a full -+ tid queue that is paused, leading to a software tx queue hang. - +- - This fixes a regression introduced in - commit 723e711356b5a8a95728a890e254e8b0d47b55cf - "ath9k: fix handling of broken descriptors" @@ -2276,26 +2422,18 @@ index a1af6c2..892f51e 100644 -Date: Mon Feb 24 11:43:50 2014 +0100 - - ath9k: reduce baseband hang detection false positive rate -+ Since the tx queueing rework, pausing per-tid queues on aggregation -+ session setup is no longer necessary. The driver will assign sequence -+ numbers to buffered frames when a new session is established, in order -+ to get the correct starting sequence number. - +- - Check if the baseband state remains stable, and add a small delay - between register reads. -+ mac80211 prevents new frames from entering the queue during setup. - - Signed-off-by: Felix Fietkau - +- +- Signed-off-by: Felix Fietkau +- -commit 118945bb12082e9d4edddc868d88143164e0f440 -+commit 98a713933d8495f4078f561c1e651b738dd5b531 - Author: Felix Fietkau +-Author: Felix Fietkau -Date: Sat Feb 22 14:55:23 2014 +0100 -+Date: Sun Apr 27 14:49:03 2014 +0200 - +- - ath5k: set SURVEY_INFO_IN_USE on get_survey -+ ath9k_hw: do not lower ANI setting below default on AR913x - +- - Only one channel is returned - the one currently being used. - - Signed-off-by: Felix Fietkau @@ -2305,88 +2443,65 @@ index a1af6c2..892f51e 100644 -Date: Sat Feb 22 14:44:52 2014 +0100 - - ath9k: make some hardware reset log messages debug-only -+ When the amount of noise fluctuates strongly, low immunity settings -+ can sometimes disrupt signal detection on AR913x chips. When that -+ happens, no OFDM/CCK errors are reported anymore, and ANI tunes the -+ radio to the lowest immunity settings. -+ Usually rx/tx fails as well in that case. - +- - On some chips, baseband watchdog hangs are more common than others, and - the driver has support for handling them. - Interrupts even after a watchdog hang are also quite common, so there's - not much point in spamming the user's logfiles. -+ To fix this, keep noise immunity settings at or above ANI default level, -+ which will keep radio parameters at or above INI values. - - Signed-off-by: Felix Fietkau - +- +- Signed-off-by: Felix Fietkau +- -commit b14fbb554fc65a2e0b5c41a319269b0350f187e7 -+commit 7cbb4c021bfd1e656f5b9953a947ab3c64e4e3b0 - Author: Felix Fietkau +-Author: Felix Fietkau -Date: Sat Feb 22 14:35:25 2014 +0100 -+Date: Thu Apr 10 10:49:01 2014 +0200 - +- - ath9k: do not set half/quarter channel flags in AR_PHY_MODE - - 5/10 MHz channel bandwidth is configured via the PLL clock, instead of - the AR_PHY_MODE register. Using that register is AR93xx specific, and - makes the mode incompatible with earlier chipsets. -+ mac80211: exclude AP_VLAN interfaces from tx power calculation - +- - In some early versions, these flags were apparently applied at the wrong - point in time and thus did not cause connectivity issues, however now - they are causing problems, as pointed out in this OpenWrt ticket: - - https://dev.openwrt.org/ticket/14916 -+ Their power value is initialized to zero. This patch fixes an issue -+ where the configured power drops to the minimum value when AP_VLAN -+ interfaces are created/removed. - -+ Cc: stable@vger.kernel.org - Signed-off-by: Felix Fietkau - +- +- Signed-off-by: Felix Fietkau +- -commit 0f1cb7be2551b30b02cd54c897e0e29e483cfda5 -+commit 0ca13e26341733bf9577287fb04a3bef0d2f5cc9 - Author: Felix Fietkau +-Author: Felix Fietkau -Date: Sat Feb 22 13:43:29 2014 +0100 -+Date: Wed Apr 9 00:07:01 2014 +0200 - +- - ath9k: fix ps-poll responses under a-mpdu sessions -+ mac80211: suppress BSS info change notifications for AP_VLAN - +- - When passing tx frames to the U-APSD queue for powersave poll responses, - the ath_atx_tid pointer needs to be passed to ath_tx_setup_buffer for - proper sequence number accounting. -+ Fixes warnings on tx power changes - +- - This fixes high latency and connection stability issues with ath9k - running as AP and a few kinds of mobile phones as client, when PS-Poll - is heavily used - - Cc: stable@vger.kernel.org - Signed-off-by: Felix Fietkau - --commit d5d87a37bbd6066b2c3c5d0bd0fe2a6e2ea45cc5 -+commit ec998e5991781ecdaad0911dc64f1c8d3749c308 - Author: Felix Fietkau --Date: Fri Feb 21 11:39:59 2014 +0100 -+Date: Tue Apr 8 23:42:17 2014 +0200 - -- ath9k: list more reset causes in debugfs -+ ath9k: fix a scheduling while atomic bug in CSA handling - -- Number of MAC hangs and stuck beacons were missing -+ Commit "ath9k: prepare for multi-interface CSA support" added a call to -+ ieee80211_iterate_active_interfaces in atomic context (beacon tasklet), -+ which is crashing. -+ Use ieee80211_iterate_active_interfaces_atomic instead. - - Signed-off-by: Felix Fietkau - --commit d84856012e0f10fe598a5ad3b7b869397a089e07 --Author: Johannes Berg --Date: Thu Feb 20 11:19:58 2014 +0100 +- Signed-off-by: Felix Fietkau - +-commit d5d87a37bbd6066b2c3c5d0bd0fe2a6e2ea45cc5 +-Author: Felix Fietkau +-Date: Fri Feb 21 11:39:59 2014 +0100 +- +- ath9k: list more reset causes in debugfs +- +- Number of MAC hangs and stuck beacons were missing +- +- Signed-off-by: Felix Fietkau +- +-commit d84856012e0f10fe598a5ad3b7b869397a089e07 ++commit 6788105c46babaa6938cbacb72fdf20bec4bb2e3 + Author: Johannes Berg +-Date: Thu Feb 20 11:19:58 2014 +0100 ++Date: Mon May 19 17:53:16 2014 +0200 + - mac80211: fix station wakeup powersave race - - Consider the following (relatively unlikely) scenario: @@ -2404,24 +2519,32 @@ index a1af6c2..892f51e 100644 - As a result, no frames will be delivered to the client, even - though it is awake, until it sends another frame to us that - triggers ieee80211_sta_ps_deliver_wakeup() in sta_ps_end(). -- ++ cfg80211: constify more pointers in the cfg80211 API + - Since we now take the PS spinlock, we can fix this while at - the same time removing the complexity with the pending skb - queue function. This was broken since my commit 50a9432daeec - ("mac80211: fix powersaving clients races") due to removing - the clearing of WLAN_STA_PS_STA in the RX path. -- ++ This also propagates through the drivers. + - While at it, fix a cleanup path issue when a station is - removed while the driver is still blocking its wakeup. -- -- Signed-off-by: Johannes Berg -- ++ The orinoco driver uses the cfg80211 API structs for internal ++ bookkeeping, and so needs a (void *) cast that removes the ++ const - but that's OK because it allocates those pointers. + + Signed-off-by: Johannes Berg + -commit 798f2786602cbe93e6b928299614aa36ebf50692 --Author: Johannes Berg ++commit c3d95010fd881da0fa0a4e88532412f5d0c092f6 + Author: Johannes Berg -Date: Mon Feb 17 20:49:03 2014 +0100 -- ++Date: Mon May 19 17:19:31 2014 +0200 + - mac80211: insert stations before adding to driver -- ++ cfg80211: constify MAC addresses in cfg80211 ops + - There's a race condition in mac80211 because we add stations - to the internal lists after adding them to the driver, which - means that (for example) the following can happen: @@ -2443,13 +2566,17 @@ index a1af6c2..892f51e 100644 - driver fails to add the station, in that case a bit more is - needed. To not make that overly complex prevent starting BA - sessions in the meantime. -- -- Signed-off-by: Johannes Berg -- ++ This propagates through all the drivers and mac80211. + + Signed-off-by: Johannes Berg + -commit b9ba6a520cb07ab3aa7aaaf9ce4a0bc7a6bc06fe -Author: Emmanuel Grumbach -Date: Thu Feb 20 09:22:11 2014 +0200 -- ++commit ddf1e6f0f0354c601af7d42e5ace4b51f8b0bffc ++Author: Luciano Coelho ++Date: Thu May 15 20:32:08 2014 +0300 + - mac80211: fix AP powersave TX vs. wakeup race - - There is a race between the TX path and the STA wakeup: while @@ -2457,18 +2584,24 @@ index a1af6c2..892f51e 100644 - up, then the frames are transmitted. However, the RX and TX - path are concurrent, so the packet indicating wakeup can be - processed while a packet is being transmitted. -- ++ mac80211: fix csa_counter_offs argument name in docbook + - This can lead to a situation where the buffered frames list - is emptied on the one side, while a frame is being added on - the other side, as the station is still seen as sleeping in - the TX path. -- ++ The csa_counter_offs was erroneously described as csa_offs in ++ the docbook section. + - As a result, the newly added frame will not be send anytime - soon. It might be sent much later (and out of order) when the - station goes to sleep and wakes up the next time. -- ++ This fixes two warnings when making htmldocs (at least): + - Additionally, it can lead to the crash below. -- ++ Warning(include/net/mac80211.h:3428): No description found for parameter 'csa_counter_offs[IEEE80211_MAX_CSA_COUNTERS_NUM]' ++ Warning(include/net/mac80211.h:3428): Excess struct/union/enum/typedef member 'csa_offs' description in 'ieee80211_mutable_offsets' + - Fix all this by synchronising both paths with a new lock. - Both path are not fastpath since they handle PS situations. - @@ -2523,8 +2656,9 @@ index a1af6c2..892f51e 100644 - when the status is not "IGNORE" nor "ALREADY_SET". - - Signed-off-by: Inbal Hacohen -- Signed-off-by: Johannes Berg -- ++ Signed-off-by: Luciano Coelho + Signed-off-by: Johannes Berg + -commit 6514c93afede55284e2cb63359aadedb85884c80 -Author: Jouni Malinen -Date: Tue Feb 18 20:41:08 2014 +0200 @@ -2540,13 +2674,19 @@ index a1af6c2..892f51e 100644 -commit a63caf0a357ad5c1f08d6b7827dc76c451445017 -Author: Stanislaw Gruszka -Date: Wed Feb 19 13:15:17 2014 +0100 -- ++commit 202322d1c04b8e498bd5bb78606fcf3941512b35 ++Author: Luciano Coelho ++Date: Thu May 15 20:18:09 2014 +0300 + - ath9k: protect tid->sched check -- ++ cfg80211: add documentation for max_num_csa_counters + - We check tid->sched without a lock taken on ath_tx_aggr_sleep(). That - is race condition which can result of doing list_del(&tid->list) twice - (second time with poisoned list node) and cause crash like shown below: -- ++ Move the comment in the structure to a description of the ++ max_num_csa_counters field in the docbook area. + - [424271.637220] BUG: unable to handle kernel paging request at 00100104 - [424271.637328] IP: [] ath_tx_aggr_sleep+0x62/0xe0 [ath9k] - ... @@ -2569,37 +2709,46 @@ index a1af6c2..892f51e 100644 - [424271.641266] [] ath_rx_tasklet+0x88e/0xf70 [ath9k] - [424271.641358] [] ? ieee80211_rx+0x1dc/0x7c0 [mac80211] - [424271.641445] [] ath9k_tasklet+0xcb/0x130 [ath9k] -- ++ This fixes a warning when building htmldocs (at least): + - Bug report: - https://bugzilla.kernel.org/show_bug.cgi?id=70551 -- ++ Warning(include/net/cfg80211.h:3064): No description found for parameter 'max_num_csa_counters' + - Reported-and-tested-by: Max Sydorenko - Cc: stable@vger.kernel.org - Signed-off-by: Stanislaw Gruszka -- ++ Signed-off-by: Luciano Coelho ++ Signed-off-by: Johannes Berg + -commit 82ed9e3ccc02797df2ffe4b78127c4cd5f799a41 -+commit 93f310a38a1d81a4bc8fcd9bf29628bd721cf2ef - Author: Felix Fietkau +-Author: Felix Fietkau -Date: Tue Feb 11 15:54:13 2014 +0100 -+Date: Sun Apr 6 23:35:28 2014 +0200 ++commit 457a33192f64b7637e8fd0ae0e9f32701c908603 ++Author: Johannes Berg ++Date: Mon May 19 11:24:19 2014 +0200 - mac80211: send control port protocol frames to the VO queue -+ ath9k_hw: reduce ANI firstep range for older chips ++ mac80211: minstrel-ht: small clarifications - Improves reliability of wifi connections with WPA, since authentication - frames are prioritized over normal traffic and also typically exempt - from aggregation. -+ Use 0-8 instead of 0-16, which is closer to the old implementation. -+ Also drop the overwrite of the firstep_low parameter to improve -+ stability. ++ Antonio and I were looking over this code and some things ++ didn't immediately make sense, so we came up with two small ++ clarifications. - Cc: stable@vger.kernel.org - Signed-off-by: Felix Fietkau +- Signed-off-by: Felix Fietkau ++ Signed-off-by: Johannes Berg -commit d4426800f71e972feaa33e04c5801fc730627bdd -Author: Stanislaw Gruszka -Date: Mon Feb 10 22:38:28 2014 +0100 -- ++commit 1e35dce952a64a957de97ae1f2bb19301756b936 ++Author: Andrei Otcheretianski ++Date: Fri May 9 14:11:50 2014 +0300 + - rtl8187: fix regression on MIPS without coherent DMA - - This patch fixes regression caused by commit a16dad77634 "MIPS: Fix @@ -2626,44 +2775,77 @@ index a1af6c2..892f51e 100644 - reproducible regression and seems other possible corruptions do not - happen in practice, since Yeeloong laptop works stable without rtl8187 - driver. -- ++ mac80211: Handle the CSA counters correctly + - Bug report: - https://bugzilla.kernel.org/show_bug.cgi?id=54391 -- ++ Make the beacon CSA counters part of ieee80211_mutable_offsets and don't ++ decrement CSA counters when generating a beacon template. This permits the ++ driver to offload the CSA counters handling. Since mac80211 updates the probe ++ responses with the correct counter, the driver should sync the counter's value ++ with mac80211 using ieee80211_csa_update_counter function. + - Reported-by: Petr Pisar - Bisected-by: Tom Li - Reported-and-tested-by: Tom Li - Cc: stable@vger.kernel.org - Signed-off-by: Stanislaw Gruszka -- ++ Signed-off-by: Andrei Otcheretianski ++ Signed-off-by: Luciano Coelho ++ Signed-off-by: Johannes Berg + -commit e2f141d67ad1e7fe10aaab61811e8a409dfb2442 -Author: Sujith Manoharan -Date: Fri Feb 7 10:29:55 2014 +0530 -- ++commit e7b5c449815d28a2105fde5b42e112f78cc711ac ++Author: Andrei Otcheretianski ++Date: Fri May 9 14:11:49 2014 +0300 + - ath9k: Calculate IQ-CAL median -- ++ mac80211: Provide ieee80211_beacon_get_template API + - This patch adds a routine to calculate the median IQ correction - values for AR955x, which is used for outlier detection. - The normal method which is used for all other chips is - bypassed for AR955x. -- ++ Add a new API ieee80211_beacon_get_template, which doesn't ++ affect DTIM counter and should be used if the device generates beacon ++ frames, and new beacon template is needed. In addition set the offsets ++ to TIM IE for MESH interface. + - Signed-off-by: Sujith Manoharan -- ++ Signed-off-by: Andrei Otcheretianski ++ Signed-off-by: Luciano Coelho ++ Signed-off-by: Johannes Berg + -commit c52a6fce0820c8d0687443ab86058ae03b478c8f -Author: Sujith Manoharan -Date: Fri Feb 7 10:29:54 2014 +0530 -- ++commit e54eda80273ce8aded058c3c9365dca2342e2e75 ++Author: Andrei Otcheretianski ++Date: Fri May 9 14:11:47 2014 +0300 + - ath9k: Expand the IQ coefficient array -- ++ mac80211: Support multiple CSA counters + - This will be used for storing data for mutiple - IQ calibration runs, for AR955x. -- ++ Support up to IEEE80211_MAX_CSA_COUNTERS_NUM csa counters. ++ This is defined to be 2 now, to support both CSA and eCSA ++ counters. + - Signed-off-by: Sujith Manoharan -- ++ Signed-off-by: Andrei Otcheretianski ++ Signed-off-by: Luciano Coelho ++ Signed-off-by: Johannes Berg + -commit 034969ff5c2b6431d10e07c1938f0b916da85cc3 -Author: Sujith Manoharan -Date: Fri Feb 7 10:29:53 2014 +0530 -- ++commit 678e87c3b929dd60d59470e8981eb551cee10319 ++Author: Andrei Otcheretianski ++Date: Fri May 9 14:11:46 2014 +0300 + - ath9k: Modify IQ calibration for AR955x - - IQ calibration post-processing for AR955x is different @@ -2679,25 +2861,53 @@ index a1af6c2..892f51e 100644 - in subsequent patches) is set to zero. - - Signed-off-by: Sujith Manoharan -- ++ cfg80211: Support multiple CSA counters ++ ++ Change the type of NL80211_ATTR_CSA_C_OFF_BEACON and ++ NL80211_ATTR_CSA_C_OFF_PRESP to be NLA_BINARY which allows ++ userspace to use beacons and probe responses with ++ multiple CSA counters. ++ This isn't breaking the API since userspace can ++ continue to use nla_put_u16 for this attributes, which ++ is equivalent to a single element u16 array. ++ In addition advertise max number of supported CSA counters. ++ This is needed when using CSA and eCSA IEs together. ++ ++ Signed-off-by: Andrei Otcheretianski ++ Signed-off-by: Luciano Coelho ++ Signed-off-by: Johannes Berg + -commit 9b1ed6454e6f3511f24266be99b4e403f243f6a8 -Author: Sujith Manoharan -Date: Fri Feb 7 10:29:52 2014 +0530 -- ++commit 93f4867a966cc8645659031bbd44a9bb4b78485f ++Author: Andrei Otcheretianski ++Date: Fri May 9 14:11:45 2014 +0300 + - ath9k: Fix magnitude/phase calculation -- ++ mac80211: Update CSA counters in mgmt frames + - Incorrect values are programmed in the registers - containing the IQ correction coefficients by the IQ-CAL - post-processing code. Fix this. -- ++ Track current csa counter value and use it ++ to update mgmt frames at the provided offsets. + - Signed-off-by: Sujith Manoharan -- ++ Signed-off-by: Andrei Otcheretianski ++ Signed-off-by: Luciano Coelho ++ Signed-off-by: Johannes Berg + -commit 36f93484f96f79171dcecb67c5ef0c3de22531a6 -Author: Sujith Manoharan -Date: Fri Feb 7 10:29:51 2014 +0530 -- ++commit 6c8461fcc03ff4d250027e47f53315b5e0ec43aa ++Author: Andrei Otcheretianski ++Date: Fri May 9 14:11:44 2014 +0300 + - ath9k: Rename ar9003_hw_tx_iqcal_load_avg_2_passes -- ++ cfg80211: Add API to update CSA counters in mgmt frames + - Use ar9003_hw_tx_iq_cal_outlier_detection instead. - - Signed-off-by: Sujith Manoharan @@ -2707,26 +2917,43 @@ index a1af6c2..892f51e 100644 -Date: Fri Feb 7 10:29:50 2014 +0530 - - ath9k: Check explicitly for IQ calibration -- ++ Add NL80211_ATTR_CSA_C_OFFSETS_TX which holds an array ++ of offsets to the CSA counters which should be updated ++ when sending a management frames with NL80211_CMD_FRAME. + - In chips like AR955x, the initvals contain the information - whether IQ calibration is to be done in the HW when an - AGC calibration is triggered. Check if IQ-CAL is enabled - in the initvals before flagging 'txiqcal_done' as true. -- ++ This API should be used by the drivers that wish to keep the ++ CSA counter updated in probe responses, but do not implement ++ probe response offloading and so, do not use ++ ieee80211_proberesp_get function. + - Signed-off-by: Sujith Manoharan -- ++ Signed-off-by: Andrei Otcheretianski ++ Signed-off-by: Luciano Coelho ++ Signed-off-by: Johannes Berg + -commit cb4969634b93c4643a32cc3fbd27d2b288b25771 -Author: Sujith Manoharan -Date: Fri Feb 7 10:29:49 2014 +0530 -- ++commit 7d09fc9f1903b3d5e7d046bdf10467f37a97c4f9 ++Author: Luciano Coelho ++Date: Thu May 15 13:05:39 2014 +0300 + - ath9k: Fix IQ cal post processing for SoC -- ++ cfg80211: pass the actual iftype when calling cfg80211_chandef_dfs_required() + - Calibration data is not reused for SoC chips, so - call ar9003_hw_tx_iq_cal_post_proc() with the correct - argument. The 'is_reusable' flag is currently used - only for PC-OEM chips, but it makes things clearer to - specify it explicity. -- ++ There is no need to pass NL80211_IFTYPE_UNSPECIFIED when calling ++ cfg80211_chandef_dfs_required() since we always already have the ++ interface type. So, pass the actual interface type instead. + - Signed-off-by: Sujith Manoharan - -commit e138e0ef9560c46ce93dbb22a728a57888e94d1c @@ -2734,7 +2961,10 @@ index a1af6c2..892f51e 100644 -Date: Mon Feb 3 13:31:37 2014 +0530 - - ath9k: Fix TX power calculation -- ++ Additionally, have cfg80211_chandef_dfs_required() WARN if the passed ++ interface type is NL80211_IFTYPE_UNSPECIFIED, so we can detect ++ problems more easily. + - The commit, "ath9k_hw: Fix incorrect Tx control power in AR9003 template" - fixed the incorrect values in the eeprom templates, but if - boards have already been calibrated with incorrect values, @@ -2743,22 +2973,33 @@ index a1af6c2..892f51e 100644 - - Cc: Rajkumar Manoharan - Signed-off-by: Sujith Manoharan -- ++ Tested-by: Janusz Dziedzic ++ Reported-by: Eliad Peller ++ Signed-off-by: Luciano Coelho ++ Signed-off-by: Johannes Berg + -commit b9f268b5b01331c3c82179abca551429450e9417 -Author: Michal Kazior -Date: Wed Jan 29 14:22:27 2014 +0100 -- ++commit 2b7443b15f26ecb98281474666383cf2a882fbad ++Author: Janusz Dziedzic ++Date: Wed May 14 13:25:04 2014 +0200 + - cfg80211: consider existing DFS interfaces - - It was possible to break interface combinations in - the following way: -- ++ cfg80211: fix start_radar_detection issue + - combo 1: iftype = AP, num_ifaces = 2, num_chans = 2, - combo 2: iftype = AP, num_ifaces = 1, num_chans = 1, radar = HT20 -- ++ After patch: ++ cfg80211/mac80211: refactor cfg80211_chandef_dfs_required() + - With the above interface combinations it was - possible to: -- ++ start_radar_detection always fail with -EINVAL. + - step 1. start AP on DFS channel by matching combo 2 - step 2. start AP on non-DFS channel by matching combo 1 - @@ -2770,12 +3011,17 @@ index a1af6c2..892f51e 100644 - is stored. - - Signed-off-by: Michal Kazior -- Signed-off-by: Johannes Berg -- ++ Acked-by: Luciano Coelho ++ Signed-off-by: Janusz Dziedzic + Signed-off-by: Johannes Berg + -commit bc9c62f5f511cc395c62dbf4cdd437f23db53b28 -Author: Antonio Quartulli -Date: Wed Jan 29 17:53:43 2014 +0100 -- ++commit 4f46eb8b28f96aca212a364e0fa847eb5333df67 ++Author: Felix Fietkau ++Date: Mon May 5 11:48:40 2014 +0200 + - cfg80211: fix channel configuration in IBSS join - - When receiving an IBSS_JOINED event select the BSS object @@ -2787,7 +3033,8 @@ index a1af6c2..892f51e 100644 - The result is a mismatching channel configuration between - cfg80211 and the driver, that can lead to any sort of - problem. -- ++ cfg80211: allow restricting supported dfs regions + - The issue can be triggered by having an IBSS sitting on - given channel and then asking the driver to create a new - cell using the same BSSID but with a different frequency. @@ -2795,7 +3042,12 @@ index a1af6c2..892f51e 100644 - this ambiguity and retrieve/create the correct BSS object. - All the users of cfg80211_ibss_joined() have been changed - accordingly. -- ++ At the moment, the ath9k/ath10k DFS module only supports detecting ETSI ++ radar patterns. ++ Add a bitmap in the interface combinations, indicating which DFS regions ++ are supported by the detector. If unset, support for all regions is ++ assumed. + - Moreover WARN when cfg80211_ibss_joined() gets a NULL - channel as argument and remove a bogus call of the same - function in ath6kl (it does not make sense to call @@ -2809,36 +3061,53 @@ index a1af6c2..892f51e 100644 - Acked-by: Kalle Valo - Signed-off-by: Antonio Quartulli - [minor code cleanup in ath6kl] -- Signed-off-by: Johannes Berg -- ++ Signed-off-by: Felix Fietkau + Signed-off-by: Johannes Berg + -commit 7e0c41cb41f215aba2c39b1c237bb4d42ec49a85 --Author: Johannes Berg ++commit 0277b034768d1800a00829a755fc56b925aa6b95 + Author: Johannes Berg -Date: Fri Jan 24 14:41:44 2014 +0100 -- ++Date: Wed Apr 30 14:19:04 2014 +0200 + - mac80211: fix bufferable MMPDU RX handling -- ++ mac80211: handle failed restart/resume better + - Action, disassoc and deauth frames are bufferable, and as such don't - have the PM bit in the frame control field reserved which means we - need to react to the bit when receiving in such a frame. -- ++ When the driver fails during HW restart or resume, the whole ++ stack goes into a very confused state with interfaces being ++ up while the hardware is down etc. + - Fix this by introducing a new helper ieee80211_is_bufferable_mmpdu() - and using it for the RX path that currently ignores the PM bit in - any non-data frames for doze->wake transitions, but listens to it in - all frames for wake->doze transitions, both of which are wrong. - - Also use the new helper in the TX path to clean up the code. -- -- Signed-off-by: Johannes Berg -- ++ Address this by shutting down everything; we'll run into a ++ lot of warnings in the process but that's better than having ++ the whole stack get messed up. + ++ Reviewed-by: Arik Nemtsov + Signed-off-by: Johannes Berg + -commit fc0df6d2343636e3f48a069330d5b972e3d8659d -Author: Janusz Dziedzic -Date: Fri Jan 24 14:29:21 2014 +0100 -- ++commit 43fd71bc4b83d24981e90ca178f505cf6a6b16dc ++Author: Luciano Coelho ++Date: Wed May 7 20:05:12 2014 +0300 + - cfg80211: set preset_chandef after channel switch -- ++ mac80211: fix sparse warning caused by __ieee80211_channel_switch() + - Set preset_chandef in channel switch notification. - In other case we will have old preset_chandef. -- ++ Commit 59af6928 (mac80211: fix CSA tx queue stopping) introduced a ++ sparse warning: + - Signed-off-by: Janusz Dziedzic - Signed-off-by: Johannes Berg - @@ -2847,38 +3116,57 @@ index a1af6c2..892f51e 100644 -Date: Fri Jan 24 23:48:29 2014 +0100 - - mac80211: send ibss probe responses with noack flag -- ++ net/mac80211/cfg.c:3274:5: warning: symbol '__ieee80211_channel_switch' was not declared. Should it be static? + - Responding to probe requests for scanning clients will often create - excessive retries, as it happens quite often that the scanning client - already left the channel. Therefore do it like hostapd and send probe - responses for wildcard SSID only once by using the noack flag. -- ++ Fix it by declaring the function static. + - Signed-off-by: Simon Wunderlich - [fix typo & 'wildcard SSID' in commit log] -- Signed-off-by: Johannes Berg -- ++ Signed-off-by: Luciano Coelho + Signed-off-by: Johannes Berg + -commit 0b865d1e6b9c05052adae9315df7cb195dc60c3b --Author: Luciano Coelho ++commit dd4371e2957db19870bb22ab84e841e1ac6e8997 + Author: Luciano Coelho -Date: Tue Jan 28 17:09:08 2014 +0200 -- ++Date: Wed May 7 19:07:05 2014 +0300 + - mac80211: ibss: remove unnecessary call to release channel -- ++ cfg80211: fix docbook warning ++ ++ When trying to generate documentation, at least xmldocs, we get the ++ following warning: ++ ++ Warning(include/net/cfg80211.h:461): No description found for parameter 'nl80211_iftype' + - The ieee80211_vif_use_channel() function calls - ieee80211_vif_release_channel(), so there's no need to call it - explicitly in __ieee80211_sta_join_ibss(). -- -- Signed-off-by: Luciano Coelho -- Signed-off-by: Johannes Berg -- ++ Fix it by adding the iftype argument name to the ++ cfg80211_chandef_dfs_required() function declaration. + ++ Reported-and-tested-by: Masanari Iida + Signed-off-by: Luciano Coelho + Signed-off-by: Johannes Berg + -commit e1b6c17e971f0a51ff86c2dac2584c63cd999cd7 --Author: Michal Kazior ++commit 56de850ae960f096c784ec07864ca5b71abd16e6 + Author: Michal Kazior -Date: Wed Jan 29 07:56:21 2014 +0100 -- ++Date: Thu May 8 09:10:02 2014 +0200 + - mac80211: add missing CSA locking -- ++ mac80211: disconnect iface if CSA unexpectedly fails + - The patch adds a missing sdata lock and adds a few - lockdeps for easier maintenance. -- ++ It doesn't make much sense to leave a crippled ++ interface running. + - Signed-off-by: Michal Kazior - Signed-off-by: Johannes Berg - @@ -2887,48 +3175,76 @@ index a1af6c2..892f51e 100644 -Date: Wed Jan 29 07:56:20 2014 +0100 - - mac80211: fix sdata->radar_required locking -- ++ As a side effect this will unblock tx queues with ++ CSA reason immediately after failure instead of ++ until after userspace requests interface to stop. + - radar_required setting wasn't protected by - local->mtx in some places. This should prevent - from scanning/radar detection/roc colliding. -- -- Signed-off-by: Michal Kazior -- Signed-off-by: Johannes Berg -- ++ This also gives userspace an opportunity to ++ indirectly see CSA failure. + + Signed-off-by: Michal Kazior ++ [small code cleanup] + Signed-off-by: Johannes Berg + -commit 5fcd5f1808813a3d9e502fd756e01bee8a79c85d -Author: Michal Kazior -Date: Wed Jan 29 07:56:19 2014 +0100 -- ++commit f5894c4f19e55bb1ea6376031fe9d47d7528be9e ++Author: Loic Poulain ++Date: Wed May 7 11:38:11 2014 +0200 + - mac80211: move csa_active setting in STA CSA -- ++ rfkill-gpio: Use gpio cansleep version + - The sdata->vif.csa_active could be left set after, - e.g. channel context constraints check fail in STA - mode leaving the interface in a strange state for - a brief period of time until it is disconnected. - This was harmless but ugly. -- ++ If gpio controller requires waiting for read and write ++ GPIO values, then we have to use the gpio cansleep api. ++ Fix the rfkill_gpio_set_power which calls only the ++ nonsleep version (causing kernel warning). ++ There is no problem to use the cansleep version here ++ because we are not in IRQ handler or similar context ++ (cf rfkill_set_block). + - Signed-off-by: Michal Kazior - Reviewed-by: Luciano Coelho -- Signed-off-by: Johannes Berg -- ++ Signed-off-by: Loic Poulain + Signed-off-by: Johannes Berg + -commit e486da4b7eed71821c6b4c1bb9ac62ffd3ab13e9 --Author: Michal Kazior ++commit 47fdf5d4f3704d2db9d1c0f647f788edef104fc8 + Author: Michal Kazior -Date: Wed Jan 29 07:56:18 2014 +0100 -- ++Date: Wed Apr 9 15:45:36 2014 +0200 + - mac80211: fix possible memory leak on AP CSA failure -- ++ mac80211: ignore cqm during csa + - If CSA for AP interface failed and the interface - was not stopped afterwards another CSA request - would leak sdata->u.ap.next_beacon. -- -- Signed-off-by: Michal Kazior ++ It is not guaranteed that multi-vif channel ++ switching is tightly synchronized. It makes sense ++ to ignore cqm (missing beacons, et al) while csa ++ is progressing and re-check it after it completes. + + Signed-off-by: Michal Kazior - Reviewed-by: Luciano Coelho -- Signed-off-by: Johannes Berg -- + Signed-off-by: Johannes Berg + -commit 3a77ba08940682bf3d52cf14f980337324af9d4a -Author: Johannes Berg -Date: Sat Feb 1 00:33:29 2014 +0100 -- ++commit 1a8ed386e1684b266a15dacf675102ae53361ee5 ++Author: Michal Kazior ++Date: Wed Apr 9 15:11:01 2014 +0200 + - mac80211: fix fragmentation code, particularly for encryption - - The "new" fragmentation code (since my rewrite almost 5 years ago) @@ -2938,7 +3254,8 @@ index a1af6c2..892f51e 100644 - originally ended, and thus causes the encryption MIC to be written - at that point, rather than where it belongs: immediately after the - data. -- ++ cfg80211: export interface stopping function + - The impact of this is that if software encryption is done, then - a) encryption doesn't work for the first fragment, the connection - becomes unusable as the first fragment will never be properly @@ -2946,20 +3263,27 @@ index a1af6c2..892f51e 100644 - be wrong - b) we leak up to 8 bytes of plaintext (!) of the packet out into - the air -- ++ This exports a new cfg80211_stop_iface() function. + - This is only mitigated by the fact that many devices are capable - of doing encryption in hardware, in which case this can't happen - as the tail pointer is irrelevant in that case. Additionally, - fragmentation is not used very frequently and would normally have - to be configured manually. -- ++ This is intended for driver internal interface ++ combination management and channel switching. + - Fix this by using skb_trim() properly. -- ++ Due to locking issues (it re-enters driver) the ++ call is asynchronous and uses cfg80211 event ++ list/worker. + - Cc: stable@vger.kernel.org - Fixes: 2de8e0d999b8 ("mac80211: rewrite fragmentation") - Reported-by: Jouni Malinen -- Signed-off-by: Johannes Berg -- ++ Signed-off-by: Michal Kazior + Signed-off-by: Johannes Berg + -commit de5f242e0c10e841017e37eb8c38974a642dbca8 -Author: Sujith Manoharan -Date: Tue Jan 28 06:21:59 2014 +0530 @@ -2992,20 +3316,29 @@ index a1af6c2..892f51e 100644 -commit a4a634a6937ebdd827fa58e8fcdb8ca49a3769f6 -Author: Emmanuel Grumbach -Date: Mon Jan 27 11:07:42 2014 +0200 -- ++commit 573f31d6d0e572ff8186c45a1ecd9273242233e6 ++Author: Michal Kazior ++Date: Wed Apr 9 15:11:00 2014 +0200 + - mac80211: release the channel in error path in start_ap -- ++ mac80211: split CSA finalize function + - When the driver cannot start the AP or when the assignement - of the beacon goes wrong, we need to unassign the vif. -- ++ Improves readability and modularity. + - Cc: stable@vger.kernel.org - Signed-off-by: Emmanuel Grumbach -- Signed-off-by: Johannes Berg -- ++ Signed-off-by: Michal Kazior + Signed-off-by: Johannes Berg + -commit dfb6889a75c601aedb7450b7e606668e77da6679 -Author: Johannes Berg -Date: Wed Jan 22 11:14:19 2014 +0200 -- ++commit 2d104d52e7c7640d68f29f2136dbe3938b7bc9ba ++Author: Michal Kazior ++Date: Wed Apr 9 15:10:59 2014 +0200 + - cfg80211: send scan results from work queue - - Due to the previous commit, when a scan finishes, it is in theory @@ -3027,13 +3360,39 @@ index a1af6c2..892f51e 100644 - - As this can't work for wext, so we send the message immediately, - but this shouldn't be an issue since we still return -EBUSY. -- -- Signed-off-by: Johannes Berg -- --commit 45b7ab41fc08627d9a8428cb413d5d84662a9707 --Author: Johannes Berg --Date: Wed Jan 22 11:14:18 2014 +0200 ++ mac80211: fix CSA tx queue stopping ++ ++ It was possible for tx queues to be stuck stopped ++ if AP CSA finalization failed. In that case ++ neither stop_ap nor do_stop woke the queues up. ++ This means it was impossible to perform tx at all ++ until driver was reloaded or a successful CSA was ++ performed later. ++ ++ It was possible to solve this in a simpler manner ++ however this is more robust and future proof ++ (having multi-vif CSA in mind). ++ ++ New sdata->csa_block_tx is introduced to keep ++ track of which interfaces requested tx to be ++ blocked for CSA. This is required because mac80211 ++ stops all tx queues for that purpose. This means ++ queues must be awoken only when last tx-blocking ++ CSA interface is finished. ++ ++ It is still possible to have tx queues stopped ++ after CSA failure but as soon as offending ++ interfaces are stopped from userspace (stop_ap or ++ ifdown) tx queues are woken up properly. + ++ Signed-off-by: Michal Kazior + Signed-off-by: Johannes Berg +-commit 45b7ab41fc08627d9a8428cb413d5d84662a9707 ++commit 6be615d6d42aa7fdab6c4278031d8fa0953e594f + Author: Johannes Berg +-Date: Wed Jan 22 11:14:18 2014 +0200 +- - cfg80211: fix scan done race - - When an interface/wdev is removed, any ongoing scan should be @@ -3060,7 +3419,8 @@ index a1af6c2..892f51e 100644 -commit ae04fa489ab31b5a10d3cc8399f52761175d4321 -Author: Emmanuel Grumbach -Date: Thu Jan 23 14:28:16 2014 +0200 -- ++Date: Wed Apr 9 21:31:13 2014 +0200 + - mac80211: avoid deadlock revealed by lockdep - - sdata->u.ap.request_smps_work can’t be flushed synchronously @@ -3070,14 +3430,18 @@ index a1af6c2..892f51e 100644 - stopped to its default: OFF. - - This solves: -- ++ mac80211: mark local variable __maybe_unused + - ====================================================== - [ INFO: possible circular locking dependency detected ] - 3.12.0-ipeer+ #2 Tainted: G O - ------------------------------------------------------- - rmmod/2867 is trying to acquire lock: - ((&sdata->u.ap.request_smps_work)){+.+...}, at: [] flush_work+0x0/0x90 -- ++ The 'local' variable in __ieee80211_vif_copy_chanctx_to_vlans() ++ is only used/needed when lockdep is compiled in, mark it as such ++ to avoid compile warnings in the other case. + - but task is already holding lock: - (&wdev->mtx){+.+.+.}, at: [] cfg80211_stop_ap+0x26/0x230 [cfg80211] - @@ -3137,38 +3501,53 @@ index a1af6c2..892f51e 100644 - Unfortunately I forgot this during the merge window, but the - patch seems small enough to go in as a fix. The userspace API - bug that was the reason for disabling it has long been fixed. -- -- Signed-off-by: Johannes Berg -- ++ While at it, fix some indentation where it's used. + ++ Reviewed-by: Luciano Coelho ++ Reviewed-by: Emmanuel Grumbach + Signed-off-by: Johannes Berg + -commit 110a1c79acda14edc83b7c8dc5af9c7ddd23eb61 -Author: Pontus Fuchs -Date: Thu Jan 16 15:00:40 2014 +0100 -- ++commit 43279e584aeb78aa0c853728db047b58156c0753 ++Author: Arik Nemtsov ++Date: Thu May 1 10:17:28 2014 +0300 + - nl80211: Reset split_start when netlink skb is exhausted - - When the netlink skb is exhausted split_start is left set. In the - subsequent retry, with a larger buffer, the dump is continued from the - failing point instead of from the beginning. -- ++ mac80211: move TDLS code to another file + - This was causing my rt28xx based USB dongle to now show up when - running "iw list" with an old iw version without split dump support. -- ++ With new additions planned, this code is getting too big for cfg.c. + - Cc: stable@vger.kernel.org - Fixes: 3713b4e364ef ("nl80211: allow splitting wiphy information in dumps") - Signed-off-by: Pontus Fuchs - [avoid the entire workaround when state->split is set] -- Signed-off-by: Johannes Berg -- ++ Signed-off-by: Arik Nemtsov + Signed-off-by: Johannes Berg + -commit b4c31b45ffc7ef110fa9ecc34d7878fe7c5b9da4 -Author: Eliad Peller -Date: Sun Jan 12 11:06:37 2014 +0200 -- ++commit bf9c234b83c77f1ebbcbab73de2a9e4a5d4aafc6 ++Author: Arik Nemtsov ++Date: Thu May 1 10:17:27 2014 +0300 + - mac80211: move roc cookie assignment earlier -- ++ mac80211: set an external flag for TDLS stations + - ieee80211_start_roc_work() might add a new roc - to existing roc, and tell cfg80211 it has already - started. -- ++ Expose a new tdls flag for the public ieee80211_sta struct. ++ This can be used in some rate control decisions. + - However, this might happen before the roc cookie - was set, resulting in REMAIN_ON_CHANNEL (started) - event with null cookie. Consequently, it can make @@ -3178,44 +3557,59 @@ index a1af6c2..892f51e 100644 - - Cc: stable@vger.kernel.org - Signed-off-by: Eliad Peller -- Signed-off-by: Johannes Berg -- ++ Signed-off-by: Arik Nemtsov + Signed-off-by: Johannes Berg + -commit cfdc9157bfd7bcf88ab4dae08873a9907eba984c --Author: Johannes Berg ++commit 910e65141a17f645ab85dae1a497e64ebe63df70 + Author: Johannes Berg -Date: Fri Jan 24 14:06:29 2014 +0100 -- ++Date: Tue Apr 29 17:55:26 2014 +0200 + - nl80211: send event when AP operation is stopped -- ++ mac80211: remove BUG_ON usage + - There are a few cases, e.g. suspend, where an AP interface is - stopped by the kernel rather than by userspace request, most - commonly when suspending. To let userspace know about this, - send the NL80211_CMD_STOP_AP command as an event every time - an AP interface is stopped. This also happens when userspace - did in fact request the AP stop, but that's not a problem. -- ++ These BUG_ON statements should never trigger, but in the unlikely ++ event that somebody does manage don't stop everything but simply ++ exit the code path with an error. + - For full-MAC drivers this may need to be extended to also - cover cases where the device stopped the AP operation for - some reason, this a bit more complicated because then all - cfg80211 state also needs to be reset; such API is not part - of this patch. -- -- Signed-off-by: Johannes Berg -- ++ Leave the one BUG_ON where changing it would result in a NULL ++ pointer dereference. + + Signed-off-by: Johannes Berg + -commit d5d567eda7704f190379ca852a8f9a4112e3eee3 --Author: Johannes Berg ++commit ff36b582a10285530351aab036087b57ddb4ae2b + Author: Johannes Berg -Date: Thu Jan 23 16:20:29 2014 +0100 -- ++Date: Tue Apr 29 17:52:36 2014 +0200 + - mac80211: add length check in ieee80211_is_robust_mgmt_frame() -- ++ cfg80211: remove BUG_ON usage + - A few places weren't checking that the frame passed to the - function actually has enough data even though the function - clearly documents it must have a payload byte. Make this - safer by changing the function to take an skb and checking - the length inside. The old version is preserved for now as - the rtl* drivers use it and don't have a correct skb. -- -- Signed-off-by: Johannes Berg -- ++ These really can't trigger unless somebody messes up the code, ++ but don't make debugging it needlessly complicated, WARN and ++ return instead of BUG_ON(). + + Signed-off-by: Johannes Berg + -commit f8f6d212a047fc65c7d3442dfc038f65517236fc -Author: Johannes Berg -Date: Fri Jan 24 10:53:53 2014 +0100 @@ -3293,8 +3687,8 @@ index a1af6c2..892f51e 100644 - Cc: Helmut Schaa - Cc: Emmanuel Grumbach - Signed-off-by: Johannes Berg ----- a/drivers/net/wireless/ath/ath6kl/cfg80211.c --+++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c + --- a/drivers/net/wireless/ath/ath6kl/cfg80211.c + +++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c -@@ -790,7 +790,7 @@ void ath6kl_cfg80211_connect_event(struc - if (nw_type & ADHOC_NETWORK) { - ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "ad-hoc %s selected\n", @@ -3318,7 +3712,9 @@ index a1af6c2..892f51e 100644 -- cfg80211_ibss_joined(vif->ndev, bssid, GFP_KERNEL); - return; - } -- ++@@ -1759,7 +1759,7 @@ static bool is_rate_ht40(s32 rate, u8 *m ++ } + -@@ -3256,6 +3252,15 @@ static int ath6kl_cfg80211_sscan_start(s - struct ath6kl_vif *vif = netdev_priv(dev); - u16 interval; @@ -3378,7 +3774,10 @@ index a1af6c2..892f51e 100644 - -@@ -1534,7 +1534,7 @@ EXPORT_SYMBOL(ath9k_hw_check_nav); - bool ath9k_hw_check_alive(struct ath_hw *ah) -- { ++ static int ath6kl_get_station(struct wiphy *wiphy, struct net_device *dev, ++- u8 *mac, struct station_info *sinfo) +++ const u8 *mac, struct station_info *sinfo) + { - int count = 50; -- u32 reg; -+ u32 reg, last_val; @@ -3441,9 +3840,16 @@ index a1af6c2..892f51e 100644 - goto out; - } -@@ -1866,7 +1866,7 @@ static void ath9k_set_coverage_class(str -- ++ struct ath6kl *ar = ath6kl_priv(dev); ++ struct ath6kl_vif *vif = netdev_priv(dev); ++@@ -2974,7 +2974,7 @@ static int ath6kl_stop_ap(struct wiphy * ++ static const u8 bcast_addr[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; + - static bool ath9k_has_tx_pending(struct ath_softc *sc) -- { ++ static int ath6kl_del_station(struct wiphy *wiphy, struct net_device *dev, ++- u8 *mac) +++ const u8 *mac) + { -- int i, npend; -+ int i, npend = 0; - @@ -3508,8 +3914,11 @@ index a1af6c2..892f51e 100644 ---- a/include/linux/ieee80211.h -+++ b/include/linux/ieee80211.h -@@ -597,6 +597,20 @@ static inline int ieee80211_is_qos_nullf -- } -- ++ struct ath6kl *ar = ath6kl_priv(dev); ++ struct ath6kl_vif *vif = netdev_priv(dev); ++@@ -2985,7 +2985,8 @@ static int ath6kl_del_station(struct wip + } + - /** -+ * ieee80211_is_bufferable_mmpdu - check if frame is bufferable MMPDU -+ * @fc: frame control field in little-endian byteorder @@ -3529,8 +3938,19 @@ index a1af6c2..892f51e 100644 - * @seq_ctrl: frame sequence control bytes in little-endian byteorder - */ -@@ -2192,10 +2206,10 @@ static inline u8 *ieee80211_get_DA(struc -- } -- ++ static int ath6kl_change_station(struct wiphy *wiphy, struct net_device *dev, ++- u8 *mac, struct station_parameters *params) +++ const u8 *mac, +++ struct station_parameters *params) ++ { ++ struct ath6kl *ar = ath6kl_priv(dev); ++ struct ath6kl_vif *vif = netdev_priv(dev); ++--- a/drivers/net/wireless/ath/ath6kl/wmi.c +++++ b/drivers/net/wireless/ath/ath6kl/wmi.c ++@@ -2320,7 +2320,7 @@ int ath6kl_wmi_addkey_cmd(struct wmi *wm ++ return ret; + } + - /** -- * ieee80211_is_robust_mgmt_frame - check if frame is a robust management frame -+ * _ieee80211_is_robust_mgmt_frame - check if frame is a robust management frame @@ -3538,12 +3958,36 @@ index a1af6c2..892f51e 100644 - */ --static inline bool ieee80211_is_robust_mgmt_frame(struct ieee80211_hdr *hdr) -+static inline bool _ieee80211_is_robust_mgmt_frame(struct ieee80211_hdr *hdr) -- { ++-int ath6kl_wmi_add_krk_cmd(struct wmi *wmi, u8 if_idx, u8 *krk) +++int ath6kl_wmi_add_krk_cmd(struct wmi *wmi, u8 if_idx, const u8 *krk) ++ { ++ struct sk_buff *skb; ++ struct wmi_add_krk_cmd *cmd; ++--- a/drivers/net/wireless/ath/ath6kl/wmi.h +++++ b/drivers/net/wireless/ath/ath6kl/wmi.h ++@@ -2616,7 +2616,7 @@ int ath6kl_wmi_addkey_cmd(struct wmi *wm ++ u8 *key_material, ++ u8 key_op_ctrl, u8 *mac_addr, ++ enum wmi_sync_flag sync_flag); ++-int ath6kl_wmi_add_krk_cmd(struct wmi *wmi, u8 if_idx, u8 *krk); +++int ath6kl_wmi_add_krk_cmd(struct wmi *wmi, u8 if_idx, const u8 *krk); ++ int ath6kl_wmi_deletekey_cmd(struct wmi *wmi, u8 if_idx, u8 key_index); ++ int ath6kl_wmi_setpmkid_cmd(struct wmi *wmi, u8 if_idx, const u8 *bssid, ++ const u8 *pmkid, bool set); ++--- a/drivers/net/wireless/ath/ath9k/htc.h +++++ b/drivers/net/wireless/ath/ath9k/htc.h ++@@ -378,7 +378,7 @@ void ath9k_htc_get_et_stats(struct ieee8 ++ #define TX_QSTAT_INC(c) do { } while (0) ++ ++ static inline void ath9k_htc_err_stat_rx(struct ath9k_htc_priv *priv, ++- struct ath_htc_rx_status *rxs) +++ struct ath_rx_status *rs); + { - if (ieee80211_is_disassoc(hdr->frame_control) || - ieee80211_is_deauth(hdr->frame_control)) -@@ -2224,6 +2238,17 @@ static inline bool ieee80211_is_robust_m -- } -- + } + - /** -+ * ieee80211_is_robust_mgmt_frame - check if skb contains a robust mgmt frame -+ * @skb: the skb containing the frame, length will be checked @@ -3629,7 +4073,10 @@ index a1af6c2..892f51e 100644 --void cfg80211_ibss_joined(struct net_device *dev, const u8 *bssid, gfp_t gfp); -+void cfg80211_ibss_joined(struct net_device *dev, const u8 *bssid, -+ struct ieee80211_channel *channel, gfp_t gfp); -- ++--- a/drivers/net/wireless/ath/wil6210/cfg80211.c +++++ b/drivers/net/wireless/ath/wil6210/cfg80211.c ++@@ -172,7 +172,7 @@ static int wil_cid_fill_sinfo(struct wil + - /** - * cfg80211_notify_new_candidate - notify cfg80211 of a new mesh peer candidate ---- a/include/uapi/linux/nl80211.h @@ -3660,8 +4107,16 @@ index a1af6c2..892f51e 100644 - -- ieee80211_tx_skb_tid(sdata, skb, tid); -+ ieee80211_tx_skb(sdata, skb); -- } -- ++ static int wil_cfg80211_get_station(struct wiphy *wiphy, ++ struct net_device *ndev, ++- u8 *mac, struct station_info *sinfo) +++ const u8 *mac, struct station_info *sinfo) ++ { ++ struct wil6210_priv *wil = wiphy_to_wil(wiphy); ++ int rc; ++@@ -671,7 +671,7 @@ static int wil_cfg80211_stop_ap(struct w + } + - void ieee80211_send_bar(struct ieee80211_vif *vif, u8 *ra, u16 tid, u16 ssn) ---- a/net/mac80211/cfg.c -+++ b/net/mac80211/cfg.c @@ -3678,7 +4133,12 @@ index a1af6c2..892f51e 100644 - mutex_unlock(&local->mtx); -@@ -1021,8 +1021,10 @@ static int ieee80211_start_ap(struct wip - IEEE80211_P2P_OPPPS_ENABLE_BIT; -- ++ static int wil_cfg80211_del_station(struct wiphy *wiphy, ++- struct net_device *dev, u8 *mac) +++ struct net_device *dev, const u8 *mac) ++ { ++ struct wil6210_priv *wil = wiphy_to_wil(wiphy); + - err = ieee80211_assign_beacon(sdata, ¶ms->beacon); -- if (err < 0) -+ if (err < 0) { @@ -3695,19 +4155,59 @@ index a1af6c2..892f51e 100644 -+ ieee80211_vif_release_channel(sdata); - return err; - } -- ++--- a/drivers/net/wireless/ath/wil6210/main.c +++++ b/drivers/net/wireless/ath/wil6210/main.c ++@@ -81,7 +81,7 @@ static void wil_disconnect_cid(struct wi ++ memset(&sta->stats, 0, sizeof(sta->stats)); ++ } + -@@ -1053,6 +1056,7 @@ static int ieee80211_change_beacon(struc - int err; -- ++-static void _wil6210_disconnect(struct wil6210_priv *wil, void *bssid) +++static void _wil6210_disconnect(struct wil6210_priv *wil, const u8 *bssid) ++ { ++ int cid = -ENOENT; ++ struct net_device *ndev = wil_to_ndev(wil); ++@@ -252,7 +252,7 @@ int wil_priv_init(struct wil6210_priv *w ++ return 0; ++ } + - sdata = IEEE80211_DEV_TO_SUB_IF(dev); -+ sdata_assert_lock(sdata); -- ++-void wil6210_disconnect(struct wil6210_priv *wil, void *bssid) +++void wil6210_disconnect(struct wil6210_priv *wil, const u8 *bssid) ++ { ++ del_timer_sync(&wil->connect_timer); ++ _wil6210_disconnect(wil, bssid); ++--- a/drivers/net/wireless/ath/wil6210/wil6210.h +++++ b/drivers/net/wireless/ath/wil6210/wil6210.h ++@@ -508,7 +508,7 @@ void wil_wdev_free(struct wil6210_priv * ++ int wmi_set_mac_address(struct wil6210_priv *wil, void *addr); ++ int wmi_pcp_start(struct wil6210_priv *wil, int bi, u8 wmi_nettype, u8 chan); ++ int wmi_pcp_stop(struct wil6210_priv *wil); ++-void wil6210_disconnect(struct wil6210_priv *wil, void *bssid); +++void wil6210_disconnect(struct wil6210_priv *wil, const u8 *bssid); ++ ++ int wil_rx_init(struct wil6210_priv *wil); ++ void wil_rx_fini(struct wil6210_priv *wil); ++--- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c +++++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c ++@@ -2236,7 +2236,7 @@ brcmf_cfg80211_config_default_mgmt_key(s + - /* don't allow changing the beacon while CSA is in place - offset - * of channel switch counter may change -@@ -1080,6 +1084,8 @@ static int ieee80211_stop_ap(struct wiph - struct probe_resp *old_probe_resp; - struct cfg80211_chan_def chandef; -- ++ static s32 ++ brcmf_cfg80211_get_station(struct wiphy *wiphy, struct net_device *ndev, ++- u8 *mac, struct station_info *sinfo) +++ const u8 *mac, struct station_info *sinfo) ++ { ++ struct brcmf_if *ifp = netdev_priv(ndev); ++ struct brcmf_cfg80211_profile *profile = &ifp->vif->profile; ++@@ -4014,7 +4014,7 @@ brcmf_cfg80211_change_beacon(struct wiph + -+ sdata_assert_lock(sdata); -+ - old_beacon = sdata_dereference(sdata->u.ap.beacon, sdata); @@ -3716,7 +4216,16 @@ index a1af6c2..892f51e 100644 -@@ -1090,8 +1096,6 @@ static int ieee80211_stop_ap(struct wiph - kfree(sdata->u.ap.next_beacon); - sdata->u.ap.next_beacon = NULL; -- ++ static int ++ brcmf_cfg80211_del_station(struct wiphy *wiphy, struct net_device *ndev, ++- u8 *mac) +++ const u8 *mac) ++ { ++ struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); ++ struct brcmf_scb_val_le scbval; ++@@ -4242,7 +4242,7 @@ static int brcmf_convert_nl80211_tdls_op ++ } + -- cancel_work_sync(&sdata->u.ap.request_smps_work); -- - /* turn off carrier for this interface and dependent VLANs */ @@ -3743,7 +4252,29 @@ index a1af6c2..892f51e 100644 -@@ -2638,6 +2646,24 @@ static int ieee80211_start_roc_work(stru - INIT_DELAYED_WORK(&roc->work, ieee80211_sw_roc_work); - INIT_LIST_HEAD(&roc->dependents); -- ++ static int brcmf_cfg80211_tdls_oper(struct wiphy *wiphy, ++- struct net_device *ndev, u8 *peer, +++ struct net_device *ndev, const u8 *peer, ++ enum nl80211_tdls_operation oper) ++ { ++ struct brcmf_if *ifp; ++--- a/drivers/net/wireless/libertas/cfg.c +++++ b/drivers/net/wireless/libertas/cfg.c ++@@ -1006,9 +1006,8 @@ struct cmd_key_material { ++ } __packed; ++ ++ static int lbs_set_key_material(struct lbs_private *priv, ++- int key_type, ++- int key_info, ++- u8 *key, u16 key_len) +++ int key_type, int key_info, +++ const u8 *key, u16 key_len) ++ { ++ struct cmd_key_material cmd; ++ int ret; ++@@ -1610,7 +1609,7 @@ static int lbs_cfg_del_key(struct wiphy ++ */ + -+ /* -+ * cookie is either the roc cookie (for normal roc) -+ * or the SKB (for mgmt TX) @@ -3768,7 +4299,24 @@ index a1af6c2..892f51e 100644 -@@ -2772,24 +2798,6 @@ static int ieee80211_start_roc_work(stru - if (!queued) - list_add_tail(&roc->list, &local->roc_list); -- ++ static int lbs_cfg_get_station(struct wiphy *wiphy, struct net_device *dev, ++- u8 *mac, struct station_info *sinfo) +++ const u8 *mac, struct station_info *sinfo) ++ { ++ struct lbs_private *priv = wiphy_priv(wiphy); ++ s8 signal, noise; ++--- a/drivers/net/wireless/libertas/defs.h +++++ b/drivers/net/wireless/libertas/defs.h ++@@ -90,7 +90,8 @@ do { if ((lbs_debug & (grp)) == (grp)) \ ++ #define lbs_deb_cfg80211(fmt, args...) LBS_DEB_LL(LBS_DEB_CFG80211, " cfg80211", fmt, ##args) ++ ++ #ifdef DEBUG ++-static inline void lbs_deb_hex(unsigned int grp, const char *prompt, u8 *buf, int len) +++static inline void lbs_deb_hex(unsigned int grp, const char *prompt, +++ const u8 *buf, int len) ++ { ++ int i = 0; + -- /* -- * cookie is either the roc cookie (for normal roc) -- * or the SKB (for mgmt TX) @@ -3788,8 +4336,11 @@ index a1af6c2..892f51e 100644 -- } -- - return 0; -- } -- ++--- a/drivers/net/wireless/mwifiex/11n.h +++++ b/drivers/net/wireless/mwifiex/11n.h ++@@ -200,7 +200,7 @@ static inline int mwifiex_is_sta_11n_ena + } + -@@ -3004,8 +3012,10 @@ void ieee80211_csa_finalize_work(struct - if (!ieee80211_sdata_running(sdata)) - goto unlock; @@ -3811,7 +4362,23 @@ index a1af6c2..892f51e 100644 -+ - if (err < 0) - goto unlock; -- ++ static inline u8 ++-mwifiex_tdls_peer_11n_enabled(struct mwifiex_private *priv, u8 *ra) +++mwifiex_tdls_peer_11n_enabled(struct mwifiex_private *priv, const u8 *ra) ++ { ++ struct mwifiex_sta_node *node = mwifiex_get_sta_entry(priv, ra); ++ if (node) ++--- a/drivers/net/wireless/mwifiex/cfg80211.c +++++ b/drivers/net/wireless/mwifiex/cfg80211.c ++@@ -994,7 +994,7 @@ mwifiex_dump_station_info(struct mwifiex ++ */ ++ static int ++ mwifiex_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev, ++- u8 *mac, struct station_info *sinfo) +++ const u8 *mac, struct station_info *sinfo) ++ { ++ struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); + - changed |= err; -- kfree(sdata->u.ap.next_beacon); -- sdata->u.ap.next_beacon = NULL; @@ -3822,10 +4389,35 @@ index a1af6c2..892f51e 100644 -@@ -3066,7 +3076,7 @@ int ieee80211_channel_switch(struct wiph - struct ieee80211_if_mesh __maybe_unused *ifmsh; - int err, num_chanctx; -- ++@@ -1270,7 +1270,7 @@ static int mwifiex_cfg80211_change_beaco ++ */ ++ static int ++ mwifiex_cfg80211_del_station(struct wiphy *wiphy, struct net_device *dev, ++- u8 *mac) +++ const u8 *mac) ++ { ++ struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); ++ struct mwifiex_sta_node *sta_node; ++@@ -2629,7 +2629,7 @@ static int mwifiex_cfg80211_set_coalesce ++ */ ++ static int ++ mwifiex_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev, ++- u8 *peer, u8 action_code, u8 dialog_token, +++ const u8 *peer, u8 action_code, u8 dialog_token, ++ u16 status_code, u32 peer_capability, ++ const u8 *extra_ies, size_t extra_ies_len) ++ { ++@@ -2701,7 +2701,7 @@ mwifiex_cfg80211_tdls_mgmt(struct wiphy + -- lockdep_assert_held(&sdata->wdev.mtx); -+ sdata_assert_lock(sdata); -- ++ static int ++ mwifiex_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev, ++- u8 *peer, enum nl80211_tdls_operation action) +++ const u8 *peer, enum nl80211_tdls_operation action) ++ { ++ struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); + - if (!list_empty(&local->roc_list) || local->scanning) - return -EBUSY; ---- a/net/mac80211/ht.c @@ -3836,20 +4428,30 @@ index a1af6c2..892f51e 100644 - -- ieee80211_tx_skb_tid(sdata, skb, tid); -+ ieee80211_tx_skb(sdata, skb); -- } -- ++@@ -2748,9 +2748,8 @@ mwifiex_cfg80211_tdls_oper(struct wiphy + } + - void ieee80211_process_delba(struct ieee80211_sub_if_data *sdata, -@@ -466,7 +466,9 @@ void ieee80211_request_smps_ap_work(stru - u.ap.request_smps_work); -- ++ static int ++-mwifiex_cfg80211_add_station(struct wiphy *wiphy, ++- struct net_device *dev, ++- u8 *mac, struct station_parameters *params) +++mwifiex_cfg80211_add_station(struct wiphy *wiphy, struct net_device *dev, +++ const u8 *mac, struct station_parameters *params) ++ { ++ struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); + - sdata_lock(sdata); -- __ieee80211_request_smps_ap(sdata, sdata->u.ap.driver_smps_mode); -+ if (sdata_dereference(sdata->u.ap.beacon, sdata)) -+ __ieee80211_request_smps_ap(sdata, -+ sdata->u.ap.driver_smps_mode); - sdata_unlock(sdata); -- } -- ++@@ -2765,9 +2764,9 @@ mwifiex_cfg80211_add_station(struct wiph + } + ---- a/net/mac80211/iface.c -+++ b/net/mac80211/iface.c -@@ -770,12 +770,19 @@ static void ieee80211_do_stop(struct iee @@ -3873,47 +4475,201 @@ index a1af6c2..892f51e 100644 -+ default: -+ break; -+ } -- ++ static int ++-mwifiex_cfg80211_change_station(struct wiphy *wiphy, ++- struct net_device *dev, ++- u8 *mac, struct station_parameters *params) +++mwifiex_cfg80211_change_station(struct wiphy *wiphy, struct net_device *dev, +++ const u8 *mac, +++ struct station_parameters *params) ++ { ++ int ret; ++ struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); ++--- a/drivers/net/wireless/mwifiex/main.h +++++ b/drivers/net/wireless/mwifiex/main.h ++@@ -910,8 +910,6 @@ int mwifiex_handle_uap_rx_forward(struct ++ struct sk_buff *skb); ++ int mwifiex_process_sta_event(struct mwifiex_private *); ++ int mwifiex_process_uap_event(struct mwifiex_private *); ++-struct mwifiex_sta_node * ++-mwifiex_get_sta_entry(struct mwifiex_private *priv, u8 *mac); ++ void mwifiex_delete_all_station_list(struct mwifiex_private *priv); ++ void *mwifiex_process_sta_txpd(struct mwifiex_private *, struct sk_buff *skb); ++ void *mwifiex_process_uap_txpd(struct mwifiex_private *, struct sk_buff *skb); ++@@ -1220,26 +1218,26 @@ void mwifiex_dnld_txpwr_table(struct mwi ++ extern const struct ethtool_ops mwifiex_ethtool_ops; ++ ++ void mwifiex_del_all_sta_list(struct mwifiex_private *priv); ++-void mwifiex_del_sta_entry(struct mwifiex_private *priv, u8 *mac); +++void mwifiex_del_sta_entry(struct mwifiex_private *priv, const u8 *mac); ++ void ++ mwifiex_set_sta_ht_cap(struct mwifiex_private *priv, const u8 *ies, ++ int ies_len, struct mwifiex_sta_node *node); ++ struct mwifiex_sta_node * ++-mwifiex_add_sta_entry(struct mwifiex_private *priv, u8 *mac); +++mwifiex_add_sta_entry(struct mwifiex_private *priv, const u8 *mac); ++ struct mwifiex_sta_node * ++-mwifiex_get_sta_entry(struct mwifiex_private *priv, u8 *mac); ++-int mwifiex_send_tdls_data_frame(struct mwifiex_private *priv, u8 *peer, +++mwifiex_get_sta_entry(struct mwifiex_private *priv, const u8 *mac); +++int mwifiex_send_tdls_data_frame(struct mwifiex_private *priv, const u8 *peer, ++ u8 action_code, u8 dialog_token, ++ u16 status_code, const u8 *extra_ies, ++ size_t extra_ies_len); ++-int mwifiex_send_tdls_action_frame(struct mwifiex_private *priv, ++- u8 *peer, u8 action_code, u8 dialog_token, ++- u16 status_code, const u8 *extra_ies, ++- size_t extra_ies_len); +++int mwifiex_send_tdls_action_frame(struct mwifiex_private *priv, const u8 *peer, +++ u8 action_code, u8 dialog_token, +++ u16 status_code, const u8 *extra_ies, +++ size_t extra_ies_len); ++ void mwifiex_process_tdls_action_frame(struct mwifiex_private *priv, ++ u8 *buf, int len); ++-int mwifiex_tdls_oper(struct mwifiex_private *priv, u8 *peer, u8 action); ++-int mwifiex_get_tdls_link_status(struct mwifiex_private *priv, u8 *mac); +++int mwifiex_tdls_oper(struct mwifiex_private *priv, const u8 *peer, u8 action); +++int mwifiex_get_tdls_link_status(struct mwifiex_private *priv, const u8 *mac); ++ void mwifiex_disable_all_tdls_links(struct mwifiex_private *priv); ++ bool mwifiex_is_bss_in_11ac_mode(struct mwifiex_private *priv); ++ u8 mwifiex_get_center_freq_index(struct mwifiex_private *priv, u8 band, ++--- a/drivers/net/wireless/mwifiex/tdls.c +++++ b/drivers/net/wireless/mwifiex/tdls.c ++@@ -25,8 +25,8 @@ ++ #define TDLS_RESP_FIX_LEN 8 ++ #define TDLS_CONFIRM_FIX_LEN 6 ++ ++-static void ++-mwifiex_restore_tdls_packets(struct mwifiex_private *priv, u8 *mac, u8 status) +++static void mwifiex_restore_tdls_packets(struct mwifiex_private *priv, +++ const u8 *mac, u8 status) ++ { ++ struct mwifiex_ra_list_tbl *ra_list; ++ struct list_head *tid_list; ++@@ -84,7 +84,8 @@ mwifiex_restore_tdls_packets(struct mwif ++ return; ++ } + - /* - * Remove all stations associated with this interface. -@@ -827,7 +834,9 @@ static void ieee80211_do_stop(struct iee - cancel_work_sync(&local->dynamic_ps_enable_work); -- ++-static void mwifiex_hold_tdls_packets(struct mwifiex_private *priv, u8 *mac) +++static void mwifiex_hold_tdls_packets(struct mwifiex_private *priv, +++ const u8 *mac) ++ { ++ struct mwifiex_ra_list_tbl *ra_list; ++ struct list_head *ra_list_head; ++@@ -228,7 +229,7 @@ mwifiex_tdls_add_ht_oper(struct mwifiex_ ++ } + - cancel_work_sync(&sdata->recalc_smps); -+ sdata_lock(sdata); - sdata->vif.csa_active = false; -+ sdata_unlock(sdata); - cancel_work_sync(&sdata->csa_finalize_work); -- ++ static int mwifiex_tdls_add_vht_oper(struct mwifiex_private *priv, ++- u8 *mac, struct sk_buff *skb) +++ const u8 *mac, struct sk_buff *skb) ++ { ++ struct mwifiex_bssdescriptor *bss_desc; ++ struct ieee80211_vht_operation *vht_oper; ++@@ -367,8 +368,9 @@ static void mwifiex_tdls_add_qos_capab(s ++ } + - cancel_delayed_work_sync(&sdata->dfs_cac_timer_work); ---- a/net/mac80211/rx.c -+++ b/net/mac80211/rx.c -@@ -599,10 +599,10 @@ static int ieee80211_is_unicast_robust_m -- { ++ static int mwifiex_prep_tdls_encap_data(struct mwifiex_private *priv, ++- u8 *peer, u8 action_code, u8 dialog_token, ++- u16 status_code, struct sk_buff *skb) +++ const u8 *peer, u8 action_code, +++ u8 dialog_token, +++ u16 status_code, struct sk_buff *skb) + { - struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; -- ++ struct ieee80211_tdls_data *tf; ++ int ret; ++@@ -506,7 +508,8 @@ static int mwifiex_prep_tdls_encap_data( ++ } + -- if (skb->len < 24 || is_multicast_ether_addr(hdr->addr1)) -+ if (is_multicast_ether_addr(hdr->addr1)) - return 0; -- ++ static void ++-mwifiex_tdls_add_link_ie(struct sk_buff *skb, u8 *src_addr, u8 *peer, u8 *bssid) +++mwifiex_tdls_add_link_ie(struct sk_buff *skb, const u8 *src_addr, +++ const u8 *peer, const u8 *bssid) ++ { ++ struct ieee80211_tdls_lnkie *lnkid; + -- return ieee80211_is_robust_mgmt_frame(hdr); -+ return ieee80211_is_robust_mgmt_frame(skb); -- } -- -- ++@@ -520,8 +523,8 @@ mwifiex_tdls_add_link_ie(struct sk_buff ++ memcpy(lnkid->resp_sta, peer, ETH_ALEN); + } + ++-int mwifiex_send_tdls_data_frame(struct mwifiex_private *priv, ++- u8 *peer, u8 action_code, u8 dialog_token, +++int mwifiex_send_tdls_data_frame(struct mwifiex_private *priv, const u8 *peer, +++ u8 action_code, u8 dialog_token, ++ u16 status_code, const u8 *extra_ies, ++ size_t extra_ies_len) ++ { ++@@ -613,7 +616,8 @@ int mwifiex_send_tdls_data_frame(struct ++ } + -@@ -610,10 +610,10 @@ static int ieee80211_is_multicast_robust -- { ++ static int ++-mwifiex_construct_tdls_action_frame(struct mwifiex_private *priv, u8 *peer, +++mwifiex_construct_tdls_action_frame(struct mwifiex_private *priv, +++ const u8 *peer, ++ u8 action_code, u8 dialog_token, ++ u16 status_code, struct sk_buff *skb) + { - struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; -- ++@@ -691,10 +695,10 @@ mwifiex_construct_tdls_action_frame(stru ++ return 0; ++ } + -- if (skb->len < 24 || !is_multicast_ether_addr(hdr->addr1)) -+ if (!is_multicast_ether_addr(hdr->addr1)) - return 0; -- ++-int mwifiex_send_tdls_action_frame(struct mwifiex_private *priv, ++- u8 *peer, u8 action_code, u8 dialog_token, ++- u16 status_code, const u8 *extra_ies, ++- size_t extra_ies_len) +++int mwifiex_send_tdls_action_frame(struct mwifiex_private *priv, const u8 *peer, +++ u8 action_code, u8 dialog_token, +++ u16 status_code, const u8 *extra_ies, +++ size_t extra_ies_len) ++ { ++ struct sk_buff *skb; ++ struct mwifiex_txinfo *tx_info; ++@@ -901,7 +905,7 @@ void mwifiex_process_tdls_action_frame(s ++ } + -- return ieee80211_is_robust_mgmt_frame(hdr); -+ return ieee80211_is_robust_mgmt_frame(skb); -- } -- -- ++ static int ++-mwifiex_tdls_process_config_link(struct mwifiex_private *priv, u8 *peer) +++mwifiex_tdls_process_config_link(struct mwifiex_private *priv, const u8 *peer) ++ { ++ struct mwifiex_sta_node *sta_ptr; ++ struct mwifiex_ds_tdls_oper tdls_oper; ++@@ -922,7 +926,7 @@ mwifiex_tdls_process_config_link(struct + } + ++ static int ++-mwifiex_tdls_process_create_link(struct mwifiex_private *priv, u8 *peer) +++mwifiex_tdls_process_create_link(struct mwifiex_private *priv, const u8 *peer) ++ { ++ struct mwifiex_sta_node *sta_ptr; ++ struct mwifiex_ds_tdls_oper tdls_oper; ++@@ -949,7 +953,7 @@ mwifiex_tdls_process_create_link(struct ++ } + -@@ -626,7 +626,7 @@ static int ieee80211_get_mmie_keyidx(str - if (skb->len < 24 + sizeof(*mmie) || !is_multicast_ether_addr(hdr->da)) - return -1; @@ -3973,7 +4729,15 @@ index a1af6c2..892f51e 100644 -+ ieee80211_is_robust_mgmt_frame(rx->skb))) - return -EACCES; - } -- ++ static int ++-mwifiex_tdls_process_disable_link(struct mwifiex_private *priv, u8 *peer) +++mwifiex_tdls_process_disable_link(struct mwifiex_private *priv, const u8 *peer) ++ { ++ struct mwifiex_sta_node *sta_ptr; ++ struct mwifiex_ds_tdls_oper tdls_oper; ++@@ -978,7 +982,7 @@ mwifiex_tdls_process_disable_link(struct ++ } + ---- a/net/mac80211/tx.c -+++ b/net/mac80211/tx.c -@@ -452,8 +452,7 @@ static int ieee80211_use_mfp(__le16 fc, @@ -4052,17 +4816,36 @@ index a1af6c2..892f51e 100644 - I802_DEBUG_INC(tx->local->tx_handlers_drop_unencrypted); -@@ -878,7 +890,7 @@ static int ieee80211_fragment(struct iee - } -- ++ static int ++-mwifiex_tdls_process_enable_link(struct mwifiex_private *priv, u8 *peer) +++mwifiex_tdls_process_enable_link(struct mwifiex_private *priv, const u8 *peer) ++ { ++ struct mwifiex_sta_node *sta_ptr; ++ struct ieee80211_mcs_info mcs; ++@@ -1035,7 +1039,7 @@ mwifiex_tdls_process_enable_link(struct ++ return 0; ++ } + - /* adjust first fragment's length */ -- skb->len = hdrlen + per_fragm; -+ skb_trim(skb, hdrlen + per_fragm); -- return 0; -- } -- ++-int mwifiex_tdls_oper(struct mwifiex_private *priv, u8 *peer, u8 action) +++int mwifiex_tdls_oper(struct mwifiex_private *priv, const u8 *peer, u8 action) ++ { ++ switch (action) { ++ case MWIFIEX_TDLS_ENABLE_LINK: ++@@ -1050,7 +1054,7 @@ int mwifiex_tdls_oper(struct mwifiex_pri + return 0; + } + -@@ -2900,7 +2912,7 @@ ieee80211_get_buffered_bc(struct ieee802 - cpu_to_le16(IEEE80211_FCTL_MOREDATA); - } -- ++-int mwifiex_get_tdls_link_status(struct mwifiex_private *priv, u8 *mac) +++int mwifiex_get_tdls_link_status(struct mwifiex_private *priv, const u8 *mac) ++ { ++ struct mwifiex_sta_node *sta_ptr; + -- if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) -+ if (sdata->vif.type == NL80211_IFTYPE_AP) - sdata = IEEE80211_DEV_TO_SUB_IF(skb->dev); @@ -4072,12 +4855,33 @@ index a1af6c2..892f51e 100644 -+++ b/net/mac80211/wpa.c -@@ -499,7 +499,7 @@ ieee80211_crypto_ccmp_decrypt(struct iee - hdrlen = ieee80211_hdrlen(hdr->frame_control); -- ++--- a/drivers/net/wireless/mwifiex/util.c +++++ b/drivers/net/wireless/mwifiex/util.c ++@@ -259,7 +259,7 @@ int mwifiex_complete_cmd(struct mwifiex_ ++ * NULL is returned if station entry is not found in associated STA list. ++ */ ++ struct mwifiex_sta_node * ++-mwifiex_get_sta_entry(struct mwifiex_private *priv, u8 *mac) +++mwifiex_get_sta_entry(struct mwifiex_private *priv, const u8 *mac) ++ { ++ struct mwifiex_sta_node *node; + - if (!ieee80211_is_data(hdr->frame_control) && -- !ieee80211_is_robust_mgmt_frame(hdr)) -+ !ieee80211_is_robust_mgmt_frame(skb)) - return RX_CONTINUE; -- ++@@ -280,7 +280,7 @@ mwifiex_get_sta_entry(struct mwifiex_pri ++ * If received mac address is NULL, NULL is returned. ++ */ ++ struct mwifiex_sta_node * ++-mwifiex_add_sta_entry(struct mwifiex_private *priv, u8 *mac) +++mwifiex_add_sta_entry(struct mwifiex_private *priv, const u8 *mac) ++ { ++ struct mwifiex_sta_node *node; ++ unsigned long flags; ++@@ -332,7 +332,7 @@ mwifiex_set_sta_ht_cap(struct mwifiex_pr ++ } + - data_len = skb->len - hdrlen - IEEE80211_CCMP_HDR_LEN - ---- a/net/wireless/ap.c -+++ b/net/wireless/ap.c @@ -4091,14 +4895,127 @@ index a1af6c2..892f51e 100644 - rdev_set_qos_map(rdev, dev, NULL); -+ nl80211_send_ap_stopped(wdev); - } -- ++ /* This function will delete a station entry from station list */ ++-void mwifiex_del_sta_entry(struct mwifiex_private *priv, u8 *mac) +++void mwifiex_del_sta_entry(struct mwifiex_private *priv, const u8 *mac) ++ { ++ struct mwifiex_sta_node *node; ++ unsigned long flags; ++--- a/drivers/net/wireless/mwifiex/wmm.c +++++ b/drivers/net/wireless/mwifiex/wmm.c ++@@ -92,7 +92,7 @@ mwifiex_wmm_ac_debug_print(const struct ++ * The function also initializes the list with the provided RA. ++ */ ++ static struct mwifiex_ra_list_tbl * ++-mwifiex_wmm_allocate_ralist_node(struct mwifiex_adapter *adapter, u8 *ra) +++mwifiex_wmm_allocate_ralist_node(struct mwifiex_adapter *adapter, const u8 *ra) ++ { ++ struct mwifiex_ra_list_tbl *ra_list; + - return err; ---- a/net/wireless/core.c -+++ b/net/wireless/core.c -@@ -203,8 +203,11 @@ void cfg80211_stop_p2p_device(struct cfg -- ++@@ -139,8 +139,7 @@ static u8 mwifiex_get_random_ba_threshol ++ * This function allocates and adds a RA list for all TIDs ++ * with the given RA. ++ */ ++-void ++-mwifiex_ralist_add(struct mwifiex_private *priv, u8 *ra) +++void mwifiex_ralist_add(struct mwifiex_private *priv, const u8 *ra) ++ { ++ int i; ++ struct mwifiex_ra_list_tbl *ra_list; ++@@ -566,7 +565,7 @@ mwifiex_clean_txrx(struct mwifiex_privat ++ */ ++ static struct mwifiex_ra_list_tbl * ++ mwifiex_wmm_get_ralist_node(struct mwifiex_private *priv, u8 tid, ++- u8 *ra_addr) +++ const u8 *ra_addr) ++ { ++ struct mwifiex_ra_list_tbl *ra_list; ++ ++@@ -587,7 +586,8 @@ mwifiex_wmm_get_ralist_node(struct mwifi ++ * retrieved. ++ */ ++ struct mwifiex_ra_list_tbl * ++-mwifiex_wmm_get_queue_raptr(struct mwifiex_private *priv, u8 tid, u8 *ra_addr) +++mwifiex_wmm_get_queue_raptr(struct mwifiex_private *priv, u8 tid, +++ const u8 *ra_addr) ++ { ++ struct mwifiex_ra_list_tbl *ra_list; ++ ++--- a/drivers/net/wireless/mwifiex/wmm.h +++++ b/drivers/net/wireless/mwifiex/wmm.h ++@@ -99,7 +99,7 @@ mwifiex_wmm_is_ra_list_empty(struct list ++ ++ void mwifiex_wmm_add_buf_txqueue(struct mwifiex_private *priv, ++ struct sk_buff *skb); ++-void mwifiex_ralist_add(struct mwifiex_private *priv, u8 *ra); +++void mwifiex_ralist_add(struct mwifiex_private *priv, const u8 *ra); ++ void mwifiex_rotate_priolists(struct mwifiex_private *priv, ++ struct mwifiex_ra_list_tbl *ra, int tid); ++ ++@@ -123,7 +123,8 @@ void mwifiex_wmm_setup_ac_downgrade(stru ++ int mwifiex_ret_wmm_get_status(struct mwifiex_private *priv, ++ const struct host_cmd_ds_command *resp); ++ struct mwifiex_ra_list_tbl * ++-mwifiex_wmm_get_queue_raptr(struct mwifiex_private *priv, u8 tid, u8 *ra_addr); +++mwifiex_wmm_get_queue_raptr(struct mwifiex_private *priv, u8 tid, +++ const u8 *ra_addr); ++ u8 mwifiex_wmm_downgrade_tid(struct mwifiex_private *priv, u32 tid); ++ ++ #endif /* !_MWIFIEX_WMM_H_ */ ++--- a/drivers/net/wireless/orinoco/hw.c +++++ b/drivers/net/wireless/orinoco/hw.c ++@@ -988,8 +988,8 @@ int __orinoco_hw_setup_enc(struct orinoc ++ * tsc must be NULL or up to 8 bytes ++ */ ++ int __orinoco_hw_set_tkip_key(struct orinoco_private *priv, int key_idx, ++- int set_tx, u8 *key, u8 *rsc, size_t rsc_len, ++- u8 *tsc, size_t tsc_len) +++ int set_tx, const u8 *key, const u8 *rsc, +++ size_t rsc_len, const u8 *tsc, size_t tsc_len) ++ { ++ struct { ++ __le16 idx; ++--- a/drivers/net/wireless/orinoco/hw.h +++++ b/drivers/net/wireless/orinoco/hw.h ++@@ -38,8 +38,8 @@ int __orinoco_hw_set_wap(struct orinoco_ ++ int __orinoco_hw_setup_wepkeys(struct orinoco_private *priv); ++ int __orinoco_hw_setup_enc(struct orinoco_private *priv); ++ int __orinoco_hw_set_tkip_key(struct orinoco_private *priv, int key_idx, ++- int set_tx, u8 *key, u8 *rsc, size_t rsc_len, ++- u8 *tsc, size_t tsc_len); +++ int set_tx, const u8 *key, const u8 *rsc, +++ size_t rsc_len, const u8 *tsc, size_t tsc_len); ++ int orinoco_clear_tkip_key(struct orinoco_private *priv, int key_idx); ++ int __orinoco_hw_set_multicast_list(struct orinoco_private *priv, ++ struct net_device *dev, ++--- a/drivers/net/wireless/orinoco/wext.c +++++ b/drivers/net/wireless/orinoco/wext.c ++@@ -52,9 +52,9 @@ static int orinoco_set_key(struct orinoc ++ priv->keys[index].seq_len = seq_len; ++ ++ if (key_len) ++- memcpy(priv->keys[index].key, key, key_len); +++ memcpy((void *)priv->keys[index].key, key, key_len); ++ if (seq_len) ++- memcpy(priv->keys[index].seq, seq, seq_len); +++ memcpy((void *)priv->keys[index].seq, seq, seq_len); ++ ++ switch (alg) { ++ case ORINOCO_ALG_TKIP: ++--- a/drivers/net/wireless/rndis_wlan.c +++++ b/drivers/net/wireless/rndis_wlan.c ++@@ -517,7 +517,7 @@ static int rndis_set_default_key(struct ++ u8 key_index, bool unicast, bool multicast); + - rdev->opencount--; -- ++ static int rndis_get_station(struct wiphy *wiphy, struct net_device *dev, ++- u8 *mac, struct station_info *sinfo); +++ const u8 *mac, struct station_info *sinfo); + -- WARN_ON(rdev->scan_req && rdev->scan_req->wdev == wdev && -- !rdev->scan_req->notified); -+ if (rdev->scan_req && rdev->scan_req->wdev == wdev) { @@ -4106,8 +5023,11 @@ index a1af6c2..892f51e 100644 -+ rdev->scan_req->aborted = true; -+ ___cfg80211_scan_done(rdev, false); -+ } -- } -- ++ static int rndis_dump_station(struct wiphy *wiphy, struct net_device *dev, ++ int idx, u8 *mac, struct station_info *sinfo); ++@@ -2490,7 +2490,7 @@ static void rndis_fill_station_info(stru + } + - static int cfg80211_rfkill_set_block(void *data, bool blocked) -@@ -447,9 +450,6 @@ int wiphy_register(struct wiphy *wiphy) - int i; @@ -4126,7 +5046,56 @@ index a1af6c2..892f51e 100644 -- -- wdev->beacon_interval = 0; - } -- ++ static int rndis_get_station(struct wiphy *wiphy, struct net_device *dev, ++- u8 *mac, struct station_info *sinfo) +++ const u8 *mac, struct station_info *sinfo) ++ { ++ struct rndis_wlan_private *priv = wiphy_priv(wiphy); ++ struct usbnet *usbdev = priv->usbdev; ++--- a/drivers/net/wireless/ti/wlcore/main.c +++++ b/drivers/net/wireless/ti/wlcore/main.c ++@@ -1416,7 +1416,7 @@ void wl1271_rx_filter_free(struct wl12xx ++ ++ int wl1271_rx_filter_alloc_field(struct wl12xx_rx_filter *filter, ++ u16 offset, u8 flags, ++- u8 *pattern, u8 len) +++ const u8 *pattern, u8 len) ++ { ++ struct wl12xx_rx_filter_field *field; ++ ++--- a/drivers/net/wireless/ti/wlcore/wlcore_i.h +++++ b/drivers/net/wireless/ti/wlcore/wlcore_i.h ++@@ -512,8 +512,8 @@ int wl1271_recalc_rx_streaming(struct wl ++ void wl12xx_queue_recovery_work(struct wl1271 *wl); ++ size_t wl12xx_copy_fwlog(struct wl1271 *wl, u8 *memblock, size_t maxlen); ++ int wl1271_rx_filter_alloc_field(struct wl12xx_rx_filter *filter, ++- u16 offset, u8 flags, ++- u8 *pattern, u8 len); +++ u16 offset, u8 flags, +++ const u8 *pattern, u8 len); ++ void wl1271_rx_filter_free(struct wl12xx_rx_filter *filter); ++ struct wl12xx_rx_filter *wl1271_rx_filter_alloc(void); ++ int wl1271_rx_filter_get_fields_size(struct wl12xx_rx_filter *filter); ++--- a/include/net/cfg80211.h +++++ b/include/net/cfg80211.h ++@@ -341,8 +341,8 @@ struct vif_params { ++ * @seq_len: length of @seq. ++ */ ++ struct key_params { ++- u8 *key; ++- u8 *seq; +++ const u8 *key; +++ const u8 *seq; ++ int key_len; ++ int seq_len; ++ u32 cipher; ++@@ -458,7 +458,7 @@ bool cfg80211_chandef_usable(struct wiph ++ */ ++ int cfg80211_chandef_dfs_required(struct wiphy *wiphy, ++ const struct cfg80211_chan_def *chandef, ++- enum nl80211_iftype); +++ enum nl80211_iftype iftype); + - static int cfg80211_netdev_notifier_call(struct notifier_block *nb, -@@ -875,8 +873,11 @@ static int cfg80211_netdev_notifier_call - break; @@ -4139,7 +5108,66 @@ index a1af6c2..892f51e 100644 -+ rdev->scan_req->aborted = true; -+ ___cfg80211_scan_done(rdev, false); -+ } -- ++ /** ++ * ieee80211_chandef_rate_flags - returns rate flags for a channel ++@@ -694,8 +694,10 @@ struct cfg80211_ap_settings { ++ * ++ * @chandef: defines the channel to use after the switch ++ * @beacon_csa: beacon data while performing the switch ++- * @counter_offset_beacon: offset for the counter within the beacon (tail) ++- * @counter_offset_presp: offset for the counter within the probe response +++ * @counter_offsets_beacon: offsets of the counters within the beacon (tail) +++ * @counter_offsets_presp: offsets of the counters within the probe response +++ * @n_counter_offsets_beacon: number of csa counters the beacon (tail) +++ * @n_counter_offsets_presp: number of csa counters in the probe response ++ * @beacon_after: beacon data to be used on the new channel ++ * @radar_required: whether radar detection is required on the new channel ++ * @block_tx: whether transmissions should be blocked while changing ++@@ -704,7 +706,10 @@ struct cfg80211_ap_settings { ++ struct cfg80211_csa_settings { ++ struct cfg80211_chan_def chandef; ++ struct cfg80211_beacon_data beacon_csa; ++- u16 counter_offset_beacon, counter_offset_presp; +++ const u16 *counter_offsets_beacon; +++ const u16 *counter_offsets_presp; +++ unsigned int n_counter_offsets_beacon; +++ unsigned int n_counter_offsets_presp; ++ struct cfg80211_beacon_data beacon_after; ++ bool radar_required; ++ bool block_tx; ++@@ -1164,7 +1169,7 @@ struct bss_parameters { ++ int use_cts_prot; ++ int use_short_preamble; ++ int use_short_slot_time; ++- u8 *basic_rates; +++ const u8 *basic_rates; ++ u8 basic_rates_len; ++ int ap_isolate; ++ int ht_opmode; ++@@ -1694,10 +1699,10 @@ struct cfg80211_disassoc_request { ++ * @ht_capa_mask: The bits of ht_capa which are to be used. ++ */ ++ struct cfg80211_ibss_params { ++- u8 *ssid; ++- u8 *bssid; +++ const u8 *ssid; +++ const u8 *bssid; ++ struct cfg80211_chan_def chandef; ++- u8 *ie; +++ const u8 *ie; ++ u8 ssid_len, ie_len; ++ u16 beacon_interval; ++ u32 basic_rates; ++@@ -1806,8 +1811,8 @@ struct cfg80211_bitrate_mask { ++ * @pmkid: The PMK material itself. ++ */ ++ struct cfg80211_pmksa { ++- u8 *bssid; ++- u8 *pmkid; +++ const u8 *bssid; +++ const u8 *pmkid; ++ }; + - if (WARN_ON(rdev->sched_scan_req && - rdev->sched_scan_req->dev == wdev->netdev)) { ---- a/net/wireless/core.h @@ -4159,7 +5187,32 @@ index a1af6c2..892f51e 100644 -+ struct ieee80211_channel *channel; - } ij; - }; -- }; ++ /** ++@@ -1822,7 +1827,7 @@ struct cfg80211_pmksa { ++ * memory, free @mask only! ++ */ ++ struct cfg80211_pkt_pattern { ++- u8 *mask, *pattern; +++ const u8 *mask, *pattern; ++ int pattern_len; ++ int pkt_offset; ++ }; ++@@ -1986,6 +1991,8 @@ struct cfg80211_update_ft_ies_params { ++ * @len: buffer length ++ * @no_cck: don't use cck rates for this frame ++ * @dont_wait_for_ack: tells the low level not to wait for an ack +++ * @n_csa_offsets: length of csa_offsets array +++ * @csa_offsets: array of all the csa offsets in the frame ++ */ ++ struct cfg80211_mgmt_tx_params { ++ struct ieee80211_channel *chan; ++@@ -1995,6 +2002,8 @@ struct cfg80211_mgmt_tx_params { ++ size_t len; ++ bool no_cck; ++ bool dont_wait_for_ack; +++ int n_csa_offsets; +++ const u16 *csa_offsets; + }; -@@ -257,7 +259,8 @@ int __cfg80211_leave_ibss(struct cfg8021 - struct net_device *dev, bool nowext); - int cfg80211_leave_ibss(struct cfg80211_registered_device *rdev, @@ -4265,7 +5318,7 @@ index a1af6c2..892f51e 100644 -@@ -5509,11 +5515,40 @@ static int nl80211_start_sched_scan(stru - if (n_ssids > wiphy->max_sched_scan_ssids) - return -EINVAL; -- + -- if (info->attrs[NL80211_ATTR_SCHED_SCAN_MATCH]) -+ /* -+ * First, count the number of 'real' matchsets. Due to an issue with @@ -4299,11 +5352,103 @@ index a1af6c2..892f51e 100644 -+ default_match_rssi = nla_get_s32(rssi); -+ } -+ } --+ ++ /** ++@@ -2336,28 +2345,29 @@ struct cfg80211_ops { ++ ++ ++ int (*add_station)(struct wiphy *wiphy, struct net_device *dev, ++- u8 *mac, struct station_parameters *params); +++ const u8 *mac, +++ struct station_parameters *params); ++ int (*del_station)(struct wiphy *wiphy, struct net_device *dev, ++- u8 *mac); +++ const u8 *mac); ++ int (*change_station)(struct wiphy *wiphy, struct net_device *dev, ++- u8 *mac, struct station_parameters *params); +++ const u8 *mac, +++ struct station_parameters *params); ++ int (*get_station)(struct wiphy *wiphy, struct net_device *dev, ++- u8 *mac, struct station_info *sinfo); +++ const u8 *mac, struct station_info *sinfo); ++ int (*dump_station)(struct wiphy *wiphy, struct net_device *dev, ++- int idx, u8 *mac, struct station_info *sinfo); +++ int idx, u8 *mac, struct station_info *sinfo); ++ ++ int (*add_mpath)(struct wiphy *wiphy, struct net_device *dev, ++- u8 *dst, u8 *next_hop); +++ const u8 *dst, const u8 *next_hop); ++ int (*del_mpath)(struct wiphy *wiphy, struct net_device *dev, ++- u8 *dst); +++ const u8 *dst); ++ int (*change_mpath)(struct wiphy *wiphy, struct net_device *dev, ++- u8 *dst, u8 *next_hop); +++ const u8 *dst, const u8 *next_hop); ++ int (*get_mpath)(struct wiphy *wiphy, struct net_device *dev, ++- u8 *dst, u8 *next_hop, ++- struct mpath_info *pinfo); +++ u8 *dst, u8 *next_hop, struct mpath_info *pinfo); ++ int (*dump_mpath)(struct wiphy *wiphy, struct net_device *dev, ++- int idx, u8 *dst, u8 *next_hop, ++- struct mpath_info *pinfo); +++ int idx, u8 *dst, u8 *next_hop, +++ struct mpath_info *pinfo); ++ int (*get_mesh_config)(struct wiphy *wiphy, ++ struct net_device *dev, ++ struct mesh_config *conf); ++@@ -2487,11 +2497,11 @@ struct cfg80211_ops { ++ struct cfg80211_gtk_rekey_data *data); ++ ++ int (*tdls_mgmt)(struct wiphy *wiphy, struct net_device *dev, ++- u8 *peer, u8 action_code, u8 dialog_token, +++ const u8 *peer, u8 action_code, u8 dialog_token, ++ u16 status_code, u32 peer_capability, ++ const u8 *buf, size_t len); ++ int (*tdls_oper)(struct wiphy *wiphy, struct net_device *dev, ++- u8 *peer, enum nl80211_tdls_operation oper); +++ const u8 *peer, enum nl80211_tdls_operation oper); ++ ++ int (*probe_client)(struct wiphy *wiphy, struct net_device *dev, ++ const u8 *peer, u64 *cookie); ++@@ -2638,6 +2648,7 @@ struct ieee80211_iface_limit { ++ * between infrastructure and AP types must match. This is required ++ * only in special cases. ++ * @radar_detect_widths: bitmap of channel widths supported for radar detection +++ * @radar_detect_regions: bitmap of regions supported for radar detection ++ * ++ * With this structure the driver can describe which interface ++ * combinations it supports concurrently. ++@@ -2695,6 +2706,7 @@ struct ieee80211_iface_combination { ++ u8 n_limits; ++ bool beacon_int_infra_match; ++ u8 radar_detect_widths; +++ u8 radar_detect_regions; ++ }; ++ ++ struct ieee80211_txrx_stypes { ++@@ -2925,6 +2937,11 @@ struct wiphy_vendor_command { ++ * (including P2P GO) or 0 to indicate no such limit is advertised. The ++ * driver is allowed to advertise a theoretical limit that it can reach in ++ * some cases, but may not always reach. +++ * +++ * @max_num_csa_counters: Number of supported csa_counters in beacons +++ * and probe responses. This value should be set if the driver +++ * wishes to limit the number of csa counters. Default (0) means +++ * infinite. ++ */ ++ struct wiphy { ++ /* assign these fields before you register the wiphy */ ++@@ -3045,6 +3062,8 @@ struct wiphy { ++ ++ u16 max_ap_assoc_sta; ++ +++ u8 max_num_csa_counters; + + -+ /* However, if there's no other matchset, add the RSSI one */ -+ if (!n_match_sets && default_match_rssi != NL80211_SCAN_RSSI_THOLD_OFF) -+ n_match_sets = 1; -- ++ char priv[0] __aligned(NETDEV_ALIGN); ++ }; + - if (n_match_sets > wiphy->max_match_sets) - return -EINVAL; -@@ -5634,11 +5669,22 @@ static int nl80211_start_sched_scan(stru @@ -4352,11 +5497,70 @@ index a1af6c2..892f51e 100644 -- NL80211_SCAN_RSSI_THOLD_OFF; - i++; - } --+ ++@@ -3273,7 +3292,7 @@ struct wireless_dev { ++ struct cfg80211_ibss_params ibss; ++ struct cfg80211_connect_params connect; ++ struct cfg80211_cached_keys *keys; ++- u8 *ie; +++ const u8 *ie; ++ size_t ie_len; ++ u8 bssid[ETH_ALEN], prev_bssid[ETH_ALEN]; ++ u8 ssid[IEEE80211_MAX_SSID_LEN]; ++@@ -3514,7 +3533,8 @@ int ieee80211_data_to_8023(struct sk_buf ++ * Return: 0 on success, or a negative error code. ++ */ ++ int ieee80211_data_from_8023(struct sk_buff *skb, const u8 *addr, ++- enum nl80211_iftype iftype, u8 *bssid, bool qos); +++ enum nl80211_iftype iftype, const u8 *bssid, +++ bool qos); ++ ++ /** ++ * ieee80211_amsdu_to_8023s - decode an IEEE 802.11n A-MSDU frame ++@@ -4315,7 +4335,7 @@ void cfg80211_roamed_bss(struct net_devi ++ * and not try to connect to any AP any more. ++ */ ++ void cfg80211_disconnected(struct net_device *dev, u16 reason, ++- u8 *ie, size_t ie_len, gfp_t gfp); +++ const u8 *ie, size_t ie_len, gfp_t gfp); ++ ++ /** ++ * cfg80211_ready_on_channel - notification of remain_on_channel start ++@@ -4771,6 +4791,35 @@ int cfg80211_iter_combinations(struct wi ++ void *data), ++ void *data); ++ +++/* +++ * cfg80211_stop_iface - trigger interface disconnection +++ * +++ * @wiphy: the wiphy +++ * @wdev: wireless device +++ * @gfp: context flags +++ * +++ * Trigger interface to be stopped as if AP was stopped, IBSS/mesh left, STA +++ * disconnected. +++ * +++ * Note: This doesn't need any locks and is asynchronous. +++ */ +++void cfg80211_stop_iface(struct wiphy *wiphy, struct wireless_dev *wdev, +++ gfp_t gfp); + + -+ /* there was no other matchset, so the RSSI one is alone */ -+ if (i == 0) -+ request->match_sets[0].rssi_thold = default_match_rssi; --+ +++/** +++ * cfg80211_shutdown_all_interfaces - shut down all interfaces for a wiphy +++ * @wiphy: the wiphy to shut down +++ * +++ * This function shuts down all interfaces belonging to this wiphy by +++ * calling dev_close() (and treating non-netdev interfaces as needed). +++ * It shouldn't really be used unless there are some fatal device errors +++ * that really can't be recovered in any other way. +++ * +++ * Callers must hold the RTNL and be able to deal with callbacks into +++ * the driver while the function is running. +++ */ +++void cfg80211_shutdown_all_interfaces(struct wiphy *wiphy); + + -+ request->min_rssi_thold = INT_MAX; -+ for (i = 0; i < n_match_sets; i++) -+ request->min_rssi_thold = @@ -4368,7 +5572,42 @@ index a1af6c2..892f51e 100644 - - if (info->attrs[NL80211_ATTR_IE]) { -@@ -5751,7 +5810,7 @@ static int nl80211_start_radar_detection -- ++ /* Logging, debugging and troubleshooting/diagnostic helpers. */ ++ ++ /* wiphy_printk helpers, similar to dev_printk */ ++--- a/include/net/mac80211.h +++++ b/include/net/mac80211.h ++@@ -1113,7 +1113,9 @@ enum ieee80211_vif_flags { ++ * @addr: address of this interface ++ * @p2p: indicates whether this AP or STA interface is a p2p ++ * interface, i.e. a GO or p2p-sta respectively ++- * @csa_active: marks whether a channel switch is going on +++ * @csa_active: marks whether a channel switch is going on. Internally it is +++ * write-protected by sdata_lock and local->mtx so holding either is fine +++ * for read access. ++ * @driver_flags: flags/capabilities the driver has for this interface, ++ * these need to be set (or cleared) when the interface is added ++ * or, if supported by the driver, the interface type is changed ++@@ -1374,6 +1376,7 @@ struct ieee80211_sta_rates { ++ * the station moves to associated state. ++ * @smps_mode: current SMPS mode (off, static or dynamic) ++ * @rates: rate control selection table +++ * @tdls: indicates whether the STA is a TDLS peer ++ */ ++ struct ieee80211_sta { ++ u32 supp_rates[IEEE80211_NUM_BANDS]; ++@@ -1388,6 +1391,7 @@ struct ieee80211_sta { ++ enum ieee80211_sta_rx_bandwidth bandwidth; ++ enum ieee80211_smps_mode smps_mode; ++ struct ieee80211_sta_rates __rcu *rates; +++ bool tdls; ++ ++ /* must be last */ ++ u8 drv_priv[0] __aligned(sizeof(void *)); ++@@ -3407,6 +3411,47 @@ void ieee80211_tx_status_irqsafe(struct ++ */ ++ void ieee80211_report_low_ack(struct ieee80211_sta *sta, u32 num_packets); + - err = rdev->ops->start_radar_detection(&rdev->wiphy, dev, &chandef); - if (!err) { -- wdev->channel = chandef.chan; @@ -4402,8 +5641,73 @@ index a1af6c2..892f51e 100644 - sband, -@@ -10054,40 +10116,31 @@ void nl80211_send_scan_start(struct cfg8 - NL80211_MCGRP_SCAN, GFP_KERNEL); -- } -- +++#define IEEE80211_MAX_CSA_COUNTERS_NUM 2 +++ +++/** +++ * struct ieee80211_mutable_offsets - mutable beacon offsets +++ * @tim_offset: position of TIM element +++ * @tim_length: size of TIM element +++ * @csa_counter_offs: array of IEEE80211_MAX_CSA_COUNTERS_NUM offsets +++ * to CSA counters. This array can contain zero values which +++ * should be ignored. +++ */ +++struct ieee80211_mutable_offsets { +++ u16 tim_offset; +++ u16 tim_length; +++ +++ u16 csa_counter_offs[IEEE80211_MAX_CSA_COUNTERS_NUM]; +++}; +++ +++/** +++ * ieee80211_beacon_get_template - beacon template generation function +++ * @hw: pointer obtained from ieee80211_alloc_hw(). +++ * @vif: &struct ieee80211_vif pointer from the add_interface callback. +++ * @offs: &struct ieee80211_mutable_offsets pointer to struct that will +++ * receive the offsets that may be updated by the driver. +++ * +++ * If the driver implements beaconing modes, it must use this function to +++ * obtain the beacon template. +++ * +++ * This function should be used if the beacon frames are generated by the +++ * device, and then the driver must use the returned beacon as the template +++ * The driver or the device are responsible to update the DTIM and, when +++ * applicable, the CSA count. +++ * +++ * The driver is responsible for freeing the returned skb. +++ * +++ * Return: The beacon template. %NULL on error. +++ */ +++struct sk_buff * +++ieee80211_beacon_get_template(struct ieee80211_hw *hw, +++ struct ieee80211_vif *vif, +++ struct ieee80211_mutable_offsets *offs); +++ ++ /** ++ * ieee80211_beacon_get_tim - beacon generation function ++ * @hw: pointer obtained from ieee80211_alloc_hw(). ++@@ -3418,16 +3463,12 @@ void ieee80211_report_low_ack(struct iee ++ * Set to 0 if invalid (in non-AP modes). ++ * ++ * If the driver implements beaconing modes, it must use this function to ++- * obtain the beacon frame/template. +++ * obtain the beacon frame. ++ * ++ * If the beacon frames are generated by the host system (i.e., not in ++ * hardware/firmware), the driver uses this function to get each beacon ++- * frame from mac80211 -- it is responsible for calling this function ++- * before the beacon is needed (e.g. based on hardware interrupt). ++- * ++- * If the beacon frames are generated by the device, then the driver ++- * must use the returned beacon as the template and change the TIM IE ++- * according to the current DTIM parameters/TIM bitmap. +++ * frame from mac80211 -- it is responsible for calling this function exactly +++ * once before the beacon is needed (e.g. based on hardware interrupt). ++ * ++ * The driver is responsible for freeing the returned skb. ++ * ++@@ -3453,6 +3494,20 @@ static inline struct sk_buff *ieee80211_ + } + --void nl80211_send_scan_done(struct cfg80211_registered_device *rdev, -- struct wireless_dev *wdev) -+struct sk_buff *nl80211_build_scan_msg(struct cfg80211_registered_device *rdev, @@ -4415,7 +5719,65 @@ index a1af6c2..892f51e 100644 - if (!msg) -- return; -+ return NULL; -- ++ /** +++ * ieee80211_csa_update_counter - request mac80211 to decrement the csa counter +++ * @vif: &struct ieee80211_vif pointer from the add_interface callback. +++ * +++ * The csa counter should be updated after each beacon transmission. +++ * This function is called implicitly when +++ * ieee80211_beacon_get/ieee80211_beacon_get_tim are called, however if the +++ * beacon frames are generated by the device, the driver should call this +++ * function after each beacon transmission to sync mac80211's csa counters. +++ * +++ * Return: new csa counter value +++ */ +++u8 ieee80211_csa_update_counter(struct ieee80211_vif *vif); +++ +++/** ++ * ieee80211_csa_finish - notify mac80211 about channel switch ++ * @vif: &struct ieee80211_vif pointer from the add_interface callback. ++ * ++--- a/include/uapi/linux/nl80211.h +++++ b/include/uapi/linux/nl80211.h ++@@ -503,6 +503,9 @@ ++ * TX status event pertaining to the TX request. ++ * %NL80211_ATTR_TX_NO_CCK_RATE is used to decide whether to send the ++ * management frames at CCK rate or not in 2GHz band. +++ * %NL80211_ATTR_CSA_C_OFFSETS_TX is an array of offsets to CSA +++ * counters which will be updated to the current value. This attribute +++ * is used during CSA period. ++ * @NL80211_CMD_FRAME_WAIT_CANCEL: When an off-channel TX was requested, this ++ * command may be used with the corresponding cookie to cancel the wait ++ * time if it is known that it is no longer necessary. ++@@ -1525,10 +1528,10 @@ enum nl80211_commands { ++ * operation). ++ * @NL80211_ATTR_CSA_IES: Nested set of attributes containing the IE information ++ * for the time while performing a channel switch. ++- * @NL80211_ATTR_CSA_C_OFF_BEACON: Offset of the channel switch counter ++- * field in the beacons tail (%NL80211_ATTR_BEACON_TAIL). ++- * @NL80211_ATTR_CSA_C_OFF_PRESP: Offset of the channel switch counter ++- * field in the probe response (%NL80211_ATTR_PROBE_RESP). +++ * @NL80211_ATTR_CSA_C_OFF_BEACON: An array of offsets (u16) to the channel +++ * switch counters in the beacons tail (%NL80211_ATTR_BEACON_TAIL). +++ * @NL80211_ATTR_CSA_C_OFF_PRESP: An array of offsets (u16) to the channel +++ * switch counters in the probe response (%NL80211_ATTR_PROBE_RESP). ++ * ++ * @NL80211_ATTR_RXMGMT_FLAGS: flags for nl80211_send_mgmt(), u32. ++ * As specified in the &enum nl80211_rxmgmt_flags. ++@@ -1576,6 +1579,11 @@ enum nl80211_commands { ++ * advertise values that cannot always be met. In such cases, an attempt ++ * to add a new station entry with @NL80211_CMD_NEW_STATION may fail. ++ * +++ * @NL80211_ATTR_CSA_C_OFFSETS_TX: An array of csa counter offsets (u16) which +++ * should be updated when the frame is transmitted. +++ * @NL80211_ATTR_MAX_CSA_COUNTERS: U8 attribute used to advertise the maximum +++ * supported number of csa counters. +++ * ++ * @NL80211_ATTR_TDLS_PEER_CAPABILITY: flags for TDLS peer capabilities, u32. ++ * As specified in the &enum nl80211_tdls_peer_capability. ++ * ++@@ -1920,6 +1928,9 @@ enum nl80211_attrs { + - if (nl80211_send_scan_msg(msg, rdev, wdev, 0, 0, 0, -- NL80211_CMD_NEW_SCAN_RESULTS) < 0) { -+ aborted ? NL80211_CMD_SCAN_ABORTED : @@ -4424,17 +5786,59 @@ index a1af6c2..892f51e 100644 -- return; -+ return NULL; - } -- ++ NL80211_ATTR_IFACE_SOCKET_OWNER, + -- genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0, -- NL80211_MCGRP_SCAN, GFP_KERNEL); -+ return msg; -- } -- +++ NL80211_ATTR_CSA_C_OFFSETS_TX, +++ NL80211_ATTR_MAX_CSA_COUNTERS, +++ ++ /* add attributes here, update the policy in nl80211.c */ ++ ++ __NL80211_ATTR_AFTER_LAST, ++@@ -3688,6 +3699,8 @@ enum nl80211_iface_limit_attrs { ++ * different channels may be used within this group. ++ * @NL80211_IFACE_COMB_RADAR_DETECT_WIDTHS: u32 attribute containing the bitmap ++ * of supported channel widths for radar detection. +++ * @NL80211_IFACE_COMB_RADAR_DETECT_REGIONS: u32 attribute containing the bitmap +++ * of supported regulatory regions for radar detection. ++ * @NUM_NL80211_IFACE_COMB: number of attributes ++ * @MAX_NL80211_IFACE_COMB: highest attribute number ++ * ++@@ -3721,6 +3734,7 @@ enum nl80211_if_combination_attrs { ++ NL80211_IFACE_COMB_STA_AP_BI_MATCH, ++ NL80211_IFACE_COMB_NUM_CHANNELS, ++ NL80211_IFACE_COMB_RADAR_DETECT_WIDTHS, +++ NL80211_IFACE_COMB_RADAR_DETECT_REGIONS, ++ ++ /* keep last */ ++ NUM_NL80211_IFACE_COMB, ++--- a/net/mac80211/Makefile +++++ b/net/mac80211/Makefile ++@@ -25,7 +25,8 @@ mac80211-y := \ ++ wme.o \ ++ event.o \ ++ chan.o \ ++- trace.o mlme.o +++ trace.o mlme.o \ +++ tdls.o ++ ++ mac80211-$(CPTCFG_MAC80211_LEDS) += led.o ++ mac80211-$(CPTCFG_MAC80211_DEBUGFS) += \ ++--- a/net/mac80211/cfg.c +++++ b/net/mac80211/cfg.c ++@@ -777,7 +777,7 @@ static void ieee80211_get_et_strings(str + } + --void nl80211_send_scan_aborted(struct cfg80211_registered_device *rdev, -- struct wireless_dev *wdev) -+void nl80211_send_scan_result(struct cfg80211_registered_device *rdev, -+ struct sk_buff *msg) -- { ++ static int ieee80211_dump_station(struct wiphy *wiphy, struct net_device *dev, ++- int idx, u8 *mac, struct station_info *sinfo) +++ int idx, u8 *mac, struct station_info *sinfo) + { -- struct sk_buff *msg; -- -- msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); @@ -4449,11 +5853,14 @@ index a1af6c2..892f51e 100644 -- - genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0, - NL80211_MCGRP_SCAN, GFP_KERNEL); -- } ++ struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); ++ struct ieee80211_local *local = sdata->local; ++@@ -807,7 +807,7 @@ static int ieee80211_dump_survey(struct + } -@@ -11158,7 +11211,8 @@ void cfg80211_ch_switch_notify(struct ne - wdev->iftype != NL80211_IFTYPE_MESH_POINT)) - return; -- + -- wdev->channel = chandef->chan; -+ wdev->chandef = *chandef; -+ wdev->preset_chandef = *chandef; @@ -4461,38 +5868,63 @@ index a1af6c2..892f51e 100644 - } - EXPORT_SYMBOL(cfg80211_ch_switch_notify); -@@ -11673,6 +11727,35 @@ void cfg80211_crit_proto_stopped(struct -- } ++ static int ieee80211_get_station(struct wiphy *wiphy, struct net_device *dev, ++- u8 *mac, struct station_info *sinfo) +++ const u8 *mac, struct station_info *sinfo) ++ { ++ struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); ++ struct ieee80211_local *local = sdata->local; ++@@ -1084,6 +1084,31 @@ static int ieee80211_change_beacon(struc ++ return 0; + } - EXPORT_SYMBOL(cfg80211_crit_proto_stopped); -- + -+void nl80211_send_ap_stopped(struct wireless_dev *wdev) --+{ +++bool ieee80211_csa_needs_block_tx(struct ieee80211_local *local) + +{ -+ struct wiphy *wiphy = wdev->wiphy; -+ struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); -+ struct sk_buff *msg; -+ void *hdr; --+ +++ struct ieee80211_sub_if_data *sdata; + + -+ msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); -+ if (!msg) -+ return; --+ +++ lockdep_assert_held(&local->mtx); +++ +++ rcu_read_lock(); +++ list_for_each_entry_rcu(sdata, &local->interfaces, list) { +++ if (!ieee80211_sdata_running(sdata)) +++ continue; + + -+ hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_STOP_AP); -+ if (!hdr) -+ goto out; --+ +++ if (!sdata->vif.csa_active) +++ continue; + + -+ if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) || -+ nla_put_u32(msg, NL80211_ATTR_IFINDEX, wdev->netdev->ifindex) || -+ nla_put_u64(msg, NL80211_ATTR_WDEV, wdev_id(wdev))) -+ goto out; --+ +++ if (!sdata->csa_block_tx) +++ continue; + + -+ genlmsg_end(msg, hdr); --+ +++ rcu_read_unlock(); +++ return true; +++ } +++ rcu_read_unlock(); + + -+ genlmsg_multicast_netns(&nl80211_fam, wiphy_net(wiphy), msg, 0, -+ NL80211_MCGRP_MLME, GFP_KERNEL); -+ return; -+ out: -+ nlmsg_free(msg); --+} --+ +++ return false; + +} + + - /* initialisation/exit functions */ - - int nl80211_init(void) @@ -4531,7 +5963,8 @@ index a1af6c2..892f51e 100644 --void ___cfg80211_scan_done(struct cfg80211_registered_device *rdev) -+void ___cfg80211_scan_done(struct cfg80211_registered_device *rdev, -+ bool send_message) -- { ++ static int ieee80211_stop_ap(struct wiphy *wiphy, struct net_device *dev) + { - struct cfg80211_scan_request *request; - struct wireless_dev *wdev; -+ struct sk_buff *msg; @@ -4540,18 +5973,34 @@ index a1af6c2..892f51e 100644 - #endif - - ASSERT_RTNL(); -- ++ struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); ++@@ -1101,7 +1126,14 @@ static int ieee80211_stop_ap(struct wiph ++ old_probe_resp = sdata_dereference(sdata->u.ap.probe_resp, sdata); + -- request = rdev->scan_req; -+ if (rdev->scan_msg) { -+ nl80211_send_scan_result(rdev, rdev->scan_msg); -+ rdev->scan_msg = NULL; -+ return; -+ } -- ++ /* abort any running channel switch */ +++ mutex_lock(&local->mtx); ++ sdata->vif.csa_active = false; +++ if (!ieee80211_csa_needs_block_tx(local)) +++ ieee80211_wake_queues_by_reason(&local->hw, +++ IEEE80211_MAX_QUEUE_MAP, +++ IEEE80211_QUEUE_STOP_REASON_CSA); +++ mutex_unlock(&local->mtx); +++ ++ kfree(sdata->u.ap.next_beacon); ++ sdata->u.ap.next_beacon = NULL; + -+ request = rdev->scan_req; - if (!request) - return; -- ++@@ -1425,7 +1457,8 @@ static int sta_apply_parameters(struct i ++ } + -@@ -186,18 +193,16 @@ void ___cfg80211_scan_done(struct cfg802 - if (wdev->netdev) - cfg80211_sme_scan_done(wdev->netdev); @@ -4572,15 +6021,31 @@ index a1af6c2..892f51e 100644 -+ spin_lock_bh(&rdev->bss_lock); -+ __cfg80211_bss_expire(rdev, request->scan_start); -+ spin_unlock_bh(&rdev->bss_lock); -- } -- ++ static int ieee80211_add_station(struct wiphy *wiphy, struct net_device *dev, ++- u8 *mac, struct station_parameters *params) +++ const u8 *mac, +++ struct station_parameters *params) ++ { ++ struct ieee80211_local *local = wiphy_priv(wiphy); ++ struct sta_info *sta; ++@@ -1459,6 +1492,8 @@ static int ieee80211_add_station(struct ++ if (!(params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER))) { ++ sta_info_pre_move_state(sta, IEEE80211_STA_AUTH); ++ sta_info_pre_move_state(sta, IEEE80211_STA_ASSOC); +++ } else { +++ sta->sta.tdls = true; + } + -+ msg = nl80211_build_scan_msg(rdev, wdev, request->aborted); -+ - #ifdef CPTCFG_CFG80211_WEXT - if (wdev->netdev && !request->aborted) { - memset(&wrqu, 0, sizeof(wrqu)); -@@ -211,6 +216,11 @@ void ___cfg80211_scan_done(struct cfg802 -- ++ err = sta_apply_parameters(local, sta, params); ++@@ -1492,7 +1527,7 @@ static int ieee80211_add_station(struct ++ } + - rdev->scan_req = NULL; - kfree(request); -+ @@ -4588,22 +6053,49 @@ index a1af6c2..892f51e 100644 -+ rdev->scan_msg = msg; -+ else -+ nl80211_send_scan_result(rdev, msg); -- } -- ++ static int ieee80211_del_station(struct wiphy *wiphy, struct net_device *dev, ++- u8 *mac) +++ const u8 *mac) ++ { ++ struct ieee80211_sub_if_data *sdata; ++ ++@@ -1506,7 +1541,7 @@ static int ieee80211_del_station(struct + } + - void __cfg80211_scan_done(struct work_struct *wk) -@@ -221,7 +231,7 @@ void __cfg80211_scan_done(struct work_st - scan_done_wk); -- ++ static int ieee80211_change_station(struct wiphy *wiphy, ++- struct net_device *dev, u8 *mac, +++ struct net_device *dev, const u8 *mac, ++ struct station_parameters *params) ++ { ++ struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); ++@@ -1631,7 +1666,7 @@ out_err: + - rtnl_lock(); -- ___cfg80211_scan_done(rdev); -+ ___cfg80211_scan_done(rdev, true); - rtnl_unlock(); -- } -- ++ #ifdef CPTCFG_MAC80211_MESH ++ static int ieee80211_add_mpath(struct wiphy *wiphy, struct net_device *dev, ++- u8 *dst, u8 *next_hop) +++ const u8 *dst, const u8 *next_hop) ++ { ++ struct ieee80211_sub_if_data *sdata; ++ struct mesh_path *mpath; ++@@ -1659,7 +1694,7 @@ static int ieee80211_add_mpath(struct wi + } + -@@ -1079,7 +1089,7 @@ int cfg80211_wext_siwscan(struct net_dev - if (IS_ERR(rdev)) - return PTR_ERR(rdev); -- ++ static int ieee80211_del_mpath(struct wiphy *wiphy, struct net_device *dev, ++- u8 *dst) +++ const u8 *dst) ++ { ++ struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); + -- if (rdev->scan_req) { -+ if (rdev->scan_req || rdev->scan_msg) { - err = -EBUSY; @@ -4612,39 +6104,167 @@ index a1af6c2..892f51e 100644 -@@ -1481,7 +1491,7 @@ int cfg80211_wext_giwscan(struct net_dev - if (IS_ERR(rdev)) - return PTR_ERR(rdev); -- ++@@ -1670,9 +1705,8 @@ static int ieee80211_del_mpath(struct wi ++ return 0; ++ } ++ ++-static int ieee80211_change_mpath(struct wiphy *wiphy, ++- struct net_device *dev, ++- u8 *dst, u8 *next_hop) +++static int ieee80211_change_mpath(struct wiphy *wiphy, struct net_device *dev, +++ const u8 *dst, const u8 *next_hop) ++ { ++ struct ieee80211_sub_if_data *sdata; ++ struct mesh_path *mpath; ++@@ -1764,8 +1798,8 @@ static int ieee80211_get_mpath(struct wi ++ } + -- if (rdev->scan_req) -+ if (rdev->scan_req || rdev->scan_msg) - return -EAGAIN; -- ++ static int ieee80211_dump_mpath(struct wiphy *wiphy, struct net_device *dev, ++- int idx, u8 *dst, u8 *next_hop, ++- struct mpath_info *pinfo) +++ int idx, u8 *dst, u8 *next_hop, +++ struct mpath_info *pinfo) ++ { ++ struct ieee80211_sub_if_data *sdata; ++ struct mesh_path *mpath; ++@@ -3019,26 +3053,11 @@ void ieee80211_csa_finish(struct ieee802 ++ } ++ EXPORT_SYMBOL(ieee80211_csa_finish); + - res = ieee80211_scan_results(rdev, info, extra, data->length); ---- a/net/wireless/sme.c -+++ b/net/wireless/sme.c -@@ -67,7 +67,7 @@ static int cfg80211_conn_scan(struct wir - ASSERT_RDEV_LOCK(rdev); - ASSERT_WDEV_LOCK(wdev); -- ++-static void ieee80211_csa_finalize(struct ieee80211_sub_if_data *sdata) +++static int ieee80211_set_after_csa_beacon(struct ieee80211_sub_if_data *sdata, +++ u32 *changed) ++ { ++- struct ieee80211_local *local = sdata->local; ++- int err, changed = 0; ++- ++- sdata_assert_lock(sdata); ++- ++- mutex_lock(&local->mtx); ++- sdata->radar_required = sdata->csa_radar_required; ++- err = ieee80211_vif_change_channel(sdata, &changed); ++- mutex_unlock(&local->mtx); ++- if (WARN_ON(err < 0)) ++- return; ++- ++- if (!local->use_chanctx) { ++- local->_oper_chandef = sdata->csa_chandef; ++- ieee80211_hw_config(local, 0); ++- } +++ int err; + -- if (rdev->scan_req) -+ if (rdev->scan_req || rdev->scan_msg) - return -EBUSY; -- ++- sdata->vif.csa_active = false; ++ switch (sdata->vif.type) { ++ case NL80211_IFTYPE_AP: ++ err = ieee80211_assign_beacon(sdata, sdata->u.ap.next_beacon); ++@@ -3046,35 +3065,75 @@ static void ieee80211_csa_finalize(struc ++ sdata->u.ap.next_beacon = NULL; + - if (wdev->conn->params.channel) ---- a/net/mac80211/mlme.c -+++ b/net/mac80211/mlme.c -@@ -1001,7 +1001,6 @@ ieee80211_sta_process_chanswitch(struct -- } -- ++ if (err < 0) ++- return; ++- changed |= err; +++ return err; +++ *changed |= err; ++ break; ++ case NL80211_IFTYPE_ADHOC: ++ err = ieee80211_ibss_finish_csa(sdata); ++ if (err < 0) ++- return; ++- changed |= err; +++ return err; +++ *changed |= err; ++ break; ++ #ifdef CPTCFG_MAC80211_MESH ++ case NL80211_IFTYPE_MESH_POINT: ++ err = ieee80211_mesh_finish_csa(sdata); ++ if (err < 0) ++- return; ++- changed |= err; +++ return err; +++ *changed |= err; ++ break; ++ #endif ++ default: ++ WARN_ON(1); ++- return; +++ return -EINVAL; + } + - ifmgd->flags |= IEEE80211_STA_CSA_RECEIVED; -- sdata->vif.csa_active = true; -- +++ +++ return 0; +++} +++ +++static int __ieee80211_csa_finalize(struct ieee80211_sub_if_data *sdata) +++{ +++ struct ieee80211_local *local = sdata->local; +++ u32 changed = 0; +++ int err; +++ +++ sdata_assert_lock(sdata); +++ lockdep_assert_held(&local->mtx); +++ +++ sdata->radar_required = sdata->csa_radar_required; +++ err = ieee80211_vif_change_channel(sdata, &changed); +++ if (err < 0) +++ return err; +++ +++ if (!local->use_chanctx) { +++ local->_oper_chandef = sdata->csa_chandef; +++ ieee80211_hw_config(local, 0); +++ } +++ +++ sdata->vif.csa_active = false; +++ +++ err = ieee80211_set_after_csa_beacon(sdata, &changed); +++ if (err) +++ return err; +++ ++ ieee80211_bss_info_change_notify(sdata, changed); +++ cfg80211_ch_switch_notify(sdata->dev, &sdata->csa_chandef); + - mutex_lock(&local->chanctx_mtx); - if (local->use_chanctx) { -@@ -1039,6 +1038,7 @@ ieee80211_sta_process_chanswitch(struct - mutex_unlock(&local->chanctx_mtx); -- ++- ieee80211_wake_queues_by_reason(&sdata->local->hw, +++ if (!ieee80211_csa_needs_block_tx(local)) +++ ieee80211_wake_queues_by_reason(&local->hw, ++ IEEE80211_MAX_QUEUE_MAP, ++ IEEE80211_QUEUE_STOP_REASON_CSA); + - sdata->csa_chandef = csa_ie.chandef; -+ sdata->vif.csa_active = true; -- ++- cfg80211_ch_switch_notify(sdata->dev, &sdata->csa_chandef); +++ return 0; +++} +++ +++static void ieee80211_csa_finalize(struct ieee80211_sub_if_data *sdata) +++{ +++ if (__ieee80211_csa_finalize(sdata)) { +++ sdata_info(sdata, "failed to finalize CSA, disconnecting\n"); +++ cfg80211_stop_iface(sdata->local->hw.wiphy, &sdata->wdev, +++ GFP_KERNEL); +++ } ++ } + - if (csa_ie.mode) - ieee80211_stop_queues_by_reason(&local->hw, ---- a/net/mac80211/chan.c @@ -4652,9 +6272,17 @@ index a1af6c2..892f51e 100644 -@@ -196,6 +196,8 @@ static bool ieee80211_is_radar_required( - { - struct ieee80211_sub_if_data *sdata; -- ++ void ieee80211_csa_finalize_work(struct work_struct *work) ++@@ -3082,8 +3141,11 @@ void ieee80211_csa_finalize_work(struct ++ struct ieee80211_sub_if_data *sdata = ++ container_of(work, struct ieee80211_sub_if_data, ++ csa_finalize_work); +++ struct ieee80211_local *local = sdata->local; + -+ lockdep_assert_held(&local->mtx); --+ ++ sdata_lock(sdata); +++ mutex_lock(&local->mtx); + + - rcu_read_lock(); - list_for_each_entry_rcu(sdata, &local->interfaces, list) { - if (sdata->radar_required) { @@ -4674,7 +6302,12 @@ index a1af6c2..892f51e 100644 - } -+ sdata->radar_required = radar_required; - mutex_unlock(&local->mtx); -- ++ /* AP might have been stopped while waiting for the lock. */ ++ if (!sdata->vif.csa_active) ++ goto unlock; ++@@ -3094,6 +3156,7 @@ void ieee80211_csa_finalize_work(struct ++ ieee80211_csa_finalize(sdata); + - memcpy(ifibss->bssid, bssid, ETH_ALEN); -@@ -318,7 +318,6 @@ static void __ieee80211_sta_join_ibss(st - rcu_assign_pointer(ifibss->presp, presp); @@ -4690,15 +6323,29 @@ index a1af6c2..892f51e 100644 - netif_carrier_on(sdata->dev); -- cfg80211_ibss_joined(sdata->dev, ifibss->bssid, GFP_KERNEL); -+ cfg80211_ibss_joined(sdata->dev, ifibss->bssid, chan, GFP_KERNEL); -- } -- ++ unlock: +++ mutex_unlock(&local->mtx); ++ sdata_unlock(sdata); + } + - static void ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata, -@@ -802,6 +801,8 @@ ieee80211_ibss_process_chanswitch(struct - int err; - u32 sta_flags; -- ++@@ -3129,9 +3192,25 @@ static int ieee80211_set_csa_beacon(stru ++ if (params->count <= 1) ++ break; + -+ sdata_assert_lock(sdata); --+ ++- sdata->csa_counter_offset_beacon = ++- params->counter_offset_beacon; ++- sdata->csa_counter_offset_presp = params->counter_offset_presp; +++ if ((params->n_counter_offsets_beacon > +++ IEEE80211_MAX_CSA_COUNTERS_NUM) || +++ (params->n_counter_offsets_presp > +++ IEEE80211_MAX_CSA_COUNTERS_NUM)) +++ return -EINVAL; + + - sta_flags = IEEE80211_STA_DISABLE_VHT; - switch (ifibss->chandef.width) { - case NL80211_CHAN_WIDTH_5: @@ -4706,20 +6353,46 @@ index a1af6c2..892f51e 100644 - memcpy(((struct ieee80211_mgmt *) skb->data)->da, mgmt->sa, ETH_ALEN); - ibss_dbg(sdata, "Sending ProbeResp to %pM\n", mgmt->sa); - IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT; --+ +++ /* make sure we don't have garbage in other counters */ +++ memset(sdata->csa_counter_offset_beacon, 0, +++ sizeof(sdata->csa_counter_offset_beacon)); +++ memset(sdata->csa_counter_offset_presp, 0, +++ sizeof(sdata->csa_counter_offset_presp)); + + -+ /* avoid excessive retries for probe request to wildcard SSIDs */ -+ if (pos[1] == 0) -+ IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_CTL_NO_ACK; --+ +++ memcpy(sdata->csa_counter_offset_beacon, +++ params->counter_offsets_beacon, +++ params->n_counter_offsets_beacon * sizeof(u16)); +++ memcpy(sdata->csa_counter_offset_presp, +++ params->counter_offsets_presp, +++ params->n_counter_offsets_presp * sizeof(u16)); + + - ieee80211_tx_skb(sdata, skb); -- } -- ++ err = ieee80211_assign_beacon(sdata, ¶ms->beacon_csa); ++ if (err < 0) { ++ kfree(sdata->u.ap.next_beacon); ++@@ -3220,8 +3299,9 @@ static int ieee80211_set_csa_beacon(stru ++ return 0; + } + ---- a/net/mac80211/mesh.c -+++ b/net/mac80211/mesh.c -@@ -872,6 +872,8 @@ ieee80211_mesh_process_chnswitch(struct - if (!ifmsh->mesh_id) - return false; -- ++-int ieee80211_channel_switch(struct wiphy *wiphy, struct net_device *dev, ++- struct cfg80211_csa_settings *params) +++static int +++__ieee80211_channel_switch(struct wiphy *wiphy, struct net_device *dev, +++ struct cfg80211_csa_settings *params) ++ { ++ struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); ++ struct ieee80211_local *local = sdata->local; ++@@ -3230,6 +3310,7 @@ int ieee80211_channel_switch(struct wiph ++ int err, num_chanctx, changed = 0; + -+ sdata_assert_lock(sdata); -+ - sta_flags = IEEE80211_STA_DISABLE_VHT; @@ -4752,11 +6425,17 @@ index a1af6c2..892f51e 100644 -@@ -1766,7 +1766,8 @@ static void lbs_join_post(struct lbs_pri - memcpy(priv->wdev->ssid, params->ssid, params->ssid_len); - priv->wdev->ssid_len = params->ssid_len; -- ++ sdata_assert_lock(sdata); +++ lockdep_assert_held(&local->mtx); + -- cfg80211_ibss_joined(priv->dev, bssid, GFP_KERNEL); -+ cfg80211_ibss_joined(priv->dev, bssid, params->chandef.chan, -+ GFP_KERNEL); -- ++ if (!list_empty(&local->roc_list) || local->scanning) ++ return -EBUSY; ++@@ -3272,15 +3353,16 @@ int ieee80211_channel_switch(struct wiph ++ return err; + - /* TODO: consider doing this at MACREG_INT_CODE_LINK_SENSED time */ - priv->connect_status = LBS_CONNECTED; ---- a/drivers/net/wireless/mwifiex/cfg80211.c @@ -4781,105 +6460,510 @@ index a1af6c2..892f51e 100644 -+ cfg80211_ibss_joined(usbdev->net, bssid, -+ get_current_channel(usbdev, NULL), -+ GFP_KERNEL); -- ++ sdata->csa_radar_required = params->radar_required; ++- ++- if (params->block_tx) ++- ieee80211_stop_queues_by_reason(&local->hw, ++- IEEE80211_MAX_QUEUE_MAP, ++- IEEE80211_QUEUE_STOP_REASON_CSA); ++- ++ sdata->csa_chandef = params->chandef; +++ sdata->csa_block_tx = params->block_tx; +++ sdata->csa_current_counter = params->count; ++ sdata->vif.csa_active = true; ++ +++ if (sdata->csa_block_tx) +++ ieee80211_stop_queues_by_reason(&local->hw, +++ IEEE80211_MAX_QUEUE_MAP, +++ IEEE80211_QUEUE_STOP_REASON_CSA); +++ ++ if (changed) { ++ ieee80211_bss_info_change_notify(sdata, changed); ++ drv_channel_switch_beacon(sdata, ¶ms->chandef); ++@@ -3292,6 +3374,20 @@ int ieee80211_channel_switch(struct wiph ++ return 0; ++ } + - kfree(info); -+--- a/drivers/net/wireless/ath/ath9k/ar5008_phy.c -++++ b/drivers/net/wireless/ath/ath9k/ar5008_phy.c -+@@ -1004,11 +1004,9 @@ static bool ar5008_hw_ani_control_new(st -+ case ATH9K_ANI_FIRSTEP_LEVEL:{ -+ u32 level = param; +++int ieee80211_channel_switch(struct wiphy *wiphy, struct net_device *dev, +++ struct cfg80211_csa_settings *params) +++{ +++ struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); +++ struct ieee80211_local *local = sdata->local; +++ int err; +++ +++ mutex_lock(&local->mtx); +++ err = __ieee80211_channel_switch(wiphy, dev, params); +++ mutex_unlock(&local->mtx); +++ +++ return err; +++} +++ ++ static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev, ++ struct cfg80211_mgmt_tx_params *params, ++ u64 *cookie) ++@@ -3304,6 +3400,7 @@ static int ieee80211_mgmt_tx(struct wiph ++ bool need_offchan = false; ++ u32 flags; ++ int ret; +++ u8 *data; ---- a/net/wireless/ibss.c -+++ b/net/wireless/ibss.c -@@ -14,7 +14,8 @@ - #include "rdev-ops.h" -+- value = level * 2; -++ value = level; -+ REG_RMW_FIELD(ah, AR_PHY_FIND_SIG, -+ AR_PHY_FIND_SIG_FIRSTEP, value); -+- REG_RMW_FIELD(ah, AR_PHY_FIND_SIG_LOW, -+- AR_PHY_FIND_SIG_FIRSTEP_LOW, value); ++ if (params->dont_wait_for_ack) ++ flags = IEEE80211_TX_CTL_NO_ACK; ++@@ -3397,7 +3494,20 @@ static int ieee80211_mgmt_tx(struct wiph ++ } ++ skb_reserve(skb, local->hw.extra_tx_headroom); -+ if (level != aniState->firstepLevel) { -+ ath_dbg(common, ANI, -+--- a/drivers/net/wireless/ath/ath9k/beacon.c -++++ b/drivers/net/wireless/ath/ath9k/beacon.c -+@@ -312,10 +312,9 @@ static void ath9k_csa_update_vif(void *d ++- memcpy(skb_put(skb, params->len), params->buf, params->len); +++ data = skb_put(skb, params->len); +++ memcpy(data, params->buf, params->len); +++ +++ /* Update CSA counters */ +++ if (sdata->vif.csa_active && +++ (sdata->vif.type == NL80211_IFTYPE_AP || +++ sdata->vif.type == NL80211_IFTYPE_ADHOC) && +++ params->n_csa_offsets) { +++ int i; +++ u8 c = sdata->csa_current_counter; +++ +++ for (i = 0; i < params->n_csa_offsets; i++) +++ data[params->csa_offsets[i]] = c; +++ } --void __cfg80211_ibss_joined(struct net_device *dev, const u8 *bssid) -+void __cfg80211_ibss_joined(struct net_device *dev, const u8 *bssid, -+ struct ieee80211_channel *channel) -+ void ath9k_csa_update(struct ath_softc *sc) - { +- { - struct wireless_dev *wdev = dev->ieee80211_ptr; - struct cfg80211_bss *bss; -@@ -28,8 +29,7 @@ void __cfg80211_ibss_joined(struct net_d - if (!wdev->ssid_len) - return; -- ++ IEEE80211_SKB_CB(skb)->flags = flags; + -- bss = cfg80211_get_bss(wdev->wiphy, NULL, bssid, -- wdev->ssid, wdev->ssid_len, -+ bss = cfg80211_get_bss(wdev->wiphy, channel, bssid, NULL, 0, - WLAN_CAPABILITY_IBSS, WLAN_CAPABILITY_IBSS); -- ++@@ -3506,320 +3616,6 @@ static int ieee80211_set_rekey_data(stru ++ return 0; ++ } + - if (WARN_ON(!bss)) -@@ -54,21 +54,26 @@ void __cfg80211_ibss_joined(struct net_d - #endif -- } -- ++-static void ieee80211_tdls_add_ext_capab(struct sk_buff *skb) ++-{ ++- u8 *pos = (void *)skb_put(skb, 7); ++- ++- *pos++ = WLAN_EID_EXT_CAPABILITY; ++- *pos++ = 5; /* len */ ++- *pos++ = 0x0; ++- *pos++ = 0x0; ++- *pos++ = 0x0; ++- *pos++ = 0x0; ++- *pos++ = WLAN_EXT_CAPA5_TDLS_ENABLED; ++-} ++- ++-static u16 ieee80211_get_tdls_sta_capab(struct ieee80211_sub_if_data *sdata) ++-{ ++- struct ieee80211_local *local = sdata->local; ++- u16 capab; ++- ++- capab = 0; ++- if (ieee80211_get_sdata_band(sdata) != IEEE80211_BAND_2GHZ) ++- return capab; ++- ++- if (!(local->hw.flags & IEEE80211_HW_2GHZ_SHORT_SLOT_INCAPABLE)) ++- capab |= WLAN_CAPABILITY_SHORT_SLOT_TIME; ++- if (!(local->hw.flags & IEEE80211_HW_2GHZ_SHORT_PREAMBLE_INCAPABLE)) ++- capab |= WLAN_CAPABILITY_SHORT_PREAMBLE; ++- ++- return capab; ++-} ++- ++-static void ieee80211_tdls_add_link_ie(struct sk_buff *skb, u8 *src_addr, ++- u8 *peer, u8 *bssid) ++-{ ++- struct ieee80211_tdls_lnkie *lnkid; ++- ++- lnkid = (void *)skb_put(skb, sizeof(struct ieee80211_tdls_lnkie)); ++- ++- lnkid->ie_type = WLAN_EID_LINK_ID; ++- lnkid->ie_len = sizeof(struct ieee80211_tdls_lnkie) - 2; ++- ++- memcpy(lnkid->bssid, bssid, ETH_ALEN); ++- memcpy(lnkid->init_sta, src_addr, ETH_ALEN); ++- memcpy(lnkid->resp_sta, peer, ETH_ALEN); ++-} ++- ++-static int ++-ieee80211_prep_tdls_encap_data(struct wiphy *wiphy, struct net_device *dev, ++- u8 *peer, u8 action_code, u8 dialog_token, ++- u16 status_code, struct sk_buff *skb) ++-{ ++- struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); ++- enum ieee80211_band band = ieee80211_get_sdata_band(sdata); ++- struct ieee80211_tdls_data *tf; ++- ++- tf = (void *)skb_put(skb, offsetof(struct ieee80211_tdls_data, u)); ++- ++- memcpy(tf->da, peer, ETH_ALEN); ++- memcpy(tf->sa, sdata->vif.addr, ETH_ALEN); ++- tf->ether_type = cpu_to_be16(ETH_P_TDLS); ++- tf->payload_type = WLAN_TDLS_SNAP_RFTYPE; ++- ++- switch (action_code) { ++- case WLAN_TDLS_SETUP_REQUEST: ++- tf->category = WLAN_CATEGORY_TDLS; ++- tf->action_code = WLAN_TDLS_SETUP_REQUEST; ++- ++- skb_put(skb, sizeof(tf->u.setup_req)); ++- tf->u.setup_req.dialog_token = dialog_token; ++- tf->u.setup_req.capability = ++- cpu_to_le16(ieee80211_get_tdls_sta_capab(sdata)); ++- ++- ieee80211_add_srates_ie(sdata, skb, false, band); ++- ieee80211_add_ext_srates_ie(sdata, skb, false, band); ++- ieee80211_tdls_add_ext_capab(skb); ++- break; ++- case WLAN_TDLS_SETUP_RESPONSE: ++- tf->category = WLAN_CATEGORY_TDLS; ++- tf->action_code = WLAN_TDLS_SETUP_RESPONSE; ++- ++- skb_put(skb, sizeof(tf->u.setup_resp)); ++- tf->u.setup_resp.status_code = cpu_to_le16(status_code); ++- tf->u.setup_resp.dialog_token = dialog_token; ++- tf->u.setup_resp.capability = ++- cpu_to_le16(ieee80211_get_tdls_sta_capab(sdata)); ++- ++- ieee80211_add_srates_ie(sdata, skb, false, band); ++- ieee80211_add_ext_srates_ie(sdata, skb, false, band); ++- ieee80211_tdls_add_ext_capab(skb); ++- break; ++- case WLAN_TDLS_SETUP_CONFIRM: ++- tf->category = WLAN_CATEGORY_TDLS; ++- tf->action_code = WLAN_TDLS_SETUP_CONFIRM; ++- ++- skb_put(skb, sizeof(tf->u.setup_cfm)); ++- tf->u.setup_cfm.status_code = cpu_to_le16(status_code); ++- tf->u.setup_cfm.dialog_token = dialog_token; ++- break; ++- case WLAN_TDLS_TEARDOWN: ++- tf->category = WLAN_CATEGORY_TDLS; ++- tf->action_code = WLAN_TDLS_TEARDOWN; ++- ++- skb_put(skb, sizeof(tf->u.teardown)); ++- tf->u.teardown.reason_code = cpu_to_le16(status_code); ++- break; ++- case WLAN_TDLS_DISCOVERY_REQUEST: ++- tf->category = WLAN_CATEGORY_TDLS; ++- tf->action_code = WLAN_TDLS_DISCOVERY_REQUEST; ++- ++- skb_put(skb, sizeof(tf->u.discover_req)); ++- tf->u.discover_req.dialog_token = dialog_token; ++- break; ++- default: ++- return -EINVAL; ++- } ++- ++- return 0; ++-} ++- ++-static int ++-ieee80211_prep_tdls_direct(struct wiphy *wiphy, struct net_device *dev, ++- u8 *peer, u8 action_code, u8 dialog_token, ++- u16 status_code, struct sk_buff *skb) ++-{ ++- struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); ++- enum ieee80211_band band = ieee80211_get_sdata_band(sdata); ++- struct ieee80211_mgmt *mgmt; ++- ++- mgmt = (void *)skb_put(skb, 24); ++- memset(mgmt, 0, 24); ++- memcpy(mgmt->da, peer, ETH_ALEN); ++- memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN); ++- memcpy(mgmt->bssid, sdata->u.mgd.bssid, ETH_ALEN); ++- ++- mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | ++- IEEE80211_STYPE_ACTION); ++- ++- switch (action_code) { ++- case WLAN_PUB_ACTION_TDLS_DISCOVER_RES: ++- skb_put(skb, 1 + sizeof(mgmt->u.action.u.tdls_discover_resp)); ++- mgmt->u.action.category = WLAN_CATEGORY_PUBLIC; ++- mgmt->u.action.u.tdls_discover_resp.action_code = ++- WLAN_PUB_ACTION_TDLS_DISCOVER_RES; ++- mgmt->u.action.u.tdls_discover_resp.dialog_token = ++- dialog_token; ++- mgmt->u.action.u.tdls_discover_resp.capability = ++- cpu_to_le16(ieee80211_get_tdls_sta_capab(sdata)); ++- ++- ieee80211_add_srates_ie(sdata, skb, false, band); ++- ieee80211_add_ext_srates_ie(sdata, skb, false, band); ++- ieee80211_tdls_add_ext_capab(skb); ++- break; ++- default: ++- return -EINVAL; ++- } ++- ++- return 0; ++-} ++- ++-static int ieee80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev, ++- u8 *peer, u8 action_code, u8 dialog_token, ++- u16 status_code, u32 peer_capability, ++- const u8 *extra_ies, size_t extra_ies_len) ++-{ ++- struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); ++- struct ieee80211_local *local = sdata->local; ++- struct sk_buff *skb = NULL; ++- bool send_direct; ++- int ret; ++- ++- if (!(wiphy->flags & WIPHY_FLAG_SUPPORTS_TDLS)) ++- return -ENOTSUPP; ++- ++- /* make sure we are in managed mode, and associated */ ++- if (sdata->vif.type != NL80211_IFTYPE_STATION || ++- !sdata->u.mgd.associated) ++- return -EINVAL; ++- ++- tdls_dbg(sdata, "TDLS mgmt action %d peer %pM\n", ++- action_code, peer); ++- ++- skb = dev_alloc_skb(local->hw.extra_tx_headroom + ++- max(sizeof(struct ieee80211_mgmt), ++- sizeof(struct ieee80211_tdls_data)) + ++- 50 + /* supported rates */ ++- 7 + /* ext capab */ ++- extra_ies_len + ++- sizeof(struct ieee80211_tdls_lnkie)); ++- if (!skb) ++- return -ENOMEM; ++- ++- skb_reserve(skb, local->hw.extra_tx_headroom); ++- ++- switch (action_code) { ++- case WLAN_TDLS_SETUP_REQUEST: ++- case WLAN_TDLS_SETUP_RESPONSE: ++- case WLAN_TDLS_SETUP_CONFIRM: ++- case WLAN_TDLS_TEARDOWN: ++- case WLAN_TDLS_DISCOVERY_REQUEST: ++- ret = ieee80211_prep_tdls_encap_data(wiphy, dev, peer, ++- action_code, dialog_token, ++- status_code, skb); ++- send_direct = false; ++- break; ++- case WLAN_PUB_ACTION_TDLS_DISCOVER_RES: ++- ret = ieee80211_prep_tdls_direct(wiphy, dev, peer, action_code, ++- dialog_token, status_code, ++- skb); ++- send_direct = true; ++- break; ++- default: ++- ret = -ENOTSUPP; ++- break; ++- } ++- ++- if (ret < 0) ++- goto fail; ++- ++- if (extra_ies_len) ++- memcpy(skb_put(skb, extra_ies_len), extra_ies, extra_ies_len); ++- ++- /* the TDLS link IE is always added last */ ++- switch (action_code) { ++- case WLAN_TDLS_SETUP_REQUEST: ++- case WLAN_TDLS_SETUP_CONFIRM: ++- case WLAN_TDLS_TEARDOWN: ++- case WLAN_TDLS_DISCOVERY_REQUEST: ++- /* we are the initiator */ ++- ieee80211_tdls_add_link_ie(skb, sdata->vif.addr, peer, ++- sdata->u.mgd.bssid); ++- break; ++- case WLAN_TDLS_SETUP_RESPONSE: ++- case WLAN_PUB_ACTION_TDLS_DISCOVER_RES: ++- /* we are the responder */ ++- ieee80211_tdls_add_link_ie(skb, peer, sdata->vif.addr, ++- sdata->u.mgd.bssid); ++- break; ++- default: ++- ret = -ENOTSUPP; ++- goto fail; ++- } ++- ++- if (send_direct) { ++- ieee80211_tx_skb(sdata, skb); ++- return 0; ++- } ++- ++- /* ++- * According to 802.11z: Setup req/resp are sent in AC_BK, otherwise ++- * we should default to AC_VI. ++- */ ++- switch (action_code) { ++- case WLAN_TDLS_SETUP_REQUEST: ++- case WLAN_TDLS_SETUP_RESPONSE: ++- skb_set_queue_mapping(skb, IEEE80211_AC_BK); ++- skb->priority = 2; ++- break; ++- default: ++- skb_set_queue_mapping(skb, IEEE80211_AC_VI); ++- skb->priority = 5; ++- break; ++- } ++- ++- /* disable bottom halves when entering the Tx path */ ++- local_bh_disable(); ++- ret = ieee80211_subif_start_xmit(skb, dev); ++- local_bh_enable(); ++- ++- return ret; ++- ++-fail: ++- dev_kfree_skb(skb); ++- return ret; ++-} ++- ++-static int ieee80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev, ++- u8 *peer, enum nl80211_tdls_operation oper) ++-{ ++- struct sta_info *sta; ++- struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); ++- ++- if (!(wiphy->flags & WIPHY_FLAG_SUPPORTS_TDLS)) ++- return -ENOTSUPP; ++- ++- if (sdata->vif.type != NL80211_IFTYPE_STATION) ++- return -EINVAL; ++- ++- tdls_dbg(sdata, "TDLS oper %d peer %pM\n", oper, peer); ++- ++- switch (oper) { ++- case NL80211_TDLS_ENABLE_LINK: ++- rcu_read_lock(); ++- sta = sta_info_get(sdata, peer); ++- if (!sta) { ++- rcu_read_unlock(); ++- return -ENOLINK; ++- } ++- ++- set_sta_flag(sta, WLAN_STA_TDLS_PEER_AUTH); ++- rcu_read_unlock(); ++- break; ++- case NL80211_TDLS_DISABLE_LINK: ++- return sta_info_destroy_addr(sdata, peer); ++- case NL80211_TDLS_TEARDOWN: ++- case NL80211_TDLS_SETUP: ++- case NL80211_TDLS_DISCOVERY_REQ: ++- /* We don't support in-driver setup/teardown/discovery */ ++- return -ENOTSUPP; ++- default: ++- return -ENOTSUPP; ++- } ++- ++- return 0; ++-} ++- ++ static int ieee80211_probe_client(struct wiphy *wiphy, struct net_device *dev, ++ const u8 *peer, u64 *cookie) ++ { ++--- a/net/mac80211/chan.c +++++ b/net/mac80211/chan.c ++@@ -855,7 +855,7 @@ static void ++ __ieee80211_vif_copy_chanctx_to_vlans(struct ieee80211_sub_if_data *sdata, ++ bool clear) ++ { ++- struct ieee80211_local *local = sdata->local; +++ struct ieee80211_local *local __maybe_unused = sdata->local; ++ struct ieee80211_sub_if_data *vlan; ++ struct ieee80211_chanctx_conf *conf; ++ ++@@ -871,7 +871,7 @@ __ieee80211_vif_copy_chanctx_to_vlans(st ++ * to a channel context that has already been freed. ++ */ ++ conf = rcu_dereference_protected(sdata->vif.chanctx_conf, ++- lockdep_is_held(&local->chanctx_mtx)); +++ lockdep_is_held(&local->chanctx_mtx)); ++ WARN_ON(!conf); ++ ++ if (clear) ++--- a/net/mac80211/driver-ops.h +++++ b/net/mac80211/driver-ops.h ++@@ -5,11 +5,11 @@ ++ #include "ieee80211_i.h" ++ #include "trace.h" ++ ++-static inline void check_sdata_in_driver(struct ieee80211_sub_if_data *sdata) +++static inline bool check_sdata_in_driver(struct ieee80211_sub_if_data *sdata) ++ { ++- WARN(!(sdata->flags & IEEE80211_SDATA_IN_DRIVER), ++- "%s: Failed check-sdata-in-driver check, flags: 0x%x\n", ++- sdata->dev ? sdata->dev->name : sdata->name, sdata->flags); +++ return !WARN(!(sdata->flags & IEEE80211_SDATA_IN_DRIVER), +++ "%s: Failed check-sdata-in-driver check, flags: 0x%x\n", +++ sdata->dev ? sdata->dev->name : sdata->name, sdata->flags); + } + --void cfg80211_ibss_joined(struct net_device *dev, const u8 *bssid, gfp_t gfp) -+void cfg80211_ibss_joined(struct net_device *dev, const u8 *bssid, -+ struct ieee80211_channel *channel, gfp_t gfp) -+- ieee80211_iterate_active_interfaces(sc->hw, -+- IEEE80211_IFACE_ITER_NORMAL, -+- ath9k_csa_update_vif, -+- sc); -++ ieee80211_iterate_active_interfaces_atomic(sc->hw, -++ IEEE80211_IFACE_ITER_NORMAL, -++ ath9k_csa_update_vif, sc); -+ } ++ static inline struct ieee80211_sub_if_data * ++@@ -168,7 +168,8 @@ static inline int drv_change_interface(s + -+ void ath9k_beacon_tasklet(unsigned long data) -+--- a/net/mac80211/main.c -++++ b/net/mac80211/main.c -+@@ -152,6 +152,8 @@ static u32 ieee80211_hw_conf_chan(struct -+ list_for_each_entry_rcu(sdata, &local->interfaces, list) { -+ if (!rcu_access_pointer(sdata->vif.chanctx_conf)) -+ continue; -++ if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) -++ continue; -+ power = min(power, sdata->vif.bss_conf.txpower); -+ } -+ rcu_read_unlock(); -+@@ -203,7 +205,7 @@ void ieee80211_bss_info_change_notify(st ++ might_sleep(); ++ ++- check_sdata_in_driver(sdata); +++ if (!check_sdata_in_driver(sdata)) +++ return -EIO; ++ ++ trace_drv_change_interface(local, sdata, type, p2p); ++ ret = local->ops->change_interface(&local->hw, &sdata->vif, type, p2p); ++@@ -181,7 +182,8 @@ static inline void drv_remove_interface( { - struct wireless_dev *wdev = dev->ieee80211_ptr; - struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); - struct cfg80211_event *ev; - unsigned long flags; -- ++ might_sleep(); + -- trace_cfg80211_ibss_joined(dev, bssid); -+ trace_cfg80211_ibss_joined(dev, bssid, channel); -+ -+ if (WARN_ON(!channel)) --+ return; -+ struct ieee80211_local *local = sdata->local; ++- check_sdata_in_driver(sdata); +++ if (!check_sdata_in_driver(sdata)) + + return; - ev = kzalloc(sizeof(*ev), gfp); - if (!ev) -+- if (!changed) -++ if (!changed || sdata->vif.type == NL80211_IFTYPE_AP_VLAN) ++ trace_drv_remove_interface(local, sdata); ++ local->ops->remove_interface(&local->hw, &sdata->vif); ++@@ -219,7 +221,8 @@ static inline void drv_bss_info_changed( ++ sdata->vif.type == NL80211_IFTYPE_MONITOR)) return; - ev->type = EVENT_IBSS_JOINED; -- memcpy(ev->cr.bssid, bssid, ETH_ALEN); -+ memcpy(ev->ij.bssid, bssid, ETH_ALEN); -+ ev->ij.channel = channel; -- ++- check_sdata_in_driver(sdata); +++ if (!check_sdata_in_driver(sdata)) +++ return; + - spin_lock_irqsave(&wdev->event_lock, flags); - list_add_tail(&ev->list, &wdev->event_list); -@@ -117,6 +122,7 @@ int __cfg80211_join_ibss(struct cfg80211 -- ++ trace_drv_bss_info_changed(local, sdata, info, changed); ++ if (local->ops->bss_info_changed) ++@@ -278,7 +281,8 @@ static inline int drv_set_key(struct iee ++ might_sleep(); + - wdev->ibss_fixed = params->channel_fixed; - wdev->ibss_dfs_possible = params->userspace_handles_dfs; -+ wdev->chandef = params->chandef; @@ -4887,7 +6971,11 @@ index a1af6c2..892f51e 100644 - wdev->wext.ibss.chandef = params->chandef; - #endif -@@ -200,6 +206,7 @@ static void __cfg80211_clear_ibss(struct -- ++ sdata = get_bss_sdata(sdata); ++- check_sdata_in_driver(sdata); +++ if (!check_sdata_in_driver(sdata)) +++ return -EIO; + - wdev->current_bss = NULL; - wdev->ssid_len = 0; -+ memset(&wdev->chandef, 0, sizeof(wdev->chandef)); @@ -4899,7 +6987,11 @@ index a1af6c2..892f51e 100644 -@@ -2278,11 +2278,6 @@ DECLARE_EVENT_CLASS(cfg80211_rx_evt, - TP_printk(NETDEV_PR_FMT ", " MAC_PR_FMT, NETDEV_PR_ARG, MAC_PR_ARG(addr)) - ); -- ++ trace_drv_set_key(local, cmd, sdata, sta, key); ++ ret = local->ops->set_key(&local->hw, cmd, &sdata->vif, sta, key); ++@@ -298,7 +302,8 @@ static inline void drv_update_tkip_key(s ++ ista = &sta->sta; + --DEFINE_EVENT(cfg80211_rx_evt, cfg80211_ibss_joined, -- TP_PROTO(struct net_device *netdev, const u8 *addr), -- TP_ARGS(netdev, addr) @@ -4911,7 +7003,11 @@ index a1af6c2..892f51e 100644 -@@ -2293,6 +2288,24 @@ DEFINE_EVENT(cfg80211_rx_evt, cfg80211_r - TP_ARGS(netdev, addr) - ); -- ++ sdata = get_bss_sdata(sdata); ++- check_sdata_in_driver(sdata); +++ if (!check_sdata_in_driver(sdata)) +++ return; + -+TRACE_EVENT(cfg80211_ibss_joined, -+ TP_PROTO(struct net_device *netdev, const u8 *bssid, -+ struct ieee80211_channel *channel), @@ -4929,7 +7025,216 @@ index a1af6c2..892f51e 100644 -+ TP_printk(NETDEV_PR_FMT ", bssid: " MAC_PR_FMT ", " CHAN_PR_FMT, -+ NETDEV_PR_ARG, MAC_PR_ARG(bssid), CHAN_PR_ARG) -+); --+ ++ trace_drv_update_tkip_key(local, sdata, conf, ista, iv32); ++ if (local->ops->update_tkip_key) ++@@ -315,7 +320,8 @@ static inline int drv_hw_scan(struct iee ++ ++ might_sleep(); ++ ++- check_sdata_in_driver(sdata); +++ if (!check_sdata_in_driver(sdata)) +++ return -EIO; ++ ++ trace_drv_hw_scan(local, sdata); ++ ret = local->ops->hw_scan(&local->hw, &sdata->vif, req); ++@@ -328,7 +334,8 @@ static inline void drv_cancel_hw_scan(st ++ { ++ might_sleep(); ++ ++- check_sdata_in_driver(sdata); +++ if (!check_sdata_in_driver(sdata)) +++ return; ++ ++ trace_drv_cancel_hw_scan(local, sdata); ++ local->ops->cancel_hw_scan(&local->hw, &sdata->vif); ++@@ -345,7 +352,8 @@ drv_sched_scan_start(struct ieee80211_lo ++ ++ might_sleep(); ++ ++- check_sdata_in_driver(sdata); +++ if (!check_sdata_in_driver(sdata)) +++ return -EIO; ++ ++ trace_drv_sched_scan_start(local, sdata); ++ ret = local->ops->sched_scan_start(&local->hw, &sdata->vif, ++@@ -361,7 +369,8 @@ static inline int drv_sched_scan_stop(st ++ ++ might_sleep(); ++ ++- check_sdata_in_driver(sdata); +++ if (!check_sdata_in_driver(sdata)) +++ return -EIO; ++ ++ trace_drv_sched_scan_stop(local, sdata); ++ ret = local->ops->sched_scan_stop(&local->hw, &sdata->vif); ++@@ -462,7 +471,8 @@ static inline void drv_sta_notify(struct ++ struct ieee80211_sta *sta) ++ { ++ sdata = get_bss_sdata(sdata); ++- check_sdata_in_driver(sdata); +++ if (!check_sdata_in_driver(sdata)) +++ return; ++ ++ trace_drv_sta_notify(local, sdata, cmd, sta); ++ if (local->ops->sta_notify) ++@@ -479,7 +489,8 @@ static inline int drv_sta_add(struct iee ++ might_sleep(); ++ ++ sdata = get_bss_sdata(sdata); ++- check_sdata_in_driver(sdata); +++ if (!check_sdata_in_driver(sdata)) +++ return -EIO; ++ ++ trace_drv_sta_add(local, sdata, sta); ++ if (local->ops->sta_add) ++@@ -497,7 +508,8 @@ static inline void drv_sta_remove(struct ++ might_sleep(); ++ ++ sdata = get_bss_sdata(sdata); ++- check_sdata_in_driver(sdata); +++ if (!check_sdata_in_driver(sdata)) +++ return; ++ ++ trace_drv_sta_remove(local, sdata, sta); ++ if (local->ops->sta_remove) ++@@ -515,7 +527,8 @@ static inline void drv_sta_add_debugfs(s ++ might_sleep(); ++ ++ sdata = get_bss_sdata(sdata); ++- check_sdata_in_driver(sdata); +++ if (!check_sdata_in_driver(sdata)) +++ return; ++ ++ if (local->ops->sta_add_debugfs) ++ local->ops->sta_add_debugfs(&local->hw, &sdata->vif, ++@@ -545,7 +558,8 @@ static inline void drv_sta_pre_rcu_remov ++ might_sleep(); ++ ++ sdata = get_bss_sdata(sdata); ++- check_sdata_in_driver(sdata); +++ if (!check_sdata_in_driver(sdata)) +++ return; ++ ++ trace_drv_sta_pre_rcu_remove(local, sdata, &sta->sta); ++ if (local->ops->sta_pre_rcu_remove) ++@@ -566,7 +580,8 @@ int drv_sta_state(struct ieee80211_local ++ might_sleep(); ++ ++ sdata = get_bss_sdata(sdata); ++- check_sdata_in_driver(sdata); +++ if (!check_sdata_in_driver(sdata)) +++ return -EIO; ++ ++ trace_drv_sta_state(local, sdata, &sta->sta, old_state, new_state); ++ if (local->ops->sta_state) { ++@@ -590,7 +605,8 @@ static inline void drv_sta_rc_update(str ++ struct ieee80211_sta *sta, u32 changed) ++ { ++ sdata = get_bss_sdata(sdata); ++- check_sdata_in_driver(sdata); +++ if (!check_sdata_in_driver(sdata)) +++ return; ++ ++ WARN_ON(changed & IEEE80211_RC_SUPP_RATES_CHANGED && ++ (sdata->vif.type != NL80211_IFTYPE_ADHOC && ++@@ -612,7 +628,8 @@ static inline int drv_conf_tx(struct iee ++ ++ might_sleep(); ++ ++- check_sdata_in_driver(sdata); +++ if (!check_sdata_in_driver(sdata)) +++ return -EIO; ++ ++ trace_drv_conf_tx(local, sdata, ac, params); ++ if (local->ops->conf_tx) ++@@ -629,7 +646,8 @@ static inline u64 drv_get_tsf(struct iee ++ ++ might_sleep(); ++ ++- check_sdata_in_driver(sdata); +++ if (!check_sdata_in_driver(sdata)) +++ return ret; ++ ++ trace_drv_get_tsf(local, sdata); ++ if (local->ops->get_tsf) ++@@ -644,7 +662,8 @@ static inline void drv_set_tsf(struct ie ++ { ++ might_sleep(); ++ ++- check_sdata_in_driver(sdata); +++ if (!check_sdata_in_driver(sdata)) +++ return; ++ ++ trace_drv_set_tsf(local, sdata, tsf); ++ if (local->ops->set_tsf) ++@@ -657,7 +676,8 @@ static inline void drv_reset_tsf(struct ++ { ++ might_sleep(); ++ ++- check_sdata_in_driver(sdata); +++ if (!check_sdata_in_driver(sdata)) +++ return; ++ ++ trace_drv_reset_tsf(local, sdata); ++ if (local->ops->reset_tsf) ++@@ -689,7 +709,8 @@ static inline int drv_ampdu_action(struc ++ might_sleep(); ++ ++ sdata = get_bss_sdata(sdata); ++- check_sdata_in_driver(sdata); +++ if (!check_sdata_in_driver(sdata)) +++ return -EIO; ++ ++ trace_drv_ampdu_action(local, sdata, action, sta, tid, ssn, buf_size); ++ ++@@ -733,8 +754,8 @@ static inline void drv_flush(struct ieee ++ ++ might_sleep(); ++ ++- if (sdata) ++- check_sdata_in_driver(sdata); +++ if (sdata && !check_sdata_in_driver(sdata)) +++ return; ++ ++ trace_drv_flush(local, queues, drop); ++ if (local->ops->flush) ++@@ -854,7 +875,8 @@ static inline int drv_set_bitrate_mask(s ++ ++ might_sleep(); ++ ++- check_sdata_in_driver(sdata); +++ if (!check_sdata_in_driver(sdata)) +++ return -EIO; ++ ++ trace_drv_set_bitrate_mask(local, sdata, mask); ++ if (local->ops->set_bitrate_mask) ++@@ -869,7 +891,8 @@ static inline void drv_set_rekey_data(st ++ struct ieee80211_sub_if_data *sdata, ++ struct cfg80211_gtk_rekey_data *data) ++ { ++- check_sdata_in_driver(sdata); +++ if (!check_sdata_in_driver(sdata)) +++ return; ++ ++ trace_drv_set_rekey_data(local, sdata, data); ++ if (local->ops->set_rekey_data) ++@@ -937,7 +960,8 @@ static inline void drv_mgd_prepare_tx(st ++ { ++ might_sleep(); ++ ++- check_sdata_in_driver(sdata); +++ if (!check_sdata_in_driver(sdata)) +++ return; ++ WARN_ON_ONCE(sdata->vif.type != NL80211_IFTYPE_STATION); ++ ++ trace_drv_mgd_prepare_tx(local, sdata); ++@@ -964,6 +988,9 @@ static inline int drv_add_chanctx(struct ++ static inline void drv_remove_chanctx(struct ieee80211_local *local, ++ struct ieee80211_chanctx *ctx) ++ { +++ if (WARN_ON(!ctx->driver_present)) +++ return; + + - TRACE_EVENT(cfg80211_probe_status, - TP_PROTO(struct net_device *netdev, const u8 *addr, u64 cookie, - bool acked), @@ -4952,13 +7257,7 @@ index a1af6c2..892f51e 100644 -- cfg80211_get_chan_state(wdev_iter, &ch, &chmode); -+ cfg80211_get_chan_state(wdev_iter, &ch, &chmode, &radar_detect); - wdev_unlock(wdev_iter); -+ drv_bss_info_changed(local, sdata, &sdata->vif.bss_conf, changed); -+--- a/drivers/net/wireless/ath/ath9k/ani.c -++++ b/drivers/net/wireless/ath/ath9k/ani.c -+@@ -155,6 +155,9 @@ static void ath9k_hw_set_ofdm_nil(struct -+ ATH9K_ANI_RSSI_THR_LOW, -+ ATH9K_ANI_RSSI_THR_HIGH); - +- - switch (chmode) { ---- a/net/wireless/chan.c -+++ b/net/wireless/chan.c @@ -4969,7 +7268,11 @@ index a1af6c2..892f51e 100644 -- enum cfg80211_chan_mode *chanmode) -+ enum cfg80211_chan_mode *chanmode, -+ u8 *radar_detect) -- { ++ trace_drv_remove_chanctx(local, ctx); ++ if (local->ops->remove_chanctx) ++ local->ops->remove_chanctx(&local->hw, &ctx->conf); ++@@ -989,7 +1016,8 @@ static inline int drv_assign_vif_chanctx + { - *chan = NULL; - *chanmode = CHAN_MODE_UNDEFINED; -@@ -660,6 +661,11 @@ cfg80211_get_chan_state(struct wireless_ @@ -5007,9 +7310,7 @@ index a1af6c2..892f51e 100644 -- *chan = wdev->channel; -+ *chan = wdev->chandef.chan; - *chanmode = CHAN_MODE_SHARED; -++ if (AR_SREV_9100(ah) && immunityLevel < ATH9K_ANI_OFDM_DEF_LEVEL) -++ immunityLevel = ATH9K_ANI_OFDM_DEF_LEVEL; - + +-+ -+ if (cfg80211_chandef_dfs_required(wdev->wiphy, -+ &wdev->chandef)) -+ *radar_detect |= BIT(wdev->chandef.width); @@ -5024,8 +7325,85 @@ index a1af6c2..892f51e 100644 - wdev->mesh_id_len = setup->mesh_id_len; -- wdev->channel = setup->chandef.chan; -+ wdev->chandef = setup->chandef; -- } -- ++ int ret = 0; ++ ++- check_sdata_in_driver(sdata); +++ if (!check_sdata_in_driver(sdata)) +++ return -EIO; ++ ++ trace_drv_assign_vif_chanctx(local, sdata, ctx); ++ if (local->ops->assign_vif_chanctx) { ++@@ -1007,7 +1035,8 @@ static inline void drv_unassign_vif_chan ++ struct ieee80211_sub_if_data *sdata, ++ struct ieee80211_chanctx *ctx) ++ { ++- check_sdata_in_driver(sdata); +++ if (!check_sdata_in_driver(sdata)) +++ return; ++ ++ trace_drv_unassign_vif_chanctx(local, sdata, ctx); ++ if (local->ops->unassign_vif_chanctx) { ++@@ -1024,7 +1053,8 @@ static inline int drv_start_ap(struct ie ++ { ++ int ret = 0; ++ ++- check_sdata_in_driver(sdata); +++ if (!check_sdata_in_driver(sdata)) +++ return -EIO; ++ ++ trace_drv_start_ap(local, sdata, &sdata->vif.bss_conf); ++ if (local->ops->start_ap) ++@@ -1036,7 +1066,8 @@ static inline int drv_start_ap(struct ie ++ static inline void drv_stop_ap(struct ieee80211_local *local, ++ struct ieee80211_sub_if_data *sdata) ++ { ++- check_sdata_in_driver(sdata); +++ if (!check_sdata_in_driver(sdata)) +++ return; ++ ++ trace_drv_stop_ap(local, sdata); ++ if (local->ops->stop_ap) ++@@ -1059,7 +1090,8 @@ drv_set_default_unicast_key(struct ieee8 ++ struct ieee80211_sub_if_data *sdata, ++ int key_idx) ++ { ++- check_sdata_in_driver(sdata); +++ if (!check_sdata_in_driver(sdata)) +++ return; ++ ++ WARN_ON_ONCE(key_idx < -1 || key_idx > 3); ++ ++@@ -1101,7 +1133,8 @@ static inline int drv_join_ibss(struct i ++ int ret = 0; ++ ++ might_sleep(); ++- check_sdata_in_driver(sdata); +++ if (!check_sdata_in_driver(sdata)) +++ return -EIO; ++ ++ trace_drv_join_ibss(local, sdata, &sdata->vif.bss_conf); ++ if (local->ops->join_ibss) ++@@ -1114,7 +1147,8 @@ static inline void drv_leave_ibss(struct ++ struct ieee80211_sub_if_data *sdata) ++ { ++ might_sleep(); ++- check_sdata_in_driver(sdata); +++ if (!check_sdata_in_driver(sdata)) +++ return; ++ ++ trace_drv_leave_ibss(local, sdata); ++ if (local->ops->leave_ibss) ++--- a/net/mac80211/ibss.c +++++ b/net/mac80211/ibss.c ++@@ -143,7 +143,7 @@ ieee80211_ibss_build_presp(struct ieee80 ++ *pos++ = csa_settings->block_tx ? 1 : 0; ++ *pos++ = ieee80211_frequency_to_channel( ++ csa_settings->chandef.chan->center_freq); ++- sdata->csa_counter_offset_beacon = (pos - presp->head); +++ sdata->csa_counter_offset_beacon[0] = (pos - presp->head); ++ *pos++ = csa_settings->count; + } + - return err; -@@ -244,7 +244,7 @@ int cfg80211_set_mesh_channel(struct cfg - err = rdev_libertas_set_mesh_channel(rdev, wdev->netdev, @@ -5033,8 +7411,138 @@ index a1af6c2..892f51e 100644 - if (!err) -- wdev->channel = chandef->chan; -+ wdev->chandef = *chandef; -+ if (!scan) -+ aniState->ofdmNoiseImmunityLevel = immunityLevel; ++--- a/net/mac80211/ieee80211_i.h +++++ b/net/mac80211/ieee80211_i.h ++@@ -754,9 +754,10 @@ struct ieee80211_sub_if_data { ++ struct mac80211_qos_map __rcu *qos_map; ++ ++ struct work_struct csa_finalize_work; ++- int csa_counter_offset_beacon; ++- int csa_counter_offset_presp; +++ u16 csa_counter_offset_beacon[IEEE80211_MAX_CSA_COUNTERS_NUM]; +++ u16 csa_counter_offset_presp[IEEE80211_MAX_CSA_COUNTERS_NUM]; ++ bool csa_radar_required; +++ bool csa_block_tx; /* write-protected by sdata_lock and local->mtx */ ++ struct cfg80211_chan_def csa_chandef; ++ ++ struct list_head assigned_chanctx_list; /* protected by chanctx_mtx */ ++@@ -766,6 +767,7 @@ struct ieee80211_sub_if_data { ++ struct ieee80211_chanctx *reserved_chanctx; ++ struct cfg80211_chan_def reserved_chandef; ++ bool reserved_radar_required; +++ u8 csa_current_counter; ++ ++ /* used to reconfigure hardware SM PS */ ++ struct work_struct recalc_smps; ++@@ -1462,6 +1464,7 @@ __ieee80211_request_sched_scan_start(str ++ int ieee80211_request_sched_scan_start(struct ieee80211_sub_if_data *sdata, ++ struct cfg80211_sched_scan_request *req); ++ int ieee80211_request_sched_scan_stop(struct ieee80211_sub_if_data *sdata); +++void ieee80211_sched_scan_end(struct ieee80211_local *local); ++ void ieee80211_sched_scan_stopped_work(struct work_struct *work); ++ ++ /* off-channel helpers */ ++@@ -1476,6 +1479,7 @@ void ieee80211_sw_roc_work(struct work_s ++ void ieee80211_handle_roc_started(struct ieee80211_roc_work *roc); ++ ++ /* channel switch handling */ +++bool ieee80211_csa_needs_block_tx(struct ieee80211_local *local); ++ void ieee80211_csa_finalize_work(struct work_struct *work); ++ int ieee80211_channel_switch(struct wiphy *wiphy, struct net_device *dev, ++ struct cfg80211_csa_settings *params); ++@@ -1837,6 +1841,15 @@ int ieee80211_check_combinations(struct ++ u8 radar_detect); ++ int ieee80211_max_num_channels(struct ieee80211_local *local); ++ +++/* TDLS */ +++int ieee80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev, +++ const u8 *peer, u8 action_code, u8 dialog_token, +++ u16 status_code, u32 peer_capability, +++ const u8 *extra_ies, size_t extra_ies_len); +++int ieee80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev, +++ const u8 *peer, enum nl80211_tdls_operation oper); +++ +++ ++ #ifdef CPTCFG_MAC80211_NOINLINE ++ #define debug_noinline noinline ++ #else ++--- a/net/mac80211/iface.c +++++ b/net/mac80211/iface.c ++@@ -838,8 +838,15 @@ static void ieee80211_do_stop(struct iee ++ ++ cancel_work_sync(&sdata->recalc_smps); ++ sdata_lock(sdata); +++ mutex_lock(&local->mtx); ++ sdata->vif.csa_active = false; +++ if (!ieee80211_csa_needs_block_tx(local)) +++ ieee80211_wake_queues_by_reason(&local->hw, +++ IEEE80211_MAX_QUEUE_MAP, +++ IEEE80211_QUEUE_STOP_REASON_CSA); +++ mutex_unlock(&local->mtx); ++ sdata_unlock(sdata); +++ ++ cancel_work_sync(&sdata->csa_finalize_work); ++ ++ cancel_delayed_work_sync(&sdata->dfs_cac_timer_work); ++--- a/net/mac80211/key.c +++++ b/net/mac80211/key.c ++@@ -325,7 +325,8 @@ ieee80211_key_alloc(u32 cipher, int idx, ++ struct ieee80211_key *key; ++ int i, j, err; ++ ++- BUG_ON(idx < 0 || idx >= NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS); +++ if (WARN_ON(idx < 0 || idx >= NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS)) +++ return ERR_PTR(-EINVAL); ++ ++ key = kzalloc(sizeof(struct ieee80211_key) + key_len, GFP_KERNEL); ++ if (!key) ++@@ -481,8 +482,8 @@ int ieee80211_key_link(struct ieee80211_ ++ int idx, ret; ++ bool pairwise; ++ ++- BUG_ON(!sdata); ++- BUG_ON(!key); +++ if (WARN_ON(!sdata || !key)) +++ return -EINVAL; ++ ++ pairwise = key->conf.flags & IEEE80211_KEY_FLAG_PAIRWISE; ++ idx = key->conf.keyidx; ++--- a/net/mac80211/main.c +++++ b/net/mac80211/main.c ++@@ -956,6 +956,8 @@ int ieee80211_register_hw(struct ieee802 ++ if (local->hw.wiphy->flags & WIPHY_FLAG_SUPPORTS_TDLS) ++ local->hw.wiphy->flags |= WIPHY_FLAG_TDLS_EXTERNAL_SETUP; ++ +++ local->hw.wiphy->max_num_csa_counters = IEEE80211_MAX_CSA_COUNTERS_NUM; +++ ++ result = wiphy_register(local->hw.wiphy); ++ if (result < 0) ++ goto fail_wiphy_register; ++--- a/net/mac80211/mesh.c +++++ b/net/mac80211/mesh.c ++@@ -679,7 +679,7 @@ ieee80211_mesh_build_beacon(struct ieee8 ++ *pos++ = 0x0; ++ *pos++ = ieee80211_frequency_to_channel( ++ csa->settings.chandef.chan->center_freq); ++- sdata->csa_counter_offset_beacon = hdr_len + 6; +++ sdata->csa_counter_offset_beacon[0] = hdr_len + 6; ++ *pos++ = csa->settings.count; ++ *pos++ = WLAN_EID_CHAN_SWITCH_PARAM; ++ *pos++ = 6; ++--- a/net/mac80211/mesh_pathtbl.c +++++ b/net/mac80211/mesh_pathtbl.c ++@@ -287,8 +287,10 @@ static void mesh_path_move_to_queue(stru ++ struct sk_buff_head failq; ++ unsigned long flags; ++ ++- BUG_ON(gate_mpath == from_mpath); ++- BUG_ON(!gate_mpath->next_hop); +++ if (WARN_ON(gate_mpath == from_mpath)) +++ return; +++ if (WARN_ON(!gate_mpath->next_hop)) +++ return; ++ ++ __skb_queue_head_init(&failq); - return err; - } @@ -5046,20 +7554,31 @@ index a1af6c2..892f51e 100644 -+ memset(&wdev->chandef, 0, sizeof(wdev->chandef)); - rdev_set_qos_map(rdev, dev, NULL); - } -- ++--- a/net/mac80211/mesh_sync.c +++++ b/net/mac80211/mesh_sync.c ++@@ -171,7 +171,7 @@ static void mesh_sync_offset_adjust_tbtt ++ u8 cap; + ---- a/net/wireless/mlme.c -+++ b/net/wireless/mlme.c -@@ -772,7 +772,7 @@ void cfg80211_cac_event(struct net_devic - if (WARN_ON(!wdev->cac_started)) - return; -+@@ -235,6 +238,9 @@ static void ath9k_hw_set_cck_nil(struct -+ BEACON_RSSI(ah), ATH9K_ANI_RSSI_THR_LOW, -+ ATH9K_ANI_RSSI_THR_HIGH); ++ WARN_ON(ifmsh->mesh_sp_id != IEEE80211_SYNC_METHOD_NEIGHBOR_OFFSET); ++- BUG_ON(!rcu_read_lock_held()); +++ WARN_ON(!rcu_read_lock_held()); ++ cap = beacon->meshconf->meshconf_cap; -- if (WARN_ON(!wdev->channel)) -+ if (WARN_ON(!wdev->chandef.chan)) - return; -- ++ spin_lock_bh(&ifmsh->sync_offset_lock); ++--- a/net/mac80211/mlme.c +++++ b/net/mac80211/mlme.c ++@@ -975,16 +975,23 @@ static void ieee80211_chswitch_work(stru ++ /* XXX: shouldn't really modify cfg80211-owned data! */ ++ ifmgd->associated->channel = sdata->csa_chandef.chan; + - switch (event) { ---- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c -+++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c @@ -5067,15 +7586,34 @@ index a1af6c2..892f51e 100644 - break; - } - } -++ if (AR_SREV_9100(ah) && immunityLevel < ATH9K_ANI_CCK_DEF_LEVEL) -++ immunityLevel = ATH9K_ANI_CCK_DEF_LEVEL; +++ ieee80211_bss_info_change_notify(sdata, changed); + -+ if (is2GHz && !twiceMaxEdgePower) -+ twiceMaxEdgePower = 60; --+ +++ mutex_lock(&local->mtx); +++ sdata->vif.csa_active = false; ++ /* XXX: wait for a beacon first? */ ++- ieee80211_wake_queues_by_reason(&local->hw, +++ if (!ieee80211_csa_needs_block_tx(local)) +++ ieee80211_wake_queues_by_reason(&local->hw, ++ IEEE80211_MAX_QUEUE_MAP, ++ IEEE80211_QUEUE_STOP_REASON_CSA); +++ mutex_unlock(&local->mtx); ++ ++- ieee80211_bss_info_change_notify(sdata, changed); ++- ++- out: ++- sdata->vif.csa_active = false; ++ ifmgd->flags &= ~IEEE80211_STA_CSA_RECEIVED; +++ +++ ieee80211_sta_reset_beacon_monitor(sdata); +++ ieee80211_sta_reset_conn_monitor(sdata); + + - return twiceMaxEdgePower; -- } -- +++out: ++ sdata_unlock(sdata); + } + ---- a/drivers/net/wireless/ath/ath9k/ar9003_calib.c -+++ b/drivers/net/wireless/ath/ath9k/ar9003_calib.c -@@ -23,10 +23,11 @@ @@ -5090,41 +7628,100 @@ index a1af6c2..892f51e 100644 -+ int mag_coeff[AR9300_MAX_CHAINS][MAX_MEASUREMENT][MAXIQCAL]; -+ int phs_coeff[AR9300_MAX_CHAINS][MAX_MEASUREMENT][MAXIQCAL]; - int iqc_coeff[2]; -+ if (ah->opmode == NL80211_IFTYPE_STATION && -+ BEACON_RSSI(ah) <= ATH9K_ANI_RSSI_THR_LOW && -+ immunityLevel > ATH9K_ANI_CCK_MAX_LEVEL_LOW_RSSI) -+--- a/drivers/net/wireless/ath/ath9k/ath9k.h -++++ b/drivers/net/wireless/ath/ath9k/ath9k.h -+@@ -251,7 +251,6 @@ struct ath_atx_tid { +- }; ++@@ -1100,12 +1107,16 @@ ieee80211_sta_process_chanswitch(struct ++ mutex_unlock(&local->chanctx_mtx); + -+ s8 bar_index; -+ bool sched; -+- bool paused; -+ bool active; - }; ++ sdata->csa_chandef = csa_ie.chandef; +++ +++ mutex_lock(&local->mtx); ++ sdata->vif.csa_active = true; +++ sdata->csa_block_tx = csa_ie.mode; ++ ++- if (csa_ie.mode) +++ if (sdata->csa_block_tx) ++ ieee80211_stop_queues_by_reason(&local->hw, ++- IEEE80211_MAX_QUEUE_MAP, ++- IEEE80211_QUEUE_STOP_REASON_CSA); +++ IEEE80211_MAX_QUEUE_MAP, +++ IEEE80211_QUEUE_STOP_REASON_CSA); +++ mutex_unlock(&local->mtx); ++ ++ if (local->ops->channel_switch) { ++ /* use driver's channel switch callback */ ++@@ -1817,6 +1828,12 @@ static void ieee80211_set_disassoc(struc ++ ifmgd->flags = 0; ++ mutex_lock(&local->mtx); ++ ieee80211_vif_release_channel(sdata); +++ +++ sdata->vif.csa_active = false; +++ if (!ieee80211_csa_needs_block_tx(local)) +++ ieee80211_wake_queues_by_reason(&local->hw, +++ IEEE80211_MAX_QUEUE_MAP, +++ IEEE80211_QUEUE_STOP_REASON_CSA); ++ mutex_unlock(&local->mtx); -@@ -800,7 +801,7 @@ static bool ar9003_hw_calc_iq_corr(struc - if (q_q_coff > 63) - q_q_coff = 63; -- ++ sdata->encrypt_headroom = IEEE80211_ENCRYPT_HEADROOM; ++@@ -2045,6 +2062,7 @@ EXPORT_SYMBOL(ieee80211_ap_probereq_get) + -- iqc_coeff[0] = (q_q_coff * 128) + q_i_coff; -+ iqc_coeff[0] = (q_q_coff * 128) + (0x7f & q_i_coff); -- ++ static void __ieee80211_disconnect(struct ieee80211_sub_if_data *sdata) ++ { +++ struct ieee80211_local *local = sdata->local; ++ struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; ++ u8 frame_buf[IEEE80211_DEAUTH_FRAME_LEN]; + - ath_dbg(common, CALIBRATE, "tx chain %d: iq corr coeff=%x\n", - chain_idx, iqc_coeff[0]); -@@ -831,7 +832,7 @@ static bool ar9003_hw_calc_iq_corr(struc - if (q_q_coff > 63) - q_q_coff = 63; -- ++@@ -2058,10 +2076,14 @@ static void __ieee80211_disconnect(struc ++ WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY, ++ true, frame_buf); ++ ifmgd->flags &= ~IEEE80211_STA_CSA_RECEIVED; +++ +++ mutex_lock(&local->mtx); ++ sdata->vif.csa_active = false; ++- ieee80211_wake_queues_by_reason(&sdata->local->hw, +++ if (!ieee80211_csa_needs_block_tx(local)) +++ ieee80211_wake_queues_by_reason(&local->hw, ++ IEEE80211_MAX_QUEUE_MAP, ++ IEEE80211_QUEUE_STOP_REASON_CSA); +++ mutex_unlock(&local->mtx); ++ ++ cfg80211_tx_mlme_mgmt(sdata->dev, frame_buf, ++ IEEE80211_DEAUTH_FRAME_LEN); ++@@ -3546,6 +3568,9 @@ static void ieee80211_sta_bcn_mon_timer( ++ if (local->quiescing) ++ return; + -- iqc_coeff[1] = (q_q_coff * 128) + q_i_coff; -+ iqc_coeff[1] = (q_q_coff * 128) + (0x7f & q_i_coff); -- +++ if (sdata->vif.csa_active) +++ return; +++ ++ sdata->u.mgd.connection_loss = false; ++ ieee80211_queue_work(&sdata->local->hw, ++ &sdata->u.mgd.beacon_connection_loss_work); ++@@ -3561,6 +3586,9 @@ static void ieee80211_sta_conn_mon_timer ++ if (local->quiescing) ++ return; + - ath_dbg(common, CALIBRATE, "rx chain %d: iq corr coeff=%x\n", - chain_idx, iqc_coeff[1]); -@@ -839,7 +840,8 @@ static bool ar9003_hw_calc_iq_corr(struc - return true; -- } -- +++ if (sdata->vif.csa_active) +++ return; +++ ++ ieee80211_queue_work(&local->hw, &ifmgd->monitor_work); + } + --static void ar9003_hw_detect_outlier(int *mp_coeff, int nmeasurement, -+static void ar9003_hw_detect_outlier(int mp_coeff[][MAXIQCAL], -+ int nmeasurement, @@ -5147,7 +7744,11 @@ index a1af6c2..892f51e 100644 - min_idx = i; - } - } -- ++--- a/net/mac80211/rc80211_minstrel_ht.c +++++ b/net/mac80211/rc80211_minstrel_ht.c ++@@ -22,7 +22,7 @@ ++ #define MCS_NBITS (AVG_PKT_SIZE << 3) + - /* find average (exclude max abs value) */ - for (i = 0; i < nmeasurement; i++) { -- if ((abs(mp_coeff[i]) < abs(mp_max)) || @@ -5175,17 +7776,37 @@ index a1af6c2..892f51e 100644 -- mp_coeff[outlier_idx] = mp_avg; -+ mp_coeff[outlier_idx][0] = mp_avg; - } -- } -- ++ /* Number of symbols for a packet with (bps) bits per symbol */ ++-#define MCS_NSYMS(bps) ((MCS_NBITS + (bps) - 1) / (bps)) +++#define MCS_NSYMS(bps) DIV_ROUND_UP(MCS_NBITS, (bps)) ++ ++ /* Transmission time (nanoseconds) for a packet containing (syms) symbols */ ++ #define MCS_SYMBOL_TIME(sgi, syms) \ ++@@ -226,8 +226,9 @@ minstrel_ht_calc_tp(struct minstrel_ht_s ++ nsecs = 1000 * mi->overhead / MINSTREL_TRUNC(mi->avg_ampdu_len); ++ ++ nsecs += minstrel_mcs_groups[group].duration[rate]; ++- tp = 1000000 * ((prob * 1000) / nsecs); ++ +++ /* prob is scaled - see MINSTREL_FRAC above */ +++ tp = 1000000 * ((prob * 1000) / nsecs); ++ mr->cur_tp = MINSTREL_TRUNC(tp); + } + --static void ar9003_hw_tx_iqcal_load_avg_2_passes(struct ath_hw *ah, -- struct coeff *coeff, -- bool is_reusable) -+static void ar9003_hw_tx_iq_cal_outlier_detection(struct ath_hw *ah, -+ struct coeff *coeff, -+ bool is_reusable) -+--- a/drivers/net/wireless/ath/ath9k/xmit.c -++++ b/drivers/net/wireless/ath/ath9k/xmit.c -+@@ -107,9 +107,6 @@ static void ath_tx_queue_tid(struct ath_ ++--- a/net/mac80211/scan.c +++++ b/net/mac80211/scan.c ++@@ -1076,12 +1076,8 @@ void ieee80211_sched_scan_results(struct ++ } ++ EXPORT_SYMBOL(ieee80211_sched_scan_results); ++ ++-void ieee80211_sched_scan_stopped_work(struct work_struct *work) +++void ieee80211_sched_scan_end(struct ieee80211_local *local) { - int i, im, nmeasurement; -+ int magnitude, phase; @@ -5195,15 +7816,15 @@ index a1af6c2..892f51e 100644 -@@ -920,21 +923,30 @@ static void ar9003_hw_tx_iqcal_load_avg_ - if (nmeasurement > MAX_MEASUREMENT) - nmeasurement = MAX_MEASUREMENT; -+ struct ath_atx_ac *ac = tid->ac; - +- -- /* detect outlier only if nmeasurement > 1 */ -- if (nmeasurement > 1) { -- /* Detect magnitude outlier */ -- ar9003_hw_detect_outlier(coeff->mag_coeff[i], -- nmeasurement, MAX_MAG_DELTA); -+- if (tid->paused) -+- return; ++- struct ieee80211_local *local = ++- container_of(work, struct ieee80211_local, ++- sched_scan_stopped_work); - -- /* Detect phase outlier */ -- ar9003_hw_detect_outlier(coeff->phs_coeff[i], @@ -5234,22 +7855,23 @@ index a1af6c2..892f51e 100644 -- ((coeff->phs_coeff[i][im] & 0x7f) << 7); -+ coeff->iqc_coeff[0] = -+ (phase & 0x7f) | ((magnitude & 0x7f) << 7); -+ if (tid->sched) -+ return; ++ mutex_lock(&local->mtx); - if ((im % 2) == 0) - REG_RMW_FIELD(ah, tx_corr_coeff[im][i], -@@ -991,7 +1003,63 @@ static bool ar9003_hw_tx_iq_cal_run(stru - return true; -- } -+@@ -1407,7 +1404,6 @@ int ath_tx_aggr_start(struct ath_softc * -+ ath_tx_tid_change_state(sc, txtid); ++ if (!rcu_access_pointer(local->sched_scan_sdata)) { ++@@ -1099,6 +1095,15 @@ void ieee80211_sched_scan_stopped_work(s ++ cfg80211_sched_scan_stopped(local->hw.wiphy); + } --static void ar9003_hw_tx_iq_cal_post_proc(struct ath_hw *ah, bool is_reusable) -+static void __ar955x_tx_iq_cal_sort(struct ath_hw *ah, -+ struct coeff *coeff, -+ int i, int nmeasurement) --+{ +++void ieee80211_sched_scan_stopped_work(struct work_struct *work) + +{ -+ struct ath_common *common = ath9k_hw_common(ah); -+ int im, ix, iy, temp; -+ @@ -5280,30 +7902,367 @@ index a1af6c2..892f51e 100644 -+ i, im, -+ coeff->mag_coeff[i][im][0], -+ coeff->phs_coeff[i][im][0]); --+ } --+} --+ +++ struct ieee80211_local *local = +++ container_of(work, struct ieee80211_local, +++ sched_scan_stopped_work); +++ +++ ieee80211_sched_scan_end(local); +++} +++ ++ void ieee80211_sched_scan_stopped(struct ieee80211_hw *hw) ++ { ++ struct ieee80211_local *local = hw_to_local(hw); ++--- /dev/null +++++ b/net/mac80211/tdls.c ++@@ -0,0 +1,325 @@ +++/* +++ * mac80211 TDLS handling code +++ * +++ * Copyright 2006-2010 Johannes Berg +++ * Copyright 2014, Intel Corporation +++ * +++ * This file is GPLv2 as found in COPYING. +++ */ +++ +++#include +++#include "ieee80211_i.h" +++ +++static void ieee80211_tdls_add_ext_capab(struct sk_buff *skb) +++{ +++ u8 *pos = (void *)skb_put(skb, 7); +++ +++ *pos++ = WLAN_EID_EXT_CAPABILITY; +++ *pos++ = 5; /* len */ +++ *pos++ = 0x0; +++ *pos++ = 0x0; +++ *pos++ = 0x0; +++ *pos++ = 0x0; +++ *pos++ = WLAN_EXT_CAPA5_TDLS_ENABLED; +++} +++ +++static u16 ieee80211_get_tdls_sta_capab(struct ieee80211_sub_if_data *sdata) +++{ +++ struct ieee80211_local *local = sdata->local; +++ u16 capab; +++ +++ capab = 0; +++ if (ieee80211_get_sdata_band(sdata) != IEEE80211_BAND_2GHZ) +++ return capab; +++ +++ if (!(local->hw.flags & IEEE80211_HW_2GHZ_SHORT_SLOT_INCAPABLE)) +++ capab |= WLAN_CAPABILITY_SHORT_SLOT_TIME; +++ if (!(local->hw.flags & IEEE80211_HW_2GHZ_SHORT_PREAMBLE_INCAPABLE)) +++ capab |= WLAN_CAPABILITY_SHORT_PREAMBLE; +++ +++ return capab; +++} +++ +++static void ieee80211_tdls_add_link_ie(struct sk_buff *skb, const u8 *src_addr, +++ const u8 *peer, const u8 *bssid) +++{ +++ struct ieee80211_tdls_lnkie *lnkid; +++ +++ lnkid = (void *)skb_put(skb, sizeof(struct ieee80211_tdls_lnkie)); +++ +++ lnkid->ie_type = WLAN_EID_LINK_ID; +++ lnkid->ie_len = sizeof(struct ieee80211_tdls_lnkie) - 2; +++ +++ memcpy(lnkid->bssid, bssid, ETH_ALEN); +++ memcpy(lnkid->init_sta, src_addr, ETH_ALEN); +++ memcpy(lnkid->resp_sta, peer, ETH_ALEN); +++} +++ +++static int +++ieee80211_prep_tdls_encap_data(struct wiphy *wiphy, struct net_device *dev, +++ const u8 *peer, u8 action_code, u8 dialog_token, +++ u16 status_code, struct sk_buff *skb) +++{ +++ struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); +++ enum ieee80211_band band = ieee80211_get_sdata_band(sdata); +++ struct ieee80211_tdls_data *tf; +++ +++ tf = (void *)skb_put(skb, offsetof(struct ieee80211_tdls_data, u)); +++ +++ memcpy(tf->da, peer, ETH_ALEN); +++ memcpy(tf->sa, sdata->vif.addr, ETH_ALEN); +++ tf->ether_type = cpu_to_be16(ETH_P_TDLS); +++ tf->payload_type = WLAN_TDLS_SNAP_RFTYPE; +++ +++ switch (action_code) { +++ case WLAN_TDLS_SETUP_REQUEST: +++ tf->category = WLAN_CATEGORY_TDLS; +++ tf->action_code = WLAN_TDLS_SETUP_REQUEST; +++ +++ skb_put(skb, sizeof(tf->u.setup_req)); +++ tf->u.setup_req.dialog_token = dialog_token; +++ tf->u.setup_req.capability = +++ cpu_to_le16(ieee80211_get_tdls_sta_capab(sdata)); +++ +++ ieee80211_add_srates_ie(sdata, skb, false, band); +++ ieee80211_add_ext_srates_ie(sdata, skb, false, band); +++ ieee80211_tdls_add_ext_capab(skb); +++ break; +++ case WLAN_TDLS_SETUP_RESPONSE: +++ tf->category = WLAN_CATEGORY_TDLS; +++ tf->action_code = WLAN_TDLS_SETUP_RESPONSE; +++ +++ skb_put(skb, sizeof(tf->u.setup_resp)); +++ tf->u.setup_resp.status_code = cpu_to_le16(status_code); +++ tf->u.setup_resp.dialog_token = dialog_token; +++ tf->u.setup_resp.capability = +++ cpu_to_le16(ieee80211_get_tdls_sta_capab(sdata)); +++ +++ ieee80211_add_srates_ie(sdata, skb, false, band); +++ ieee80211_add_ext_srates_ie(sdata, skb, false, band); +++ ieee80211_tdls_add_ext_capab(skb); +++ break; +++ case WLAN_TDLS_SETUP_CONFIRM: +++ tf->category = WLAN_CATEGORY_TDLS; +++ tf->action_code = WLAN_TDLS_SETUP_CONFIRM; +++ +++ skb_put(skb, sizeof(tf->u.setup_cfm)); +++ tf->u.setup_cfm.status_code = cpu_to_le16(status_code); +++ tf->u.setup_cfm.dialog_token = dialog_token; +++ break; +++ case WLAN_TDLS_TEARDOWN: +++ tf->category = WLAN_CATEGORY_TDLS; +++ tf->action_code = WLAN_TDLS_TEARDOWN; +++ +++ skb_put(skb, sizeof(tf->u.teardown)); +++ tf->u.teardown.reason_code = cpu_to_le16(status_code); +++ break; +++ case WLAN_TDLS_DISCOVERY_REQUEST: +++ tf->category = WLAN_CATEGORY_TDLS; +++ tf->action_code = WLAN_TDLS_DISCOVERY_REQUEST; +++ +++ skb_put(skb, sizeof(tf->u.discover_req)); +++ tf->u.discover_req.dialog_token = dialog_token; +++ break; +++ default: +++ return -EINVAL; +++ } +++ +++ return 0; +++} +++ +++static int +++ieee80211_prep_tdls_direct(struct wiphy *wiphy, struct net_device *dev, +++ const u8 *peer, u8 action_code, u8 dialog_token, +++ u16 status_code, struct sk_buff *skb) +++{ +++ struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); +++ enum ieee80211_band band = ieee80211_get_sdata_band(sdata); +++ struct ieee80211_mgmt *mgmt; +++ +++ mgmt = (void *)skb_put(skb, 24); +++ memset(mgmt, 0, 24); +++ memcpy(mgmt->da, peer, ETH_ALEN); +++ memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN); +++ memcpy(mgmt->bssid, sdata->u.mgd.bssid, ETH_ALEN); +++ +++ mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | +++ IEEE80211_STYPE_ACTION); +++ +++ switch (action_code) { +++ case WLAN_PUB_ACTION_TDLS_DISCOVER_RES: +++ skb_put(skb, 1 + sizeof(mgmt->u.action.u.tdls_discover_resp)); +++ mgmt->u.action.category = WLAN_CATEGORY_PUBLIC; +++ mgmt->u.action.u.tdls_discover_resp.action_code = +++ WLAN_PUB_ACTION_TDLS_DISCOVER_RES; +++ mgmt->u.action.u.tdls_discover_resp.dialog_token = +++ dialog_token; +++ mgmt->u.action.u.tdls_discover_resp.capability = +++ cpu_to_le16(ieee80211_get_tdls_sta_capab(sdata)); +++ +++ ieee80211_add_srates_ie(sdata, skb, false, band); +++ ieee80211_add_ext_srates_ie(sdata, skb, false, band); +++ ieee80211_tdls_add_ext_capab(skb); +++ break; +++ default: +++ return -EINVAL; + + } +++ +++ return 0; + +} + + -+static bool ar955x_tx_iq_cal_median(struct ath_hw *ah, -+ struct coeff *coeff, -+ int iqcal_idx, -+ int nmeasurement) --+{ +++int ieee80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev, +++ const u8 *peer, u8 action_code, u8 dialog_token, +++ u16 status_code, u32 peer_capability, +++ const u8 *extra_ies, size_t extra_ies_len) + +{ -+ int i; --+ +++ struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); +++ struct ieee80211_local *local = sdata->local; +++ struct sk_buff *skb = NULL; +++ bool send_direct; +++ int ret; +++ +++ if (!(wiphy->flags & WIPHY_FLAG_SUPPORTS_TDLS)) +++ return -ENOTSUPP; +++ +++ /* make sure we are in managed mode, and associated */ +++ if (sdata->vif.type != NL80211_IFTYPE_STATION || +++ !sdata->u.mgd.associated) +++ return -EINVAL; +++ +++ tdls_dbg(sdata, "TDLS mgmt action %d peer %pM\n", +++ action_code, peer); +++ +++ skb = dev_alloc_skb(local->hw.extra_tx_headroom + +++ max(sizeof(struct ieee80211_mgmt), +++ sizeof(struct ieee80211_tdls_data)) + +++ 50 + /* supported rates */ +++ 7 + /* ext capab */ +++ extra_ies_len + +++ sizeof(struct ieee80211_tdls_lnkie)); +++ if (!skb) +++ return -ENOMEM; +++ +++ skb_reserve(skb, local->hw.extra_tx_headroom); +++ +++ switch (action_code) { +++ case WLAN_TDLS_SETUP_REQUEST: +++ case WLAN_TDLS_SETUP_RESPONSE: +++ case WLAN_TDLS_SETUP_CONFIRM: +++ case WLAN_TDLS_TEARDOWN: +++ case WLAN_TDLS_DISCOVERY_REQUEST: +++ ret = ieee80211_prep_tdls_encap_data(wiphy, dev, peer, +++ action_code, dialog_token, +++ status_code, skb); +++ send_direct = false; +++ break; +++ case WLAN_PUB_ACTION_TDLS_DISCOVER_RES: +++ ret = ieee80211_prep_tdls_direct(wiphy, dev, peer, action_code, +++ dialog_token, status_code, +++ skb); +++ send_direct = true; +++ break; +++ default: +++ ret = -ENOTSUPP; +++ break; +++ } +++ +++ if (ret < 0) +++ goto fail; +++ +++ if (extra_ies_len) +++ memcpy(skb_put(skb, extra_ies_len), extra_ies, extra_ies_len); +++ +++ /* the TDLS link IE is always added last */ +++ switch (action_code) { +++ case WLAN_TDLS_SETUP_REQUEST: +++ case WLAN_TDLS_SETUP_CONFIRM: +++ case WLAN_TDLS_TEARDOWN: +++ case WLAN_TDLS_DISCOVERY_REQUEST: +++ /* we are the initiator */ +++ ieee80211_tdls_add_link_ie(skb, sdata->vif.addr, peer, +++ sdata->u.mgd.bssid); +++ break; +++ case WLAN_TDLS_SETUP_RESPONSE: +++ case WLAN_PUB_ACTION_TDLS_DISCOVER_RES: +++ /* we are the responder */ +++ ieee80211_tdls_add_link_ie(skb, peer, sdata->vif.addr, +++ sdata->u.mgd.bssid); +++ break; +++ default: +++ ret = -ENOTSUPP; +++ goto fail; +++ } + + -+ if ((iqcal_idx + 1) != MAXIQCAL) -+ return false; --+ +++ if (send_direct) { +++ ieee80211_tx_skb(sdata, skb); +++ return 0; +++ } + + -+ for (i = 0; i < AR9300_MAX_CHAINS; i++) { -+ __ar955x_tx_iq_cal_sort(ah, coeff, i, nmeasurement); --+ } --+ +++ /* +++ * According to 802.11z: Setup req/resp are sent in AC_BK, otherwise +++ * we should default to AC_VI. +++ */ +++ switch (action_code) { +++ case WLAN_TDLS_SETUP_REQUEST: +++ case WLAN_TDLS_SETUP_RESPONSE: +++ skb_set_queue_mapping(skb, IEEE80211_AC_BK); +++ skb->priority = 2; +++ break; +++ default: +++ skb_set_queue_mapping(skb, IEEE80211_AC_VI); +++ skb->priority = 5; +++ break; + + } + + -+ return true; --+} --+ +++ /* disable bottom halves when entering the Tx path */ +++ local_bh_disable(); +++ ret = ieee80211_subif_start_xmit(skb, dev); +++ local_bh_enable(); +++ +++ return ret; +++ +++fail: +++ dev_kfree_skb(skb); +++ return ret; + +} + + -+static void ar9003_hw_tx_iq_cal_post_proc(struct ath_hw *ah, -+ int iqcal_idx, -+ bool is_reusable) -- { +++int ieee80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev, +++ const u8 *peer, enum nl80211_tdls_operation oper) +++{ +++ struct sta_info *sta; +++ struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); +++ +++ if (!(wiphy->flags & WIPHY_FLAG_SUPPORTS_TDLS)) +++ return -ENOTSUPP; +++ +++ if (sdata->vif.type != NL80211_IFTYPE_STATION) +++ return -EINVAL; +++ +++ tdls_dbg(sdata, "TDLS oper %d peer %pM\n", oper, peer); +++ +++ switch (oper) { +++ case NL80211_TDLS_ENABLE_LINK: +++ rcu_read_lock(); +++ sta = sta_info_get(sdata, peer); +++ if (!sta) { +++ rcu_read_unlock(); +++ return -ENOLINK; +++ } +++ +++ set_sta_flag(sta, WLAN_STA_TDLS_PEER_AUTH); +++ rcu_read_unlock(); +++ break; +++ case NL80211_TDLS_DISABLE_LINK: +++ return sta_info_destroy_addr(sdata, peer); +++ case NL80211_TDLS_TEARDOWN: +++ case NL80211_TDLS_SETUP: +++ case NL80211_TDLS_DISCOVERY_REQ: +++ /* We don't support in-driver setup/teardown/discovery */ +++ return -ENOTSUPP; +++ default: +++ return -ENOTSUPP; +++ } +++ +++ return 0; +++} ++--- a/net/mac80211/tx.c +++++ b/net/mac80211/tx.c ++@@ -2330,7 +2330,8 @@ void ieee80211_tx_pending(unsigned long ++ /* functions for drivers to get certain frames */ ++ ++ static void __ieee80211_beacon_add_tim(struct ieee80211_sub_if_data *sdata, ++- struct ps_data *ps, struct sk_buff *skb) +++ struct ps_data *ps, struct sk_buff *skb, +++ bool is_template) + { - struct ath_common *common = ath9k_hw_common(ah); - const u32 txiqcal_status[AR9300_MAX_CHAINS] = { -@@ -1004,10 +1072,11 @@ static void ar9003_hw_tx_iq_cal_post_pro @@ -5317,17 +8276,29 @@ index a1af6c2..892f51e 100644 -- int nmeasurement; -+ int nmeasurement = 0; -+ bool outlier_detect = true; -+ txtid->active = true; -+- txtid->paused = true; -+ *ssn = txtid->seq_start = txtid->seq_next; -+ txtid->bar_index = -1; - +- - for (i = 0; i < AR9300_MAX_CHAINS; i++) { - if (!(ah->txchainmask & (1 << i))) -@@ -1065,17 +1134,23 @@ static void ar9003_hw_tx_iq_cal_post_pro - goto tx_iqcal_fail; - } -+@@ -1427,7 +1423,6 @@ void ath_tx_aggr_stop(struct ath_softc * ++ u8 *pos, *tim; ++ int aid0 = 0; ++@@ -2343,11 +2344,12 @@ static void __ieee80211_beacon_add_tim(s ++ * checking byte-for-byte */ ++ have_bits = !bitmap_empty((unsigned long *)ps->tim, ++ IEEE80211_MAX_AID+1); ++- ++- if (ps->dtim_count == 0) ++- ps->dtim_count = sdata->vif.bss_conf.dtim_period - 1; ++- else ++- ps->dtim_count--; +++ if (!is_template) { +++ if (ps->dtim_count == 0) +++ ps->dtim_count = sdata->vif.bss_conf.dtim_period - 1; +++ else +++ ps->dtim_count--; +++ } -- coeff.mag_coeff[i][im] = coeff.iqc_coeff[0] & 0x7f; -- coeff.phs_coeff[i][im] = @@ -5335,16 +8306,7 @@ index a1af6c2..892f51e 100644 -+ coeff.iqc_coeff[0] & 0x7f; -+ coeff.mag_coeff[i][im][iqcal_idx] = - (coeff.iqc_coeff[0] >> 7) & 0x7f; -+ ath_txq_lock(sc, txq); -+ txtid->active = false; -+- txtid->paused = false; -+ ath_tx_flush_tid(sc, txtid); -+ ath_tx_tid_change_state(sc, txtid); -+ ath_txq_unlock_complete(sc, txq); -+@@ -1487,7 +1482,7 @@ void ath_tx_aggr_wakeup(struct ath_softc -+ ath_txq_lock(sc, txq); -+ ac->clear_ps_filter = true; - +- -- if (coeff.mag_coeff[i][im] > 63) -- coeff.mag_coeff[i][im] -= 128; -- if (coeff.phs_coeff[i][im] > 63) @@ -5353,39 +8315,325 @@ index a1af6c2..892f51e 100644 -+ coeff.mag_coeff[i][im][iqcal_idx] -= 128; -+ if (coeff.phs_coeff[i][im][iqcal_idx] > 63) -+ coeff.phs_coeff[i][im][iqcal_idx] -= 128; -+- if (!tid->paused && ath_tid_has_buffered(tid)) { -++ if (ath_tid_has_buffered(tid)) { -+ ath_tx_queue_tid(txq, tid); -+ ath_txq_schedule(sc, txq); ++ tim = pos = (u8 *) skb_put(skb, 6); ++ *pos++ = WLAN_EID_TIM; ++@@ -2393,7 +2395,8 @@ static void __ieee80211_beacon_add_tim(s ++ } ++ ++ static int ieee80211_beacon_add_tim(struct ieee80211_sub_if_data *sdata, ++- struct ps_data *ps, struct sk_buff *skb) +++ struct ps_data *ps, struct sk_buff *skb, +++ bool is_template) ++ { ++ struct ieee80211_local *local = sdata->local; ++ ++@@ -2405,24 +2408,24 @@ static int ieee80211_beacon_add_tim(stru ++ * of the tim bitmap in mac80211 and the driver. ++ */ ++ if (local->tim_in_locked_section) { ++- __ieee80211_beacon_add_tim(sdata, ps, skb); +++ __ieee80211_beacon_add_tim(sdata, ps, skb, is_template); ++ } else { ++ spin_lock_bh(&local->tim_lock); ++- __ieee80211_beacon_add_tim(sdata, ps, skb); +++ __ieee80211_beacon_add_tim(sdata, ps, skb, is_template); ++ spin_unlock_bh(&local->tim_lock); ++ } ++ ++ return 0; ++ } ++ ++-static void ieee80211_update_csa(struct ieee80211_sub_if_data *sdata, ++- struct beacon_data *beacon) +++static void ieee80211_set_csa(struct ieee80211_sub_if_data *sdata, +++ struct beacon_data *beacon) ++ { ++ struct probe_resp *resp; ++- int counter_offset_beacon = sdata->csa_counter_offset_beacon; ++- int counter_offset_presp = sdata->csa_counter_offset_presp; ++ u8 *beacon_data; ++ size_t beacon_data_len; +++ int i; +++ u8 count = sdata->csa_current_counter; ++ ++ switch (sdata->vif.type) { ++ case NL80211_IFTYPE_AP: ++@@ -2440,40 +2443,57 @@ static void ieee80211_update_csa(struct ++ default: ++ return; ++ } ++- if (WARN_ON(counter_offset_beacon >= beacon_data_len)) ++- return; ++ ++- /* Warn if the driver did not check for/react to csa ++- * completeness. A beacon with CSA counter set to 0 should ++- * never occur, because a counter of 1 means switch just ++- * before the next beacon. ++- */ ++- if (WARN_ON(beacon_data[counter_offset_beacon] == 1)) ++- return; +++ for (i = 0; i < IEEE80211_MAX_CSA_COUNTERS_NUM; ++i) { +++ u16 counter_offset_beacon = +++ sdata->csa_counter_offset_beacon[i]; +++ u16 counter_offset_presp = sdata->csa_counter_offset_presp[i]; +++ +++ if (counter_offset_beacon) { +++ if (WARN_ON(counter_offset_beacon >= beacon_data_len)) +++ return; ++ ++- beacon_data[counter_offset_beacon]--; +++ beacon_data[counter_offset_beacon] = count; +++ } ++ ++- if (sdata->vif.type == NL80211_IFTYPE_AP && counter_offset_presp) { ++- rcu_read_lock(); ++- resp = rcu_dereference(sdata->u.ap.probe_resp); +++ if (sdata->vif.type == NL80211_IFTYPE_AP && +++ counter_offset_presp) { +++ rcu_read_lock(); +++ resp = rcu_dereference(sdata->u.ap.probe_resp); ++ ++- /* if nl80211 accepted the offset, this should not happen. */ ++- if (WARN_ON(!resp)) { +++ /* If nl80211 accepted the offset, this should +++ * not happen. +++ */ +++ if (WARN_ON(!resp)) { +++ rcu_read_unlock(); +++ return; +++ } +++ resp->data[counter_offset_presp] = count; ++ rcu_read_unlock(); ++- return; } -- } ++- resp->data[counter_offset_presp]--; ++- rcu_read_unlock(); + } -- ar9003_hw_tx_iqcal_load_avg_2_passes(ah, &coeff, is_reusable); --+ ++ } ++ +++u8 ieee80211_csa_update_counter(struct ieee80211_vif *vif) +++{ +++ struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); +++ +++ sdata->csa_current_counter--; +++ +++ /* the counter should never reach 0 */ +++ WARN_ON(!sdata->csa_current_counter); + + -+ if (AR_SREV_9550(ah)) -+ outlier_detect = ar955x_tx_iq_cal_median(ah, &coeff, -+ iqcal_idx, nmeasurement); -+ if (outlier_detect) -+ ar9003_hw_tx_iq_cal_outlier_detection(ah, &coeff, is_reusable); -- +++ return sdata->csa_current_counter; +++} +++EXPORT_SYMBOL(ieee80211_csa_update_counter); +++ ++ bool ieee80211_csa_is_complete(struct ieee80211_vif *vif) ++ { ++ struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); ++ struct beacon_data *beacon = NULL; ++ u8 *beacon_data; ++ size_t beacon_data_len; ++- int counter_beacon = sdata->csa_counter_offset_beacon; +++ int counter_beacon = sdata->csa_counter_offset_beacon[0]; ++ int ret = false; + - return; -- ++ if (!ieee80211_sdata_running(sdata)) ++@@ -2523,9 +2543,11 @@ bool ieee80211_csa_is_complete(struct ie ++ } ++ EXPORT_SYMBOL(ieee80211_csa_is_complete); ++ ++-struct sk_buff *ieee80211_beacon_get_tim(struct ieee80211_hw *hw, ++- struct ieee80211_vif *vif, ++- u16 *tim_offset, u16 *tim_length) +++static struct sk_buff * +++__ieee80211_beacon_get(struct ieee80211_hw *hw, +++ struct ieee80211_vif *vif, +++ struct ieee80211_mutable_offsets *offs, +++ bool is_template) ++ { ++ struct ieee80211_local *local = hw_to_local(hw); ++ struct sk_buff *skb = NULL; ++@@ -2534,6 +2556,7 @@ struct sk_buff *ieee80211_beacon_get_tim ++ enum ieee80211_band band; ++ struct ieee80211_tx_rate_control txrc; ++ struct ieee80211_chanctx_conf *chanctx_conf; +++ int csa_off_base = 0; ++ ++ rcu_read_lock(); ++ ++@@ -2543,18 +2566,20 @@ struct sk_buff *ieee80211_beacon_get_tim ++ if (!ieee80211_sdata_running(sdata) || !chanctx_conf) ++ goto out; ++ ++- if (tim_offset) ++- *tim_offset = 0; ++- if (tim_length) ++- *tim_length = 0; +++ if (offs) +++ memset(offs, 0, sizeof(*offs)); ++ ++ if (sdata->vif.type == NL80211_IFTYPE_AP) { ++ struct ieee80211_if_ap *ap = &sdata->u.ap; ++ struct beacon_data *beacon = rcu_dereference(ap->beacon); ++ ++ if (beacon) { ++- if (sdata->vif.csa_active) ++- ieee80211_update_csa(sdata, beacon); +++ if (sdata->vif.csa_active) { +++ if (!is_template) +++ ieee80211_csa_update_counter(vif); +++ +++ ieee80211_set_csa(sdata, beacon); +++ } ++ ++ /* ++ * headroom, head length, ++@@ -2571,12 +2596,16 @@ struct sk_buff *ieee80211_beacon_get_tim ++ memcpy(skb_put(skb, beacon->head_len), beacon->head, ++ beacon->head_len); ++ ++- ieee80211_beacon_add_tim(sdata, &ap->ps, skb); +++ ieee80211_beacon_add_tim(sdata, &ap->ps, skb, +++ is_template); +++ +++ if (offs) { +++ offs->tim_offset = beacon->head_len; +++ offs->tim_length = skb->len - beacon->head_len; ++ ++- if (tim_offset) ++- *tim_offset = beacon->head_len; ++- if (tim_length) ++- *tim_length = skb->len - beacon->head_len; +++ /* for AP the csa offsets are from tail */ +++ csa_off_base = skb->len; +++ } ++ ++ if (beacon->tail) ++ memcpy(skb_put(skb, beacon->tail_len), ++@@ -2591,9 +2620,12 @@ struct sk_buff *ieee80211_beacon_get_tim ++ if (!presp) ++ goto out; ++ ++- if (sdata->vif.csa_active) ++- ieee80211_update_csa(sdata, presp); +++ if (sdata->vif.csa_active) { +++ if (!is_template) +++ ieee80211_csa_update_counter(vif); ++ +++ ieee80211_set_csa(sdata, presp); +++ } ++ ++ skb = dev_alloc_skb(local->tx_headroom + presp->head_len + ++ local->hw.extra_beacon_tailroom); ++@@ -2613,8 +2645,17 @@ struct sk_buff *ieee80211_beacon_get_tim ++ if (!bcn) ++ goto out; ++ ++- if (sdata->vif.csa_active) ++- ieee80211_update_csa(sdata, bcn); +++ if (sdata->vif.csa_active) { +++ if (!is_template) +++ /* TODO: For mesh csa_counter is in TU, so +++ * decrementing it by one isn't correct, but +++ * for now we leave it consistent with overall +++ * mac80211's behavior. +++ */ +++ ieee80211_csa_update_counter(vif); +++ +++ ieee80211_set_csa(sdata, bcn); +++ } + -@@ -1409,7 +1484,7 @@ skip_tx_iqcal: -- } -- ++ if (ifmsh->sync_ops) ++ ifmsh->sync_ops->adjust_tbtt(sdata, bcn); ++@@ -2628,13 +2669,33 @@ struct sk_buff *ieee80211_beacon_get_tim ++ goto out; ++ skb_reserve(skb, local->tx_headroom); ++ memcpy(skb_put(skb, bcn->head_len), bcn->head, bcn->head_len); ++- ieee80211_beacon_add_tim(sdata, &ifmsh->ps, skb); +++ ieee80211_beacon_add_tim(sdata, &ifmsh->ps, skb, is_template); +++ +++ if (offs) { +++ offs->tim_offset = bcn->head_len; +++ offs->tim_length = skb->len - bcn->head_len; +++ } +++ ++ memcpy(skb_put(skb, bcn->tail_len), bcn->tail, bcn->tail_len); ++ } else { ++ WARN_ON(1); ++ goto out; + } + - if (txiqcal_done) -- ar9003_hw_tx_iq_cal_post_proc(ah, is_reusable); -+ ar9003_hw_tx_iq_cal_post_proc(ah, 0, is_reusable); - else if (caldata && test_bit(TXIQCAL_DONE, &caldata->cal_flags)) - ar9003_hw_tx_iq_cal_reload(ah); -+@@ -1510,7 +1505,6 @@ void ath_tx_aggr_resume(struct ath_softc -+ ath_txq_lock(sc, txq); +++ /* CSA offsets */ +++ if (offs) { +++ int i; +++ +++ for (i = 0; i < IEEE80211_MAX_CSA_COUNTERS_NUM; i++) { +++ u16 csa_off = sdata->csa_counter_offset_beacon[i]; +++ +++ if (!csa_off) +++ continue; +++ +++ offs->csa_counter_offs[i] = csa_off_base + csa_off; +++ } +++ } +++ ++ band = chanctx_conf->def.chan->band; ++ ++ info = IEEE80211_SKB_CB(skb); ++@@ -2665,6 +2726,32 @@ struct sk_buff *ieee80211_beacon_get_tim ++ out: ++ rcu_read_unlock(); ++ return skb; +++ +++} +++ +++struct sk_buff * +++ieee80211_beacon_get_template(struct ieee80211_hw *hw, +++ struct ieee80211_vif *vif, +++ struct ieee80211_mutable_offsets *offs) +++{ +++ return __ieee80211_beacon_get(hw, vif, offs, true); +++} +++EXPORT_SYMBOL(ieee80211_beacon_get_template); +++ +++struct sk_buff *ieee80211_beacon_get_tim(struct ieee80211_hw *hw, +++ struct ieee80211_vif *vif, +++ u16 *tim_offset, u16 *tim_length) +++{ +++ struct ieee80211_mutable_offsets offs = {}; +++ struct sk_buff *bcn = __ieee80211_beacon_get(hw, vif, &offs, false); +++ +++ if (tim_offset) +++ *tim_offset = offs.tim_offset; +++ +++ if (tim_length) +++ *tim_length = offs.tim_length; +++ +++ return bcn; ++ } ++ EXPORT_SYMBOL(ieee80211_beacon_get_tim); -@@ -1455,14 +1530,38 @@ skip_tx_iqcal: - return true; -- } -- ++--- a/net/mac80211/util.c +++++ b/net/mac80211/util.c ++@@ -1457,6 +1457,44 @@ void ieee80211_stop_device(struct ieee80 ++ drv_stop(local); + } + -+static bool do_ar9003_agc_cal(struct ath_hw *ah) --+{ +++static void ieee80211_handle_reconfig_failure(struct ieee80211_local *local) + +{ -+ struct ath_common *common = ath9k_hw_common(ah); -+ bool status; -+ @@ -5403,13 +8651,48 @@ index a1af6c2..892f51e 100644 -+ AH_WAIT_TIMEOUT / 1000); -+ return false; -+ } --+ +++ struct ieee80211_sub_if_data *sdata; +++ struct ieee80211_chanctx *ctx; +++ +++ /* +++ * We get here if during resume the device can't be restarted properly. +++ * We might also get here if this happens during HW reset, which is a +++ * slightly different situation and we need to drop all connections in +++ * the latter case. +++ * +++ * Ask cfg80211 to turn off all interfaces, this will result in more +++ * warnings but at least we'll then get into a clean stopped state. +++ */ +++ +++ local->resuming = false; +++ local->suspended = false; +++ local->started = false; +++ +++ /* scheduled scan clearly can't be running any more, but tell +++ * cfg80211 and clear local state +++ */ +++ ieee80211_sched_scan_end(local); + + -+ return true; --+} --+ +++ list_for_each_entry(sdata, &local->interfaces, list) +++ sdata->flags &= ~IEEE80211_SDATA_IN_DRIVER; +++ +++ /* Mark channel contexts as not being in the driver any more to avoid +++ * removing them from the driver during the shutdown process... +++ */ +++ mutex_lock(&local->chanctx_mtx); +++ list_for_each_entry(ctx, &local->chanctx_list, list) +++ ctx->driver_present = false; +++ mutex_unlock(&local->chanctx_mtx); +++ +++ cfg80211_shutdown_all_interfaces(local->hw.wiphy); + +} + + - static bool ar9003_hw_init_cal_soc(struct ath_hw *ah, - struct ath9k_channel *chan) -- { ++ static void ieee80211_assign_chanctx(struct ieee80211_local *local, ++ struct ieee80211_sub_if_data *sdata) + { - struct ath_common *common = ath9k_hw_common(ah); - struct ath9k_hw_cal_data *caldata = ah->caldata; - bool txiqcal_done = false; @@ -5417,14 +8700,13 @@ index a1af6c2..892f51e 100644 -+ bool status = true; - bool run_agc_cal = false, sep_iq_cal = false; -+ int i = 0; -+ tid->baw_size = IEEE80211_MIN_AMPDU_BUF << sta->ht_cap.ampdu_factor; -+- tid->paused = false; - +- - /* Use chip chainmask only for calibration */ - ar9003_hw_set_chain_masks(ah, ah->caps.rx_chainmask, ah->caps.tx_chainmask); -@@ -1485,7 +1584,12 @@ static bool ar9003_hw_init_cal_soc(struc - * AGC calibration. Specifically, AR9550 in SoC chips. -- */ ++@@ -1520,9 +1558,11 @@ int ieee80211_reconfig(struct ieee80211_ + */ - if (ah->enabled_cals & TX_IQ_ON_AGC_CAL) { -- txiqcal_done = true; -+ if (REG_READ_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_0, @@ -5439,11 +8721,7 @@ index a1af6c2..892f51e 100644 -@@ -1512,27 +1616,37 @@ skip_tx_iqcal: - if (AR_SREV_9330_11(ah)) - ar9003_hw_manual_peak_cal(ah, 0, IS_CHAN_2GHZ(chan)); -+ if (ath_tid_has_buffered(tid)) { -+ ath_tx_queue_tid(txq, tid); -+@@ -1544,8 +1538,6 @@ void ath9k_release_buffered_frames(struc -+ continue; - +- -- /* Calibrate the AGC */ -- REG_WRITE(ah, AR_PHY_AGC_CONTROL, -- REG_READ(ah, AR_PHY_AGC_CONTROL) | @@ -5466,10 +8744,7 @@ index a1af6c2..892f51e 100644 -+ status = do_ar9003_agc_cal(ah); -+ if (!status) -+ return false; -+ tid = ATH_AN_2_TID(an, i); -+- if (tid->paused) -+- continue; - +- -- if (!status) { -- ath_dbg(common, CALIBRATE, -- "offset calibration failed to complete in %d ms; noisy environment?\n", @@ -5491,32 +8766,74 @@ index a1af6c2..892f51e 100644 -+ } -+ } -+ } -- } -+ ath_txq_lock(sc, tid->ac->txq); -+ while (nframes > 0) { -+@@ -1844,9 +1836,6 @@ void ath_txq_schedule(struct ath_softc * -+ list_del(&tid->list); -+ tid->sched = false; ++ res = drv_start(local); ++ if (res) { ++- WARN(local->suspended, "Hardware became unavailable " ++- "upon resume. This could be a software issue " ++- "prior to suspend or a hardware issue.\n"); +++ if (local->suspended) +++ WARN(1, "Hardware became unavailable upon resume. This could be a software issue prior to suspend or a hardware issue.\n"); +++ else +++ WARN(1, "Hardware became unavailable during restart.\n"); +++ ieee80211_handle_reconfig_failure(local); ++ return res; + } -- if (txiqcal_done) -- ar9003_hw_tx_iq_cal_post_proc(ah, is_reusable); -+- if (tid->paused) -+- continue; - - +-- - /* Revert chainmask to runtime parameters */ - ar9003_hw_set_chain_masks(ah, ah->rxchainmask, ah->txchainmask); -- ++--- a/net/wireless/ap.c +++++ b/net/wireless/ap.c ++@@ -6,8 +6,8 @@ ++ #include "rdev-ops.h" + ---- a/drivers/net/wireless/rtl818x/rtl8187/rtl8187.h -+++ b/drivers/net/wireless/rtl818x/rtl8187/rtl8187.h -@@ -15,6 +15,8 @@ - #ifndef RTL8187_H - #define RTL8187_H -- + -+#include -+ - #include "rtl818x.h" - #include "leds.h" -- ++-static int __cfg80211_stop_ap(struct cfg80211_registered_device *rdev, ++- struct net_device *dev, bool notify) +++int __cfg80211_stop_ap(struct cfg80211_registered_device *rdev, +++ struct net_device *dev, bool notify) ++ { ++ struct wireless_dev *wdev = dev->ieee80211_ptr; ++ int err; ++--- a/net/wireless/chan.c +++++ b/net/wireless/chan.c ++@@ -370,8 +370,8 @@ int cfg80211_chandef_dfs_required(struct ++ case NL80211_IFTYPE_AP_VLAN: ++ case NL80211_IFTYPE_WDS: ++ case NL80211_IFTYPE_P2P_DEVICE: ++- case NL80211_IFTYPE_UNSPECIFIED: ++ break; +++ case NL80211_IFTYPE_UNSPECIFIED: ++ case NUM_NL80211_IFTYPES: ++ WARN_ON(1); ++ } ++@@ -796,8 +796,7 @@ bool cfg80211_reg_can_beacon(struct wiph ++ !cfg80211_go_permissive_chan(rdev, chandef->chan)) ++ prohibited_flags |= IEEE80211_CHAN_NO_IR; ++ ++- if (cfg80211_chandef_dfs_required(wiphy, chandef, ++- NL80211_IFTYPE_UNSPECIFIED) > 0 && +++ if (cfg80211_chandef_dfs_required(wiphy, chandef, iftype) > 0 && ++ cfg80211_chandef_dfs_available(wiphy, chandef)) { ++ /* We can skip IEEE80211_CHAN_NO_IR if chandef dfs available */ ++ prohibited_flags = IEEE80211_CHAN_DISABLED; ++--- a/net/wireless/core.c +++++ b/net/wireless/core.c ++@@ -210,15 +210,12 @@ void cfg80211_stop_p2p_device(struct cfg ++ } ++ } + -@@ -139,7 +141,10 @@ struct rtl8187_priv { - u8 aifsn[4]; - u8 rfkill_mask; @@ -5543,13 +8860,36 @@ index a1af6c2..892f51e 100644 -+++ b/net/mac80211/wme.c -@@ -154,6 +154,11 @@ u16 ieee80211_select_queue(struct ieee80 - return IEEE80211_AC_BE; -- } -- ++-static int cfg80211_rfkill_set_block(void *data, bool blocked) +++void cfg80211_shutdown_all_interfaces(struct wiphy *wiphy) ++ { ++- struct cfg80211_registered_device *rdev = data; +++ struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy); ++ struct wireless_dev *wdev; ++ ++- if (!blocked) ++- return 0; ++- ++- rtnl_lock(); +++ ASSERT_RTNL(); ++ ++ list_for_each_entry(wdev, &rdev->wdev_list, list) { ++ if (wdev->netdev) { ++@@ -234,7 +231,18 @@ static int cfg80211_rfkill_set_block(voi ++ break; ++ } + } +++} +++EXPORT_SYMBOL_GPL(cfg80211_shutdown_all_interfaces); + -+ if (skb->protocol == sdata->control_port_protocol) { -+ skb->priority = 7; -+ return ieee80211_downgrade_queue(sdata, skb); -+ } --+ +++static int cfg80211_rfkill_set_block(void *data, bool blocked) +++{ +++ struct cfg80211_registered_device *rdev = data; + + - /* use the data classifier to determine what 802.1d tag the - * data frame has */ - rcu_read_lock(); @@ -5558,61 +8898,77 @@ index a1af6c2..892f51e 100644 -@@ -1444,14 +1444,16 @@ void ath_tx_aggr_sleep(struct ieee80211_ - for (tidno = 0, tid = &an->tid[tidno]; - tidno < IEEE80211_NUM_TIDS; tidno++, tid++) { -+ if (ath_tx_sched_aggr(sc, txq, tid, &stop)) -+ sent = true; -+ -+@@ -2698,7 +2687,6 @@ void ath_tx_node_init(struct ath_softc * -+ tid->baw_size = WME_MAX_BA; -+ tid->baw_head = tid->baw_tail = 0; -+ tid->sched = false; -+- tid->paused = false; -+ tid->active = false; -+ __skb_queue_head_init(&tid->buf_q); -+ __skb_queue_head_init(&tid->retry_q); -+--- a/drivers/net/wireless/ath/ath9k/recv.c -++++ b/drivers/net/wireless/ath/ath9k/recv.c -+@@ -975,6 +975,7 @@ int ath_rx_tasklet(struct ath_softc *sc, -+ u64 tsf = 0; -+ unsigned long flags; -+ dma_addr_t new_buf_addr; -++ unsigned int budget = 512; - +- -- if (!tid->sched) -+ if (edma) -+ dma_type = DMA_BIDIRECTIONAL; -+@@ -1113,15 +1114,17 @@ requeue_drop_frag: -+ } -+ requeue: -+ list_add_tail(&bf->list, &sc->rx.rxbuf); -+- if (flush) - - continue; +-- continue; -- - ac = tid->ac; - txq = ac->txq; -- +++ if (!blocked) +++ return 0; +++ +++ rtnl_lock(); +++ cfg80211_shutdown_all_interfaces(&rdev->wiphy); ++ rtnl_unlock(); + - ath_txq_lock(sc, txq); -- ++ return 0; ++@@ -401,6 +409,8 @@ struct wiphy *wiphy_new(const struct cfg ++ rdev->wiphy.rts_threshold = (u32) -1; ++ rdev->wiphy.coverage_class = 0; + -+ if (!tid->sched) { -+ ath_txq_unlock(sc, txq); -+ continue; -+ } --+ +++ rdev->wiphy.max_num_csa_counters = 1; + + - buffered = ath_tid_has_buffered(tid); ++ return &rdev->wiphy; ++ } ++ EXPORT_SYMBOL(wiphy_new); ++@@ -697,7 +707,7 @@ void wiphy_unregister(struct wiphy *wiph ++ rtnl_lock(); ++ rdev->wiphy.registered = false; - tid->sched = false; -@@ -1696,7 +1698,7 @@ int ath_cabq_update(struct ath_softc *sc -- ++- BUG_ON(!list_empty(&rdev->wdev_list)); +++ WARN_ON(!list_empty(&rdev->wdev_list)); + - ath9k_hw_get_txq_props(sc->sc_ah, qnum, &qi); -- ++ /* ++ * First remove the hardware from everywhere, this makes ++@@ -799,23 +809,23 @@ void cfg80211_update_iface_num(struct cf ++ rdev->num_running_monitor_ifaces += num; ++ } + -- qi.tqi_readyTime = (cur_conf->beacon_interval * -+ qi.tqi_readyTime = (TU_TO_USEC(cur_conf->beacon_interval) * - ATH_CABQ_READY_TIME) / 100; - ath_txq_update(sc, qnum, &qi); -- ++-void cfg80211_leave(struct cfg80211_registered_device *rdev, ++- struct wireless_dev *wdev) +++void __cfg80211_leave(struct cfg80211_registered_device *rdev, +++ struct wireless_dev *wdev) ++ { ++ struct net_device *dev = wdev->netdev; + -@@ -2061,7 +2063,7 @@ static struct ath_buf *ath_tx_setup_buff -- ++ ASSERT_RTNL(); +++ ASSERT_WDEV_LOCK(wdev); + - ATH_TXBUF_RESET(bf); -- ++ switch (wdev->iftype) { ++ case NL80211_IFTYPE_ADHOC: ++- cfg80211_leave_ibss(rdev, dev, true); +++ __cfg80211_leave_ibss(rdev, dev, true); ++ break; ++ case NL80211_IFTYPE_P2P_CLIENT: ++ case NL80211_IFTYPE_STATION: ++ if (rdev->sched_scan_req && dev == rdev->sched_scan_req->dev) ++ __cfg80211_stop_sched_scan(rdev, false); + -- if (tid) { -+ if (tid && ieee80211_is_data_present(hdr->frame_control)) { - fragno = le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_FRAG; @@ -5620,19 +8976,32 @@ index a1af6c2..892f51e 100644 - hdr->seq_ctrl = cpu_to_le16(tid->seq_next << IEEE80211_SEQ_SEQ_SHIFT); -@@ -2184,14 +2186,15 @@ int ath_tx_start(struct ieee80211_hw *hw - txq->stopped = true; -- } ++- wdev_lock(wdev); ++ #ifdef CPTCFG_CFG80211_WEXT ++ kfree(wdev->wext.ie); ++ wdev->wext.ie = NULL; ++@@ -824,20 +834,49 @@ void cfg80211_leave(struct cfg80211_regi ++ #endif ++ cfg80211_disconnect(rdev, dev, ++ WLAN_REASON_DEAUTH_LEAVING, true); ++- wdev_unlock(wdev); ++ break; ++ case NL80211_IFTYPE_MESH_POINT: ++- cfg80211_leave_mesh(rdev, dev); +++ __cfg80211_leave_mesh(rdev, dev); ++ break; ++ case NL80211_IFTYPE_AP: ++ case NL80211_IFTYPE_P2P_GO: ++- cfg80211_stop_ap(rdev, dev, true); +++ __cfg80211_stop_ap(rdev, dev, true); ++ break; ++ default: ++ break; + } - -+ if (txctl->an && ieee80211_is_data_present(hdr->frame_control)) -+ tid = ath_get_skb_tid(sc, txctl->an, skb); -+ if (edma) { -+ ath_rx_edma_buf_link(sc, qtype); -+ } else { -+ ath_rx_buf_relink(sc, bf); -+- ath9k_hw_rxena(ah); -++ if (!flush) -++ ath9k_hw_rxena(ah); -+ } - + +-+ - if (info->flags & IEEE80211_TX_CTL_PS_RESPONSE) { - ath_txq_unlock(sc, txq); - txq = sc->tx.uapsdq; @@ -5642,34 +9011,10 @@ index a1af6c2..892f51e 100644 -- tid = ath_get_skb_tid(sc, txctl->an, skb); -- - WARN_ON(tid->ac->txq != txctl->txq); -++ if (!budget--) -++ break; -+ } while (1); -+ -+ if (!(ah->imask & ATH9K_INT_RXEOL)) { -+--- a/drivers/net/wireless/ath/ath9k/ahb.c -++++ b/drivers/net/wireless/ath/ath9k/ahb.c -+@@ -86,7 +86,6 @@ static int ath_ahb_probe(struct platform -+ int irq; -+ int ret = 0; -+ struct ath_hw *ah; -+- struct ath_common *common; -+ char hw_name[64]; -+ -+ if (!dev_get_platdata(&pdev->dev)) { -+@@ -146,9 +145,6 @@ static int ath_ahb_probe(struct platform -+ wiphy_info(hw->wiphy, "%s mem=0x%lx, irq=%d\n", -+ hw_name, (unsigned long)mem, irq); -+ -+- common = ath9k_hw_common(sc->sc_ah); -+- /* Will be cleared in ath9k_start() */ -+- set_bit(ATH_OP_INVALID, &common->op_flags); -+ return 0; - +- - if (info->flags & IEEE80211_TX_CTL_CLEAR_PS_FILT) -+ err_irq: - --- a/drivers/net/wireless/ath/ath9k/init.c - +++ b/drivers/net/wireless/ath/ath9k/init.c +---- a/drivers/net/wireless/ath/ath9k/init.c +-+++ b/drivers/net/wireless/ath/ath9k/init.c -@@ -943,6 +943,7 @@ static void ath9k_set_hw_capab(struct at - hw->wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL; - hw->wiphy->flags |= WIPHY_FLAG_SUPPORTS_5_10_MHZ; @@ -5701,8 +9046,8 @@ index a1af6c2..892f51e 100644 -+++ b/net/mac80211/sta_info.c -@@ -91,7 +91,7 @@ static int sta_info_hash_del(struct ieee - return -ENOENT; -- } -- + } + --static void cleanup_single_sta(struct sta_info *sta) -+static void __cleanup_single_sta(struct sta_info *sta) - { @@ -5730,13 +9075,25 @@ index a1af6c2..892f51e 100644 - ieee80211_purge_tx_queue(&local->hw, &tid_tx->pending); - kfree(tid_tx); - } --+} +++void cfg80211_leave(struct cfg80211_registered_device *rdev, +++ struct wireless_dev *wdev) +++{ +++ wdev_lock(wdev); +++ __cfg80211_leave(rdev, wdev); +++ wdev_unlock(wdev); + +} - -+static void cleanup_single_sta(struct sta_info *sta) --+{ +++ +++void cfg80211_stop_iface(struct wiphy *wiphy, struct wireless_dev *wdev, +++ gfp_t gfp) + +{ -+ struct ieee80211_sub_if_data *sdata = sta->sdata; -+ struct ieee80211_local *local = sdata->local; --+ +++ struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy); +++ struct cfg80211_event *ev; +++ unsigned long flags; + + -+ __cleanup_single_sta(sta); - sta_info_free(local, sta); - } @@ -5764,12 +9121,64 @@ index a1af6c2..892f51e 100644 - -+ /* simplify things and don't accept BA sessions yet */ -+ set_sta_flag(sta, WLAN_STA_BLOCK_BA); --+ +++ trace_cfg80211_stop_iface(wiphy, wdev); +++ +++ ev = kzalloc(sizeof(*ev), gfp); +++ if (!ev) +++ return; + + - /* make the station visible */ - sta_info_hash_add(local, sta); -- +++ ev->type = EVENT_STOPPED; +++ +++ spin_lock_irqsave(&wdev->event_lock, flags); +++ list_add_tail(&ev->list, &wdev->event_list); +++ spin_unlock_irqrestore(&wdev->event_lock, flags); +++ queue_work(cfg80211_wq, &rdev->event_work); +++} +++EXPORT_SYMBOL(cfg80211_stop_iface); +++ ++ static int cfg80211_netdev_notifier_call(struct notifier_block *nb, ++ unsigned long state, void *ptr) ++ { ++--- a/net/wireless/core.h +++++ b/net/wireless/core.h ++@@ -185,6 +185,7 @@ enum cfg80211_event_type { ++ EVENT_ROAMED, ++ EVENT_DISCONNECTED, ++ EVENT_IBSS_JOINED, +++ EVENT_STOPPED, ++ }; + - list_add_rcu(&sta->list, &local->sta_list); -- ++ struct cfg80211_event { ++@@ -281,6 +282,8 @@ int cfg80211_join_mesh(struct cfg80211_r ++ struct net_device *dev, ++ struct mesh_setup *setup, ++ const struct mesh_config *conf); +++int __cfg80211_leave_mesh(struct cfg80211_registered_device *rdev, +++ struct net_device *dev); ++ int cfg80211_leave_mesh(struct cfg80211_registered_device *rdev, ++ struct net_device *dev); ++ int cfg80211_set_mesh_channel(struct cfg80211_registered_device *rdev, ++@@ -288,6 +291,8 @@ int cfg80211_set_mesh_channel(struct cfg ++ struct cfg80211_chan_def *chandef); ++ ++ /* AP */ +++int __cfg80211_stop_ap(struct cfg80211_registered_device *rdev, +++ struct net_device *dev, bool notify); ++ int cfg80211_stop_ap(struct cfg80211_registered_device *rdev, ++ struct net_device *dev, bool notify); ++ ++@@ -441,6 +446,8 @@ int cfg80211_validate_beacon_int(struct ++ void cfg80211_update_iface_num(struct cfg80211_registered_device *rdev, ++ enum nl80211_iftype iftype, int num); ++ +++void __cfg80211_leave(struct cfg80211_registered_device *rdev, +++ struct wireless_dev *wdev); ++ void cfg80211_leave(struct cfg80211_registered_device *rdev, ++ struct wireless_dev *wdev); + -+ /* notify driver */ -+ err = sta_info_insert_drv_state(local, sdata, sta); -+ if (err) @@ -5778,13 +9187,26 @@ index a1af6c2..892f51e 100644 - set_sta_flag(sta, WLAN_STA_INSERTED); -+ /* accept BA sessions now */ -+ clear_sta_flag(sta, WLAN_STA_BLOCK_BA); -- ++--- a/net/wireless/ibss.c +++++ b/net/wireless/ibss.c ++@@ -420,8 +420,8 @@ int cfg80211_ibss_wext_siwessid(struct n ++ if (len > 0 && ssid[len - 1] == '\0') ++ len--; + - ieee80211_recalc_min_chandef(sdata); - ieee80211_sta_debugfs_add(sta); -@@ -522,6 +537,12 @@ static int sta_info_insert_finish(struct - mesh_accept_plinks_update(sdata); -- -- return 0; +++ memcpy(wdev->ssid, ssid, len); ++ wdev->wext.ibss.ssid = wdev->ssid; ++- memcpy(wdev->wext.ibss.ssid, ssid, len); ++ wdev->wext.ibss.ssid_len = len; + ++ wdev_lock(wdev); ++--- a/net/wireless/mesh.c +++++ b/net/wireless/mesh.c ++@@ -238,8 +238,8 @@ int cfg80211_set_mesh_channel(struct cfg + return 0; -+ out_remove: -+ sta_info_hash_del(local, sta); -+ list_del_rcu(&sta->list); @@ -5795,13 +9217,17 @@ index a1af6c2..892f51e 100644 - mutex_unlock(&local->sta_mtx); - rcu_read_lock(); -@@ -1071,10 +1092,14 @@ struct ieee80211_sta *ieee80211_find_sta -- } + } - EXPORT_SYMBOL(ieee80211_find_sta); -- + --static void clear_sta_ps_flags(void *_sta) -+/* powersave support code */ -+void ieee80211_sta_ps_deliver_wakeup(struct sta_info *sta) -- { ++-static int __cfg80211_leave_mesh(struct cfg80211_registered_device *rdev, ++- struct net_device *dev) +++int __cfg80211_leave_mesh(struct cfg80211_registered_device *rdev, +++ struct net_device *dev) + { -- struct sta_info *sta = _sta; - struct ieee80211_sub_if_data *sdata = sta->sdata; -+ struct ieee80211_local *local = sdata->local; @@ -5809,12 +9235,63 @@ index a1af6c2..892f51e 100644 -+ int filtered = 0, buffered = 0, ac; -+ unsigned long flags; - struct ps_data *ps; -- ++ struct wireless_dev *wdev = dev->ieee80211_ptr; ++ int err; ++--- a/net/wireless/nl80211.c +++++ b/net/wireless/nl80211.c ++@@ -371,8 +371,8 @@ static const struct nla_policy nl80211_p ++ [NL80211_ATTR_CH_SWITCH_COUNT] = { .type = NLA_U32 }, ++ [NL80211_ATTR_CH_SWITCH_BLOCK_TX] = { .type = NLA_FLAG }, ++ [NL80211_ATTR_CSA_IES] = { .type = NLA_NESTED }, ++- [NL80211_ATTR_CSA_C_OFF_BEACON] = { .type = NLA_U16 }, ++- [NL80211_ATTR_CSA_C_OFF_PRESP] = { .type = NLA_U16 }, +++ [NL80211_ATTR_CSA_C_OFF_BEACON] = { .type = NLA_BINARY }, +++ [NL80211_ATTR_CSA_C_OFF_PRESP] = { .type = NLA_BINARY }, ++ [NL80211_ATTR_STA_SUPPORTED_CHANNELS] = { .type = NLA_BINARY }, ++ [NL80211_ATTR_STA_SUPPORTED_OPER_CLASSES] = { .type = NLA_BINARY }, ++ [NL80211_ATTR_HANDLE_DFS] = { .type = NLA_FLAG }, ++@@ -386,6 +386,7 @@ static const struct nla_policy nl80211_p ++ [NL80211_ATTR_WIPHY_FREQ_HINT] = { .type = NLA_U32 }, ++ [NL80211_ATTR_TDLS_PEER_CAPABILITY] = { .type = NLA_U32 }, ++ [NL80211_ATTR_IFACE_SOCKET_OWNER] = { .type = NLA_FLAG }, +++ [NL80211_ATTR_CSA_C_OFFSETS_TX] = { .type = NLA_BINARY }, ++ }; + - if (sdata->vif.type == NL80211_IFTYPE_AP || -@@ -1085,20 +1110,6 @@ static void clear_sta_ps_flags(void *_st - else - return; -- ++ /* policy for the key attributes */ ++@@ -970,8 +971,10 @@ static int nl80211_put_iface_combination ++ c->max_interfaces)) ++ goto nla_put_failure; ++ if (large && ++- nla_put_u32(msg, NL80211_IFACE_COMB_RADAR_DETECT_WIDTHS, ++- c->radar_detect_widths)) +++ (nla_put_u32(msg, NL80211_IFACE_COMB_RADAR_DETECT_WIDTHS, +++ c->radar_detect_widths) || +++ nla_put_u32(msg, NL80211_IFACE_COMB_RADAR_DETECT_REGIONS, +++ c->radar_detect_regions))) ++ goto nla_put_failure; ++ ++ nla_nest_end(msg, nl_combi); ++@@ -1667,6 +1670,13 @@ static int nl80211_send_wiphy(struct cfg ++ } ++ nla_nest_end(msg, nested); ++ } +++ state->split_start++; +++ break; +++ case 12: +++ if (rdev->wiphy.flags & WIPHY_FLAG_HAS_CHANNEL_SWITCH && +++ nla_put_u8(msg, NL80211_ATTR_MAX_CSA_COUNTERS, +++ rdev->wiphy.max_num_csa_counters)) +++ goto nla_put_failure; ++ ++ /* done */ ++ state->split_start = 0; ++@@ -5825,7 +5835,7 @@ static int nl80211_start_radar_detection ++ return -EBUSY; + -- clear_sta_flag(sta, WLAN_STA_PS_DRIVER); -- if (test_and_clear_sta_flag(sta, WLAN_STA_PS_STA)) -- atomic_dec(&ps->num_sta_ps); @@ -5830,25 +9307,26 @@ index a1af6c2..892f51e 100644 -- unsigned long flags; -- - clear_sta_flag(sta, WLAN_STA_SP); -- ++ err = cfg80211_chandef_dfs_required(wdev->wiphy, &chandef, ++- NL80211_IFTYPE_UNSPECIFIED); +++ wdev->iftype); ++ if (err < 0) ++ return err; + - BUILD_BUG_ON(BITS_TO_LONGS(IEEE80211_NUM_TIDS) > 1); -@@ -1109,6 +1120,8 @@ void ieee80211_sta_ps_deliver_wakeup(str -- ++@@ -5866,6 +5876,7 @@ static int nl80211_channel_switch(struct ++ u8 radar_detect_width = 0; ++ int err; ++ bool need_new_beacon = false; +++ int len, i; + - skb_queue_head_init(&pending); -+@@ -670,6 +670,7 @@ static const struct ieee80211_iface_comb -+ .num_different_channels = 1, -+ .beacon_int_infra_match = true, -+ }, -++#ifdef CONFIG_ATH9K_DFS_CERTIFIED -+ { -+ .limits = if_dfs_limits, -+ .n_limits = ARRAY_SIZE(if_dfs_limits), -+@@ -679,6 +680,7 @@ static const struct ieee80211_iface_comb -+ .radar_detect_widths = BIT(NL80211_CHAN_WIDTH_20_NOHT) | -+ BIT(NL80211_CHAN_WIDTH_20), -+ } -++#endif -+ }; ++ if (!rdev->ops->channel_switch || ++ !(rdev->wiphy.flags & WIPHY_FLAG_HAS_CHANNEL_SWITCH)) ++@@ -5924,26 +5935,55 @@ static int nl80211_channel_switch(struct ++ if (!csa_attrs[NL80211_ATTR_CSA_C_OFF_BEACON]) ++ return -EINVAL; -+ /* sync with ieee80211_tx_h_unicast_ps_buf */ -+ spin_lock(&sta->ps_lock); @@ -5858,19 +9336,19 @@ index a1af6c2..892f51e 100644 -@@ -1127,7 +1140,12 @@ void ieee80211_sta_ps_deliver_wakeup(str - buffered += tmp - count; - } -+ static void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw) -+@@ -781,6 +783,9 @@ int ath9k_init_device(u16 devid, struct -+ common = ath9k_hw_common(ah); -+ ath9k_set_hw_capab(sc, hw); ++- params.counter_offset_beacon = ++- nla_get_u16(csa_attrs[NL80211_ATTR_CSA_C_OFF_BEACON]); ++- if (params.counter_offset_beacon >= params.beacon_csa.tail_len) +++ len = nla_len(csa_attrs[NL80211_ATTR_CSA_C_OFF_BEACON]); +++ if (!len || (len % sizeof(u16))) ++ return -EINVAL; -- ieee80211_add_pending_skbs_fn(local, &pending, clear_sta_ps_flags, sta); -+ ieee80211_add_pending_skbs(local, &pending); -+ clear_sta_flag(sta, WLAN_STA_PS_DRIVER); -+ clear_sta_flag(sta, WLAN_STA_PS_STA); -+ spin_unlock(&sta->ps_lock); -++ /* Will be cleared in ath9k_start() */ -++ set_bit(ATH_OP_INVALID, &common->op_flags); - + +-+ -+ atomic_dec(&ps->num_sta_ps); - - /* This station just woke up and isn't aware of our SMPS state */ @@ -5888,7 +9366,15 @@ index a1af6c2..892f51e 100644 -@@ -356,10 +357,8 @@ struct sta_info { - /* use the accessors defined below */ - unsigned long _flags; -- ++- /* sanity check - counters should be the same */ ++- if (params.beacon_csa.tail[params.counter_offset_beacon] != ++- params.count) +++ params.n_counter_offsets_beacon = len / sizeof(u16); +++ if (rdev->wiphy.max_num_csa_counters && +++ (params.n_counter_offsets_beacon > +++ rdev->wiphy.max_num_csa_counters)) ++ return -EINVAL; + -- /* -- * STA powersave frame queues, no more than the internal -- * locking required. @@ -5903,41 +9389,66 @@ index a1af6c2..892f51e 100644 -@@ -435,9 +435,8 @@ void ieee80211_add_pending_skb(struct ie - spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); - } -- +++ params.counter_offsets_beacon = +++ nla_data(csa_attrs[NL80211_ATTR_CSA_C_OFF_BEACON]); +++ +++ /* sanity checks - counters should fit and be the same */ +++ for (i = 0; i < params.n_counter_offsets_beacon; i++) { +++ u16 offset = params.counter_offsets_beacon[i]; +++ +++ if (offset >= params.beacon_csa.tail_len) +++ return -EINVAL; +++ +++ if (params.beacon_csa.tail[offset] != params.count) +++ return -EINVAL; +++ } +++ ++ if (csa_attrs[NL80211_ATTR_CSA_C_OFF_PRESP]) { ++- params.counter_offset_presp = ++- nla_get_u16(csa_attrs[NL80211_ATTR_CSA_C_OFF_PRESP]); ++- if (params.counter_offset_presp >= ++- params.beacon_csa.probe_resp_len) +++ len = nla_len(csa_attrs[NL80211_ATTR_CSA_C_OFF_PRESP]); +++ if (!len || (len % sizeof(u16))) ++ return -EINVAL; + --void ieee80211_add_pending_skbs_fn(struct ieee80211_local *local, -- struct sk_buff_head *skbs, -- void (*fn)(void *data), void *data) -+void ieee80211_add_pending_skbs(struct ieee80211_local *local, -+ struct sk_buff_head *skbs) -+ /* Initialize regulatory */ -+ error = ath_regd_init(&common->regulatory, sc->hw->wiphy, -+ ath9k_reg_notifier); -+--- a/drivers/net/wireless/ath/ath9k/pci.c -++++ b/drivers/net/wireless/ath/ath9k/pci.c -+@@ -784,7 +784,6 @@ static int ath_pci_probe(struct pci_dev - { +- { - struct ieee80211_hw *hw = &local->hw; - struct sk_buff *skb; -@@ -461,9 +460,6 @@ void ieee80211_add_pending_skbs_fn(struc - __skb_queue_tail(&local->pending[queue], skb); -- } -- ++- if (params.beacon_csa.probe_resp[params.counter_offset_presp] != ++- params.count) +++ params.n_counter_offsets_presp = len / sizeof(u16); +++ if (rdev->wiphy.max_num_csa_counters && +++ (params.n_counter_offsets_beacon > +++ rdev->wiphy.max_num_csa_counters)) ++ return -EINVAL; +++ +++ params.counter_offsets_presp = +++ nla_data(csa_attrs[NL80211_ATTR_CSA_C_OFF_PRESP]); +++ +++ /* sanity checks - counters should fit and be the same */ +++ for (i = 0; i < params.n_counter_offsets_presp; i++) { +++ u16 offset = params.counter_offsets_presp[i]; +++ +++ if (offset >= params.beacon_csa.probe_resp_len) +++ return -EINVAL; +++ +++ if (params.beacon_csa.probe_resp[offset] != +++ params.count) +++ return -EINVAL; +++ } + } + -- if (fn) -- fn(data); -+ struct ath_softc *sc; -+ struct ieee80211_hw *hw; -+- struct ath_common *common; -+ u8 csz; -+ u32 val; -+ int ret = 0; -+@@ -877,10 +876,6 @@ static int ath_pci_probe(struct pci_dev -+ wiphy_info(hw->wiphy, "%s mem=0x%lx, irq=%d\n", -+ hw_name, (unsigned long)sc->mem, pdev->irq); -+ -+- /* Will be cleared in ath9k_start() */ -+- common = ath9k_hw_common(sc->sc_ah); -+- set_bit(ATH_OP_INVALID, &common->op_flags); - - +-- - for (i = 0; i < hw->queues; i++) - __ieee80211_wake_queue(hw, i, - IEEE80211_QUEUE_STOP_REASON_SKB_ADD); @@ -5992,7 +9503,11 @@ index a1af6c2..892f51e 100644 -+ if (common->disable_ani) - goto exit; -- } -- ++ skip_beacons: ++@@ -7793,6 +7833,27 @@ static int nl80211_tx_mgmt(struct sk_buf ++ if (!chandef.chan && params.offchan) ++ return -EINVAL; + -- len += scnprintf(buf + len, size - len, "%15s: %s\n", -- "ANI", "ENABLED"); -- len += scnprintf(buf + len, size - len, "%15s: %u\n", @@ -6083,16 +9598,47 @@ index a1af6c2..892f51e 100644 -+ */ -+ rs->rs_datalen = 0; -+ rs->rs_more = true; --+ } -- } -- +++ params.buf = nla_data(info->attrs[NL80211_ATTR_FRAME]); +++ params.len = nla_len(info->attrs[NL80211_ATTR_FRAME]); +++ +++ if (info->attrs[NL80211_ATTR_CSA_C_OFFSETS_TX]) { +++ int len = nla_len(info->attrs[NL80211_ATTR_CSA_C_OFFSETS_TX]); +++ int i; +++ +++ if (len % sizeof(u16)) +++ return -EINVAL; +++ +++ params.n_csa_offsets = len / sizeof(u16); +++ params.csa_offsets = +++ nla_data(info->attrs[NL80211_ATTR_CSA_C_OFFSETS_TX]); +++ +++ /* check that all the offsets fit the frame */ +++ for (i = 0; i < params.n_csa_offsets; i++) { +++ if (params.csa_offsets[i] >= params.len) +++ return -EINVAL; + + } +++ } +++ ++ if (!params.dont_wait_for_ack) { ++ msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); ++ if (!msg) ++@@ -7807,8 +7868,6 @@ static int nl80211_tx_mgmt(struct sk_buf ++ } + } + - list_del(&bf->list); -@@ -985,32 +992,32 @@ static int ath9k_rx_skb_preprocess(struc - struct ath_common *common = ath9k_hw_common(ah); - struct ieee80211_hdr *hdr; - bool discard_current = sc->rx.discard_next; -- int ret = 0; -- ++- params.buf = nla_data(info->attrs[NL80211_ATTR_FRAME]); ++- params.len = nla_len(info->attrs[NL80211_ATTR_FRAME]); ++ params.chan = chandef.chan; ++ err = cfg80211_mlme_mgmt_tx(rdev, wdev, ¶ms, &cookie); ++ if (err) ++@@ -8507,6 +8566,8 @@ static int nl80211_set_wowlan(struct sk_ + - /* - * Discard corrupt descriptors which are marked in - * ath_get_next_rx_buf(). @@ -6101,7 +9647,10 @@ index a1af6c2..892f51e 100644 - if (discard_current) -- return -EINVAL; -+ goto corrupt; --+ ++ nla_for_each_nested(pat, tb[NL80211_WOWLAN_TRIG_PKT_PATTERN], ++ rem) { +++ u8 *mask_pat; + + -+ sc->rx.discard_next = false; - - /* @@ -6112,7 +9661,38 @@ index a1af6c2..892f51e 100644 -- return -EINVAL; -+ goto corrupt; - } -- ++ nla_parse(pat_tb, MAX_NL80211_PKTPAT, nla_data(pat), ++ nla_len(pat), NULL); ++ err = -EINVAL; ++@@ -8530,19 +8591,18 @@ static int nl80211_set_wowlan(struct sk_ ++ goto error; ++ new_triggers.patterns[i].pkt_offset = pkt_offset; ++ ++- new_triggers.patterns[i].mask = ++- kmalloc(mask_len + pat_len, GFP_KERNEL); ++- if (!new_triggers.patterns[i].mask) { +++ mask_pat = kmalloc(mask_len + pat_len, GFP_KERNEL); +++ if (!mask_pat) { ++ err = -ENOMEM; ++ goto error; ++ } ++- new_triggers.patterns[i].pattern = ++- new_triggers.patterns[i].mask + mask_len; ++- memcpy(new_triggers.patterns[i].mask, ++- nla_data(pat_tb[NL80211_PKTPAT_MASK]), +++ new_triggers.patterns[i].mask = mask_pat; +++ memcpy(mask_pat, nla_data(pat_tb[NL80211_PKTPAT_MASK]), ++ mask_len); +++ mask_pat += mask_len; +++ new_triggers.patterns[i].pattern = mask_pat; ++ new_triggers.patterns[i].pattern_len = pat_len; ++- memcpy(new_triggers.patterns[i].pattern, +++ memcpy(mask_pat, ++ nla_data(pat_tb[NL80211_PKTPAT_PATTERN]), ++ pat_len); ++ i++; ++@@ -8735,6 +8795,8 @@ static int nl80211_parse_coalesce_rule(s + -- /* -- * rs_status follows rs_datalen so if rs_datalen is too large -- * we can take a hint that hardware corrupted it, so ignore @@ -6127,8 +9707,42 @@ index a1af6c2..892f51e 100644 - RX_STAT_INC(rx_len_err); -- return -EINVAL; -+ goto corrupt; -- } -- ++ nla_for_each_nested(pat, tb[NL80211_ATTR_COALESCE_RULE_PKT_PATTERN], ++ rem) { +++ u8 *mask_pat; +++ ++ nla_parse(pat_tb, MAX_NL80211_PKTPAT, nla_data(pat), ++ nla_len(pat), NULL); ++ if (!pat_tb[NL80211_PKTPAT_MASK] || ++@@ -8756,17 +8818,19 @@ static int nl80211_parse_coalesce_rule(s ++ return -EINVAL; ++ new_rule->patterns[i].pkt_offset = pkt_offset; ++ ++- new_rule->patterns[i].mask = ++- kmalloc(mask_len + pat_len, GFP_KERNEL); ++- if (!new_rule->patterns[i].mask) +++ mask_pat = kmalloc(mask_len + pat_len, GFP_KERNEL); +++ if (!mask_pat) ++ return -ENOMEM; ++- new_rule->patterns[i].pattern = ++- new_rule->patterns[i].mask + mask_len; ++- memcpy(new_rule->patterns[i].mask, ++- nla_data(pat_tb[NL80211_PKTPAT_MASK]), mask_len); +++ +++ new_rule->patterns[i].mask = mask_pat; +++ memcpy(mask_pat, nla_data(pat_tb[NL80211_PKTPAT_MASK]), +++ mask_len); +++ +++ mask_pat += mask_len; +++ new_rule->patterns[i].pattern = mask_pat; ++ new_rule->patterns[i].pattern_len = pat_len; ++- memcpy(new_rule->patterns[i].pattern, ++- nla_data(pat_tb[NL80211_PKTPAT_PATTERN]), pat_len); +++ memcpy(mask_pat, nla_data(pat_tb[NL80211_PKTPAT_PATTERN]), +++ pat_len); ++ i++; + } + - /* Only use status info from the last fragment */ -@@ -1024,10 +1031,8 @@ static int ath9k_rx_skb_preprocess(struc - * This is different from the other corrupt descriptor @@ -6146,106 +9760,35 @@ index a1af6c2..892f51e 100644 -@@ -1043,18 +1048,15 @@ static int ath9k_rx_skb_preprocess(struc - if (ath_process_fft(sc, hdr, rx_stats, rx_status->mactime)) - RX_STAT_INC(rx_spectral); -+ return 0; - +- -- ret = -EINVAL; -- goto exit; -+ return -EINVAL; -+ err_init: -+--- a/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h -++++ b/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h -+@@ -410,7 +410,7 @@ static const u32 ar9300_2p2_baseband_cor -+ {0x00009e30, 0x06336f77}, -+ {0x00009e34, 0x6af6532f}, -+ {0x00009e38, 0x0cc80c00}, -+- {0x00009e40, 0x0d261820}, -++ {0x00009e40, 0x0d261800}, -+ {0x00009e4c, 0x00001004}, -+ {0x00009e50, 0x00ff03f1}, -+ {0x00009e54, 0x00000000}, -+--- a/drivers/net/wireless/ath/ath9k/ar9330_1p1_initvals.h -++++ b/drivers/net/wireless/ath/ath9k/ar9330_1p1_initvals.h -+@@ -592,7 +592,7 @@ static const u32 ar9331_1p1_baseband_cor -+ {0x00009e30, 0x06336f77}, -+ {0x00009e34, 0x6af6532f}, -+ {0x00009e38, 0x0cc80c00}, -+- {0x00009e40, 0x0d261820}, -++ {0x00009e40, 0x0d261800}, -+ {0x00009e4c, 0x00001004}, -+ {0x00009e50, 0x00ff03f1}, -+ {0x00009fc0, 0x803e4788}, -+--- a/drivers/net/wireless/ath/ath9k/ar9330_1p2_initvals.h -++++ b/drivers/net/wireless/ath/ath9k/ar9330_1p2_initvals.h -+@@ -231,7 +231,7 @@ static const u32 ar9331_1p2_baseband_cor -+ {0x00009e30, 0x06336f77}, -+ {0x00009e34, 0x6af6532f}, -+ {0x00009e38, 0x0cc80c00}, -+- {0x00009e40, 0x0d261820}, -++ {0x00009e40, 0x0d261800}, -+ {0x00009e4c, 0x00001004}, -+ {0x00009e50, 0x00ff03f1}, -+ {0x00009fc0, 0x803e4788}, -+--- a/drivers/net/wireless/ath/ath9k/ar9340_initvals.h -++++ b/drivers/net/wireless/ath/ath9k/ar9340_initvals.h -+@@ -318,7 +318,7 @@ static const u32 ar9340_1p0_baseband_cor -+ {0x00009e30, 0x06336f77}, -+ {0x00009e34, 0x6af6532f}, -+ {0x00009e38, 0x0cc80c00}, -+- {0x00009e40, 0x0d261820}, -++ {0x00009e40, 0x0d261800}, -+ {0x00009e4c, 0x00001004}, -+ {0x00009e50, 0x00ff03f1}, -+ {0x00009e54, 0x00000000}, -+@@ -348,9 +348,9 @@ static const u32 ar9340_1p0_baseband_cor -+ {0x0000a370, 0x00000000}, -+ {0x0000a390, 0x00000001}, -+ {0x0000a394, 0x00000444}, -+- {0x0000a398, 0x00000000}, -+- {0x0000a39c, 0x210d0401}, -+- {0x0000a3a0, 0xab9a7144}, -++ {0x0000a398, 0x001f0e0f}, -++ {0x0000a39c, 0x0075393f}, -++ {0x0000a3a0, 0xb79f6427}, -+ {0x0000a3a4, 0x00000000}, -+ {0x0000a3a8, 0xaaaaaaaa}, -+ {0x0000a3ac, 0x3c466478}, -+--- a/drivers/net/wireless/ath/ath9k/ar9580_1p0_initvals.h -++++ b/drivers/net/wireless/ath/ath9k/ar9580_1p0_initvals.h -+@@ -90,7 +90,7 @@ static const u32 ar9580_1p0_baseband_cor -+ {0x00009e30, 0x06336f77}, -+ {0x00009e34, 0x6af6532f}, -+ {0x00009e38, 0x0cc80c00}, -+- {0x00009e40, 0x0d261820}, -++ {0x00009e40, 0x0d261800}, -+ {0x00009e4c, 0x00001004}, -+ {0x00009e50, 0x00ff03f1}, -+ {0x00009e54, 0x00000000}, -+--- a/drivers/net/wireless/ath/ath9k/ar953x_initvals.h -++++ b/drivers/net/wireless/ath/ath9k/ar953x_initvals.h -+@@ -257,9 +257,9 @@ static const u32 qca953x_1p0_baseband_co -+ {0x0000a370, 0x00000000}, -+ {0x0000a390, 0x00000001}, -+ {0x0000a394, 0x00000444}, -+- {0x0000a398, 0x1f020503}, -+- {0x0000a39c, 0x29180c03}, -+- {0x0000a3a0, 0x9a8b6844}, -++ {0x0000a398, 0x001f0e0f}, -++ {0x0000a39c, 0x0075393f}, -++ {0x0000a3a0, 0xb79f6427}, -+ {0x0000a3a4, 0x000000ff}, -+ {0x0000a3a8, 0x6a6a6a6a}, -+ {0x0000a3ac, 0x6a6a6a6a}, -+--- a/drivers/net/wireless/ath/ath5k/phy.c -++++ b/drivers/net/wireless/ath/ath5k/phy.c -+@@ -3709,8 +3709,8 @@ ath5k_hw_txpower(struct ath5k_hw *ah, st -+ AR5K_REG_MS(AR5K_TUNE_MAX_TXPOWER, AR5K_TPC_CHIRP), -+ AR5K_TPC); -+ } else { -+- ath5k_hw_reg_write(ah, AR5K_PHY_TXPOWER_RATE_MAX | -+- AR5K_TUNE_MAX_TXPOWER, AR5K_PHY_TXPOWER_RATE_MAX); -++ ath5k_hw_reg_write(ah, AR5K_TUNE_MAX_TXPOWER, -++ AR5K_PHY_TXPOWER_RATE_MAX); - } +- } ++--- a/net/wireless/sme.c +++++ b/net/wireless/sme.c ++@@ -149,7 +149,8 @@ static int cfg80211_conn_do_work(struct ++ case CFG80211_CONN_SCAN_AGAIN: ++ return cfg80211_conn_scan(wdev); ++ case CFG80211_CONN_AUTHENTICATE_NEXT: ++- BUG_ON(!rdev->ops->auth); +++ if (WARN_ON(!rdev->ops->auth)) +++ return -EOPNOTSUPP; ++ wdev->conn->state = CFG80211_CONN_AUTHENTICATING; ++ return cfg80211_mlme_auth(rdev, wdev->netdev, ++ params->channel, params->auth_type, ++@@ -161,7 +162,8 @@ static int cfg80211_conn_do_work(struct ++ case CFG80211_CONN_AUTH_FAILED: ++ return -ENOTCONN; ++ case CFG80211_CONN_ASSOCIATE_NEXT: ++- BUG_ON(!rdev->ops->assoc); +++ if (WARN_ON(!rdev->ops->assoc)) +++ return -EOPNOTSUPP; ++ wdev->conn->state = CFG80211_CONN_ASSOCIATING; ++ if (wdev->conn->prev_bssid_valid) ++ req.prev_bssid = wdev->conn->prev_bssid; ++@@ -877,7 +879,7 @@ void __cfg80211_disconnected(struct net_ ++ } - /* - * everything but the rate is checked here, the rate check is done @@ -6257,7 +9800,56 @@ index a1af6c2..892f51e 100644 -- } -+ if (!ath9k_rx_accept(common, hdr, rx_status, rx_stats, decrypt_error)) -+ return -EINVAL; -- ++ void cfg80211_disconnected(struct net_device *dev, u16 reason, ++- u8 *ie, size_t ie_len, gfp_t gfp) +++ const u8 *ie, size_t ie_len, gfp_t gfp) ++ { ++ struct wireless_dev *wdev = dev->ieee80211_ptr; ++ struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy); ++--- a/net/wireless/trace.h +++++ b/net/wireless/trace.h ++@@ -1876,29 +1876,33 @@ TRACE_EVENT(rdev_channel_switch, ++ WIPHY_ENTRY ++ NETDEV_ENTRY ++ CHAN_DEF_ENTRY ++- __field(u16, counter_offset_beacon) ++- __field(u16, counter_offset_presp) ++ __field(bool, radar_required) ++ __field(bool, block_tx) ++ __field(u8, count) +++ __dynamic_array(u16, bcn_ofs, params->n_counter_offsets_beacon) +++ __dynamic_array(u16, pres_ofs, params->n_counter_offsets_presp) ++ ), ++ TP_fast_assign( ++ WIPHY_ASSIGN; ++ NETDEV_ASSIGN; ++ CHAN_DEF_ASSIGN(¶ms->chandef); ++- __entry->counter_offset_beacon = params->counter_offset_beacon; ++- __entry->counter_offset_presp = params->counter_offset_presp; ++ __entry->radar_required = params->radar_required; ++ __entry->block_tx = params->block_tx; ++ __entry->count = params->count; +++ memcpy(__get_dynamic_array(bcn_ofs), +++ params->counter_offsets_beacon, +++ params->n_counter_offsets_beacon * sizeof(u16)); +++ +++ /* probe response offsets are optional */ +++ if (params->n_counter_offsets_presp) +++ memcpy(__get_dynamic_array(pres_ofs), +++ params->counter_offsets_presp, +++ params->n_counter_offsets_presp * sizeof(u16)); ++ ), ++ TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", " CHAN_DEF_PR_FMT ++- ", block_tx: %d, count: %u, radar_required: %d" ++- ", counter offsets (beacon/presp): %u/%u", +++ ", block_tx: %d, count: %u, radar_required: %d", ++ WIPHY_PR_ARG, NETDEV_PR_ARG, CHAN_DEF_PR_ARG, ++- __entry->block_tx, __entry->count, __entry->radar_required, ++- __entry->counter_offset_beacon, ++- __entry->counter_offset_presp) +++ __entry->block_tx, __entry->count, __entry->radar_required) ++ ); + - if (ath_is_mybeacon(common, hdr)) { - RX_STAT_INC(rx_beacons); -@@ -1064,15 +1066,11 @@ static int ath9k_rx_skb_preprocess(struc @@ -6270,30 +9862,127 @@ index a1af6c2..892f51e 100644 -- } -+ if (WARN_ON(!ah->curchan)) -+ return -EINVAL; -- ++ TRACE_EVENT(rdev_set_qos_map, ++@@ -2636,6 +2640,21 @@ TRACE_EVENT(cfg80211_ft_event, ++ WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(target_ap)) ++ ); + -- if (ath9k_process_rate(common, hw, rx_stats, rx_status)) { -- ret =-EINVAL; -- goto exit; -- } -+ if (ath9k_process_rate(common, hw, rx_stats, rx_status)) -+ return -EINVAL; -- +++TRACE_EVENT(cfg80211_stop_iface, +++ TP_PROTO(struct wiphy *wiphy, struct wireless_dev *wdev), +++ TP_ARGS(wiphy, wdev), +++ TP_STRUCT__entry( +++ WIPHY_ENTRY +++ WDEV_ENTRY +++ ), +++ TP_fast_assign( +++ WIPHY_ASSIGN; +++ WDEV_ASSIGN; +++ ), +++ TP_printk(WIPHY_PR_FMT ", " WDEV_PR_FMT, +++ WIPHY_PR_ARG, WDEV_PR_ARG) +++); +++ ++ #endif /* !__RDEV_OPS_TRACE || TRACE_HEADER_MULTI_READ */ + - ath9k_process_rssi(common, hw, rx_stats, rx_status); -- ++ #undef TRACE_INCLUDE_PATH ++--- a/net/wireless/util.c +++++ b/net/wireless/util.c ++@@ -476,7 +476,8 @@ int ieee80211_data_to_8023(struct sk_buf ++ EXPORT_SYMBOL(ieee80211_data_to_8023); + -@@ -1087,9 +1085,11 @@ static int ath9k_rx_skb_preprocess(struc - sc->rx.num_pkts++; - #endif -- ++ int ieee80211_data_from_8023(struct sk_buff *skb, const u8 *addr, ++- enum nl80211_iftype iftype, u8 *bssid, bool qos) +++ enum nl80211_iftype iftype, +++ const u8 *bssid, bool qos) ++ { ++ struct ieee80211_hdr hdr; ++ u16 hdrlen, ethertype; ++@@ -839,6 +840,9 @@ void cfg80211_process_wdev_events(struct ++ __cfg80211_ibss_joined(wdev->netdev, ev->ij.bssid, ++ ev->ij.channel); ++ break; +++ case EVENT_STOPPED: +++ __cfg80211_leave(wiphy_to_rdev(wdev->wiphy), wdev); +++ break; ++ } ++ wdev_unlock(wdev); + --exit: -- sc->rx.discard_next = false; -- return ret; -+ return 0; --+ ++@@ -1271,10 +1275,20 @@ int cfg80211_iter_combinations(struct wi ++ void *data), ++ void *data) ++ { +++ const struct ieee80211_regdomain *regdom; +++ enum nl80211_dfs_regions region = 0; ++ int i, j, iftype; ++ int num_interfaces = 0; ++ u32 used_iftypes = 0; ++ +++ if (radar_detect) { +++ rcu_read_lock(); +++ regdom = rcu_dereference(cfg80211_regdomain); +++ if (regdom) +++ region = regdom->dfs_region; +++ rcu_read_unlock(); +++ } + + -+corrupt: -+ sc->rx.discard_next = rx_stats->rs_more; -+ return -EINVAL; -- } -- ++ for (iftype = 0; iftype < NUM_NL80211_IFTYPES; iftype++) { ++ num_interfaces += iftype_num[iftype]; ++ if (iftype_num[iftype] > 0 && ++@@ -1315,6 +1329,10 @@ int cfg80211_iter_combinations(struct wi ++ if (radar_detect != (c->radar_detect_widths & radar_detect)) ++ goto cont; ++ +++ if (radar_detect && c->radar_detect_regions && +++ !(c->radar_detect_regions & BIT(region))) +++ goto cont; +++ ++ /* Finally check that all iftypes that we're currently ++ * using are actually part of this combination. If they ++ * aren't then we can't use this combination and have ++--- a/drivers/net/wireless/ath/ath9k/recv.c +++++ b/drivers/net/wireless/ath/ath9k/recv.c ++@@ -34,7 +34,8 @@ static inline bool ath9k_check_auto_slee ++ * buffer (or rx fifo). This can incorrectly acknowledge packets ++ * to a sender if last desc is self-linked. ++ */ ++-static void ath_rx_buf_link(struct ath_softc *sc, struct ath_rxbuf *bf) +++static void ath_rx_buf_link(struct ath_softc *sc, struct ath_rxbuf *bf, +++ bool flush) ++ { ++ struct ath_hw *ah = sc->sc_ah; ++ struct ath_common *common = ath9k_hw_common(ah); ++@@ -59,18 +60,19 @@ static void ath_rx_buf_link(struct ath_s ++ common->rx_bufsize, ++ 0); ++ ++- if (sc->rx.rxlink == NULL) ++- ath9k_hw_putrxbuf(ah, bf->bf_daddr); ++- else +++ if (sc->rx.rxlink) ++ *sc->rx.rxlink = bf->bf_daddr; +++ else if (!flush) +++ ath9k_hw_putrxbuf(ah, bf->bf_daddr); ++ ++ sc->rx.rxlink = &ds->ds_link; + } + - static void ath9k_rx_skb_postprocess(struct ath_common *common, ---- a/drivers/net/wireless/ath/ath9k/ani.c -+++ b/drivers/net/wireless/ath/ath9k/ani.c @@ -6329,7 +10018,14 @@ index a1af6c2..892f51e 100644 -+ -+ if (!AR_SREV_9300_20_OR_LATER(ah)) -+ return; -- ++-static void ath_rx_buf_relink(struct ath_softc *sc, struct ath_rxbuf *bf) +++static void ath_rx_buf_relink(struct ath_softc *sc, struct ath_rxbuf *bf, +++ bool flush) ++ { ++ if (sc->rx.buf_hold) ++- ath_rx_buf_link(sc, sc->rx.buf_hold); +++ ath_rx_buf_link(sc, sc->rx.buf_hold, flush); + - if (aniState->ofdmNoiseImmunityLevel >= ATH9K_ANI_OFDM_DEF_LEVEL) { - ah->config.ofdm_trig_high = ATH9K_ANI_OFDM_TRIG_HIGH; -@@ -308,17 +318,6 @@ void ath9k_ani_reset(struct ath_hw *ah, @@ -6369,7 +10065,16 @@ index a1af6c2..892f51e 100644 -+ ah->config.cck_trig_high = ATH9K_ANI_CCK_TRIG_HIGH_OLD; -+ ah->config.cck_trig_low = ATH9K_ANI_CCK_TRIG_LOW_OLD; -+ } -- ++ sc->rx.buf_hold = bf; ++ } ++@@ -442,7 +444,7 @@ int ath_startrecv(struct ath_softc *sc) ++ sc->rx.buf_hold = NULL; ++ sc->rx.rxlink = NULL; ++ list_for_each_entry_safe(bf, tbf, &sc->rx.rxbuf, list) { ++- ath_rx_buf_link(sc, bf); +++ ath_rx_buf_link(sc, bf, false); ++ } + - ani->spurImmunityLevel = ATH9K_ANI_SPUR_IMMUNE_LVL; - ani->firstepLevel = ATH9K_ANI_FIRSTEP_LVL; ---- a/drivers/net/wireless/ath/ath9k/ani.h @@ -6523,16 +10228,33 @@ index a1af6c2..892f51e 100644 - aniState->iniDef.cycpwrThr1Ext); - if (level > aniState->spurImmunityLevel) - ah->stats.ast_ani_spurup++; -+ return 0; ++ /* We could have deleted elements so the list may be empty now */ ++@@ -1118,12 +1120,12 @@ requeue_drop_frag: ++ requeue: ++ list_add_tail(&bf->list, &sc->rx.rxbuf); ++ ++- if (edma) { ++- ath_rx_edma_buf_link(sc, qtype); ++- } else { ++- ath_rx_buf_relink(sc, bf); +++ if (!edma) { +++ ath_rx_buf_relink(sc, bf, flush); ++ if (!flush) ++ ath9k_hw_rxena(ah); +++ } else if (!flush) { +++ ath_rx_edma_buf_link(sc, qtype); ++ } ++ ++ if (!budget--) diff --git a/package/mac80211/patches/310-ap_scan.patch b/package/mac80211/patches/310-ap_scan.patch -index 389a003..87f165a 100644 +index 389a003..a12e7e5 100644 --- a/package/mac80211/patches/310-ap_scan.patch +++ b/package/mac80211/patches/310-ap_scan.patch @@ -1,6 +1,6 @@ --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c -@@ -2148,7 +2148,7 @@ static int ieee80211_scan(struct wiphy * -+@@ -2154,7 +2154,7 @@ static int ieee80211_scan(struct wiphy * ++@@ -2197,7 +2197,7 @@ static int ieee80211_scan(struct wiphy * * the frames sent while scanning on other channel will be * lost) */ @@ -6549,21 +10271,8 @@ index 0dba7ac..4cc77af 100644 #endif /* CPTCFG_ATH_DEBUG */ /** Returns string describing opmode, or NULL if unknown mode. */ -diff --git a/package/mac80211/patches/402-ath9k-fix-invalid-mac-address-handling.patch b/package/mac80211/patches/402-ath9k-fix-invalid-mac-address-handling.patch -index 63ab0db..acaa317 100644 ---- a/package/mac80211/patches/402-ath9k-fix-invalid-mac-address-handling.patch -+++ b/package/mac80211/patches/402-ath9k-fix-invalid-mac-address-handling.patch -@@ -8,7 +8,7 @@ - #include - - #include "hw.h" --@@ -449,8 +450,16 @@ static int ath9k_hw_init_macaddr(struct -+@@ -448,8 +449,16 @@ static int ath9k_hw_init_macaddr(struct - common->macaddr[2 * i] = eeval >> 8; - common->macaddr[2 * i + 1] = eeval & 0xff; - } diff --git a/package/mac80211/patches/403-ath_regd_optional.patch b/package/mac80211/patches/403-ath_regd_optional.patch -index 07c54cc..4a9b7e4 100644 +index 07c54cc..808e729 100644 --- a/package/mac80211/patches/403-ath_regd_optional.patch +++ b/package/mac80211/patches/403-ath_regd_optional.patch @@ -58,7 +58,7 @@ @@ -6571,19 +10280,19 @@ index 07c54cc..4a9b7e4 100644 --- a/.local-symbols +++ b/.local-symbols -@@ -119,6 +119,7 @@ RTL8187_LEDS= -+@@ -120,6 +120,7 @@ RTL8187_LEDS= ++@@ -116,6 +116,7 @@ RTL8187_LEDS= ATH_COMMON= ATH_CARDS= ATH_DEBUG= diff --git a/package/mac80211/patches/405-regd_no_assoc_hints.patch b/package/mac80211/patches/405-regd_no_assoc_hints.patch -index 6ad4fda..4fa611f 100644 +index 6ad4fda..ef60f9e 100644 --- a/package/mac80211/patches/405-regd_no_assoc_hints.patch +++ b/package/mac80211/patches/405-regd_no_assoc_hints.patch @@ -1,6 +1,6 @@ --- a/net/wireless/reg.c +++ b/net/wireless/reg.c -@@ -1878,6 +1878,8 @@ void regulatory_hint_country_ie(struct w -+@@ -2000,6 +2000,8 @@ void regulatory_hint_country_ie(struct w ++@@ -2079,6 +2079,8 @@ void regulatory_hint_country_ie(struct w enum environment_cap env = ENVIRON_ANY; struct regulatory_request *request = NULL, *lr; @@ -6592,22 +10301,26 @@ index 6ad4fda..4fa611f 100644 if (country_ie_len & 0x01) return; -@@ -2072,6 +2074,7 @@ static void restore_regulatory_settings( -+@@ -2194,6 +2196,7 @@ static void restore_regulatory_settings( ++@@ -2275,6 +2277,7 @@ static void restore_regulatory_settings( void regulatory_hint_disconnect(void) { diff --git a/package/mac80211/patches/410-ath9k_allow_adhoc_and_ap.patch b/package/mac80211/patches/410-ath9k_allow_adhoc_and_ap.patch -index 1f71e0b..909a5f1 100644 +index 1f71e0b..ce752f1 100644 --- a/package/mac80211/patches/410-ath9k_allow_adhoc_and_ap.patch +++ b/package/mac80211/patches/410-ath9k_allow_adhoc_and_ap.patch -@@ -1,6 +1,6 @@ +@@ -1,8 +1,8 @@ --- a/drivers/net/wireless/ath/ath9k/init.c +++ b/drivers/net/wireless/ath/ath9k/init.c -@@ -866,6 +866,7 @@ static const struct ieee80211_iface_limi -+@@ -652,6 +652,7 @@ static const struct ieee80211_iface_limi - #endif - BIT(NL80211_IFTYPE_AP) | +- #endif +- BIT(NL80211_IFTYPE_AP) | ++@@ -655,6 +655,7 @@ static const struct ieee80211_iface_limi ++ BIT(NL80211_IFTYPE_AP) }, ++ { .max = 1, .types = BIT(NL80211_IFTYPE_P2P_CLIENT) | BIT(NL80211_IFTYPE_P2P_GO) }, + + { .max = 1, .types = BIT(NL80211_IFTYPE_ADHOC) }, + }; diff --git a/package/mac80211/patches/411-ath5k_allow_adhoc_and_ap.patch b/package/mac80211/patches/411-ath5k_allow_adhoc_and_ap.patch index 3487ab2..1f06994 100644 --- a/package/mac80211/patches/411-ath5k_allow_adhoc_and_ap.patch @@ -6640,14 +10353,14 @@ index 3487ab2..1f06994 100644 #endif BIT(NL80211_IFTYPE_AP) }, diff --git a/package/mac80211/patches/500-ath9k_eeprom_debugfs.patch b/package/mac80211/patches/500-ath9k_eeprom_debugfs.patch -index 664cf45..36e0151 100644 +index 664cf45..65821fe 100644 --- a/package/mac80211/patches/500-ath9k_eeprom_debugfs.patch +++ b/package/mac80211/patches/500-ath9k_eeprom_debugfs.patch @@ -1,6 +1,6 @@ --- a/drivers/net/wireless/ath/ath9k/debug.c +++ b/drivers/net/wireless/ath/ath9k/debug.c -@@ -1481,6 +1481,53 @@ void ath9k_deinit_debug(struct ath_softc -+@@ -1485,6 +1485,53 @@ void ath9k_deinit_debug(struct ath_softc ++@@ -1289,6 +1289,53 @@ void ath9k_deinit_debug(struct ath_softc ath9k_spectral_deinit_debug(sc); } @@ -6656,7 +10369,7 @@ index 664cf45..36e0151 100644 { struct ath_common *common = ath9k_hw_common(ah); -@@ -1500,6 +1547,8 @@ int ath9k_init_debug(struct ath_hw *ah) -+@@ -1504,6 +1551,8 @@ int ath9k_init_debug(struct ath_hw *ah) ++@@ -1308,6 +1355,8 @@ int ath9k_init_debug(struct ath_hw *ah) ath9k_tx99_init_debug(sc); ath9k_spectral_init_debug(sc); @@ -6674,7 +10387,7 @@ index 96e7c6d..169eb9a 100644 ah->get_mac_revision = pdata->get_mac_revision; ah->external_reset = pdata->external_reset; diff --git a/package/mac80211/patches/502-ath9k_ahb_init.patch b/package/mac80211/patches/502-ath9k_ahb_init.patch -index 4edc63b..de61a9e 100644 +index 4edc63b..0c8e813 100644 --- a/package/mac80211/patches/502-ath9k_ahb_init.patch +++ b/package/mac80211/patches/502-ath9k_ahb_init.patch @@ -1,15 +1,15 @@ @@ -6683,7 +10396,7 @@ index 4edc63b..de61a9e 100644 -@@ -1112,23 +1112,23 @@ static int __init ath9k_init(void) - goto err_out; - } -+@@ -897,23 +897,23 @@ static int __init ath9k_init(void) ++@@ -904,23 +904,23 @@ static int __init ath9k_init(void) + { + int error; @@ -6707,18 +10420,6 @@ index 4edc63b..de61a9e 100644 + err_out: + return error; + } -diff --git a/package/mac80211/patches/510-ath9k_intr_mitigation_tweak.patch b/package/mac80211/patches/510-ath9k_intr_mitigation_tweak.patch -index d7478ff..c818933 100644 ---- a/package/mac80211/patches/510-ath9k_intr_mitigation_tweak.patch -+++ b/package/mac80211/patches/510-ath9k_intr_mitigation_tweak.patch -@@ -1,6 +1,6 @@ - --- a/drivers/net/wireless/ath/ath9k/hw.c - +++ b/drivers/net/wireless/ath/ath9k/hw.c --@@ -359,13 +359,8 @@ static void ath9k_hw_init_config(struct -+@@ -358,13 +358,8 @@ static void ath9k_hw_init_config(struct - - ah->config.rx_intr_mitigation = true; - diff --git a/package/mac80211/patches/511-ath9k_reduce_rxbuf.patch b/package/mac80211/patches/511-ath9k_reduce_rxbuf.patch index ef0b9a1..e457267 100644 --- a/package/mac80211/patches/511-ath9k_reduce_rxbuf.patch @@ -6732,14 +10433,14 @@ index ef0b9a1..e457267 100644 } while (0) diff --git a/package/mac80211/patches/512-ath9k_channelbw_debugfs.patch b/package/mac80211/patches/512-ath9k_channelbw_debugfs.patch -index 8f3cc03..665d8aa 100644 +index 8f3cc03..c0e173f 100644 --- a/package/mac80211/patches/512-ath9k_channelbw_debugfs.patch +++ b/package/mac80211/patches/512-ath9k_channelbw_debugfs.patch @@ -1,6 +1,6 @@ --- a/drivers/net/wireless/ath/ath9k/debug.c +++ b/drivers/net/wireless/ath/ath9k/debug.c -@@ -1528,6 +1528,52 @@ static const struct file_operations fops -+@@ -1532,6 +1532,52 @@ static const struct file_operations fops ++@@ -1336,6 +1336,52 @@ static const struct file_operations fops .owner = THIS_MODULE }; @@ -6757,7 +10458,7 @@ index 8f3cc03..665d8aa 100644 { struct ath_common *common = ath9k_hw_common(ah); -@@ -1549,6 +1595,8 @@ int ath9k_init_debug(struct ath_hw *ah) -+@@ -1553,6 +1599,8 @@ int ath9k_init_debug(struct ath_hw *ah) ++@@ -1357,6 +1403,8 @@ int ath9k_init_debug(struct ath_hw *ah) debugfs_create_file("eeprom", S_IRUSR, sc->debug.debugfs_phy, sc, &fops_eeprom); @@ -6800,27 +10501,15 @@ index 8f3cc03..665d8aa 100644 struct cfg80211_chan_def *chandef) { struct ieee80211_channel *curchan = chandef->chan; -diff --git a/package/mac80211/patches/513-ath9k_add_pci_ids.patch b/package/mac80211/patches/513-ath9k_add_pci_ids.patch -index db4e6a1..540198f 100644 ---- a/package/mac80211/patches/513-ath9k_add_pci_ids.patch -+++ b/package/mac80211/patches/513-ath9k_add_pci_ids.patch -@@ -1,6 +1,6 @@ - --- a/drivers/net/wireless/ath/ath9k/hw.c - +++ b/drivers/net/wireless/ath/ath9k/hw.c --@@ -614,6 +614,7 @@ int ath9k_hw_init(struct ath_hw *ah) -+@@ -613,6 +613,7 @@ int ath9k_hw_init(struct ath_hw *ah) - - /* These are all the AR5008/AR9001/AR9002/AR9003 hardware family of chipsets */ - switch (ah->hw_version.devid) { diff --git a/package/mac80211/patches/520-mac80211_cur_txpower.patch b/package/mac80211/patches/520-mac80211_cur_txpower.patch -index 6df95bc..cb3f852 100644 +index 6df95bc..b79a3c4 100644 --- a/package/mac80211/patches/520-mac80211_cur_txpower.patch +++ b/package/mac80211/patches/520-mac80211_cur_txpower.patch @@ -1,6 +1,6 @@ --- a/include/net/mac80211.h +++ b/include/net/mac80211.h -@@ -1711,6 +1711,7 @@ struct ieee80211_hw { -+@@ -1703,6 +1703,7 @@ struct ieee80211_hw { ++@@ -1718,6 +1718,7 @@ struct ieee80211_hw { u8 max_tx_aggregation_subframes; u8 offchannel_tx_hw_queue; u8 radiotap_mcs_details; @@ -6829,7 +10518,7 @@ index 6df95bc..cb3f852 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c -@@ -2329,7 +2329,9 @@ static int ieee80211_get_tx_power(struct -+@@ -2335,7 +2335,9 @@ static int ieee80211_get_tx_power(struct ++@@ -2378,7 +2378,9 @@ static int ieee80211_get_tx_power(struct struct ieee80211_local *local = wiphy_priv(wiphy); struct ieee80211_sub_if_data *sdata = IEEE80211_WDEV_TO_SUB_IF(wdev); @@ -6838,32 +10527,40 @@ index 6df95bc..cb3f852 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c -@@ -158,6 +158,7 @@ static u32 ieee80211_hw_conf_chan(struct -+@@ -160,6 +160,7 @@ static u32 ieee80211_hw_conf_chan(struct ++@@ -156,6 +156,7 @@ static u32 ieee80211_hw_conf_chan(struct if (local->hw.conf.power_level != power) { changed |= IEEE80211_CONF_CHANGE_POWER; diff --git a/package/mac80211/patches/521-ath9k_cur_txpower.patch b/package/mac80211/patches/521-ath9k_cur_txpower.patch -index 0d6c360..24bc062 100644 +index 0d6c360..3564323 100644 --- a/package/mac80211/patches/521-ath9k_cur_txpower.patch +++ b/package/mac80211/patches/521-ath9k_cur_txpower.patch +@@ -1,6 +1,6 @@ + --- a/drivers/net/wireless/ath/ath9k/main.c + +++ b/drivers/net/wireless/ath/ath9k/main.c +-@@ -308,8 +308,12 @@ static int ath_reset_internal(struct ath ++@@ -310,8 +310,12 @@ static int ath_reset_internal(struct ath + (sc->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL)) + ath9k_mci_set_txpower(sc, true, false); + @@ -14,7 +14,7 @@ out: spin_unlock_bh(&sc->sc_pcu_lock); -@@ -1371,6 +1375,7 @@ static int ath9k_config(struct ieee80211 -+@@ -1370,6 +1374,7 @@ static int ath9k_config(struct ieee80211 ++@@ -1404,6 +1408,7 @@ static int ath9k_config(struct ieee80211 sc->config.txpowlimit = 2 * conf->power_level; ath9k_cmn_update_txpow(ah, sc->curtxpow, sc->config.txpowlimit, &sc->curtxpow); diff --git a/package/mac80211/patches/522-mac80211_configure_antenna_gain.patch b/package/mac80211/patches/522-mac80211_configure_antenna_gain.patch -index 308ee6e..611f763 100644 +index 308ee6e..6ad04ac 100644 --- a/package/mac80211/patches/522-mac80211_configure_antenna_gain.patch +++ b/package/mac80211/patches/522-mac80211_configure_antenna_gain.patch @@ -1,6 +1,6 @@ --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h -@@ -2156,6 +2156,7 @@ struct cfg80211_qos_map { -+@@ -2167,6 +2167,7 @@ struct cfg80211_qos_map { ++@@ -2188,6 +2188,7 @@ struct cfg80211_qos_map { * (as advertised by the nl80211 feature flag.) * @get_tx_power: store the current TX power into the dbm variable; * return 0 if successful @@ -6872,7 +10569,7 @@ index 308ee6e..611f763 100644 * @set_wds_peer: set the WDS peer for a WDS interface * -@@ -2380,6 +2381,7 @@ struct cfg80211_ops { -+@@ -2396,6 +2397,7 @@ struct cfg80211_ops { ++@@ -2422,6 +2423,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); @@ -6901,9 +10598,9 @@ index 308ee6e..611f763 100644 -@@ -1555,6 +1555,9 @@ enum nl80211_commands { - * data is in the format defined for the payload of the QoS Map Set element - * in IEEE Std 802.11-2012, 8.4.2.97. -+@@ -1579,6 +1579,9 @@ enum nl80211_commands { -+ * @NL80211_ATTR_TDLS_PEER_CAPABILITY: flags for TDLS peer capabilities, u32. -+ * As specified in the &enum nl80211_tdls_peer_capability. ++@@ -1591,6 +1591,9 @@ enum nl80211_commands { ++ * creation then the new interface will be owned by the netlink socket ++ * that created it and will be destroyed when the socket is closed * + * @NL80211_ATTR_WIPHY_ANTENNA_GAIN: Configured antenna gain. Used to reduce + * transmit power to stay within regulatory limits. u32, dBi. @@ -6912,10 +10609,11 @@ index 308ee6e..611f763 100644 * @__NL80211_ATTR_AFTER_LAST: internal use */ -@@ -1883,6 +1886,8 @@ enum nl80211_attrs { -+@@ -1914,6 +1917,8 @@ enum nl80211_attrs { - +- - NL80211_ATTR_QOS_MAP, -+ NL80211_ATTR_TDLS_PEER_CAPABILITY, ++@@ -1931,6 +1934,8 @@ enum nl80211_attrs { ++ NL80211_ATTR_CSA_C_OFFSETS_TX, ++ NL80211_ATTR_MAX_CSA_COUNTERS, + NL80211_ATTR_WIPHY_ANTENNA_GAIN, + @@ -6924,7 +10622,7 @@ index 308ee6e..611f763 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c -@@ -2339,6 +2339,19 @@ static int ieee80211_get_tx_power(struct -+@@ -2345,6 +2345,19 @@ static int ieee80211_get_tx_power(struct ++@@ -2388,6 +2388,19 @@ static int ieee80211_get_tx_power(struct return 0; } @@ -6933,7 +10631,7 @@ index 308ee6e..611f763 100644 const u8 *addr) { -@@ -3924,6 +3937,7 @@ struct cfg80211_ops mac80211_config_ops -+@@ -4000,6 +4013,7 @@ const struct cfg80211_ops mac80211_confi ++@@ -3820,6 +3833,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, @@ -6942,11 +10640,17 @@ index 308ee6e..611f763 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h -@@ -1221,6 +1221,7 @@ struct ieee80211_local { -+@@ -1225,6 +1225,7 @@ struct ieee80211_local { ++@@ -1233,6 +1233,7 @@ struct ieee80211_local { int dynamic_ps_forced_timeout; int user_power_level; /* in dBm, for all interfaces */ -@@ -102,34 +102,24 @@ +@@ -97,39 +97,29 @@ + + --- a/net/mac80211/main.c + +++ b/net/mac80211/main.c +-@@ -101,7 +101,7 @@ static u32 ieee80211_hw_conf_chan(struct ++@@ -97,7 +97,7 @@ static u32 ieee80211_hw_conf_chan(struct + struct ieee80211_sub_if_data *sdata; struct cfg80211_chan_def chandef = {}; u32 changed = 0; - int power; @@ -6956,7 +10660,7 @@ index 308ee6e..611f763 100644 offchannel_flag = local->hw.conf.flags & IEEE80211_CONF_OFFCHANNEL; -@@ -156,8 +156,21 @@ static u32 ieee80211_hw_conf_chan(struct -+@@ -158,6 +158,12 @@ static u32 ieee80211_hw_conf_chan(struct ++@@ -154,6 +154,12 @@ static u32 ieee80211_hw_conf_chan(struct } rcu_read_unlock(); @@ -6982,7 +10686,7 @@ index 308ee6e..611f763 100644 - local->hw.conf.power_level = power; - } -@@ -584,6 +597,7 @@ struct ieee80211_hw *ieee80211_alloc_hw( -+@@ -586,6 +592,7 @@ struct ieee80211_hw *ieee80211_alloc_hw( ++@@ -584,6 +590,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; @@ -6994,17 +10698,17 @@ index 308ee6e..611f763 100644 - [NL80211_ATTR_VENDOR_DATA] = { .type = NLA_BINARY }, - [NL80211_ATTR_QOS_MAP] = { .type = NLA_BINARY, - .len = IEEE80211_QOS_MAP_LEN_MAX }, -+@@ -385,6 +385,7 @@ static const struct nla_policy nl80211_p -+ [NL80211_ATTR_MAC_HINT] = { .len = ETH_ALEN }, -+ [NL80211_ATTR_WIPHY_FREQ_HINT] = { .type = NLA_U32 }, ++@@ -387,6 +387,7 @@ static const struct nla_policy nl80211_p + [NL80211_ATTR_TDLS_PEER_CAPABILITY] = { .type = NLA_U32 }, ++ [NL80211_ATTR_IFACE_SOCKET_OWNER] = { .type = NLA_FLAG }, ++ [NL80211_ATTR_CSA_C_OFFSETS_TX] = { .type = NLA_BINARY }, + [NL80211_ATTR_WIPHY_ANTENNA_GAIN] = { .type = NLA_U32 }, }; /* policy for the key attributes */ -@@ -2105,6 +2106,22 @@ static int nl80211_set_wiphy(struct sk_b - goto bad_res; -+@@ -2116,6 +2117,20 @@ static int nl80211_set_wiphy(struct sk_b ++@@ -2162,6 +2163,20 @@ static int nl80211_set_wiphy(struct sk_b + return result; } @@ -7029,7 +10733,7 @@ index 308ee6e..611f763 100644 + if (info->attrs[NL80211_ATTR_WIPHY_ANTENNA_TX] && diff --git a/package/mac80211/patches/523-ath9k_use_configured_antenna_gain.patch b/package/mac80211/patches/523-ath9k_use_configured_antenna_gain.patch -index 30aa9ee..b84a991 100644 +index 30aa9ee..aaefa2f 100644 --- a/package/mac80211/patches/523-ath9k_use_configured_antenna_gain.patch +++ b/package/mac80211/patches/523-ath9k_use_configured_antenna_gain.patch @@ -1,6 +1,6 @@ @@ -7040,42 +10744,25 @@ index 30aa9ee..b84a991 100644 u16 max_power_level; u16 current_rd; int16_t power_limit; -@@ -10,7 +10,7 @@ - - --- a/drivers/net/wireless/ath/ath9k/hw.c - +++ b/drivers/net/wireless/ath/ath9k/hw.c --@@ -2721,7 +2721,7 @@ void ath9k_hw_apply_txpower(struct ath_h -+@@ -2720,7 +2720,7 @@ 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); @@ -21,7 +21,7 @@ if (ant_gain > max_gain) --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c -@@ -1371,7 +1371,10 @@ static int ath9k_config(struct ieee80211 -+@@ -1370,7 +1370,10 @@ static int ath9k_config(struct ieee80211 ++@@ -1404,7 +1404,10 @@ static int ath9k_config(struct ieee80211 } if (changed & IEEE80211_CONF_CHANGE_POWER) { diff --git a/package/mac80211/patches/530-ath9k_extra_leds.patch b/package/mac80211/patches/530-ath9k_extra_leds.patch -index 59f78d9..c78a3e5 100644 +index 59f78d9..4cf0700 100644 --- a/package/mac80211/patches/530-ath9k_extra_leds.patch +++ b/package/mac80211/patches/530-ath9k_extra_leds.patch -@@ -1,6 +1,6 @@ - --- a/drivers/net/wireless/ath/ath9k/ath9k.h - +++ b/drivers/net/wireless/ath/ath9k/ath9k.h --@@ -563,6 +563,9 @@ static inline int ath9k_dump_btcoex(stru -+@@ -554,6 +554,9 @@ static inline int ath9k_dump_btcoex(stru - void ath_init_leds(struct ath_softc *sc); - void ath_deinit_leds(struct ath_softc *sc); - void ath_fill_led_pin(struct ath_softc *sc); @@ -10,7 +10,7 @@ #else static inline void ath_init_leds(struct ath_softc *sc) { -@@ -710,6 +713,13 @@ enum sc_op_flags { -+@@ -692,6 +695,13 @@ void ath_ant_comb_scan(struct ath_softc ++@@ -701,6 +704,13 @@ void ath_ant_comb_scan(struct ath_softc #define PS_BEACON_SYNC BIT(4) #define PS_WAIT_FOR_ANI BIT(5) @@ -7085,7 +10772,7 @@ index 59f78d9..c78a3e5 100644 struct device *dev; -@@ -751,9 +761,8 @@ struct ath_softc { - struct ieee80211_supported_band sbands[IEEE80211_NUM_BANDS]; -+@@ -731,9 +741,8 @@ struct ath_softc { ++@@ -743,9 +753,8 @@ struct ath_softc { + struct ath_beacon beacon; #ifdef CPTCFG_MAC80211_LEDS @@ -7095,7 +10782,7 @@ index 59f78d9..c78a3e5 100644 --- a/drivers/net/wireless/ath/ath9k/init.c +++ b/drivers/net/wireless/ath/ath9k/init.c -@@ -1018,7 +1018,7 @@ int ath9k_init_device(u16 devid, struct -+@@ -811,7 +811,7 @@ int ath9k_init_device(u16 devid, struct ++@@ -815,7 +815,7 @@ int ath9k_init_device(u16 devid, struct #ifdef CPTCFG_MAC80211_LEDS /* must be initialized before ieee80211_register_hw */ @@ -7104,7 +10791,7 @@ index 59f78d9..c78a3e5 100644 --- a/drivers/net/wireless/ath/ath9k/debug.c +++ b/drivers/net/wireless/ath/ath9k/debug.c -@@ -1573,6 +1573,61 @@ static const struct file_operations fops -+@@ -1577,6 +1577,61 @@ static const struct file_operations fops ++@@ -1381,6 +1381,61 @@ static const struct file_operations fops .llseek = default_llseek, }; @@ -7113,19 +10800,36 @@ index 59f78d9..c78a3e5 100644 int ath9k_init_debug(struct ath_hw *ah) { -@@ -1597,6 +1652,10 @@ int ath9k_init_debug(struct ath_hw *ah) -+@@ -1601,6 +1656,10 @@ int ath9k_init_debug(struct ath_hw *ah) ++@@ -1405,6 +1460,10 @@ int ath9k_init_debug(struct ath_hw *ah) &fops_eeprom); debugfs_create_file("chanbw", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy, sc, &fops_chanbw); +diff --git a/package/mac80211/patches/531-ath9k_extra_platform_leds.patch b/package/mac80211/patches/531-ath9k_extra_platform_leds.patch +index 6c9832c..718a3d0 100644 +--- a/package/mac80211/patches/531-ath9k_extra_platform_leds.patch ++++ b/package/mac80211/patches/531-ath9k_extra_platform_leds.patch +@@ -1,9 +1,9 @@ + --- a/include/linux/ath9k_platform.h + +++ b/include/linux/ath9k_platform.h +-@@ -37,6 +37,9 @@ struct ath9k_platform_data { +- +- int (*get_mac_revision)(void); ++@@ -39,6 +39,9 @@ struct ath9k_platform_data { + int (*external_reset)(void); ++ ++ bool use_eeprom; + + + + int num_leds; + + const struct gpio_led *leds; diff --git a/package/mac80211/patches/542-ath9k_debugfs_diag.patch b/package/mac80211/patches/542-ath9k_debugfs_diag.patch -index e1b6ff1..44aa905 100644 +index e1b6ff1..764e5e2 100644 --- a/package/mac80211/patches/542-ath9k_debugfs_diag.patch +++ b/package/mac80211/patches/542-ath9k_debugfs_diag.patch @@ -1,6 +1,6 @@ --- a/drivers/net/wireless/ath/ath9k/debug.c +++ b/drivers/net/wireless/ath/ath9k/debug.c -@@ -1629,6 +1629,50 @@ static const struct file_operations fops -+@@ -1633,6 +1633,50 @@ static const struct file_operations fops ++@@ -1437,6 +1437,50 @@ static const struct file_operations fops #endif @@ -7134,50 +10838,23 @@ index e1b6ff1..44aa905 100644 { struct ath_common *common = ath9k_hw_common(ah); -@@ -1656,6 +1700,8 @@ int ath9k_init_debug(struct ath_hw *ah) -+@@ -1660,6 +1704,8 @@ int ath9k_init_debug(struct ath_hw *ah) ++@@ -1464,6 +1508,8 @@ int ath9k_init_debug(struct ath_hw *ah) debugfs_create_file("gpio_led", S_IWUSR, sc->debug.debugfs_phy, sc, &fops_gpio_led); #endif -@@ -94,7 +94,7 @@ - struct ath_gen_timer *ath_gen_timer_alloc(struct ath_hw *ah, - --- a/drivers/net/wireless/ath/ath9k/hw.c - +++ b/drivers/net/wireless/ath/ath9k/hw.c --@@ -1735,6 +1735,20 @@ fail: -+@@ -1734,6 +1734,20 @@ fail: - return -EINVAL; - } - -@@ -115,7 +115,7 @@ - int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, - struct ath9k_hw_cal_data *caldata, bool fastcc) - { --@@ -1940,6 +1954,7 @@ int ath9k_hw_reset(struct ath_hw *ah, st -+@@ -1939,6 +1953,7 @@ int ath9k_hw_reset(struct ath_hw *ah, st - ar9003_hw_disable_phy_restart(ah); - - ath9k_hw_apply_gpio_override(ah); @@ -125,7 +125,7 @@ REG_SET_BIT(ah, AR_BTCOEX_WL_LNADIV, AR_BTCOEX_WL_LNADIV_FORCE_ON); --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c -@@ -602,6 +602,11 @@ irqreturn_t ath_isr(int irq, void *dev) -+@@ -603,6 +603,11 @@ irqreturn_t ath_isr(int irq, void *dev) ++@@ -605,6 +605,11 @@ irqreturn_t ath_isr(int irq, void *dev) ath9k_debug_sync_cause(sc, sync_cause); status &= ah->imask; /* discard unasked-for bits */ diff --git a/package/mac80211/patches/543-ath9k-allow-to-disable-bands-via-platform-data.patch b/package/mac80211/patches/543-ath9k-allow-to-disable-bands-via-platform-data.patch -index d26a5af..e2e18c9 100644 +index d26a5af..0501582 100644 --- a/package/mac80211/patches/543-ath9k-allow-to-disable-bands-via-platform-data.patch +++ b/package/mac80211/patches/543-ath9k-allow-to-disable-bands-via-platform-data.patch -@@ -11,7 +11,7 @@ - int (*external_reset)(void); - --- a/drivers/net/wireless/ath/ath9k/hw.c - +++ b/drivers/net/wireless/ath/ath9k/hw.c --@@ -2328,17 +2328,25 @@ int ath9k_hw_fill_cap_info(struct ath_hw -+@@ -2327,17 +2327,25 @@ int ath9k_hw_fill_cap_info(struct ath_hw - } - - eeval = ah->eep_ops->get_eeprom(ah, EEP_OP_MODE); @@ -58,7 +58,7 @@ }; --- a/drivers/net/wireless/ath/ath9k/init.c @@ -7188,7 +10865,7 @@ index d26a5af..e2e18c9 100644 ah->get_mac_revision = pdata->get_mac_revision; ah->external_reset = pdata->external_reset; diff --git a/package/mac80211/patches/550-ath9k_entropy_from_adc.patch b/package/mac80211/patches/550-ath9k_entropy_from_adc.patch -index b59c362..439a574 100644 +index b59c362..7210a02 100644 --- a/package/mac80211/patches/550-ath9k_entropy_from_adc.patch +++ b/package/mac80211/patches/550-ath9k_entropy_from_adc.patch @@ -55,7 +55,7 @@ @@ -7196,7 +10873,7 @@ index b59c362..439a574 100644 --- a/drivers/net/wireless/ath/ath9k/init.c +++ b/drivers/net/wireless/ath/ath9k/init.c -@@ -846,7 +846,8 @@ static void ath9k_init_txpower_limits(st -+@@ -643,7 +643,8 @@ static void ath9k_init_txpower_limits(st ++@@ -646,7 +646,8 @@ static void ath9k_init_txpower_limits(st if (ah->caps.hw_caps & ATH9K_HW_CAP_5GHZ) ath9k_init_band_txpower(sc, IEEE80211_BAND_5GHZ); @@ -7207,7 +10884,7 @@ index b59c362..439a574 100644 - void ath9k_reload_chainmask_settings(struct ath_softc *sc) -@@ -980,6 +981,18 @@ static void ath9k_set_hw_capab(struct at + static const struct ieee80211_iface_limit if_limits[] = { -+@@ -770,6 +771,18 @@ static void ath9k_set_hw_capab(struct at ++@@ -774,6 +775,18 @@ static void ath9k_set_hw_capab(struct at SET_IEEE80211_PERM_ADDR(hw, common->macaddr); } @@ -7216,7 +10893,7 @@ index b59c362..439a574 100644 const struct ath_bus_ops *bus_ops) { -@@ -1025,6 +1038,8 @@ int ath9k_init_device(u16 devid, struct -+@@ -818,6 +831,8 @@ int ath9k_init_device(u16 devid, struct ++@@ -822,6 +835,8 @@ int ath9k_init_device(u16 devid, struct ARRAY_SIZE(ath9k_tpt_blink)); #endif @@ -7229,306 +10906,468 @@ index b59c362..439a574 100644 unsigned int timestamp = jiffies_to_msecs(jiffies); u32 cal_interval, short_cal_interval, long_cal_interval; unsigned long flags; +diff --git a/package/mac80211/patches/551-ath9k-ar933x-usb-hang-workaround.patch b/package/mac80211/patches/551-ath9k-ar933x-usb-hang-workaround.patch +new file mode 100644 +index 0000000..10280d9 +--- /dev/null ++++ b/package/mac80211/patches/551-ath9k-ar933x-usb-hang-workaround.patch +@@ -0,0 +1,79 @@ ++--- a/drivers/net/wireless/ath/ath9k/hw.c +++++ b/drivers/net/wireless/ath/ath9k/hw.c ++@@ -215,6 +215,19 @@ void ath9k_hw_get_channel_centers(struct ++ centers->synth_center + (extoff * HT40_CHANNEL_CENTER_SHIFT); ++ } ++ +++static inline void ath9k_hw_disable_pll_lock_detect(struct ath_hw *ah) +++{ +++ /* On AR9330 and AR9340 devices, some PHY registers must be +++ * tuned to gain better stability/performance. These registers +++ * might be changed while doing wlan reset so the registers must +++ * be reprogrammed after each reset. +++ */ +++ REG_CLR_BIT(ah, AR_PHY_USB_CTRL1, BIT(20)); +++ REG_RMW(ah, AR_PHY_USB_CTRL2, +++ (1 << 21) | (0xf << 22), +++ (1 << 21) | (0x3 << 22)); +++} +++ ++ /******************/ ++ /* Chip Revisions */ ++ /******************/ ++@@ -1337,6 +1350,9 @@ static bool ath9k_hw_set_reset(struct at ++ if (AR_SREV_9100(ah)) ++ udelay(50); ++ +++ if (AR_SREV_9330(ah) || AR_SREV_9340(ah)) +++ ath9k_hw_disable_pll_lock_detect(ah); +++ ++ return true; ++ } ++ ++@@ -1436,6 +1452,9 @@ static bool ath9k_hw_chip_reset(struct a ++ ar9003_hw_internal_regulator_apply(ah); ++ ath9k_hw_init_pll(ah, chan); ++ +++ if (AR_SREV_9330(ah) || AR_SREV_9340(ah)) +++ ath9k_hw_disable_pll_lock_detect(ah); +++ ++ return true; ++ } ++ ++@@ -1730,8 +1749,14 @@ static int ath9k_hw_do_fastcc(struct ath ++ if (AR_SREV_9271(ah)) ++ ar9002_hw_load_ani_reg(ah, chan); ++ +++ if (AR_SREV_9330(ah) || AR_SREV_9340(ah)) +++ ath9k_hw_disable_pll_lock_detect(ah); +++ ++ return 0; ++ fail: +++ if (AR_SREV_9330(ah) || AR_SREV_9340(ah)) +++ ath9k_hw_disable_pll_lock_detect(ah); +++ ++ return -EINVAL; ++ } ++ ++@@ -1959,6 +1984,9 @@ int ath9k_hw_reset(struct ath_hw *ah, st ++ if (AR_SREV_9565(ah) && common->bt_ant_diversity) ++ REG_SET_BIT(ah, AR_BTCOEX_WL_LNADIV, AR_BTCOEX_WL_LNADIV_FORCE_ON); ++ +++ if (AR_SREV_9330(ah) || AR_SREV_9340(ah)) +++ ath9k_hw_disable_pll_lock_detect(ah); +++ ++ return 0; ++ } ++ EXPORT_SYMBOL(ath9k_hw_reset); ++--- a/drivers/net/wireless/ath/ath9k/phy.h +++++ b/drivers/net/wireless/ath/ath9k/phy.h ++@@ -48,6 +48,9 @@ ++ #define AR_PHY_PLL_CONTROL 0x16180 ++ #define AR_PHY_PLL_MODE 0x16184 ++ +++#define AR_PHY_USB_CTRL1 0x16c84 +++#define AR_PHY_USB_CTRL2 0x16c88 +++ ++ enum ath9k_ant_div_comb_lna_conf { ++ ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2, ++ ATH_ANT_DIV_COMB_LNA2, diff --git a/package/mac80211/patches/551-ath9k_p2p_ifcomb.patch b/package/mac80211/patches/551-ath9k_p2p_ifcomb.patch -index ffffe0c..579a633 100644 +deleted file mode 100644 +index ffffe0c..0000000 --- a/package/mac80211/patches/551-ath9k_p2p_ifcomb.patch -+++ b/package/mac80211/patches/551-ath9k_p2p_ifcomb.patch -@@ -12,7 +12,7 @@ Signed-off-by: Felix Fietkau - - --- a/drivers/net/wireless/ath/ath9k/init.c - +++ b/drivers/net/wireless/ath/ath9k/init.c ++++ /dev/null +@@ -1,33 +0,0 @@ +-From c997a1da25fe7c717ed099888b8eb35d4e139e70 Mon Sep 17 00:00:00 2001 +-From: Felix Fietkau +-Date: Sun, 8 Dec 2013 08:52:52 +0100 +-Subject: [PATCH] ath9k: support only one P2P interface +- +-Preparation for adding P2P powersave and multi-channel support. +- +-Signed-off-by: Felix Fietkau +---- +- drivers/net/wireless/ath/ath9k/init.c | 4 ++-- +- 1 file changed, 2 insertions(+), 2 deletions(-) +- +---- a/drivers/net/wireless/ath/ath9k/init.c +-+++ b/drivers/net/wireless/ath/ath9k/init.c -@@ -863,15 +863,15 @@ void ath9k_reload_chainmask_settings(str -+@@ -649,15 +649,15 @@ static void ath9k_init_txpower_limits(st - - static const struct ieee80211_iface_limit if_limits[] = { - { .max = 2048, .types = BIT(NL80211_IFTYPE_STATION) | +- +- static const struct ieee80211_iface_limit if_limits[] = { +- { .max = 2048, .types = BIT(NL80211_IFTYPE_STATION) | +-- BIT(NL80211_IFTYPE_P2P_CLIENT) | +- BIT(NL80211_IFTYPE_WDS) }, +- { .max = 8, .types = +- #ifdef CPTCFG_MAC80211_MESH +- BIT(NL80211_IFTYPE_MESH_POINT) | +- #endif +-- BIT(NL80211_IFTYPE_AP) | +-- BIT(NL80211_IFTYPE_P2P_GO) }, +-+ BIT(NL80211_IFTYPE_AP) }, +- { .max = 1, .types = BIT(NL80211_IFTYPE_ADHOC) }, +-+ { .max = 1, .types = BIT(NL80211_IFTYPE_P2P_CLIENT) | +-+ BIT(NL80211_IFTYPE_P2P_GO) }, +- }; +- +- static const struct ieee80211_iface_limit if_dfs_limits[] = { diff --git a/package/mac80211/patches/552-ath9k_p2p_ps_support.patch b/package/mac80211/patches/552-ath9k_p2p_ps_support.patch -index 4a61db3..8cf9e61 100644 +deleted file mode 100644 +index 4a61db3..0000000 --- a/package/mac80211/patches/552-ath9k_p2p_ps_support.patch -+++ b/package/mac80211/patches/552-ath9k_p2p_ps_support.patch -@@ -27,7 +27,7 @@ Signed-off-by: Felix Fietkau - return true; - } - ++++ /dev/null +@@ -1,247 +0,0 @@ +-From 6744d0a7ea037c7d65e13ca906da93009b241d00 Mon Sep 17 00:00:00 2001 +-From: Felix Fietkau +-Date: Tue, 11 Feb 2014 11:16:24 +0100 +-Subject: [PATCH] ath9k: implement p2p client powersave support +- +-Use generic TSF timers to trigger powersave state changes based +-information from the P2P NoA attribute. +-Opportunistic Powersave is not handled, because the driver does not +-support powersave at the moment. +- +-Signed-off-by: Felix Fietkau +---- +- drivers/net/wireless/ath/ath9k/ath9k.h | 12 ++++ +- drivers/net/wireless/ath/ath9k/init.c | 6 ++ +- drivers/net/wireless/ath/ath9k/main.c | 104 +++++++++++++++++++++++++++++++++ +- drivers/net/wireless/ath/ath9k/recv.c | 3 + +- 4 files changed, 125 insertions(+) +- +---- a/drivers/net/wireless/ath/ath9k/main.c +-+++ b/drivers/net/wireless/ath/ath9k/main.c +-@@ -261,6 +261,8 @@ static bool ath_complete_reset(struct at +- sc->gtt_cnt = 0; +- ieee80211_wake_queues(sc->hw); +- +-+ ath9k_p2p_ps_timer(sc); +-+ +- return true; +- } +- -@@ -1126,6 +1128,8 @@ static int ath9k_add_interface(struct ie -+@@ -1128,6 +1130,8 @@ static int ath9k_add_interface(struct ie - if (ath9k_uses_beacons(vif->type)) - ath9k_beacon_assign_slot(sc, vif); - -@@ -36,7 +36,7 @@ Signed-off-by: Felix Fietkau - an->sc = sc; - an->sta = NULL; - an->vif = vif; +- if (ath9k_uses_beacons(vif->type)) +- ath9k_beacon_assign_slot(sc, vif); +- +-+ avp->vif = vif; +-+ +- an->sc = sc; +- an->sta = NULL; +- an->vif = vif; -@@ -1170,6 +1174,29 @@ static int ath9k_change_interface(struct -+@@ -1172,6 +1176,29 @@ static int ath9k_change_interface(struct - return 0; - } - -@@ -66,7 +66,7 @@ Signed-off-by: Felix Fietkau - static void ath9k_remove_interface(struct ieee80211_hw *hw, - struct ieee80211_vif *vif) - { +- return 0; +- } +- +-+static void +-+ath9k_update_p2p_ps_timer(struct ath_softc *sc, struct ath_vif *avp) +-+{ +-+ struct ath_hw *ah = sc->sc_ah; +-+ s32 tsf, target_tsf; +-+ +-+ if (!avp || !avp->noa.has_next_tsf) +-+ return; +-+ +-+ ath9k_hw_gen_timer_stop(ah, sc->p2p_ps_timer); +-+ +-+ tsf = ath9k_hw_gettsf32(sc->sc_ah); +-+ +-+ target_tsf = avp->noa.next_tsf; +-+ if (!avp->noa.absent) +-+ target_tsf -= ATH_P2P_PS_STOP_TIME; +-+ +-+ if (target_tsf - tsf < ATH_P2P_PS_STOP_TIME) +-+ target_tsf = tsf + ATH_P2P_PS_STOP_TIME; +-+ +-+ ath9k_hw_gen_timer_start(ah, sc->p2p_ps_timer, (u32) target_tsf, 1000000); +-+} +-+ +- static void ath9k_remove_interface(struct ieee80211_hw *hw, +- struct ieee80211_vif *vif) +- { -@@ -1181,6 +1208,13 @@ static void ath9k_remove_interface(struc -+@@ -1183,6 +1210,13 @@ static void ath9k_remove_interface(struc - - mutex_lock(&sc->mutex); - -@@ -80,7 +80,7 @@ Signed-off-by: Felix Fietkau - sc->nvifs--; - sc->tx99_vif = NULL; - +- +- mutex_lock(&sc->mutex); +- +-+ spin_lock_bh(&sc->sc_pcu_lock); +-+ if (avp == sc->p2p_ps_vif) { +-+ sc->p2p_ps_vif = NULL; +-+ ath9k_update_p2p_ps_timer(sc, NULL); +-+ } +-+ spin_unlock_bh(&sc->sc_pcu_lock); +-+ +- sc->nvifs--; +- sc->tx99_vif = NULL; +- -@@ -1649,6 +1683,70 @@ static void ath9k_bss_assoc_iter(void *d -+@@ -1649,6 +1683,72 @@ static void ath9k_bss_assoc_iter(void *d - ath9k_set_assoc_state(sc, vif); - } - -@@ -130,6 +130,7 @@ Signed-off-by: Felix Fietkau - +void ath9k_update_p2p_ps(struct ath_softc *sc, struct ieee80211_vif *vif) - +{ - + struct ath_vif *avp = (void *)vif->drv_priv; -++ unsigned long flags; - + u32 tsf; - + - + if (!sc->p2p_ps_timer) -@@ -140,18 +141,19 @@ Signed-off-by: Felix Fietkau - + - + sc->p2p_ps_vif = avp; - + +- ath9k_set_assoc_state(sc, vif); +- } +- +-+void ath9k_p2p_ps_timer(void *priv) +-+{ +-+ struct ath_softc *sc = priv; +-+ struct ath_vif *avp = sc->p2p_ps_vif; +-+ struct ieee80211_vif *vif; +-+ struct ieee80211_sta *sta; +-+ struct ath_node *an; +-+ u32 tsf; +-+ +-+ if (!avp) +-+ return; +-+ +-+ tsf = ath9k_hw_gettsf32(sc->sc_ah); +-+ if (!avp->noa.absent) +-+ tsf += ATH_P2P_PS_STOP_TIME; +-+ +-+ if (!avp->noa.has_next_tsf || +-+ avp->noa.next_tsf - tsf > BIT(31)) +-+ ieee80211_update_p2p_noa(&avp->noa, tsf); +-+ +-+ ath9k_update_p2p_ps_timer(sc, avp); +-+ +-+ rcu_read_lock(); +-+ +-+ vif = avp->vif; +-+ sta = ieee80211_find_sta(vif, vif->bss_conf.bssid); +-+ if (!sta) +-+ goto out; +-+ +-+ an = (void *) sta->drv_priv; +-+ if (an->sleeping == !!avp->noa.absent) +-+ goto out; +-+ +-+ an->sleeping = avp->noa.absent; +-+ if (an->sleeping) +-+ ath_tx_aggr_sleep(sta, sc, an); +-+ else +-+ ath_tx_aggr_wakeup(sc, an); +-+ +-+out: +-+ rcu_read_unlock(); +-+} +-+ +-+void ath9k_update_p2p_ps(struct ath_softc *sc, struct ieee80211_vif *vif) +-+{ +-+ struct ath_vif *avp = (void *)vif->drv_priv; +-+ u32 tsf; +-+ +-+ if (!sc->p2p_ps_timer) +-+ return; +-+ +-+ if (vif->type != NL80211_IFTYPE_STATION || !vif->p2p) +-+ return; +-+ +-+ sc->p2p_ps_vif = avp; +-+ -+ if (sc->ps_flags & PS_BEACON_SYNC) -+ return; -+ -+ tsf = ath9k_hw_gettsf32(sc->sc_ah); -+ ieee80211_parse_p2p_noa(&vif->bss_conf.p2p_noa_attr, &avp->noa, tsf); -+ ath9k_update_p2p_ps_timer(sc, avp); -++ spin_lock_irqsave(&sc->sc_pm_lock, flags); -++ if (!(sc->ps_flags & PS_BEACON_SYNC)) { -++ tsf = ath9k_hw_gettsf32(sc->sc_ah); -++ ieee80211_parse_p2p_noa(&vif->bss_conf.p2p_noa_attr, &avp->noa, tsf); -++ ath9k_update_p2p_ps_timer(sc, avp); -++ } -++ spin_unlock_irqrestore(&sc->sc_pm_lock, flags); - +} - + - static void ath9k_bss_info_changed(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, - struct ieee80211_bss_conf *bss_conf, +-+} +-+ +- static void ath9k_bss_info_changed(struct ieee80211_hw *hw, +- struct ieee80211_vif *vif, +- struct ieee80211_bss_conf *bss_conf, -@@ -1723,6 +1821,12 @@ static void ath9k_bss_info_changed(struc -+@@ -1723,6 +1823,12 @@ static void ath9k_bss_info_changed(struc - } - } - -@@ -166,7 +168,7 @@ Signed-off-by: Felix Fietkau - - --- a/drivers/net/wireless/ath/ath9k/ath9k.h - +++ b/drivers/net/wireless/ath/ath9k/ath9k.h +- } +- } +- +-+ if (changed & BSS_CHANGED_P2P_PS) { +-+ spin_lock_bh(&sc->sc_pcu_lock); +-+ ath9k_update_p2p_ps(sc, vif); +-+ spin_unlock_bh(&sc->sc_pcu_lock); +-+ } +-+ +- if (changed & CHECK_ANI) +- ath_check_ani(sc); +- +---- a/drivers/net/wireless/ath/ath9k/ath9k.h +-+++ b/drivers/net/wireless/ath/ath9k/ath9k.h -@@ -115,6 +115,9 @@ int ath_descdma_setup(struct ath_softc * -+@@ -114,6 +114,9 @@ int ath_descdma_setup(struct ath_softc * - #define ATH_TXFIFO_DEPTH 8 - #define ATH_TX_ERROR 0x01 - -@@ -176,7 +178,7 @@ Signed-off-by: Felix Fietkau - #define IEEE80211_SEQ_SEQ_SHIFT 4 - #define IEEE80211_SEQ_MAX 4096 - #define IEEE80211_WEP_IVLEN 3 +- #define ATH_TXFIFO_DEPTH 8 +- #define ATH_TX_ERROR 0x01 +- +-+/* Stop tx traffic 1ms before the GO goes away */ +-+#define ATH_P2P_PS_STOP_TIME 1000 +-+ +- #define IEEE80211_SEQ_SEQ_SHIFT 4 +- #define IEEE80211_SEQ_MAX 4096 +- #define IEEE80211_WEP_IVLEN 3 -@@ -363,11 +366,15 @@ void ath9k_release_buffered_frames(struc -+@@ -366,11 +369,15 @@ void ath9k_release_buffered_frames(struc - /********/ - - struct ath_vif { -@@ -192,7 +194,7 @@ Signed-off-by: Felix Fietkau - }; - - struct ath9k_vif_iter_data { +- /********/ +- +- struct ath_vif { +-+ struct ieee80211_vif *vif; +- struct ath_node mcast_node; +- int av_bslot; +- bool primary_sta_vif; +- __le64 tsf_adjust; /* TSF adjustment for staggered beacons */ +- struct ath_buf *av_bcbuf; +-+ +-+ /* P2P Client */ +-+ struct ieee80211_noa_data noa; +- }; +- +- struct ath9k_vif_iter_data { -@@ -472,6 +479,8 @@ int ath_update_survey_stats(struct ath_s -+@@ -463,6 +470,8 @@ int ath_update_survey_stats(struct ath_s - void ath_update_survey_nf(struct ath_softc *sc, int channel); - void ath9k_queue_reset(struct ath_softc *sc, enum ath_reset_type type); - void ath_ps_full_sleep(unsigned long data); -@@ -201,19 +203,19 @@ Signed-off-by: Felix Fietkau - - /**********/ - /* BTCOEX */ +- void ath_update_survey_nf(struct ath_softc *sc, int channel); +- void ath9k_queue_reset(struct ath_softc *sc, enum ath_reset_type type); +- void ath_ps_full_sleep(unsigned long data); +-+void ath9k_p2p_ps_timer(void *priv); +-+void ath9k_update_p2p_ps(struct ath_softc *sc, struct ieee80211_vif *vif); +- +- /**********/ +- /* BTCOEX */ -@@ -741,6 +750,9 @@ struct ath_softc { -+@@ -723,6 +732,9 @@ struct ath_softc { - struct completion paprd_complete; - wait_queue_head_t tx_wait; - - + struct ath_gen_timer *p2p_ps_timer; - + struct ath_vif *p2p_ps_vif; - + +- struct completion paprd_complete; +- wait_queue_head_t tx_wait; +- +-+ struct ath_gen_timer *p2p_ps_timer; +-+ struct ath_vif *p2p_ps_vif; +-+ - unsigned long sc_flags; - unsigned long driver_data; - -+ u8 gtt_cnt; - --- a/drivers/net/wireless/ath/ath9k/init.c - +++ b/drivers/net/wireless/ath/ath9k/init.c +- unsigned long driver_data; +- +---- a/drivers/net/wireless/ath/ath9k/init.c +-+++ b/drivers/net/wireless/ath/ath9k/init.c -@@ -797,6 +797,9 @@ static int ath9k_init_softc(u16 devid, s -+@@ -593,6 +593,9 @@ static int ath9k_init_softc(u16 devid, s - if (ret) - goto err_btcoex; - -@@ -223,7 +225,7 @@ Signed-off-by: Felix Fietkau - ath9k_cmn_init_crypto(sc->sc_ah); - ath9k_init_misc(sc); - ath_fill_led_pin(sc); +- if (ret) +- goto err_btcoex; +- +-+ sc->p2p_ps_timer = ath_gen_timer_alloc(sc->sc_ah, ath9k_p2p_ps_timer, +-+ NULL, sc, AR_FIRST_NDP_TIMER); +-+ +- ath9k_cmn_init_crypto(sc->sc_ah); +- ath9k_init_misc(sc); +- ath_fill_led_pin(sc); -@@ -1082,6 +1085,9 @@ static void ath9k_deinit_softc(struct at -+@@ -875,6 +878,9 @@ static void ath9k_deinit_softc(struct at - { - int i = 0; - +- { +- int i = 0; +- +-+ if (sc->p2p_ps_timer) +-+ ath_gen_timer_free(sc->sc_ah, sc->p2p_ps_timer); +-+ +- ath9k_deinit_btcoex(sc); +- +- for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) +---- a/drivers/net/wireless/ath/ath9k/recv.c +-+++ b/drivers/net/wireless/ath/ath9k/recv.c +-@@ -539,6 +539,9 @@ static void ath_rx_ps_beacon(struct ath_ +- ath_dbg(common, PS, +- "Reconfigure beacon timers based on synchronized timestamp\n"); +- ath9k_set_beacon(sc); +-+ +-+ if (sc->p2p_ps_vif) +-+ ath9k_update_p2p_ps(sc, sc->p2p_ps_vif->vif); +- } +- +- if (ath_beacon_dtim_pending_cab(skb)) { diff --git a/package/mac80211/patches/566-ath9k-ar933x-usb-hang-workaround.patch b/package/mac80211/patches/566-ath9k-ar933x-usb-hang-workaround.patch -index af94c9e..eddbc6c 100644 +deleted file mode 100644 +index af94c9e..0000000 --- a/package/mac80211/patches/566-ath9k-ar933x-usb-hang-workaround.patch -+++ b/package/mac80211/patches/566-ath9k-ar933x-usb-hang-workaround.patch -@@ -1,6 +1,6 @@ - --- a/drivers/net/wireless/ath/ath9k/hw.c - +++ b/drivers/net/wireless/ath/ath9k/hw.c ++++ /dev/null +@@ -1,79 +0,0 @@ +---- a/drivers/net/wireless/ath/ath9k/hw.c +-+++ b/drivers/net/wireless/ath/ath9k/hw.c -@@ -217,6 +217,19 @@ void ath9k_hw_get_channel_centers(struct -+@@ -216,6 +216,19 @@ void ath9k_hw_get_channel_centers(struct - centers->synth_center + (extoff * HT40_CHANNEL_CENTER_SHIFT); - } - -@@ -20,7 +20,7 @@ - /******************/ - /* Chip Revisions */ - /******************/ +- centers->synth_center + (extoff * HT40_CHANNEL_CENTER_SHIFT); +- } +- +-+static inline void ath9k_hw_disable_pll_lock_detect(struct ath_hw *ah) +-+{ +-+ /* On AR9330 and AR9340 devices, some PHY registers must be +-+ * tuned to gain better stability/performance. These registers +-+ * might be changed while doing wlan reset so the registers must +-+ * be reprogrammed after each reset. +-+ */ +-+ REG_CLR_BIT(ah, AR_PHY_USB_CTRL1, BIT(20)); +-+ REG_RMW(ah, AR_PHY_USB_CTRL2, +-+ (1 << 21) | (0xf << 22), +-+ (1 << 21) | (0x3 << 22)); +-+} +-+ +- /******************/ +- /* Chip Revisions */ +- /******************/ -@@ -1337,6 +1350,9 @@ static bool ath9k_hw_set_reset(struct at -+@@ -1336,6 +1349,9 @@ static bool ath9k_hw_set_reset(struct at - if (AR_SREV_9100(ah)) - udelay(50); - -@@ -30,7 +30,7 @@ - return true; - } - +- if (AR_SREV_9100(ah)) +- udelay(50); +- +-+ if (AR_SREV_9330(ah) || AR_SREV_9340(ah)) +-+ ath9k_hw_disable_pll_lock_detect(ah); +-+ +- return true; +- } +- -@@ -1436,6 +1452,9 @@ static bool ath9k_hw_chip_reset(struct a -+@@ -1435,6 +1451,9 @@ static bool ath9k_hw_chip_reset(struct a - ar9003_hw_internal_regulator_apply(ah); - ath9k_hw_init_pll(ah, chan); - -@@ -40,7 +40,7 @@ - return true; - } - +- ar9003_hw_internal_regulator_apply(ah); +- ath9k_hw_init_pll(ah, chan); +- +-+ if (AR_SREV_9330(ah) || AR_SREV_9340(ah)) +-+ ath9k_hw_disable_pll_lock_detect(ah); +-+ +- return true; +- } +- -@@ -1730,8 +1749,14 @@ static int ath9k_hw_do_fastcc(struct ath -+@@ -1729,8 +1748,14 @@ static int ath9k_hw_do_fastcc(struct ath - if (AR_SREV_9271(ah)) - ar9002_hw_load_ani_reg(ah, chan); - -@@ -55,7 +55,7 @@ - return -EINVAL; - } - +- if (AR_SREV_9271(ah)) +- ar9002_hw_load_ani_reg(ah, chan); +- +-+ if (AR_SREV_9330(ah) || AR_SREV_9340(ah)) +-+ ath9k_hw_disable_pll_lock_detect(ah); +-+ +- return 0; +- fail: +-+ if (AR_SREV_9330(ah) || AR_SREV_9340(ah)) +-+ ath9k_hw_disable_pll_lock_detect(ah); +-+ +- return -EINVAL; +- } +- -@@ -1959,6 +1984,9 @@ int ath9k_hw_reset(struct ath_hw *ah, st -+@@ -1958,6 +1983,9 @@ int ath9k_hw_reset(struct ath_hw *ah, st - if (AR_SREV_9565(ah) && common->bt_ant_diversity) - REG_SET_BIT(ah, AR_BTCOEX_WL_LNADIV, AR_BTCOEX_WL_LNADIV_FORCE_ON); - -diff --git a/package/mac80211/patches/567-ath9k_ar953x_read_mac_rev.patch b/package/mac80211/patches/567-ath9k_ar953x_read_mac_rev.patch -new file mode 100644 -index 0000000..31778a4 ---- /dev/null -+++ b/package/mac80211/patches/567-ath9k_ar953x_read_mac_rev.patch -@@ -0,0 +1,11 @@ -+--- a/drivers/net/wireless/ath/ath9k/hw.c -++++ b/drivers/net/wireless/ath/ath9k/hw.c -+@@ -260,6 +260,8 @@ static void ath9k_hw_read_revisions(stru -+ return; -+ case AR9300_DEVID_AR953X: -+ ah->hw_version.macVersion = AR_SREV_VERSION_9531; -++ if (ah->get_mac_revision) -++ ah->hw_version.macRev = ah->get_mac_revision(); -+ return; -+ } -+ -diff --git a/package/mac80211/patches/570-restrict_dfs_regions.patch b/package/mac80211/patches/570-restrict_dfs_regions.patch -new file mode 100644 -index 0000000..10157dc ---- /dev/null -+++ b/package/mac80211/patches/570-restrict_dfs_regions.patch -@@ -0,0 +1,82 @@ -+--- a/drivers/net/wireless/ath/ath10k/mac.c -++++ b/drivers/net/wireless/ath/ath10k/mac.c -+@@ -4321,6 +4321,7 @@ static const struct ieee80211_iface_comb -+ BIT(NL80211_CHAN_WIDTH_20) | -+ BIT(NL80211_CHAN_WIDTH_40) | -+ BIT(NL80211_CHAN_WIDTH_80), -++ .radar_detect_regions = BIT(NL80211_DFS_ETSI), -+ #endif -+ }, -+ }; -+--- a/drivers/net/wireless/ath/ath9k/init.c -++++ b/drivers/net/wireless/ath/ath9k/init.c -+@@ -688,6 +688,7 @@ static const struct ieee80211_iface_comb -+ .beacon_int_infra_match = true, -+ .radar_detect_widths = BIT(NL80211_CHAN_WIDTH_20_NOHT) | -+ BIT(NL80211_CHAN_WIDTH_20), -++ .radar_detect_regions = BIT(NL80211_DFS_ETSI), -+ } -+ #endif -+ }; -+--- a/include/net/cfg80211.h -++++ b/include/net/cfg80211.h -+@@ -2620,6 +2620,7 @@ struct ieee80211_iface_limit { -+ * between infrastructure and AP types must match. This is required -+ * only in special cases. -+ * @radar_detect_widths: bitmap of channel widths supported for radar detection -++ * @radar_detect_regions: bitmap of regions supported for radar detection -+ * -+ * With this structure the driver can describe which interface -+ * combinations it supports concurrently. -+@@ -2677,6 +2678,7 @@ struct ieee80211_iface_combination { -+ u8 n_limits; -+ bool beacon_int_infra_match; -+ u8 radar_detect_widths; -++ u8 radar_detect_regions; -+ }; -+ -+ struct ieee80211_txrx_stypes { -+--- a/net/wireless/util.c -++++ b/net/wireless/util.c -+@@ -1259,6 +1259,7 @@ int cfg80211_can_use_iftype_chan(struct -+ enum cfg80211_chan_mode chanmode, -+ u8 radar_detect) -+ { -++ const struct ieee80211_regdomain *regdom; -+ struct wireless_dev *wdev_iter; -+ u32 used_iftypes = BIT(iftype); -+ int num[NUM_NL80211_IFTYPES]; -+@@ -1267,6 +1268,7 @@ int cfg80211_can_use_iftype_chan(struct -+ struct ieee80211_channel *ch; -+ enum cfg80211_chan_mode chmode; -+ int num_different_channels = 0; -++ enum nl80211_dfs_regions region = 0; -+ int total = 1; -+ int i, j; -+ -+@@ -1285,6 +1287,14 @@ int cfg80211_can_use_iftype_chan(struct -+ return 0; -+ } -+ -++ if (radar_detect) { -++ rcu_read_lock(); -++ regdom = rcu_dereference(cfg80211_regdomain); -++ if (regdom) -++ region = regdom->dfs_region; -++ rcu_read_unlock(); -++ } -++ -+ memset(num, 0, sizeof(num)); -+ memset(used_channels, 0, sizeof(used_channels)); -+ -+@@ -1392,6 +1402,10 @@ int cfg80211_can_use_iftype_chan(struct -+ if (radar_detect && !(c->radar_detect_widths & radar_detect)) -+ goto cont; -+ -++ if (radar_detect && c->radar_detect_regions && -++ !(c->radar_detect_regions & BIT(region))) -++ goto cont; -++ -+ /* -+ * Finally check that all iftypes that we're currently -+ * using are actually part of this combination. If they +- if (AR_SREV_9565(ah) && common->bt_ant_diversity) +- REG_SET_BIT(ah, AR_BTCOEX_WL_LNADIV, AR_BTCOEX_WL_LNADIV_FORCE_ON); +- +-+ if (AR_SREV_9330(ah) || AR_SREV_9340(ah)) +-+ ath9k_hw_disable_pll_lock_detect(ah); +-+ +- return 0; +- } +- EXPORT_SYMBOL(ath9k_hw_reset); +---- a/drivers/net/wireless/ath/ath9k/phy.h +-+++ b/drivers/net/wireless/ath/ath9k/phy.h +-@@ -48,6 +48,9 @@ +- #define AR_PHY_PLL_CONTROL 0x16180 +- #define AR_PHY_PLL_MODE 0x16184 +- +-+#define AR_PHY_USB_CTRL1 0x16c84 +-+#define AR_PHY_USB_CTRL2 0x16c88 +-+ +- enum ath9k_ant_div_comb_lna_conf { +- ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2, +- ATH_ANT_DIV_COMB_LNA2, diff --git a/package/mac80211/patches/600-0001-rt2x00-rt2800lib-move-rt2800_drv_data-declaration-in.patch b/package/mac80211/patches/600-0001-rt2x00-rt2800lib-move-rt2800_drv_data-declaration-in.patch new file mode 100644 index 0000000..d344957 @@ -7599,7 +11438,7 @@ index 0000000..d344957 + const unsigned int offset, u32 *value); diff --git a/package/mac80211/patches/600-0002-rt2x00-rt2800lib-introduce-RT2800_HAS_HIGH_SHARED_ME.patch b/package/mac80211/patches/600-0002-rt2x00-rt2800lib-introduce-RT2800_HAS_HIGH_SHARED_ME.patch new file mode 100644 -index 0000000..3b11b15 +index 0000000..98c9203 --- /dev/null +++ b/package/mac80211/patches/600-0002-rt2x00-rt2800lib-introduce-RT2800_HAS_HIGH_SHARED_ME.patch @@ -0,0 +1,80 @@ @@ -7629,7 +11468,7 @@ index 0000000..3b11b15 + +--- a/drivers/net/wireless/rt2x00/rt2800lib.c ++++ b/drivers/net/wireless/rt2x00/rt2800lib.c -+@@ -7712,6 +7712,7 @@ static int rt2800_probe_rt(struct rt2x00 ++@@ -7711,6 +7711,7 @@ static int rt2800_probe_rt(struct rt2x00 + + int rt2800_probe_hw(struct rt2x00_dev *rt2x00dev) + { @@ -7637,7 +11476,7 @@ index 0000000..3b11b15 + int retval; + u32 reg; + -+@@ -7719,6 +7720,9 @@ int rt2800_probe_hw(struct rt2x00_dev *r ++@@ -7718,6 +7719,9 @@ int rt2800_probe_hw(struct rt2x00_dev *r + if (retval) + return retval; + @@ -7685,7 +11524,7 @@ index 0000000..3b11b15 + u32 *value) diff --git a/package/mac80211/patches/600-0003-rt2x00-rt2800-serialize-shared-memory-access.patch b/package/mac80211/patches/600-0003-rt2x00-rt2800-serialize-shared-memory-access.patch new file mode 100644 -index 0000000..879b4cc +index 0000000..97e213f --- /dev/null +++ b/package/mac80211/patches/600-0003-rt2x00-rt2800-serialize-shared-memory-access.patch @@ -0,0 +1,531 @@ @@ -7770,8 +11609,8 @@ index 0000000..879b4cc ++ rt2800_shared_mem_unlock(rt2x00dev); + + /* -+ * Enable beaconing again. -+@@ -1027,6 +1039,8 @@ static inline void rt2800_clear_beacon_r ++ * Restore beaconing state. ++@@ -1026,6 +1038,8 @@ static inline void rt2800_clear_beacon_r + + beacon_base = rt2800_hw_beacon_base(rt2x00dev, index); + @@ -7780,7 +11619,7 @@ index 0000000..879b4cc + /* + * For the Beacon base registers we only need to clear + * the whole TXWI which (when set to 0) will invalidate -+@@ -1034,6 +1048,8 @@ static inline void rt2800_clear_beacon_r ++@@ -1033,6 +1047,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); @@ -7789,7 +11628,7 @@ index 0000000..879b4cc + } + + void rt2800_clear_beacon(struct queue_entry *entry) -+@@ -1217,7 +1233,9 @@ static void rt2800_delete_wcid_attr(stru ++@@ -1216,7 +1232,9 @@ static void rt2800_delete_wcid_attr(stru + { + u32 offset; + offset = MAC_WCID_ATTR_ENTRY(wcid); @@ -7799,7 +11638,7 @@ index 0000000..879b4cc + } + + static void rt2800_config_wcid_attr_bssidx(struct rt2x00_dev *rt2x00dev, -+@@ -1230,11 +1248,13 @@ static void rt2800_config_wcid_attr_bssi ++@@ -1229,11 +1247,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. + */ @@ -7813,7 +11652,7 @@ index 0000000..879b4cc + } + + static void rt2800_config_wcid_attr_cipher(struct rt2x00_dev *rt2x00dev, -+@@ -1247,6 +1267,7 @@ static void rt2800_config_wcid_attr_ciph ++@@ -1246,6 +1266,7 @@ static void rt2800_config_wcid_attr_ciph + + offset = MAC_WCID_ATTR_ENTRY(key->hw_key_idx); + @@ -7821,7 +11660,7 @@ index 0000000..879b4cc + if (crypto->cmd == SET_KEY) { + rt2800_register_read(rt2x00dev, offset, ®); + rt2x00_set_field32(®, MAC_WCID_ATTRIBUTE_KEYTAB, -+@@ -1271,6 +1292,7 @@ static void rt2800_config_wcid_attr_ciph ++@@ -1270,6 +1291,7 @@ static void rt2800_config_wcid_attr_ciph + rt2x00_set_field32(®, MAC_WCID_ATTRIBUTE_RX_WIUDF, 0); + rt2800_register_write(rt2x00dev, offset, reg); + } @@ -7829,7 +11668,7 @@ index 0000000..879b4cc + + offset = MAC_IVEIV_ENTRY(key->hw_key_idx); + -+@@ -1280,8 +1302,11 @@ static void rt2800_config_wcid_attr_ciph ++@@ -1279,8 +1301,11 @@ static void rt2800_config_wcid_attr_ciph + (crypto->cipher == CIPHER_AES)) + iveiv_entry.iv[3] |= 0x20; + iveiv_entry.iv[3] |= key->keyidx << 6; @@ -7841,7 +11680,7 @@ index 0000000..879b4cc + } + + int rt2800_config_shared_key(struct rt2x00_dev *rt2x00dev, -+@@ -1304,8 +1329,11 @@ int rt2800_config_shared_key(struct rt2x ++@@ -1303,8 +1328,11 @@ int rt2800_config_shared_key(struct rt2x + sizeof(key_entry.rx_mic)); + + offset = SHARED_KEY_ENTRY(key->hw_key_idx); @@ -7853,7 +11692,7 @@ index 0000000..879b4cc + } + + /* -+@@ -1320,10 +1348,12 @@ int rt2800_config_shared_key(struct rt2x ++@@ -1319,10 +1347,12 @@ int rt2800_config_shared_key(struct rt2x + + offset = SHARED_KEY_MODE_ENTRY(key->hw_key_idx / 8); + @@ -7866,7 +11705,7 @@ index 0000000..879b4cc + + /* + * Update WCID information -+@@ -1393,8 +1423,11 @@ int rt2800_config_pairwise_key(struct rt ++@@ -1392,8 +1422,11 @@ int rt2800_config_pairwise_key(struct rt + sizeof(key_entry.rx_mic)); + + offset = PAIRWISE_KEY_ENTRY(key->hw_key_idx); @@ -7878,7 +11717,7 @@ index 0000000..879b4cc + } + + /* -+@@ -4876,14 +4909,19 @@ static int rt2800_init_registers(struct ++@@ -4875,14 +4908,19 @@ static int rt2800_init_registers(struct + /* + * ASIC will keep garbage value after boot, clear encryption keys. + */ @@ -7898,7 +11737,7 @@ index 0000000..879b4cc + } + + /* -+@@ -5009,8 +5047,10 @@ static int rt2800_wait_bbp_ready(struct ++@@ -5008,8 +5046,10 @@ static int rt2800_wait_bbp_ready(struct + * BBP was enabled after firmware was loaded, + * but we need to reactivate it now. + */ @@ -7909,7 +11748,7 @@ index 0000000..879b4cc + msleep(1); + + for (i = 0; i < REGISTER_BUSY_COUNT; i++) { -+@@ -6706,11 +6746,19 @@ int rt2800_enable_radio(struct rt2x00_de ++@@ -6705,11 +6745,19 @@ int rt2800_enable_radio(struct rt2x00_de + /* + * Send signal during boot time to initialize firmware. + */ @@ -7930,7 +11769,7 @@ index 0000000..879b4cc + msleep(1); + + /* -+@@ -7716,6 +7764,8 @@ int rt2800_probe_hw(struct rt2x00_dev *r ++@@ -7715,6 +7763,8 @@ int rt2800_probe_hw(struct rt2x00_dev *r + int retval; + u32 reg; + @@ -7939,7 +11778,7 @@ index 0000000..879b4cc + retval = rt2800_probe_rt(rt2x00dev); + if (retval) + return retval; -+@@ -7795,8 +7845,11 @@ void rt2800_get_tkip_seq(struct ieee8021 ++@@ -7794,8 +7844,11 @@ void rt2800_get_tkip_seq(struct ieee8021 + u32 offset; + + offset = MAC_IVEIV_ENTRY(hw_key_idx); @@ -8063,7 +11902,7 @@ index 0000000..879b4cc + #endif /* RT2800MMIO_H */ +--- a/drivers/net/wireless/rt2x00/rt2800pci.c ++++ b/drivers/net/wireless/rt2x00/rt2800pci.c -+@@ -69,7 +69,9 @@ static void rt2800pci_mcu_status(struct ++@@ -69,7 +69,9 @@ static void rt2800pci_mcu_status(struct + return; + + for (i = 0; i < 200; i++) { @@ -8073,7 +11912,7 @@ index 0000000..879b4cc + + 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 ++@@ -83,8 +85,10 @@ static void rt2800pci_mcu_status(struct + if (i == 200) + rt2x00_err(rt2x00dev, "MCU request failed, no response from hardware\n"); + @@ -8222,7 +12061,7 @@ index 0000000..879b4cc + static const struct rt2x00lib_ops rt2800usb_rt2x00_ops = { diff --git a/package/mac80211/patches/600-0004-rt2x00-rt2800lib-fix-beacon-generation-on-RT3593.patch b/package/mac80211/patches/600-0004-rt2x00-rt2800lib-fix-beacon-generation-on-RT3593.patch new file mode 100644 -index 0000000..38dbb43 +index 0000000..5cb6eae --- /dev/null +++ b/package/mac80211/patches/600-0004-rt2x00-rt2800lib-fix-beacon-generation-on-RT3593.patch @@ -0,0 +1,131 @@ @@ -8339,7 +12178,7 @@ index 0000000..38dbb43 + rt2800_shared_mem_unlock(rt2x00dev); + + /* -+@@ -1041,6 +1081,8 @@ static inline void rt2800_clear_beacon_r ++@@ -1040,6 +1080,8 @@ static inline void rt2800_clear_beacon_r + + rt2800_shared_mem_lock(rt2x00dev); + @@ -8348,7 +12187,7 @@ index 0000000..38dbb43 + /* + * For the Beacon base registers we only need to clear + * the whole TXWI which (when set to 0) will invalidate -+@@ -1049,6 +1091,8 @@ static inline void rt2800_clear_beacon_r ++@@ -1048,6 +1090,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); + @@ -8359,7 +12198,7 @@ index 0000000..38dbb43 + diff --git a/package/mac80211/patches/600-0005-rt2x00-rt2800lib-add-hw_beacon_count-field-to-struct.patch b/package/mac80211/patches/600-0005-rt2x00-rt2800lib-add-hw_beacon_count-field-to-struct.patch new file mode 100644 -index 0000000..3d97169 +index 0000000..d832f99 --- /dev/null +++ b/package/mac80211/patches/600-0005-rt2x00-rt2800lib-add-hw_beacon_count-field-to-struct.patch @@ -0,0 +1,62 @@ @@ -8389,7 +12228,7 @@ index 0000000..3d97169 + +--- a/drivers/net/wireless/rt2x00/rt2800lib.c ++++ b/drivers/net/wireless/rt2x00/rt2800lib.c -+@@ -4584,6 +4584,7 @@ EXPORT_SYMBOL_GPL(rt2800_link_tuner); ++@@ -4583,6 +4583,7 @@ EXPORT_SYMBOL_GPL(rt2800_link_tuner); + */ + static int rt2800_init_registers(struct rt2x00_dev *rt2x00dev) + { @@ -8397,7 +12236,7 @@ index 0000000..3d97169 + u32 reg; + u16 eeprom; + unsigned int i; -+@@ -4971,7 +4972,7 @@ static int rt2800_init_registers(struct ++@@ -4970,7 +4971,7 @@ static int rt2800_init_registers(struct + /* + * Clear all beacons + */ @@ -8406,7 +12245,7 @@ index 0000000..3d97169 + rt2800_clear_beacon_register(rt2x00dev, i); + + if (rt2x00_is_usb(rt2x00dev)) { -+@@ -7817,6 +7818,8 @@ int rt2800_probe_hw(struct rt2x00_dev *r ++@@ -7816,6 +7817,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); + @@ -8427,7 +12266,7 @@ index 0000000..3d97169 + diff --git a/package/mac80211/patches/600-0006-rt2x00-rt2800lib-init-additional-beacon-offset-regis.patch b/package/mac80211/patches/600-0006-rt2x00-rt2800lib-init-additional-beacon-offset-regis.patch new file mode 100644 -index 0000000..8c52713 +index 0000000..040c69c --- /dev/null +++ b/package/mac80211/patches/600-0006-rt2x00-rt2800lib-init-additional-beacon-offset-regis.patch @@ -0,0 +1,67 @@ @@ -8467,7 +12306,7 @@ index 0000000..8c52713 + */ +--- a/drivers/net/wireless/rt2x00/rt2800lib.c ++++ b/drivers/net/wireless/rt2x00/rt2800lib.c -+@@ -4618,6 +4618,30 @@ static int rt2800_init_registers(struct ++@@ -4617,6 +4617,30 @@ static int rt2800_init_registers(struct + rt2800_get_beacon_offset(rt2x00dev, 7)); + rt2800_register_write(rt2x00dev, BCN_OFFSET1, reg); + @@ -8500,7 +12339,7 @@ index 0000000..8c52713 + diff --git a/package/mac80211/patches/600-0007-rt2x00-rt2800lib-fix-max-supported-beacon-count-for-.patch b/package/mac80211/patches/600-0007-rt2x00-rt2800lib-fix-max-supported-beacon-count-for-.patch new file mode 100644 -index 0000000..66e8245 +index 0000000..752cd89 --- /dev/null +++ b/package/mac80211/patches/600-0007-rt2x00-rt2800lib-fix-max-supported-beacon-count-for-.patch @@ -0,0 +1,24 @@ @@ -8516,7 +12355,7 @@ index 0000000..66e8245 + +--- a/drivers/net/wireless/rt2x00/rt2800lib.c ++++ b/drivers/net/wireless/rt2x00/rt2800lib.c -+@@ -7842,7 +7842,10 @@ int rt2800_probe_hw(struct rt2x00_dev *r ++@@ -7841,7 +7841,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); + @@ -8566,7 +12405,7 @@ index 0000000..8a10c6e + diff --git a/package/mac80211/patches/600-0009-rt2x00-rt2800lib-enable-support-for-RT3883.patch b/package/mac80211/patches/600-0009-rt2x00-rt2800lib-enable-support-for-RT3883.patch new file mode 100644 -index 0000000..e9d847a +index 0000000..8cb93ec --- /dev/null +++ b/package/mac80211/patches/600-0009-rt2x00-rt2800lib-enable-support-for-RT3883.patch @@ -0,0 +1,20 @@ @@ -8582,7 +12421,7 @@ index 0000000..e9d847a + +--- a/drivers/net/wireless/rt2x00/rt2800lib.c ++++ b/drivers/net/wireless/rt2x00/rt2800lib.c -+@@ -7812,6 +7812,7 @@ static int rt2800_probe_rt(struct rt2x00 ++@@ -7811,6 +7811,7 @@ static int rt2800_probe_rt(struct rt2x00 + case RT3390: + case RT3572: + case RT3593: @@ -8592,7 +12431,7 @@ index 0000000..e9d847a + case RT5592: diff --git a/package/mac80211/patches/600-0010-rt2x00-rt2800lib-add-rf_vals-for-RF3853.patch b/package/mac80211/patches/600-0010-rt2x00-rt2800lib-add-rf_vals-for-RF3853.patch new file mode 100644 -index 0000000..b096f9f +index 0000000..e85ae97 --- /dev/null +++ b/package/mac80211/patches/600-0010-rt2x00-rt2800lib-add-rf_vals-for-RF3853.patch @@ -0,0 +1,112 @@ @@ -8629,7 +12468,7 @@ index 0000000..b096f9f + #define RF5372 0x5372 +--- a/drivers/net/wireless/rt2x00/rt2800lib.c ++++ b/drivers/net/wireless/rt2x00/rt2800lib.c -+@@ -7432,6 +7432,66 @@ static const struct rf_channel rf_vals_3 ++@@ -7431,6 +7431,66 @@ static const struct rf_channel rf_vals_3 + {173, 0x61, 0, 9}, + }; + @@ -8696,7 +12535,7 @@ index 0000000..b096f9f + static const struct rf_channel rf_vals_5592_xtal20[] = { + /* Channel, N, K, mod, R */ + {1, 482, 4, 10, 3}, -+@@ -7660,6 +7720,11 @@ static int rt2800_probe_hw_mode(struct r ++@@ -7659,6 +7719,11 @@ static int rt2800_probe_hw_mode(struct r + spec->channels = rf_vals_3x; + break; + @@ -8710,7 +12549,7 @@ index 0000000..b096f9f + if (rt2x00_get_field32(reg, MAC_DEBUG_INDEX_XTAL)) { diff --git a/package/mac80211/patches/600-0011-rt2x00-rt2800lib-enable-VCO-calibration-for-RF3853.patch b/package/mac80211/patches/600-0011-rt2x00-rt2800lib-enable-VCO-calibration-for-RF3853.patch new file mode 100644 -index 0000000..4c9a3b4 +index 0000000..898e385 --- /dev/null +++ b/package/mac80211/patches/600-0011-rt2x00-rt2800lib-enable-VCO-calibration-for-RF3853.patch @@ -0,0 +1,28 @@ @@ -8726,7 +12565,7 @@ index 0000000..4c9a3b4 + +--- a/drivers/net/wireless/rt2x00/rt2800lib.c ++++ b/drivers/net/wireless/rt2x00/rt2800lib.c -+@@ -4349,6 +4349,7 @@ void rt2800_vco_calibration(struct rt2x0 ++@@ -4348,6 +4348,7 @@ void rt2800_vco_calibration(struct rt2x0 + case RF3053: + case RF3070: + case RF3290: @@ -8734,7 +12573,7 @@ index 0000000..4c9a3b4 + case RF5360: + case RF5370: + case RF5372: -+@@ -7839,6 +7840,7 @@ static int rt2800_probe_hw_mode(struct r ++@@ -7838,6 +7839,7 @@ static int rt2800_probe_hw_mode(struct r + case RF3053: + case RF3070: + case RF3290: @@ -8744,7 +12583,7 @@ index 0000000..4c9a3b4 + case RF5372: diff --git a/package/mac80211/patches/600-0012-rt2x00-rt2800lib-add-channel-configuration-function-.patch b/package/mac80211/patches/600-0012-rt2x00-rt2800lib-add-channel-configuration-function-.patch new file mode 100644 -index 0000000..e3460ff +index 0000000..1de99ea --- /dev/null +++ b/package/mac80211/patches/600-0012-rt2x00-rt2800lib-add-channel-configuration-function-.patch @@ -0,0 +1,235 @@ @@ -8761,7 +12600,7 @@ index 0000000..e3460ff + +--- a/drivers/net/wireless/rt2x00/rt2800lib.c ++++ b/drivers/net/wireless/rt2x00/rt2800lib.c -+@@ -2605,6 +2605,211 @@ static void rt2800_config_channel_rf3053 ++@@ -2604,6 +2604,211 @@ static void rt2800_config_channel_rf3053 + } + } + @@ -8973,7 +12812,7 @@ index 0000000..e3460ff + #define POWER_BOUND 0x27 + #define POWER_BOUND_5G 0x2b + -+@@ -3217,6 +3422,9 @@ static void rt2800_config_channel(struct ++@@ -3216,6 +3421,9 @@ static void rt2800_config_channel(struct + case RF3322: + rt2800_config_channel_rf3322(rt2x00dev, conf, rf, info); + break; @@ -8985,7 +12824,7 @@ index 0000000..e3460ff + case RF5370: diff --git a/package/mac80211/patches/600-0013-rt2x00-rt2800lib-enable-RF3853-support.patch b/package/mac80211/patches/600-0013-rt2x00-rt2800lib-enable-RF3853-support.patch new file mode 100644 -index 0000000..8719425 +index 0000000..e7e17a9 --- /dev/null +++ b/package/mac80211/patches/600-0013-rt2x00-rt2800lib-enable-RF3853-support.patch @@ -0,0 +1,20 @@ @@ -9001,7 +12840,7 @@ index 0000000..8719425 + +--- a/drivers/net/wireless/rt2x00/rt2800lib.c ++++ b/drivers/net/wireless/rt2x00/rt2800lib.c -+@@ -7398,6 +7398,7 @@ static int rt2800_init_eeprom(struct rt2 ++@@ -7397,6 +7397,7 @@ static int rt2800_init_eeprom(struct rt2 + case RF3290: + case RF3320: + case RF3322: @@ -9011,7 +12850,7 @@ index 0000000..8719425 + case RF5372: diff --git a/package/mac80211/patches/600-0014-rt2x00-rt2800lib-add-MAC-register-initialization-for.patch b/package/mac80211/patches/600-0014-rt2x00-rt2800lib-add-MAC-register-initialization-for.patch new file mode 100644 -index 0000000..8632ddd +index 0000000..95423d1 --- /dev/null +++ b/package/mac80211/patches/600-0014-rt2x00-rt2800lib-add-MAC-register-initialization-for.patch @@ -0,0 +1,77 @@ @@ -9052,7 +12891,7 @@ index 0000000..8632ddd + #define RX_FILTER_CFG 0x1400 +--- a/drivers/net/wireless/rt2x00/rt2800lib.c ++++ b/drivers/net/wireless/rt2x00/rt2800lib.c -+@@ -4973,6 +4973,12 @@ static int rt2800_init_registers(struct ++@@ -4972,6 +4972,12 @@ static int rt2800_init_registers(struct + rt2800_register_write(rt2x00dev, TX_SW_CFG2, + 0x00000000); + } @@ -9065,7 +12904,7 @@ index 0000000..8632ddd + } else if (rt2x00_rt(rt2x00dev, RT5390) || + rt2x00_rt(rt2x00dev, RT5392) || + rt2x00_rt(rt2x00dev, RT5592)) { -+@@ -5003,9 +5009,11 @@ static int rt2800_init_registers(struct ++@@ -5002,9 +5008,11 @@ static int rt2800_init_registers(struct + + rt2800_register_read(rt2x00dev, MAX_LEN_CFG, ®); + rt2x00_set_field32(®, MAX_LEN_CFG_MAX_MPDU, AGGREGATION_SIZE); @@ -9080,7 +12919,7 @@ index 0000000..8632ddd + rt2x00_set_field32(®, MAX_LEN_CFG_MAX_PSDU, 2); + else + rt2x00_set_field32(®, MAX_LEN_CFG_MAX_PSDU, 1); -+@@ -5158,6 +5166,11 @@ static int rt2800_init_registers(struct ++@@ -5157,6 +5165,11 @@ static int rt2800_init_registers(struct + reg = rt2x00_rt(rt2x00dev, RT5592) ? 0x00000082 : 0x00000002; + rt2800_register_write(rt2x00dev, TXOP_HLDR_ET, reg); + @@ -9130,7 +12969,7 @@ index 0000000..837c025 + static int rt2800soc_set_device_state(struct rt2x00_dev *rt2x00dev, diff --git a/package/mac80211/patches/600-0016-rt2x00-rt2800lib-add-BBP-register-initialization-for.patch b/package/mac80211/patches/600-0016-rt2x00-rt2800lib-add-BBP-register-initialization-for.patch new file mode 100644 -index 0000000..967e36a +index 0000000..d9694da --- /dev/null +++ b/package/mac80211/patches/600-0016-rt2x00-rt2800lib-add-BBP-register-initialization-for.patch @@ -0,0 +1,71 @@ @@ -9147,7 +12986,7 @@ index 0000000..967e36a + +--- a/drivers/net/wireless/rt2x00/rt2800lib.c ++++ b/drivers/net/wireless/rt2x00/rt2800lib.c -+@@ -5776,6 +5776,47 @@ static void rt2800_init_bbp_3593(struct ++@@ -5775,6 +5775,47 @@ static void rt2800_init_bbp_3593(struct + rt2800_bbp_write(rt2x00dev, 103, 0xc0); + } + @@ -9195,7 +13034,7 @@ index 0000000..967e36a + static void rt2800_init_bbp_53xx(struct rt2x00_dev *rt2x00dev) + { + int ant, div_mode; -+@@ -5994,6 +6035,9 @@ static void rt2800_init_bbp(struct rt2x0 ++@@ -5993,6 +6034,9 @@ static void rt2800_init_bbp(struct rt2x0 + case RT3593: + rt2800_init_bbp_3593(rt2x00dev); + return; @@ -9207,7 +13046,7 @@ index 0000000..967e36a + rt2800_init_bbp_53xx(rt2x00dev); diff --git a/package/mac80211/patches/600-0017-rt2x00-rt2800lib-add-RFCSR-initialization-for-RT3883.patch b/package/mac80211/patches/600-0017-rt2x00-rt2800lib-add-RFCSR-initialization-for-RT3883.patch new file mode 100644 -index 0000000..c568b99 +index 0000000..dc45109 --- /dev/null +++ b/package/mac80211/patches/600-0017-rt2x00-rt2800lib-add-RFCSR-initialization-for-RT3883.patch @@ -0,0 +1,178 @@ @@ -9234,7 +13073,7 @@ index 0000000..c568b99 + /* +--- a/drivers/net/wireless/rt2x00/rt2800lib.c ++++ b/drivers/net/wireless/rt2x00/rt2800lib.c -+@@ -6811,6 +6811,144 @@ static void rt2800_init_rfcsr_3593(struc ++@@ -6810,6 +6810,144 @@ static void rt2800_init_rfcsr_3593(struc + /* TODO: enable stream mode support */ + } + @@ -9379,7 +13218,7 @@ index 0000000..c568b99 + static void rt2800_init_rfcsr_5390(struct rt2x00_dev *rt2x00dev) + { + rt2800_rf_init_calibration(rt2x00dev, 2); -+@@ -7042,6 +7180,9 @@ static void rt2800_init_rfcsr(struct rt2 ++@@ -7041,6 +7179,9 @@ static void rt2800_init_rfcsr(struct rt2 + case RT3390: + rt2800_init_rfcsr_3390(rt2x00dev); + break; @@ -9419,7 +13258,7 @@ index 0000000..57af961 + map = rt2800_eeprom_map; diff --git a/package/mac80211/patches/600-0019-rt2x00-rt2800lib-force-rf-type-to-RF3853-on-RT3883.patch b/package/mac80211/patches/600-0019-rt2x00-rt2800lib-force-rf-type-to-RF3853-on-RT3883.patch new file mode 100644 -index 0000000..47eece0 +index 0000000..4bfe8e1 --- /dev/null +++ b/package/mac80211/patches/600-0019-rt2x00-rt2800lib-force-rf-type-to-RF3853-on-RT3883.patch @@ -0,0 +1,21 @@ @@ -9435,7 +13274,7 @@ index 0000000..47eece0 + +--- a/drivers/net/wireless/rt2x00/rt2800lib.c ++++ b/drivers/net/wireless/rt2x00/rt2800lib.c -+@@ -7579,6 +7579,8 @@ static int rt2800_init_eeprom(struct rt2 ++@@ -7578,6 +7578,8 @@ static int rt2800_init_eeprom(struct rt2 + rt2x00_rt(rt2x00dev, RT5390) || + rt2x00_rt(rt2x00dev, RT5392)) + rt2800_eeprom_read(rt2x00dev, EEPROM_CHIP_ID, &rf); @@ -9446,7 +13285,7 @@ index 0000000..47eece0 + diff --git a/package/mac80211/patches/600-0020-rt2x00-rt2800lib-add-channel-configuration-code-for-.patch b/package/mac80211/patches/600-0020-rt2x00-rt2800lib-add-channel-configuration-code-for-.patch new file mode 100644 -index 0000000..d9cbb33 +index 0000000..59b74ad --- /dev/null +++ b/package/mac80211/patches/600-0020-rt2x00-rt2800lib-add-channel-configuration-code-for-.patch @@ -0,0 +1,136 @@ @@ -9462,7 +13301,7 @@ index 0000000..d9cbb33 + +--- a/drivers/net/wireless/rt2x00/rt2800lib.c ++++ b/drivers/net/wireless/rt2x00/rt2800lib.c -+@@ -3385,6 +3385,36 @@ static char rt2800_txpower_to_dev(struct ++@@ -3384,6 +3384,36 @@ static char rt2800_txpower_to_dev(struct + return clamp_t(char, txpower, MIN_A_TXPOWER, MAX_A_TXPOWER); + } + @@ -9499,7 +13338,7 @@ index 0000000..d9cbb33 + static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev, + struct ieee80211_conf *conf, + struct rf_channel *rf, -+@@ -3403,6 +3433,12 @@ static void rt2800_config_channel(struct ++@@ -3402,6 +3432,12 @@ static void rt2800_config_channel(struct + rt2800_txpower_to_dev(rt2x00dev, rf->channel, + info->default_power3); + @@ -9512,7 +13351,7 @@ index 0000000..d9cbb33 + switch (rt2x00dev->chip.rf) { + case RF2020: + case RF3020: -+@@ -3484,6 +3520,15 @@ static void rt2800_config_channel(struct ++@@ -3483,6 +3519,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); @@ -9528,7 +13367,7 @@ index 0000000..d9cbb33 + } else { + rt2800_bbp_write(rt2x00dev, 62, 0x37 - rt2x00dev->lna_gain); + rt2800_bbp_write(rt2x00dev, 63, 0x37 - rt2x00dev->lna_gain); -+@@ -3496,6 +3541,7 @@ static void rt2800_config_channel(struct ++@@ -3495,6 +3540,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); @@ -9536,7 +13375,7 @@ index 0000000..d9cbb33 + rt2800_bbp_write(rt2x00dev, 75, 0x46); + } else { + if (rt2x00_rt(rt2x00dev, RT3593)) -+@@ -3504,19 +3550,22 @@ static void rt2800_config_channel(struct ++@@ -3503,19 +3549,22 @@ static void rt2800_config_channel(struct + rt2800_bbp_write(rt2x00dev, 82, 0x84); + rt2800_bbp_write(rt2x00dev, 75, 0x50); + } @@ -9562,13 +13401,10 @@ index 0000000..d9cbb33 + rt2800_bbp_write(rt2x00dev, 83, 0x9a); + + if (rt2x00_has_cap_external_lna_a(rt2x00dev)) -+@@ -3638,6 +3687,23 @@ static void rt2800_config_channel(struct ++@@ -3640,6 +3689,23 @@ static void rt2800_config_channel(struct ++ usleep_range(1000, 1500); ++ } + -+ 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); @@ -9583,12 +13419,15 @@ index 0000000..d9cbb33 ++ ++ rt2800_bbp_write_with_rx_chain(rt2x00dev, 66, reg); ++ -+ usleep_range(1000, 1500); -+ } -+ +++ usleep_range(1000, 1500); +++ } +++ ++ if (rt2x00_rt(rt2x00dev, RT5592)) { ++ rt2800_bbp_write(rt2x00dev, 195, 141); ++ rt2800_bbp_write(rt2x00dev, 196, conf_is_ht40(conf) ? 0x10 : 0x1a); diff --git a/package/mac80211/patches/600-0021-rt2x00-rt2800lib-fix-txpower_to_dev-function-for-RT3.patch b/package/mac80211/patches/600-0021-rt2x00-rt2800lib-fix-txpower_to_dev-function-for-RT3.patch new file mode 100644 -index 0000000..c927e45 +index 0000000..e88a7c6 --- /dev/null +++ b/package/mac80211/patches/600-0021-rt2x00-rt2800lib-fix-txpower_to_dev-function-for-RT3.patch @@ -0,0 +1,30 @@ @@ -9604,7 +13443,7 @@ index 0000000..c927e45 + +--- a/drivers/net/wireless/rt2x00/rt2800lib.c ++++ b/drivers/net/wireless/rt2x00/rt2800lib.c -+@@ -3372,13 +3372,15 @@ static char rt2800_txpower_to_dev(struct ++@@ -3371,13 +3371,15 @@ static char rt2800_txpower_to_dev(struct + unsigned int channel, + char txpower) + { @@ -9624,7 +13463,7 @@ index 0000000..c927e45 + else diff --git a/package/mac80211/patches/600-0022-rt2x00-rt2800lib-use-correct-txpower-calculation-fun.patch b/package/mac80211/patches/600-0022-rt2x00-rt2800lib-use-correct-txpower-calculation-fun.patch new file mode 100644 -index 0000000..df826e5 +index 0000000..95484a0 --- /dev/null +++ b/package/mac80211/patches/600-0022-rt2x00-rt2800lib-use-correct-txpower-calculation-fun.patch @@ -0,0 +1,23 @@ @@ -9641,7 +13480,7 @@ index 0000000..df826e5 + +--- a/drivers/net/wireless/rt2x00/rt2800lib.c ++++ b/drivers/net/wireless/rt2x00/rt2800lib.c -+@@ -4582,7 +4582,8 @@ static void rt2800_config_txpower(struct ++@@ -4581,7 +4581,8 @@ static void rt2800_config_txpower(struct + struct ieee80211_channel *chan, + int power_level) + { @@ -9653,7 +13492,7 @@ index 0000000..df826e5 + rt2800_config_txpower_rt28xx(rt2x00dev, chan, power_level); diff --git a/package/mac80211/patches/600-0023-rt2x00-rt2800lib-hardcode-txmixer-gain-values-to-zer.patch b/package/mac80211/patches/600-0023-rt2x00-rt2800lib-hardcode-txmixer-gain-values-to-zer.patch new file mode 100644 -index 0000000..8a43df2 +index 0000000..c57af60 --- /dev/null +++ b/package/mac80211/patches/600-0023-rt2x00-rt2800lib-hardcode-txmixer-gain-values-to-zer.patch @@ -0,0 +1,33 @@ @@ -9670,7 +13509,7 @@ index 0000000..8a43df2 + +--- a/drivers/net/wireless/rt2x00/rt2800lib.c ++++ b/drivers/net/wireless/rt2x00/rt2800lib.c -+@@ -7461,7 +7461,8 @@ static u8 rt2800_get_txmixer_gain_24g(st ++@@ -7460,7 +7460,8 @@ static u8 rt2800_get_txmixer_gain_24g(st + { + u16 word; + @@ -9680,7 +13519,7 @@ index 0000000..8a43df2 + return 0; + + rt2800_eeprom_read(rt2x00dev, EEPROM_TXMIXER_GAIN_BG, &word); -+@@ -7475,7 +7476,8 @@ static u8 rt2800_get_txmixer_gain_5g(str ++@@ -7474,7 +7475,8 @@ static u8 rt2800_get_txmixer_gain_5g(str + { + u16 word; + @@ -9746,7 +13585,7 @@ index 0000000..08f3f88 + return HW_BEACON_BASE(index); diff --git a/package/mac80211/patches/600-0026-rt2x00-rt2800lib-use-correct-beacon-count-for-RT3883.patch b/package/mac80211/patches/600-0026-rt2x00-rt2800lib-use-correct-beacon-count-for-RT3883.patch new file mode 100644 -index 0000000..cb7a0ae +index 0000000..f606ed4 --- /dev/null +++ b/package/mac80211/patches/600-0026-rt2x00-rt2800lib-use-correct-beacon-count-for-RT3883.patch @@ -0,0 +1,22 @@ @@ -9762,7 +13601,7 @@ index 0000000..cb7a0ae + +--- a/drivers/net/wireless/rt2x00/rt2800lib.c ++++ b/drivers/net/wireless/rt2x00/rt2800lib.c -+@@ -8393,7 +8393,8 @@ int rt2800_probe_hw(struct rt2x00_dev *r ++@@ -8392,7 +8392,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); + @@ -9774,7 +13613,7 @@ index 0000000..cb7a0ae + drv_data->hw_beacon_count = 8; diff --git a/package/mac80211/patches/600-0027-rt2x00-rt2800lib-fix-antenna-configuration-for-RT388.patch b/package/mac80211/patches/600-0027-rt2x00-rt2800lib-fix-antenna-configuration-for-RT388.patch new file mode 100644 -index 0000000..0919f90 +index 0000000..4096493 --- /dev/null +++ b/package/mac80211/patches/600-0027-rt2x00-rt2800lib-fix-antenna-configuration-for-RT388.patch @@ -0,0 +1,22 @@ @@ -9790,7 +13629,7 @@ index 0000000..0919f90 + +--- a/drivers/net/wireless/rt2x00/rt2800lib.c ++++ b/drivers/net/wireless/rt2x00/rt2800lib.c -+@@ -1917,7 +1917,8 @@ void rt2800_config_ant(struct rt2x00_dev ++@@ -1916,7 +1916,8 @@ void rt2800_config_ant(struct rt2x00_dev + rt2800_bbp_write(rt2x00dev, 3, r3); + rt2800_bbp_write(rt2x00dev, 1, r1); + @@ -9802,7 +13641,7 @@ index 0000000..0919f90 + else diff --git a/package/mac80211/patches/600-0028-rt2x00-rt2800lib-fix-LNA-gain-configuration-for-RT38.patch b/package/mac80211/patches/600-0028-rt2x00-rt2800lib-fix-LNA-gain-configuration-for-RT38.patch new file mode 100644 -index 0000000..e38ba78 +index 0000000..2fc9d9d --- /dev/null +++ b/package/mac80211/patches/600-0028-rt2x00-rt2800lib-fix-LNA-gain-configuration-for-RT38.patch @@ -0,0 +1,32 @@ @@ -9818,7 +13657,7 @@ index 0000000..e38ba78 + +--- a/drivers/net/wireless/rt2x00/rt2800lib.c ++++ b/drivers/net/wireless/rt2x00/rt2800lib.c -+@@ -1940,7 +1940,8 @@ static void rt2800_config_lna_gain(struc ++@@ -1939,7 +1939,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) { @@ -9828,7 +13667,7 @@ index 0000000..e38ba78 + rt2800_eeprom_read(rt2x00dev, EEPROM_EXT_LNA2, &eeprom); + lna_gain = rt2x00_get_field16(eeprom, + EEPROM_EXT_LNA2_A1); -+@@ -1950,7 +1951,8 @@ static void rt2800_config_lna_gain(struc ++@@ -1949,7 +1950,8 @@ static void rt2800_config_lna_gain(struc + EEPROM_RSSI_BG2_LNA_A1); + } + } else { @@ -9840,7 +13679,7 @@ index 0000000..e38ba78 + EEPROM_EXT_LNA2_A2); diff --git a/package/mac80211/patches/600-0029-rt2x00-rt2800lib-fix-VGC-setup-for-RT3883.patch b/package/mac80211/patches/600-0029-rt2x00-rt2800lib-fix-VGC-setup-for-RT3883.patch new file mode 100644 -index 0000000..4684599 +index 0000000..060d4c6 --- /dev/null +++ b/package/mac80211/patches/600-0029-rt2x00-rt2800lib-fix-VGC-setup-for-RT3883.patch @@ -0,0 +1,44 @@ @@ -9856,7 +13695,7 @@ index 0000000..4684599 + +--- a/drivers/net/wireless/rt2x00/rt2800lib.c ++++ b/drivers/net/wireless/rt2x00/rt2800lib.c -+@@ -4781,7 +4781,8 @@ static u8 rt2800_get_default_vgc(struct ++@@ -4780,7 +4780,8 @@ static u8 rt2800_get_default_vgc(struct + else + vgc = 0x2e + rt2x00dev->lna_gain; + } else { /* 5GHZ band */ @@ -9866,7 +13705,7 @@ index 0000000..4684599 + vgc = 0x20 + (rt2x00dev->lna_gain * 5) / 3; + else if (rt2x00_rt(rt2x00dev, RT5592)) + vgc = 0x24 + (2 * rt2x00dev->lna_gain); -+@@ -4801,7 +4802,8 @@ static inline void rt2800_set_vgc(struct ++@@ -4800,7 +4801,8 @@ static inline void rt2800_set_vgc(struct + { + if (qual->vgc_level != vgc_level) { + if (rt2x00_rt(rt2x00dev, RT3572) || @@ -9876,7 +13715,7 @@ index 0000000..4684599 + rt2800_bbp_write_with_rx_chain(rt2x00dev, 66, + vgc_level); + } else if (rt2x00_rt(rt2x00dev, RT5592)) { -+@@ -4848,6 +4850,11 @@ void rt2800_link_tuner(struct rt2x00_dev ++@@ -4847,6 +4849,11 @@ void rt2800_link_tuner(struct rt2x00_dev + } + break; + @@ -9890,7 +13729,7 @@ index 0000000..4684599 + vgc += 0x20; diff --git a/package/mac80211/patches/600-0030-rt2x00-rt2800lib-fix-EEPROM-LNA-validation-for-RT388.patch b/package/mac80211/patches/600-0030-rt2x00-rt2800lib-fix-EEPROM-LNA-validation-for-RT388.patch new file mode 100644 -index 0000000..bc1548d +index 0000000..3e9a7d9 --- /dev/null +++ b/package/mac80211/patches/600-0030-rt2x00-rt2800lib-fix-EEPROM-LNA-validation-for-RT388.patch @@ -0,0 +1,42 @@ @@ -9906,7 +13745,7 @@ index 0000000..bc1548d + +--- a/drivers/net/wireless/rt2x00/rt2800lib.c ++++ b/drivers/net/wireless/rt2x00/rt2800lib.c -+@@ -7598,7 +7598,8 @@ static int rt2800_validate_eeprom(struct ++@@ -7597,7 +7597,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); @@ -9916,7 +13755,7 @@ index 0000000..bc1548d + 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, -+@@ -7618,7 +7619,8 @@ static int rt2800_validate_eeprom(struct ++@@ -7617,7 +7618,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); @@ -9926,7 +13765,7 @@ index 0000000..bc1548d + 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, -+@@ -7626,7 +7628,8 @@ static int rt2800_validate_eeprom(struct ++@@ -7625,7 +7627,8 @@ static int rt2800_validate_eeprom(struct + } + rt2800_eeprom_write(rt2x00dev, EEPROM_RSSI_A2, word); + @@ -9938,7 +13777,7 @@ index 0000000..bc1548d + rt2x00_get_field16(word, EEPROM_EXT_LNA2_A1) == 0xff) diff --git a/package/mac80211/patches/600-0031-rt2x00-rt2800lib-fix-txpower-compensation-for-RT3883.patch b/package/mac80211/patches/600-0031-rt2x00-rt2800lib-fix-txpower-compensation-for-RT3883.patch new file mode 100644 -index 0000000..d6295f4 +index 0000000..b87f36a --- /dev/null +++ b/package/mac80211/patches/600-0031-rt2x00-rt2800lib-fix-txpower-compensation-for-RT3883.patch @@ -0,0 +1,22 @@ @@ -9954,7 +13793,7 @@ index 0000000..d6295f4 + +--- a/drivers/net/wireless/rt2x00/rt2800lib.c ++++ b/drivers/net/wireless/rt2x00/rt2800lib.c -+@@ -3959,6 +3959,9 @@ static u8 rt2800_compensate_txpower(stru ++@@ -3958,6 +3958,9 @@ static u8 rt2800_compensate_txpower(stru + if (rt2x00_rt(rt2x00dev, RT3593)) + return min_t(u8, txpower, 0xc); + @@ -9966,7 +13805,7 @@ index 0000000..d6295f4 + * Check if eirp txpower exceed txpower_limit. diff --git a/package/mac80211/patches/600-0032-rt2x00-rt2800lib-enable-RT2800_HAS_HIGH_SHARED_MEM-f.patch b/package/mac80211/patches/600-0032-rt2x00-rt2800lib-enable-RT2800_HAS_HIGH_SHARED_MEM-f.patch new file mode 100644 -index 0000000..c5f226a +index 0000000..18d65e0 --- /dev/null +++ b/package/mac80211/patches/600-0032-rt2x00-rt2800lib-enable-RT2800_HAS_HIGH_SHARED_MEM-f.patch @@ -0,0 +1,23 @@ @@ -9983,7 +13822,7 @@ index 0000000..c5f226a + +--- a/drivers/net/wireless/rt2x00/rt2800lib.c ++++ b/drivers/net/wireless/rt2x00/rt2800lib.c -+@@ -8406,7 +8406,8 @@ int rt2800_probe_hw(struct rt2x00_dev *r ++@@ -8405,7 +8405,8 @@ int rt2800_probe_hw(struct rt2x00_dev *r + if (retval) + return retval; + @@ -10228,14 +14067,14 @@ index a910cc3..1db09a3 100644 u32 rt2x00lib_get_bssidx(struct rt2x00_dev *rt2x00dev, struct ieee80211_vif *vif); diff --git a/package/mac80211/patches/610-rt2x00-fix-rt3352-ext-pa.patch b/package/mac80211/patches/610-rt2x00-fix-rt3352-ext-pa.patch -index 83fbcd0..3d32ecc 100644 +index 83fbcd0..725f81f 100644 --- a/package/mac80211/patches/610-rt2x00-fix-rt3352-ext-pa.patch +++ b/package/mac80211/patches/610-rt2x00-fix-rt3352-ext-pa.patch @@ -1,14 +1,15 @@ --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c -@@ -3176,11 +3176,17 @@ static void rt2800_config_channel(struct -+@@ -3506,11 +3506,18 @@ static void rt2800_config_channel(struct ++@@ -3505,11 +3505,18 @@ static void rt2800_config_channel(struct /* * Change BBP settings */ @@ -10271,7 +14110,7 @@ index 83fbcd0..3d32ecc 100644 - } - -@@ -6125,6 +6125,12 @@ static void rt2800_init_rfcsr_3290(struc -+@@ -6586,6 +6593,12 @@ static void rt2800_init_rfcsr_3290(struc ++@@ -6585,6 +6592,12 @@ static void rt2800_init_rfcsr_3290(struc static void rt2800_init_rfcsr_3352(struct rt2x00_dev *rt2x00dev) { @@ -10280,7 +14119,7 @@ index 83fbcd0..3d32ecc 100644 rt2800_rfcsr_write(rt2x00dev, 0, 0xf0); -@@ -6160,15 +6166,30 @@ static void rt2800_init_rfcsr_3352(struc -+@@ -6621,15 +6634,30 @@ static void rt2800_init_rfcsr_3352(struc ++@@ -6620,15 +6633,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); @@ -10289,7 +14128,7 @@ index 83fbcd0..3d32ecc 100644 rt2800_rfcsr_write(rt2x00dev, 44, 0xdb); rt2800_rfcsr_write(rt2x00dev, 45, 0xdb); -@@ -6176,15 +6197,20 @@ static void rt2800_init_rfcsr_3352(struc -+@@ -6637,15 +6665,20 @@ static void rt2800_init_rfcsr_3352(struc ++@@ -6636,15 +6664,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); @@ -10298,7 +14137,7 @@ index 83fbcd0..3d32ecc 100644 rt2800_rfcsr_write(rt2x00dev, 60, 0x00); rt2800_rfcsr_write(rt2x00dev, 61, 0x00); -@@ -7051,6 +7077,7 @@ static int rt2800_init_eeprom(struct rt2 -+@@ -7666,6 +7699,7 @@ static int rt2800_init_eeprom(struct rt2 ++@@ -7665,6 +7698,7 @@ static int rt2800_init_eeprom(struct rt2 * RT53xx: defined in "EEPROM_CHIP_ID" field */ if (rt2x00_rt(rt2x00dev, RT3290) || @@ -10307,7 +14146,7 @@ index 83fbcd0..3d32ecc 100644 rt2x00_rt(rt2x00dev, RT5392)) rt2800_eeprom_read(rt2x00dev, EEPROM_CHIP_ID, &rf); -@@ -7142,7 +7169,8 @@ static int rt2800_init_eeprom(struct rt2 -+@@ -7760,7 +7794,8 @@ static int rt2800_init_eeprom(struct rt2 ++@@ -7759,7 +7793,8 @@ static int rt2800_init_eeprom(struct rt2 /* * Detect if this device has Bluetooth co-existence. */ @@ -10316,7 +14155,7 @@ index 83fbcd0..3d32ecc 100644 /* -@@ -7171,6 +7199,22 @@ static int rt2800_init_eeprom(struct rt2 -+@@ -7789,6 +7824,22 @@ static int rt2800_init_eeprom(struct rt2 ++@@ -7788,6 +7823,22 @@ static int rt2800_init_eeprom(struct rt2 EIRP_MAX_TX_POWER_LIMIT) __set_bit(CAPABILITY_POWER_LIMIT, &rt2x00dev->cap_flags); @@ -10366,14 +14205,14 @@ index 83fbcd0..3d32ecc 100644 #define EEPROM_NIC_CONF1_BT_COEXIST FIELD16(0x4000) #define EEPROM_NIC_CONF1_DAC_TEST FIELD16(0x8000) diff --git a/package/mac80211/patches/611-rt2x00-rf_vals-rt3352-xtal20.patch b/package/mac80211/patches/611-rt2x00-rf_vals-rt3352-xtal20.patch -index 478a0f2..c69344c 100644 +index 478a0f2..6b29aa8 100644 --- a/package/mac80211/patches/611-rt2x00-rf_vals-rt3352-xtal20.patch +++ b/package/mac80211/patches/611-rt2x00-rf_vals-rt3352-xtal20.patch @@ -1,6 +1,6 @@ --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c -@@ -7491,6 +7491,27 @@ static const struct rf_channel rf_vals_5 -+@@ -8176,6 +8176,27 @@ static const struct rf_channel rf_vals_5 ++@@ -8175,6 +8175,27 @@ static const struct rf_channel rf_vals_5 {196, 83, 0, 12, 1}, }; @@ -10382,7 +14221,7 @@ index 478a0f2..c69344c 100644 { struct hw_mode_spec *spec = &rt2x00dev->spec; -@@ -7579,7 +7600,10 @@ static int rt2800_probe_hw_mode(struct r -+@@ -8263,7 +8284,10 @@ static int rt2800_probe_hw_mode(struct r ++@@ -8262,7 +8283,10 @@ static int rt2800_probe_hw_mode(struct r case RF5390: case RF5392: spec->num_channels = 14; @@ -10391,7 +14230,7 @@ index 478a0f2..c69344c 100644 case RF3052: -@@ -7755,6 +7779,19 @@ static int rt2800_probe_rt(struct rt2x00 -+@@ -8446,6 +8470,19 @@ static int rt2800_probe_rt(struct rt2x00 ++@@ -8445,6 +8469,19 @@ static int rt2800_probe_rt(struct rt2x00 return 0; } @@ -10402,7 +14241,7 @@ index 478a0f2..c69344c 100644 - int retval; -@@ -7784,6 +7821,15 @@ int rt2800_probe_hw(struct rt2x00_dev *r + struct rt2800_drv_data *drv_data = rt2x00dev->drv_data; -+@@ -8488,6 +8525,15 @@ int rt2800_probe_hw(struct rt2x00_dev *r ++@@ -8487,6 +8524,15 @@ int rt2800_probe_hw(struct rt2x00_dev *r rt2800_register_write(rt2x00dev, GPIO_CTRL, reg); /* @@ -10420,7 +14259,7 @@ index f6b4808..119e95c 100644 } diff --git a/package/mac80211/patches/616-rt2x00-support-rt5350.patch b/package/mac80211/patches/616-rt2x00-support-rt5350.patch -index 3bafa16..2cc136c 100644 +index 3bafa16..fd897e9 100644 --- a/package/mac80211/patches/616-rt2x00-support-rt5350.patch +++ b/package/mac80211/patches/616-rt2x00-support-rt5350.patch @@ -1,16 +1,16 @@ @@ -10439,7 +14278,7 @@ index 3bafa16..2cc136c 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c -@@ -2704,6 +2704,13 @@ static void rt2800_config_channel_rf53xx -+@@ -2994,6 +2994,13 @@ static void rt2800_config_channel_rf53xx ++@@ -2993,6 +2993,13 @@ static void rt2800_config_channel_rf53xx rt2800_rfcsr_write(rt2x00dev, 59, r59_non_bt[idx]); @@ -10449,7 +14288,7 @@ index 3bafa16..2cc136c 100644 } -@@ -3141,6 +3148,7 @@ static void rt2800_config_channel(struct - rt2800_config_channel_rf3322(rt2x00dev, conf, rf, info); -+@@ -3472,6 +3479,7 @@ static void rt2800_config_channel(struct ++@@ -3471,6 +3478,7 @@ static void rt2800_config_channel(struct + rt2800_config_channel_rf3853(rt2x00dev, conf, rf, info); break; case RF3070: @@ -10458,7 +14297,7 @@ index 3bafa16..2cc136c 100644 case RF5370: case RF5372: -@@ -3158,6 +3166,7 @@ static void rt2800_config_channel(struct -+@@ -3489,6 +3497,7 @@ static void rt2800_config_channel(struct ++@@ -3488,6 +3496,7 @@ static void rt2800_config_channel(struct if (rt2x00_rf(rt2x00dev, RF3070) || rt2x00_rf(rt2x00dev, RF3290) || rt2x00_rf(rt2x00dev, RF3322) || @@ -10467,7 +14306,7 @@ index 3bafa16..2cc136c 100644 rt2x00_rf(rt2x00dev, RF5370) || rt2x00_rf(rt2x00dev, RF5372) || -@@ -3398,7 +3407,8 @@ static void rt2800_config_channel(struct -+@@ -3766,7 +3775,8 @@ static void rt2800_config_channel(struct ++@@ -3765,7 +3774,8 @@ static void rt2800_config_channel(struct /* * Clear update flag */ @@ -10477,7 +14316,7 @@ index 3bafa16..2cc136c 100644 rt2800_bbp_write(rt2x00dev, 49, bbp); -@@ -4272,6 +4282,7 @@ void rt2800_vco_calibration(struct rt2x0 - case RF3053: -+@@ -4645,6 +4655,7 @@ void rt2800_vco_calibration(struct rt2x0 ++@@ -4644,6 +4654,7 @@ void rt2800_vco_calibration(struct rt2x0 case RF3070: case RF3290: + case RF3853: @@ -10486,7 +14325,7 @@ index 3bafa16..2cc136c 100644 case RF5370: case RF5372: -@@ -4668,6 +4679,8 @@ static int rt2800_init_registers(struct -+@@ -5079,6 +5090,8 @@ static int rt2800_init_registers(struct ++@@ -5078,6 +5089,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); @@ -10495,7 +14334,7 @@ index 3bafa16..2cc136c 100644 rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000000); rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00080606); -@@ -5309,9 +5322,13 @@ static void rt2800_init_bbp_3352(struct -+@@ -5734,9 +5747,13 @@ static void rt2800_init_bbp_3352(struct ++@@ -5733,9 +5746,13 @@ static void rt2800_init_bbp_3352(struct rt2800_bbp_write(rt2x00dev, 82, 0x62); @@ -10504,7 +14343,7 @@ index 3bafa16..2cc136c 100644 rt2800_bbp_write(rt2x00dev, 86, 0x38); -@@ -5325,9 +5342,13 @@ static void rt2800_init_bbp_3352(struct -+@@ -5750,9 +5767,13 @@ static void rt2800_init_bbp_3352(struct ++@@ -5749,9 +5766,13 @@ static void rt2800_init_bbp_3352(struct rt2800_bbp_write(rt2x00dev, 104, 0x92); @@ -10513,7 +14352,7 @@ index 3bafa16..2cc136c 100644 rt2800_bbp_write(rt2x00dev, 120, 0x50); -@@ -5352,6 +5373,13 @@ static void rt2800_init_bbp_3352(struct -+@@ -5777,6 +5798,13 @@ static void rt2800_init_bbp_3352(struct ++@@ -5776,6 +5797,13 @@ static void rt2800_init_bbp_3352(struct rt2800_bbp_write(rt2x00dev, 143, 0xa2); rt2800_bbp_write(rt2x00dev, 148, 0xc8); @@ -10522,7 +14361,7 @@ index 3bafa16..2cc136c 100644 static void rt2800_init_bbp_3390(struct rt2x00_dev *rt2x00dev) -@@ -5652,6 +5680,7 @@ static void rt2800_init_bbp(struct rt2x0 -+@@ -6118,6 +6146,7 @@ static void rt2800_init_bbp(struct rt2x0 ++@@ -6117,6 +6145,7 @@ static void rt2800_init_bbp(struct rt2x0 rt2800_init_bbp_3290(rt2x00dev); break; case RT3352: @@ -10532,7 +14371,7 @@ index 3bafa16..2cc136c 100644 case RT3390: -@@ -6462,6 +6491,76 @@ static void rt2800_init_rfcsr_3593(struc - /* TODO: enable stream mode support */ -+@@ -7069,6 +7098,76 @@ static void rt2800_init_rfcsr_3883(struc ++@@ -7068,6 +7097,76 @@ static void rt2800_init_rfcsr_3883(struc + rt2800_rfcsr_write(rt2x00dev, 20, rfcsr); } @@ -10542,7 +14381,7 @@ index 3bafa16..2cc136c 100644 { rt2800_rf_init_calibration(rt2x00dev, 2); -@@ -6699,6 +6798,9 @@ static void rt2800_init_rfcsr(struct rt2 -+@@ -7309,6 +7408,9 @@ static void rt2800_init_rfcsr(struct rt2 ++@@ -7308,6 +7407,9 @@ static void rt2800_init_rfcsr(struct rt2 case RT3593: rt2800_init_rfcsr_3593(rt2x00dev); break; @@ -10551,7 +14390,7 @@ index 3bafa16..2cc136c 100644 rt2800_init_rfcsr_5390(rt2x00dev); break; -@@ -6948,6 +7050,12 @@ static int rt2800_validate_eeprom(struct -+@@ -7568,6 +7670,12 @@ static int rt2800_validate_eeprom(struct ++@@ -7567,6 +7669,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); @@ -10562,7 +14401,7 @@ index 3bafa16..2cc136c 100644 -@@ -7081,6 +7189,8 @@ static int rt2800_init_eeprom(struct rt2 - rt2x00_rt(rt2x00dev, RT5390) || - rt2x00_rt(rt2x00dev, RT5392)) -+@@ -7706,6 +7814,8 @@ static int rt2800_init_eeprom(struct rt2 ++@@ -7705,6 +7813,8 @@ static int rt2800_init_eeprom(struct rt2 rt2800_eeprom_read(rt2x00dev, EEPROM_CHIP_ID, &rf); + else if (rt2x00_rt(rt2x00dev, RT3883)) + rf = RF3853; @@ -10573,7 +14412,7 @@ index 3bafa16..2cc136c 100644 -@@ -7099,6 +7209,7 @@ static int rt2800_init_eeprom(struct rt2 - case RF3290: -+@@ -7725,6 +7835,7 @@ static int rt2800_init_eeprom(struct rt2 ++@@ -7724,6 +7834,7 @@ static int rt2800_init_eeprom(struct rt2 case RF3320: case RF3322: + case RF3853: @@ -10582,7 +14421,7 @@ index 3bafa16..2cc136c 100644 case RF5370: case RF5372: -@@ -7594,6 +7705,7 @@ static int rt2800_probe_hw_mode(struct r -+@@ -8279,6 +8390,7 @@ static int rt2800_probe_hw_mode(struct r ++@@ -8278,6 +8389,7 @@ static int rt2800_probe_hw_mode(struct r case RF3290: case RF3320: case RF3322: @@ -10592,7 +14431,7 @@ index 3bafa16..2cc136c 100644 case RF5372: -@@ -7726,6 +7838,7 @@ static int rt2800_probe_hw_mode(struct r - case RF3053: -+@@ -8417,6 +8529,7 @@ static int rt2800_probe_hw_mode(struct r ++@@ -8416,6 +8528,7 @@ static int rt2800_probe_hw_mode(struct r case RF3070: case RF3290: + case RF3853: @@ -10602,7 +14441,7 @@ index 3bafa16..2cc136c 100644 case RF5372: -@@ -7764,6 +7877,7 @@ static int rt2800_probe_rt(struct rt2x00 - case RT3390: -+@@ -8456,6 +8569,7 @@ static int rt2800_probe_rt(struct rt2x00 ++@@ -8455,6 +8568,7 @@ static int rt2800_probe_rt(struct rt2x00 case RT3572: case RT3593: + case RT3883: @@ -10610,20 +14449,28 @@ index 3bafa16..2cc136c 100644 case RT5390: case RT5392: diff --git a/package/mac80211/patches/619-rt2x00-change-led-polarity-from-OF.patch b/package/mac80211/patches/619-rt2x00-change-led-polarity-from-OF.patch -index f9186d8..fc56847 100644 +index f9186d8..ee473dc 100644 --- a/package/mac80211/patches/619-rt2x00-change-led-polarity-from-OF.patch +++ b/package/mac80211/patches/619-rt2x00-change-led-polarity-from-OF.patch +@@ -1,6 +1,6 @@ + --- a/drivers/net/wireless/rt2x00/rt2800lib.c + +++ b/drivers/net/wireless/rt2x00/rt2800lib.c +-@@ -36,6 +36,7 @@ ++@@ -37,6 +37,7 @@ + #include + #include + #include @@ -8,7 +8,7 @@ #include "rt2x00.h" #include "rt2800lib.h" -@@ -7298,6 +7299,17 @@ static int rt2800_init_eeprom(struct rt2 -+@@ -7924,6 +7925,17 @@ static int rt2800_init_eeprom(struct rt2 ++@@ -7923,6 +7924,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); diff --git a/package/mac80211/patches/620-rt2x00-rt3352-rf-id.patch b/package/mac80211/patches/620-rt2x00-rt3352-rf-id.patch -index 5e67344..a33c01f 100644 +index 5e67344..86a990c 100644 --- a/package/mac80211/patches/620-rt2x00-rt3352-rf-id.patch +++ b/package/mac80211/patches/620-rt2x00-rt3352-rf-id.patch @@ -1,15 +1,11 @@ @@ -10634,7 +14481,7 @@ index 5e67344..a33c01f 100644 - */ - if (rt2x00_rt(rt2x00dev, RT3290) || -- rt2x00_rt(rt2x00dev, RT3352) || -+@@ -7813,6 +7813,8 @@ static int rt2800_init_eeprom(struct rt2 ++@@ -7812,6 +7812,8 @@ static int rt2800_init_eeprom(struct rt2 rt2x00_rt(rt2x00dev, RT5390) || rt2x00_rt(rt2x00dev, RT5392)) rt2800_eeprom_read(rt2x00dev, EEPROM_CHIP_ID, &rf); @@ -10646,17 +14493,237 @@ index 5e67344..a33c01f 100644 - rf = RF5350; - else diff --git a/package/mac80211/patches/700-mwl8k-missing-pci-id-for-WNR854T.patch b/package/mac80211/patches/700-mwl8k-missing-pci-id-for-WNR854T.patch -index 484c075..752fb0e 100644 +index 484c075..ae7e927 100644 --- a/package/mac80211/patches/700-mwl8k-missing-pci-id-for-WNR854T.patch +++ b/package/mac80211/patches/700-mwl8k-missing-pci-id-for-WNR854T.patch @@ -1,6 +1,6 @@ --- a/drivers/net/wireless/mwl8k.c +++ b/drivers/net/wireless/mwl8k.c -@@ -5529,6 +5529,7 @@ MODULE_FIRMWARE("mwl8k/fmimage_8366.fw") -+@@ -5714,6 +5714,7 @@ MODULE_FIRMWARE("mwl8k/fmimage_8366.fw") ++@@ -5682,6 +5682,7 @@ MODULE_FIRMWARE("mwl8k/fmimage_8366.fw") MODULE_FIRMWARE(MWL8K_8366_AP_FW(MWL8K_8366_AP_FW_API)); static DEFINE_PCI_DEVICE_TABLE(mwl8k_pci_id_table) = { +diff --git a/package/mac80211/patches/800-b43-gpio-mask-module-option.patch b/package/mac80211/patches/800-b43-gpio-mask-module-option.patch +index fc874ad..e4d2f44 100644 +--- a/package/mac80211/patches/800-b43-gpio-mask-module-option.patch ++++ b/package/mac80211/patches/800-b43-gpio-mask-module-option.patch +@@ -22,7 +22,7 @@ + static int modparam_bad_frames_preempt; + module_param_named(bad_frames_preempt, modparam_bad_frames_preempt, int, 0444); + MODULE_PARM_DESC(bad_frames_preempt, +-@@ -2747,10 +2752,10 @@ static int b43_gpio_init(struct b43_wlde ++@@ -2739,10 +2744,10 @@ static int b43_gpio_init(struct b43_wlde + u32 mask, set; + + b43_maskset32(dev, B43_MMIO_MACCTL, ~B43_MACCTL_GPOUTSMSK, 0); +diff --git a/package/mac80211/patches/810-b43_no_pio.patch b/package/mac80211/patches/810-b43_no_pio.patch +index 5cd1b8b..bc9fda2 100644 +--- a/package/mac80211/patches/810-b43_no_pio.patch ++++ b/package/mac80211/patches/810-b43_no_pio.patch +@@ -11,7 +11,7 @@ + b43-$(CPTCFG_B43_PCMCIA) += pcmcia.o + --- a/drivers/net/wireless/b43/main.c + +++ b/drivers/net/wireless/b43/main.c +-@@ -1915,10 +1915,12 @@ static void b43_do_interrupt_thread(stru ++@@ -1899,10 +1899,12 @@ static void b43_do_interrupt_thread(stru + dma_reason[0], dma_reason[1], + dma_reason[2], dma_reason[3], + dma_reason[4], dma_reason[5]); +@@ -75,12 +75,12 @@ + #endif /* B43_PIO_H_ */ + --- a/drivers/net/wireless/b43/Kconfig + +++ b/drivers/net/wireless/b43/Kconfig +-@@ -98,7 +98,7 @@ config B43_BCMA_PIO ++@@ -118,7 +118,7 @@ config B43_BCMA_PIO + default y + + config B43_PIO + - bool + + bool "Broadcom 43xx PIO support" +- depends on B43 ++ depends on B43 && B43_SSB + select SSB_BLOCKIO + default y +diff --git a/package/mac80211/patches/820-b43-add-antenna-control.patch b/package/mac80211/patches/820-b43-add-antenna-control.patch +index dea9830..b55c669 100644 +--- a/package/mac80211/patches/820-b43-add-antenna-control.patch ++++ b/package/mac80211/patches/820-b43-add-antenna-control.patch +@@ -1,6 +1,6 @@ + --- a/drivers/net/wireless/b43/main.c + +++ b/drivers/net/wireless/b43/main.c +-@@ -1562,7 +1562,7 @@ static void b43_write_beacon_template(st ++@@ -1546,7 +1546,7 @@ static void b43_write_beacon_template(st + len, ram_offset, shm_size_offset, rate); + + /* Write the PHY TX control parameters. */ +@@ -9,7 +9,7 @@ + antenna = b43_antenna_to_phyctl(antenna); + ctl = b43_shm_read16(dev, B43_SHM_SHARED, B43_SHM_SH_BEACPHYCTL); + /* We can't send beacons with short preamble. Would get PHY errors. */ +-@@ -3105,8 +3105,8 @@ static int b43_chip_init(struct b43_wlde ++@@ -3103,8 +3103,8 @@ static int b43_chip_init(struct b43_wlde + + /* Select the antennae */ + if (phy->ops->set_rx_antenna) +@@ -20,7 +20,7 @@ + + if (phy->type == B43_PHYTYPE_B) { + value16 = b43_read16(dev, 0x005E); +-@@ -3850,7 +3850,6 @@ static int b43_op_config(struct ieee8021 ++@@ -3796,7 +3796,6 @@ static int b43_op_config(struct ieee8021 + struct b43_wldev *dev; + struct b43_phy *phy; + struct ieee80211_conf *conf = &hw->conf; +@@ -28,7 +28,7 @@ + int err = 0; + bool reload_bss = false; + +-@@ -3904,11 +3903,9 @@ static int b43_op_config(struct ieee8021 ++@@ -3850,11 +3849,9 @@ static int b43_op_config(struct ieee8021 + } + + /* Antennas for RX and management frame TX. */ +@@ -42,7 +42,7 @@ + + if (wl->radio_enabled != phy->radio_on) { + if (wl->radio_enabled) { +-@@ -5041,6 +5038,47 @@ static int b43_op_get_survey(struct ieee ++@@ -4978,6 +4975,47 @@ static int b43_op_get_survey(struct ieee + return 0; + } + +@@ -90,7 +90,7 @@ + static const struct ieee80211_ops b43_hw_ops = { + .tx = b43_op_tx, + .conf_tx = b43_op_conf_tx, +-@@ -5062,6 +5100,8 @@ static const struct ieee80211_ops b43_hw ++@@ -4999,6 +5037,8 @@ static const struct ieee80211_ops b43_hw + .sw_scan_complete = b43_op_sw_scan_complete_notifier, + .get_survey = b43_op_get_survey, + .rfkill_poll = b43_rfkill_poll, +@@ -99,7 +99,7 @@ + }; + + /* Hard-reset the chip. Do not call this directly. +-@@ -5308,6 +5348,8 @@ static int b43_one_core_attach(struct b4 ++@@ -5239,6 +5279,8 @@ static int b43_one_core_attach(struct b4 + if (!wldev) + goto out; + +@@ -108,7 +108,7 @@ + wldev->use_pio = b43_modparam_pio; + wldev->dev = dev; + wldev->wl = wl; +-@@ -5398,6 +5440,9 @@ static struct b43_wl *b43_wireless_init( ++@@ -5329,6 +5371,9 @@ static struct b43_wl *b43_wireless_init( + + hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN; + +diff --git a/package/mac80211/patches/830-b43-workaround-pcie-bcm4716.patch b/package/mac80211/patches/830-b43-workaround-pcie-bcm4716.patch +index e76758c..86b61fc 100644 +--- a/package/mac80211/patches/830-b43-workaround-pcie-bcm4716.patch ++++ b/package/mac80211/patches/830-b43-workaround-pcie-bcm4716.patch +@@ -19,7 +19,7 @@ Signed-off-by: Hauke Mehrtens + + --- a/drivers/net/wireless/b43/b43.h + +++ b/drivers/net/wireless/b43/b43.h +-@@ -1061,6 +1061,31 @@ static inline bool b43_using_pio_transfe ++@@ -1054,6 +1054,31 @@ static inline bool b43_using_pio_transfe + return dev->__using_pio_transfers; + } + +@@ -53,9 +53,9 @@ Signed-off-by: Hauke Mehrtens + __printf(2, 3) void b43err(struct b43_wl *wl, const char *fmt, ...); + --- a/drivers/net/wireless/b43/bus.h + +++ b/drivers/net/wireless/b43/bus.h +-@@ -60,6 +60,16 @@ static inline bool b43_bus_host_is_sdio( +- return (dev->bus_type == B43_BUS_SSB && +- dev->sdev->bus->bustype == SSB_BUSTYPE_SDIO); ++@@ -70,6 +70,16 @@ static inline bool b43_bus_host_is_sdio( ++ return false; ++ #endif + } + +static inline bool b43_bus_host_is_pci(struct b43_bus_dev *dev) + +{ +@@ -72,7 +72,7 @@ Signed-off-by: Hauke Mehrtens + struct b43_bus_dev *b43_bus_dev_ssb_init(struct ssb_device *sdev); + --- a/drivers/net/wireless/b43/main.c + +++ b/drivers/net/wireless/b43/main.c +-@@ -4437,7 +4437,7 @@ static int b43_phy_versioning(struct b43 ++@@ -4370,7 +4370,7 @@ static int b43_phy_versioning(struct b43 + u16 radio24[3]; + + for (tmp = 0; tmp < 3; tmp++) { +@@ -81,7 +81,7 @@ Signed-off-by: Hauke Mehrtens + radio24[tmp] = b43_read16(dev, B43_MMIO_RADIO24_DATA); + } + +-@@ -4456,10 +4456,10 @@ static int b43_phy_versioning(struct b43 ++@@ -4389,10 +4389,10 @@ static int b43_phy_versioning(struct b43 + else + tmp = 0x5205017F; + } else { +@@ -96,7 +96,7 @@ Signed-off-by: Hauke Mehrtens + << 16; + --- a/drivers/net/wireless/b43/phy_common.c + +++ b/drivers/net/wireless/b43/phy_common.c +-@@ -266,6 +266,12 @@ void b43_phy_write(struct b43_wldev *dev ++@@ -267,6 +267,12 @@ void b43_phy_write(struct b43_wldev *dev + { + assert_mac_suspended(dev); + dev->phy.ops->phy_write(dev, reg, value); +@@ -197,7 +197,7 @@ Signed-off-by: Hauke Mehrtens + + --- a/drivers/net/wireless/b43/phy_n.c + +++ b/drivers/net/wireless/b43/phy_n.c +-@@ -5418,14 +5418,14 @@ static inline void check_phyreg(struct b ++@@ -5641,14 +5641,14 @@ static inline void check_phyreg(struct b + static u16 b43_nphy_op_read(struct b43_wldev *dev, u16 reg) + { + check_phyreg(dev, reg); +@@ -214,7 +214,7 @@ Signed-off-by: Hauke Mehrtens + b43_write16(dev, B43_MMIO_PHY_DATA, value); + } + +-@@ -5433,7 +5433,7 @@ static void b43_nphy_op_maskset(struct b ++@@ -5656,7 +5656,7 @@ static void b43_nphy_op_maskset(struct b + u16 set) + { + check_phyreg(dev, reg); +@@ -223,16 +223,16 @@ Signed-off-by: Hauke Mehrtens + b43_maskset16(dev, B43_MMIO_PHY_DATA, mask, set); + } + +-@@ -5444,7 +5444,7 @@ static u16 b43_nphy_op_radio_read(struct +- /* N-PHY needs 0x100 for read access */ +- reg |= 0x100; ++@@ -5670,7 +5670,7 @@ static u16 b43_nphy_op_radio_read(struct ++ else ++ reg |= 0x100; + + - b43_write16(dev, B43_MMIO_RADIO_CONTROL, reg); + + b43_wflush16(dev, B43_MMIO_RADIO_CONTROL, reg); + return b43_read16(dev, B43_MMIO_RADIO_DATA_LOW); + } + +-@@ -5453,7 +5453,7 @@ static void b43_nphy_op_radio_write(stru ++@@ -5679,7 +5679,7 @@ static void b43_nphy_op_radio_write(stru + /* Register 1 is a 32-bit register. */ + B43_WARN_ON(reg == 1); + +diff --git a/package/mac80211/patches/845-b43-only-use-gpio-0-1-for-led.patch b/package/mac80211/patches/845-b43-only-use-gpio-0-1-for-led.patch +index 50347cd..8555ccf 100644 +--- a/package/mac80211/patches/845-b43-only-use-gpio-0-1-for-led.patch ++++ b/package/mac80211/patches/845-b43-only-use-gpio-0-1-for-led.patch +@@ -1,6 +1,6 @@ + --- a/drivers/net/wireless/b43/main.c + +++ b/drivers/net/wireless/b43/main.c +-@@ -2764,6 +2764,14 @@ static int b43_gpio_init(struct b43_wlde ++@@ -2756,6 +2756,14 @@ static int b43_gpio_init(struct b43_wlde + } else if (dev->dev->chip_id == 0x5354) { + /* Don't allow overtaking buttons GPIOs */ + set &= 0x2; /* 0x2 is LED GPIO on BCM5354 */ diff --git a/package/mac80211/patches/900-wl1251-split-wl251-platform-data-to-a-separate-structure.patch b/package/mac80211/patches/900-wl1251-split-wl251-platform-data-to-a-separate-structure.patch deleted file mode 100644 index a8af257..0000000 @@ -10774,7 +14841,7 @@ index a8af257..0000000 - int ret; diff --git a/package/mac80211/patches/900-wlcore-Add-support-for-DT-platform-data.patch b/package/mac80211/patches/900-wlcore-Add-support-for-DT-platform-data.patch new file mode 100644 -index 0000000..967768a +index 0000000..856dea8 --- /dev/null +++ b/package/mac80211/patches/900-wlcore-Add-support-for-DT-platform-data.patch @@ -0,0 +1,139 @@ @@ -10868,22 +14935,22 @@ index 0000000..967768a + static int wl1271_probe(struct sdio_func *func, + const struct sdio_device_id *id) + { -+@@ -248,12 +304,9 @@ static int wl1271_probe(struct sdio_func ++@@ -245,10 +301,10 @@ static int wl1271_probe(struct sdio_func + /* Use block mode for transferring over one block size of data */ + func->card->quirks |= MMC_QUIRK_BLKSZ_FOR_BYTE_MODE; + -+- pdev_data->pdata = wl12xx_get_platform_data(); -+- if (IS_ERR(pdev_data->pdata)) { -+- ret = PTR_ERR(pdev_data->pdata); ++- pdev_data.pdata = wl12xx_get_platform_data(); ++- if (IS_ERR(pdev_data.pdata)) { ++- ret = PTR_ERR(pdev_data.pdata); +- dev_err(glue->dev, "missing wlan platform data: %d\n", ret); -++ pdev_data->pdata = get_platform_data(&func->dev); -++ if (!(pdev_data->pdata)) +++ pdev_data.pdata = get_platform_data(&func->dev); +++ if (!pdev_data.pdata) { +++ ret = -EINVAL; +++ dev_err(glue->dev, "missing wlan platform data\n"); + goto out_free_glue; -+- } ++ } + -+ /* if sdio can keep power while host is suspended, enable wow */ -+ mmcflags = sdio_get_host_pm_caps(func); -+@@ -282,7 +335,7 @@ static int wl1271_probe(struct sdio_func ++@@ -279,7 +335,7 @@ static int wl1271_probe(struct sdio_func + if (!glue->core) { + dev_err(glue->dev, "can't allocate platform_device"); + ret = -ENOMEM; @@ -10892,7 +14959,7 @@ index 0000000..967768a + } + + glue->core->dev.parent = &func->dev; -+@@ -316,6 +369,9 @@ static int wl1271_probe(struct sdio_func ++@@ -313,6 +369,9 @@ static int wl1271_probe(struct sdio_func + out_dev_put: + platform_device_put(glue->core); + @@ -10902,7 +14969,7 @@ index 0000000..967768a + out_free_glue: + kfree(glue); + -+@@ -329,11 +385,14 @@ out: ++@@ -323,11 +382,14 @@ out: + static void wl1271_remove(struct sdio_func *func) + { + struct wl12xx_sdio_glue *glue = sdio_get_drvdata(func); @@ -10917,59 +14984,48 @@ index 0000000..967768a + kfree(glue); + } + -diff --git a/package/mac80211/patches/901-wl18xx-align-event-mailbox-with-current-fw.patch b/package/mac80211/patches/901-wl18xx-align-event-mailbox-with-current-fw.patch +diff --git a/package/mac80211/patches/901-wlcore-don-t-switch-channels-on-disconnected-STA-vif.patch b/package/mac80211/patches/901-wlcore-don-t-switch-channels-on-disconnected-STA-vif.patch new file mode 100644 -index 0000000..77647bb +index 0000000..d90508e --- /dev/null -+++ b/package/mac80211/patches/901-wl18xx-align-event-mailbox-with-current-fw.patch -@@ -0,0 +1,47 @@ -+From fde3f0a7f3112527a18e06e32efdd9a354c91b02 Mon Sep 17 00:00:00 2001 -+From: Eliad Peller -+Date: Tue, 18 Mar 2014 13:19:48 +0200 -+Subject: [PATCH] wl18xx: align event mailbox with current fw ++++ b/package/mac80211/patches/901-wlcore-don-t-switch-channels-on-disconnected-STA-vif.patch +@@ -0,0 +1,36 @@ ++From 4101e8dc540d19f1f6c24930629149191786e4cd Mon Sep 17 00:00:00 2001 ++From: Arik Nemtsov ++Date: Mon, 9 Sep 2013 16:48:59 +0300 ++Subject: [PATCH 27/75] wlcore: don't switch channels on disconnected STA vifs + -+Some fields are missing from the event mailbox -+struct definitions, which cause issues when -+trying to handle some events. ++Sending the FW a channel switch command on a disconnected vif may result ++in a beacon loss event. Avoid this edge case. + -+Add the missing fields in order to align the -+struct size (without adding actual support -+for the new fields). -+ -+Signed-off-by: Eliad Peller ++Signed-off-by: Arik Nemtsov +--- -+ drivers/net/wireless/ti/wl18xx/event.h | 20 ++++++++++++++++++++ -+ 1 file changed, 20 insertions(+) ++ drivers/net/wireless/ti/wlcore/main.c | 7 +++++++ ++ 1 file changed, 7 insertions(+) + -+--- a/drivers/net/wireless/ti/wl18xx/event.h -++++ b/drivers/net/wireless/ti/wl18xx/event.h -+@@ -68,6 +68,26 @@ struct wl18xx_event_mailbox { ++--- a/drivers/net/wireless/ti/wlcore/main.c +++++ b/drivers/net/wireless/ti/wlcore/main.c ++@@ -5148,6 +5148,10 @@ static void wl12xx_op_channel_switch(str ++ if (unlikely(wl->state == WLCORE_STATE_OFF)) { ++ wl12xx_for_each_wlvif_sta(wl, wlvif) { ++ struct ieee80211_vif *vif = wl12xx_wlvif_to_vif(wlvif); +++ +++ if (!test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags)) +++ continue; +++ ++ ieee80211_chswitch_done(vif, false); ++ } ++ goto out; ++@@ -5163,6 +5167,9 @@ static void wl12xx_op_channel_switch(str ++ wl12xx_for_each_wlvif_sta(wl, wlvif) { ++ unsigned long delay_usec; + -+ /* bitmap of inactive stations (by HLID) */ -+ __le32 inactive_sta_bitmap; +++ if (!test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags)) +++ continue; ++ -++ /* rx BA win size indicated by RX_BA_WIN_SIZE_CHANGE_EVENT_ID */ -++ u8 rx_ba_role_id; -++ u8 rx_ba_link_id; -++ u8 rx_ba_win_size; -++ u8 padding; -++ -++ /* smart config */ -++ u8 sc_ssid_len; -++ u8 sc_pwd_len; -++ u8 sc_token_len; -++ u8 padding1; -++ u8 sc_ssid[32]; -++ u8 sc_pwd[32]; -++ u8 sc_token[32]; -++ -++ /* smart config sync channel */ -++ u8 sc_sync_channel; -++ u8 sc_sync_band; -++ u8 padding2[2]; -+ } __packed; -+ -+ int wl18xx_wait_for_event(struct wl1271 *wl, enum wlcore_wait_event event, ++ ret = wl->ops->channel_switch(wl, wlvif, ch_switch); ++ if (ret) ++ goto out_sleep; diff --git a/package/mac80211/patches/901-wlcore-set-irq_flags-in-the-board-files.patch b/package/mac80211/patches/901-wlcore-set-irq_flags-in-the-board-files.patch deleted file mode 100644 index f2789a9..0000000 @@ -11094,48 +15150,6 @@ index f2789a9..0000000 - /* number of currently active RX BA sessions */ - int ba_rx_session_count; - -diff --git a/package/mac80211/patches/902-wlcore-don-t-switch-channels-on-disconnected-STA-vif.patch b/package/mac80211/patches/902-wlcore-don-t-switch-channels-on-disconnected-STA-vif.patch -new file mode 100644 -index 0000000..3d501b2 ---- /dev/null -+++ b/package/mac80211/patches/902-wlcore-don-t-switch-channels-on-disconnected-STA-vif.patch -@@ -0,0 +1,36 @@ -+From 4101e8dc540d19f1f6c24930629149191786e4cd Mon Sep 17 00:00:00 2001 -+From: Arik Nemtsov -+Date: Mon, 9 Sep 2013 16:48:59 +0300 -+Subject: [PATCH 27/75] wlcore: don't switch channels on disconnected STA vifs -+ -+Sending the FW a channel switch command on a disconnected vif may result -+in a beacon loss event. Avoid this edge case. -+ -+Signed-off-by: Arik Nemtsov -+--- -+ drivers/net/wireless/ti/wlcore/main.c | 7 +++++++ -+ 1 file changed, 7 insertions(+) -+ -+--- a/drivers/net/wireless/ti/wlcore/main.c -++++ b/drivers/net/wireless/ti/wlcore/main.c -+@@ -5181,6 +5181,10 @@ static void wl12xx_op_channel_switch(str -+ if (unlikely(wl->state == WLCORE_STATE_OFF)) { -+ wl12xx_for_each_wlvif_sta(wl, wlvif) { -+ struct ieee80211_vif *vif = wl12xx_wlvif_to_vif(wlvif); -++ -++ if (!test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags)) -++ continue; -++ -+ ieee80211_chswitch_done(vif, false); -+ } -+ goto out; -+@@ -5196,6 +5200,9 @@ static void wl12xx_op_channel_switch(str -+ wl12xx_for_each_wlvif_sta(wl, wlvif) { -+ unsigned long delay_usec; -+ -++ if (!test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags)) -++ continue; -++ -+ ret = wl->ops->channel_switch(wl, wlvif, ch_switch); -+ if (ret) -+ goto out_sleep; diff --git a/package/mac80211/patches/902-wlcore-remove-pwr_in_suspend-from-platform-data.patch b/package/mac80211/patches/902-wlcore-remove-pwr_in_suspend-from-platform-data.patch deleted file mode 100644 index 6394377..0000000 @@ -11705,3 +15719,37 @@ index 6b09177..0000000 - glue->tcxoclock = NULL; - } else { - clk_prepare_enable(glue->tcxoclock); +diff --git a/package/mac80211/patches/a01-compat_fix_compile.patch b/package/mac80211/patches/a01-compat_fix_compile.patch +new file mode 100644 +index 0000000..9e9e6c7 +--- /dev/null ++++ b/package/mac80211/patches/a01-compat_fix_compile.patch +@@ -0,0 +1,15 @@ ++--- a/compat/compat-3.6.c +++++ b/compat/compat-3.6.c ++@@ -148,6 +148,7 @@ int sg_alloc_table_from_pages(struct sg_ ++ } ++ EXPORT_SYMBOL_GPL(sg_alloc_table_from_pages); ++ +++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0)) ++ /* whoopsie ! */ ++ #ifndef CONFIG_COMMON_CLK ++ int clk_enable(struct clk *clk) ++@@ -161,3 +162,4 @@ void clk_disable(struct clk *clk) ++ } ++ EXPORT_SYMBOL_GPL(clk_disable); ++ #endif +++#endif +diff --git a/target/linux/generic/files/include/linux/ath9k_platform.h b/target/linux/generic/files/include/linux/ath9k_platform.h +index a0b7531..03aa636 100644 +--- a/target/linux/generic/files/include/linux/ath9k_platform.h ++++ b/target/linux/generic/files/include/linux/ath9k_platform.h +@@ -39,6 +39,8 @@ struct ath9k_platform_data { + int (*get_mac_revision)(void); + int (*external_reset)(void); + ++ bool use_eeprom; ++ + int num_leds; + const struct gpio_led *leds; + };