From 4e155c80d3d8811e19effa7f173a863f6b22f4bf Mon Sep 17 00:00:00 2001
From: Felix Fietkau <nbd@openwrt.org>
Date: Sun, 6 Apr 2014 10:41:23 +0000
Subject: [PATCH] mac80211: update to wireless-testing 2014-03-31

Signed-off-by: Felix Fietkau <nbd@openwrt.org>

SVN-Revision: 40393
---
 package/kernel/mac80211/Makefile              |    6 +-
 ...ports-add-led_trigger_blink-_oneshot.patch |    4 +-
 ...-make-genregdb.awk-skip-antenna-gain.patch |    8 +-
 .../patches/060-no_local_ssb_bcma.patch       |    2 +-
 .../patches/100-revert_aes_ccm_port.patch     |  202 +-
 .../patches/150-disable_addr_notifier.patch   |    6 +-
 .../mac80211/patches/300-pending_work.patch   | 4142 -----------------
 .../kernel/mac80211/patches/310-ap_scan.patch |    2 +-
 .../patches/400-ath_move_debug_code.patch     |    2 +-
 ...h9k-fix-invalid-mac-address-handling.patch |    2 +-
 .../patches/403-ath_regd_optional.patch       |    2 +-
 .../patches/405-regd_no_assoc_hints.patch     |    4 +-
 .../410-ath9k_allow_adhoc_and_ap.patch        |    2 +-
 .../411-ath5k_allow_adhoc_and_ap.patch        |    6 +-
 .../patches/500-ath9k_eeprom_debugfs.patch    |    4 +-
 .../patches/501-ath9k-eeprom_endianess.patch  |    2 +-
 .../mac80211/patches/502-ath9k_ahb_init.patch |   14 +-
 .../510-ath9k_intr_mitigation_tweak.patch     |    2 +-
 .../patches/511-ath9k_reduce_rxbuf.patch      |    2 +-
 .../patches/512-ath9k_channelbw_debugfs.patch |   16 +-
 .../patches/513-ath9k_add_pci_ids.patch       |    2 +-
 .../patches/520-mac80211_cur_txpower.patch    |    4 +-
 .../patches/521-ath9k_cur_txpower.patch       |    2 +-
 .../522-mac80211_configure_antenna_gain.patch |   50 +-
 ...23-ath9k_use_configured_antenna_gain.patch |    6 +-
 .../patches/530-ath9k_extra_leds.patch        |   14 +-
 .../patches/542-ath9k_debugfs_diag.patch      |   10 +-
 ...w-to-disable-bands-via-platform-data.patch |    4 +-
 .../patches/550-ath9k_entropy_from_adc.patch  |   10 +-
 .../patches/551-ath9k_p2p_ifcomb.patch        |    2 +-
 .../patches/552-ath9k_p2p_ps_support.patch    |   38 +-
 ...566-ath9k-ar933x-usb-hang-workaround.patch |   10 +-
 .../603-rt2x00-introduce-rt2x00eeprom.patch   |    2 +-
 .../611-rt2x00-rf_vals-rt3352-xtal20.patch    |    6 +-
 .../patches/615-rt2x00-fix_20mhz_clk.patch    |    2 +-
 .../patches/616-rt2x00-support-rt5350.patch   |    6 +-
 ...700-mwl8k-missing-pci-id-for-WNR854T.patch |    2 +-
 ...align-event-mailbox-with-current-fw.patch} |    5 -
 ...ilter_enabled-to-zero-after-recovery.patch |   73 -
 ...dog-on-~-and-rearm-on-first-Tx-after.patch |   73 -
 ...ch-channels-on-disconnected-STA-vif.patch} |    4 +-
 ...e-block-read-writes-to-FW-during-ELP.patch |   36 -
 ...-start-mac80211-PS-on-non-peer-HLIDs.patch |   28 -
 ...x-wl18xx-simplify-fw_status-handling.patch |  731 ---
 ...xx-wl18xx-configure-num_links-per-hw.patch |  345 --
 ...wl18xx-configure-max_stations-per-hw.patch |  110 -
 ...-configure-iface_combinations-per-hw.patch |  176 -
 ...move-to-new-firmware-wl18xx-fw-3.bin.patch |  200 -
 ...end-EAPOL-frames-with-voice-priority.patch |   37 -
 ...stop-sched_scan-on-interface-removal.patch |   25 -
 ...e-wl18xx-allow-CCK-rates-for-AP-mode.patch |   47 -
 ...-handle-unsetting-of-default-wep-key.patch |   28 -
 ...-APs-when-checking-active_link_count.patch |   51 -
 ...se-warning-verbosity-during-recovery.patch |   42 -
 ...lcore-increase-timeout-to-5000-msecs.patch |   21 -
 ...tering-only-after-receiving-a-beacon.patch |   71 -
 ...pport-for-STA-CSA-with-chan-contexts.patch |   22 -
 57 files changed, 231 insertions(+), 6494 deletions(-)
 rename package/kernel/mac80211/patches/{919-wl18xx-align-event-mailbox-with-current-fw.patch => 901-wl18xx-align-event-mailbox-with-current-fw.patch} (89%)
 delete mode 100644 package/kernel/mac80211/patches/901-wlcore-memset-wl--rx_filter_enabled-to-zero-after-recovery.patch
 delete mode 100644 package/kernel/mac80211/patches/902-wlcore-cancel-Tx-watchdog-on-~-and-rearm-on-first-Tx-after.patch
 rename package/kernel/mac80211/patches/{920-wlcore-don-t-switch-channels-on-disconnected-STA-vif.patch => 902-wlcore-don-t-switch-channels-on-disconnected-STA-vif.patch} (89%)
 delete mode 100644 package/kernel/mac80211/patches/903-wlcore-block-read-writes-to-FW-during-ELP.patch
 delete mode 100644 package/kernel/mac80211/patches/904-wlcore-AP-don-t-start-mac80211-PS-on-non-peer-HLIDs.patch
 delete mode 100644 package/kernel/mac80211/patches/905-wlcore-wl12xx-wl18xx-simplify-fw_status-handling.patch
 delete mode 100644 package/kernel/mac80211/patches/906-wlcore-wl12xx-wl18xx-configure-num_links-per-hw.patch
 delete mode 100644 package/kernel/mac80211/patches/907-wlcore-wl12xx-wl18xx-configure-max_stations-per-hw.patch
 delete mode 100644 package/kernel/mac80211/patches/908-wlcore-wl12xx-wl18xx-configure-iface_combinations-per-hw.patch
 delete mode 100644 package/kernel/mac80211/patches/909-wl18xx-move-to-new-firmware-wl18xx-fw-3.bin.patch
 delete mode 100644 package/kernel/mac80211/patches/910-wlcore-send-EAPOL-frames-with-voice-priority.patch
 delete mode 100644 package/kernel/mac80211/patches/911-wlcore-don-t-stop-sched_scan-on-interface-removal.patch
 delete mode 100644 package/kernel/mac80211/patches/912-wlcore-wl18xx-allow-CCK-rates-for-AP-mode.patch
 delete mode 100644 package/kernel/mac80211/patches/913-wlcore-don-t-handle-unsetting-of-default-wep-key.patch
 delete mode 100644 package/kernel/mac80211/patches/914-wlcore-consider-multiple-APs-when-checking-active_link_count.patch
 delete mode 100644 package/kernel/mac80211/patches/915-wlcore-decrease-warning-verbosity-during-recovery.patch
 delete mode 100644 package/kernel/mac80211/patches/916-wlcore-increase-timeout-to-5000-msecs.patch
 delete mode 100644 package/kernel/mac80211/patches/917-wlcore-enable-beacon-filtering-only-after-receiving-a-beacon.patch
 delete mode 100644 package/kernel/mac80211/patches/918-wlcore-add-support-for-STA-CSA-with-chan-contexts.patch

diff --git a/package/kernel/mac80211/Makefile b/package/kernel/mac80211/Makefile
index 8d49d7ee91..40f08e218c 100644
--- a/package/kernel/mac80211/Makefile
+++ b/package/kernel/mac80211/Makefile
@@ -10,11 +10,11 @@ include $(INCLUDE_DIR)/kernel.mk
 
 PKG_NAME:=mac80211
 
-PKG_VERSION:=2014-01-23.1
-PKG_RELEASE:=4
+PKG_VERSION:=2014-03-31
+PKG_RELEASE:=1
 PKG_SOURCE_URL:=http://mirror2.openwrt.org/sources
 PKG_BACKPORT_VERSION:=
-PKG_MD5SUM:=8db16edbdaf4abc2e9c2f3b6c86736a6
+PKG_MD5SUM:=8b5cf82d6defc5867511014af4afc0b6
 
 PKG_SOURCE:=compat-wireless-$(PKG_VERSION)$(PKG_BACKPORT_VERSION).tar.bz2
 PKG_BUILD_DIR:=$(KERNEL_BUILD_DIR)/compat-wireless-$(PKG_VERSION)
diff --git a/package/kernel/mac80211/patches/004-backports-add-led_trigger_blink-_oneshot.patch b/package/kernel/mac80211/patches/004-backports-add-led_trigger_blink-_oneshot.patch
index 584fb05ff5..8d97224a6a 100644
--- a/package/kernel/mac80211/patches/004-backports-add-led_trigger_blink-_oneshot.patch
+++ b/package/kernel/mac80211/patches/004-backports-add-led_trigger_blink-_oneshot.patch
@@ -18,8 +18,8 @@ Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
 
 --- a/backport-include/backport/leds-disabled.h
 +++ b/backport-include/backport/leds-disabled.h
-@@ -163,6 +163,19 @@ static inline void led_trigger_event(str
- 				     enum led_brightness event)
+@@ -176,6 +176,19 @@ static inline void led_trigger_blink_one
+ 					     int invert)
  {
  }
 +
diff --git a/package/kernel/mac80211/patches/005-make-genregdb.awk-skip-antenna-gain.patch b/package/kernel/mac80211/patches/005-make-genregdb.awk-skip-antenna-gain.patch
index 5ee2d14b18..55bffbc451 100644
--- a/package/kernel/mac80211/patches/005-make-genregdb.awk-skip-antenna-gain.patch
+++ b/package/kernel/mac80211/patches/005-make-genregdb.awk-skip-antenna-gain.patch
@@ -32,10 +32,10 @@ Signed-off-by: Luis R. Rodriguez <mcgrof@do-not-panic.com>
 +	units = $7
  	sub(/\)/, "", units)
  	sub(/,/, "", units)
- 	if (units == "mW") {
-@@ -80,7 +77,7 @@ function parse_reg_rule()
- 		}
- 	}
+ 	dfs_cac = $9
+@@ -86,7 +83,7 @@ function parse_reg_rule()
+ 	sub(/\(/, "", dfs_cac)
+ 	sub(/\)/, "", dfs_cac)
  	flagstr = ""
 -	for (i=8; i<=NF; i++)
 +	for (i=7; i<=NF; i++)
diff --git a/package/kernel/mac80211/patches/060-no_local_ssb_bcma.patch b/package/kernel/mac80211/patches/060-no_local_ssb_bcma.patch
index f4b9470627..95f14f436e 100644
--- a/package/kernel/mac80211/patches/060-no_local_ssb_bcma.patch
+++ b/package/kernel/mac80211/patches/060-no_local_ssb_bcma.patch
@@ -1,6 +1,6 @@
 --- a/.local-symbols
 +++ b/.local-symbols
-@@ -379,42 +379,6 @@ USB_CDC_PHONET=
+@@ -402,42 +402,6 @@ USB_CDC_PHONET=
  USB_IPHETH=
  USB_SIERRA_NET=
  USB_VL600=
diff --git a/package/kernel/mac80211/patches/100-revert_aes_ccm_port.patch b/package/kernel/mac80211/patches/100-revert_aes_ccm_port.patch
index 4654bc8ea4..ac7d6b3495 100644
--- a/package/kernel/mac80211/patches/100-revert_aes_ccm_port.patch
+++ b/package/kernel/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)
- {
- 	__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
-@@ -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;
- }
-@@ -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 */
--		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;
- 	}
- 
diff --git a/package/kernel/mac80211/patches/150-disable_addr_notifier.patch b/package/kernel/mac80211/patches/150-disable_addr_notifier.patch
index 7b50154e86..3f749e9bfd 100644
--- a/package/kernel/mac80211/patches/150-disable_addr_notifier.patch
+++ b/package/kernel/mac80211/patches/150-disable_addr_notifier.patch
@@ -18,7 +18,7 @@
  static int ieee80211_ifa6_changed(struct notifier_block *nb,
  				  unsigned long data, void *arg)
  {
-@@ -1031,14 +1031,14 @@ int ieee80211_register_hw(struct ieee802
+@@ -1036,14 +1036,14 @@ int ieee80211_register_hw(struct ieee802
  		goto fail_pm_qos;
  	}
  
@@ -35,7 +35,7 @@
  	local->ifa6_notifier.notifier_call = ieee80211_ifa6_changed;
  	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
  
  	return 0;
  
@@ -52,7 +52,7 @@
   fail_ifa:
  	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
  
  	pm_qos_remove_notifier(PM_QOS_NETWORK_LATENCY,
  			       &local->network_latency_notifier);
diff --git a/package/kernel/mac80211/patches/300-pending_work.patch b/package/kernel/mac80211/patches/300-pending_work.patch
index 1da7941d21..e69de29bb2 100644
--- a/package/kernel/mac80211/patches/300-pending_work.patch
+++ b/package/kernel/mac80211/patches/300-pending_work.patch
@@ -1,4142 +0,0 @@
-commit 584d297fd29fb39c76af25ae74ff9d5fe74c8a14
-Author: Helmut Schaa <helmut.schaa@googlemail.com>
-Date:   Wed Mar 12 10:37:55 2014 +0100
-
-    ath9k: Fix sequence number assignment for non-data frames
-    
-    Since commit 558ff225de80ac95b132d3a115ddadcd64498b4f (ath9k: fix
-    ps-poll responses under a-mpdu sessions) non-data frames would have
-    gotten a sequence number from a TIDs sequence counter instead of
-    using the global sequence counter.
-    
-    This can lead to instable connections.
-    
-    To fix this only select the correct TID if we are processing a
-    data frame. Furthermore, prevent non-data frames to get a sequence
-    number from a TID sequence counter by adding a check to
-    ath_tx_setup_buffer.
-    
-    Cc: Felix Fietkau <nbd@openwrt.org>
-    Signed-off-by: Helmut Schaa <helmut.schaa@googlemail.com>
-
-commit 3a0f984b1cdcd6a9f8c441635ef3b05d58547f4e
-Author: Felix Fietkau <nbd@openwrt.org>
-Date:   Tue Mar 11 14:03:32 2014 +0100
-
-    ath9k_hw: set ANI firstep as absolute values instead of relative
-    
-    On older chips, the INI value differ in similar ways as cycpwr_thr1, so
-    convert it to absolute values as well.
-    
-    Since the ANI algorithm is different here compared to the old
-    implementation (fewer steps, controlled at a different point in time),
-    it makes sense to use values similar to what would be applied for newer
-    chips, just without relying on INI defaults.
-    
-    Signed-off-by: Felix Fietkau <nbd@openwrt.org>
-
-commit 91d70d40400c569b49605b78fd7c43e9405694f4
-Author: Felix Fietkau <nbd@openwrt.org>
-Date:   Tue Mar 11 14:00:37 2014 +0100
-
-    ath9k_hw: set ANI cycpwr_thr1 as absolute values instead of relative
-    
-    The table was copied from the ANI implementation of AR9300. It assumes
-    that the INI values contain a baseline value that is usable as reference
-    from which to increase/decrease based on the noise immunity value.
-    
-    On older chips, the differences are bigger and especially AR5008/AR9001
-    are configured to much more sensitive values than what is useful.
-    
-    Improve ANI behavior by reverting to the absolute values used in the
-    previous implementation (expressed as a simple formula instead of the
-    old table).
-    
-    Signed-off-by: Felix Fietkau <nbd@openwrt.org>
-
-commit c977493766310a825f406836636ffd66e1447783
-Author: Felix Fietkau <nbd@openwrt.org>
-Date:   Mon Mar 10 19:52:56 2014 +0100
-
-    ath9k_hw: remove ANI function restrictions for AP mode
-    
-    The primary purpose of this piece of code was to selectively disable
-    OFDM weak signal detection. The checks for this are elsewhere, and an
-    earlier commit relaxed the restrictions for older chips, which are more
-    sensitive to interference.
-    
-    Signed-off-by: Felix Fietkau <nbd@openwrt.org>
-
-commit 8d804f1af11e4e058b1e8453327777d73a585cb8
-Author: Felix Fietkau <nbd@openwrt.org>
-Date:   Sun Mar 9 11:25:43 2014 +0100
-
-    ath9k: clean up and enhance ANI debugfs file
-    
-    Unify scnprintf calls and include the current OFDM/CCK immunity level.
-    
-    Signed-off-by: Felix Fietkau <nbd@openwrt.org>
-
-commit 22e298b5a3a8a49e33805d4e351965123dede35b
-Author: Felix Fietkau <nbd@openwrt.org>
-Date:   Sun Mar 9 10:58:47 2014 +0100
-
-    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.
-    
-    This should hopefully fix some Tx DMA issues with buffered multicast
-    frames in AP mode.
-    
-    Cc: stable@vger.kernel.org
-    Signed-off-by: Felix Fietkau <nbd@openwrt.org>
-
-commit fcb064fdd5a27bec8d24099bc0172468f34c97cb
-Author: Felix Fietkau <nbd@openwrt.org>
-Date:   Sun Mar 9 09:43:09 2014 +0100
-
-    ath9k_hw: fix unreachable code in baseband hang detection code
-    
-    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.
-    
-    Reported-by: Dan Carpenter <dan.carpenter@oracle.com>
-    Signed-off-by: Felix Fietkau <nbd@openwrt.org>
-
-commit 31959d8df39319e32c6d5ba9c135727be90cfad7
-Author: Michal Kazior <michal.kazior@tieto.com>
-Date:   Fri Mar 7 08:09:38 2014 +0100
-
-    mac80211: fix possible NULL dereference
-    
-    If chanctx is missing on a given vif then the band
-    is assumed to be 2GHz. However if hw doesn't
-    support 2GHz band then mac80211 ended up with a
-    NULL dereference.
-    
-    This fixes a splat:
-    
-    [ 4605.207223] BUG: unable to handle kernel NULL pointer dereference at 0000000000000018
-    [ 4605.210789] IP: [<ffffffffa07b5635>] ieee80211_parse_bitrates+0x65/0x110 [mac80211]
-    
-    The splat was preceeded by WARN_ON(!chanctx_conf)
-    in ieee80211_get_sdata_band().
-    
-    Signed-off-by: Michal Kazior <michal.kazior@tieto.com>
-
-commit 6c5a3ffa0a2d22c091a2717f427259bacf77ac5e
-Author: Michael Braun <michael-dev@fami-braun.de>
-Date:   Thu Mar 6 15:08:43 2014 +0100
-
-    mac80211: fix WPA with VLAN on AP side with ps-sta again
-    
-    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.
-    
-    commit "7cbf9d017dbb5e3276de7d527925d42d4c11e732"
-      "mac80211: fix oops on mesh PS broadcast forwarding"
-    essentially reverted it, because vif.type cannot be AP_VLAN
-    due to the check to vif.type in ieee80211_get_buffered_bc before.
-    
-    As the later commit intended to fix the MESH case, fix it
-    by checking for IFTYPE_AP instead of IFTYPE_AP_VLAN.
-    
-    Fixes: 7cbf9d017dbb
-    Cc: <stable@vger.kernel.org> # 3.10.x
-    Cc: <stable@vger.kernel.org> # 3.11.x
-    Cc: <stable@vger.kernel.org> # 3.12.x
-    Cc: <stable@vger.kernel.org> # 3.13.x
-    Cc: <linux-wireless@vger.kernel.org>
-    Cc: <projekt-wlan@fem.tu-ilmenau.de>
-    Signed-off-by: Michael Braun <michael-dev@fami-braun.de>
-
-commit 9d6ab9bdb9b368a6cf9519f0f92509b5b2c297ec
-Author: Johannes Berg <johannes.berg@intel.com>
-Date:   Mon Mar 3 14:19:08 2014 +0100
-
-    cfg80211: remove racy beacon_interval assignment
-    
-    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.
-    
-    Reported-by: Michal Kazior <michal.kazior@tieto.com>
-    Signed-off-by: Johannes Berg <johannes.berg@intel.com>
-
-commit 1abdeca3c6fb9cf1f84f85e78ed8d1c33bd69db0
-Author: Felix Fietkau <nbd@openwrt.org>
-Date:   Fri Feb 28 18:52:56 2014 +0100
-
-    ath9k_hw: tweak noise immunity thresholds for older chipsets
-    
-    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.
-    
-    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.
-    
-    Signed-off-by: Felix Fietkau <nbd@openwrt.org>
-
-commit 431e506da5953adc3b65af25f4b90873d528c115
-Author: Felix Fietkau <nbd@openwrt.org>
-Date:   Fri Feb 28 18:44:13 2014 +0100
-
-    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".
-    
-    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.
-    
-    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.
-    
-    Signed-off-by: Felix Fietkau <nbd@openwrt.org>
-
-commit 98d1a6c5b14688ed030e81b889f607be308e0df9
-Author: Felix Fietkau <nbd@openwrt.org>
-Date:   Mon Feb 24 22:20:32 2014 +0100
-
-    ath9k: fix invalid descriptor discarding
-    
-    Only set sc->rx.discard_next to rx_stats->rs_more when actually
-    discarding the current descriptor.
-    
-    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.
-    
-    This fixes a regression introduced in
-    commit 723e711356b5a8a95728a890e254e8b0d47b55cf
-    "ath9k: fix handling of broken descriptors"
-    
-    Cc: stable@vger.kernel.org
-    Reported-by: Marco André Dinis <marcoandredinis@gmail.com>
-    Signed-off-by: Felix Fietkau <nbd@openwrt.org>
-
-commit 52a46300e782fe6994466523eb2b0b59091ea59f
-Author: Felix Fietkau <nbd@openwrt.org>
-Date:   Mon Feb 24 11:43:50 2014 +0100
-
-    ath9k: reduce baseband hang detection false positive rate
-    
-    Check if the baseband state remains stable, and add a small delay
-    between register reads.
-    
-    Signed-off-by: Felix Fietkau <nbd@openwrt.org>
-
-commit 118945bb12082e9d4edddc868d88143164e0f440
-Author: Felix Fietkau <nbd@openwrt.org>
-Date:   Sat Feb 22 14:55:23 2014 +0100
-
-    ath5k: set SURVEY_INFO_IN_USE on get_survey
-    
-    Only one channel is returned - the one currently being used.
-    
-    Signed-off-by: Felix Fietkau <nbd@openwrt.org>
-
-commit ee41f72476e1ea44283dfe1cbf75b9543a1e15c8
-Author: Felix Fietkau <nbd@openwrt.org>
-Date:   Sat Feb 22 14:44:52 2014 +0100
-
-    ath9k: make some hardware reset log messages debug-only
-    
-    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.
-    
-    Signed-off-by: Felix Fietkau <nbd@openwrt.org>
-
-commit b14fbb554fc65a2e0b5c41a319269b0350f187e7
-Author: Felix Fietkau <nbd@openwrt.org>
-Date:   Sat Feb 22 14:35:25 2014 +0100
-
-    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.
-    
-    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
-    
-    Signed-off-by: Felix Fietkau <nbd@openwrt.org>
-
-commit 0f1cb7be2551b30b02cd54c897e0e29e483cfda5
-Author: Felix Fietkau <nbd@openwrt.org>
-Date:   Sat Feb 22 13:43:29 2014 +0100
-
-    ath9k: fix ps-poll responses under a-mpdu sessions
-    
-    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.
-    
-    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 <nbd@openwrt.org>
-
-commit d5d87a37bbd6066b2c3c5d0bd0fe2a6e2ea45cc5
-Author: Felix Fietkau <nbd@openwrt.org>
-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 <nbd@openwrt.org>
-
-commit d84856012e0f10fe598a5ad3b7b869397a089e07
-Author: Johannes Berg <johannes.berg@intel.com>
-Date:   Thu Feb 20 11:19:58 2014 +0100
-
-    mac80211: fix station wakeup powersave race
-    
-    Consider the following (relatively unlikely) scenario:
-     1) station goes to sleep while frames are buffered in driver
-     2) driver blocks wakeup (until no more frames are buffered)
-     3) station wakes up again
-     4) driver unblocks wakeup
-    
-    In this case, the current mac80211 code will do the following:
-     1) WLAN_STA_PS_STA set
-     2) WLAN_STA_PS_DRIVER set
-     3) - nothing -
-     4) WLAN_STA_PS_DRIVER cleared
-    
-    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().
-    
-    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.
-    
-    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 <johannes.berg@intel.com>
-
-commit 798f2786602cbe93e6b928299614aa36ebf50692
-Author: Johannes Berg <johannes.berg@intel.com>
-Date:   Mon Feb 17 20:49:03 2014 +0100
-
-    mac80211: insert stations before adding to driver
-    
-    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:
-     1. a station connects and is added
-     2. first, it is added to the driver
-     3. then, it is added to the mac80211 lists
-    
-    If the station goes to sleep between steps 2 and 3, and the
-    firmware/hardware records it as being asleep, mac80211 will
-    never instruct the driver to wake it up again as it never
-    realized it went to sleep since the RX path discarded the
-    frame as a "spurious class 3 frame", no station entry was
-    present yet.
-    
-    Fix this by adding the station in software first, and only
-    then adding it to the driver. That way, any state that the
-    driver changes will be reflected properly in mac80211's
-    station state. The problematic part is the roll-back if the
-    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 <johannes.berg@intel.com>
-
-commit b9ba6a520cb07ab3aa7aaaf9ce4a0bc7a6bc06fe
-Author: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
-Date:   Thu Feb 20 09:22:11 2014 +0200
-
-    mac80211: fix AP powersave TX vs. wakeup race
-    
-    There is a race between the TX path and the STA wakeup: while
-    a station is sleeping, mac80211 buffers frames until it wakes
-    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.
-    
-    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.
-    
-    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.
-    
-    Additionally, it can lead to the crash below.
-    
-    Fix all this by synchronising both paths with a new lock.
-    Both path are not fastpath since they handle PS situations.
-    
-    In a later patch we'll remove the extra skb queue locks to
-    reduce locking overhead.
-    
-    BUG: unable to handle kernel
-    NULL pointer dereference at 000000b0
-    IP: [<ff6f1791>] ieee80211_report_used_skb+0x11/0x3e0 [mac80211]
-    *pde = 00000000
-    Oops: 0000 [#1] SMP DEBUG_PAGEALLOC
-    EIP: 0060:[<ff6f1791>] EFLAGS: 00210282 CPU: 1
-    EIP is at ieee80211_report_used_skb+0x11/0x3e0 [mac80211]
-    EAX: e5900da0 EBX: 00000000 ECX: 00000001 EDX: 00000000
-    ESI: e41d00c0 EDI: e5900da0 EBP: ebe458e4 ESP: ebe458b0
-     DS: 007b ES: 007b FS: 00d8 GS: 00e0 SS: 0068
-    CR0: 8005003b CR2: 000000b0 CR3: 25a78000 CR4: 000407d0
-    DR0: 00000000 DR1: 00000000 DR2: 00000000 DR3: 00000000
-    DR6: ffff0ff0 DR7: 00000400
-    Process iperf (pid: 3934, ti=ebe44000 task=e757c0b0 task.ti=ebe44000)
-    iwlwifi 0000:02:00.0: I iwl_pcie_enqueue_hcmd Sending command LQ_CMD (#4e), seq: 0x0903, 92 bytes at 3[3]:9
-    Stack:
-     e403b32c ebe458c4 00200002 00200286 e403b338 ebe458cc c10960bb e5900da0
-     ff76a6ec ebe458d8 00000000 e41d00c0 e5900da0 ebe458f0 ff6f1b75 e403b210
-     ebe4598c ff723dc1 00000000 ff76a6ec e597c978 e403b758 00000002 00000002
-    Call Trace:
-     [<ff6f1b75>] ieee80211_free_txskb+0x15/0x20 [mac80211]
-     [<ff723dc1>] invoke_tx_handlers+0x1661/0x1780 [mac80211]
-     [<ff7248a5>] ieee80211_tx+0x75/0x100 [mac80211]
-     [<ff7249bf>] ieee80211_xmit+0x8f/0xc0 [mac80211]
-     [<ff72550e>] ieee80211_subif_start_xmit+0x4fe/0xe20 [mac80211]
-     [<c149ef70>] dev_hard_start_xmit+0x450/0x950
-     [<c14b9aa9>] sch_direct_xmit+0xa9/0x250
-     [<c14b9c9b>] __qdisc_run+0x4b/0x150
-     [<c149f732>] dev_queue_xmit+0x2c2/0xca0
-    
-    Cc: stable@vger.kernel.org
-    Reported-by: Yaara Rozenblum <yaara.rozenblum@intel.com>
-    Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
-    Reviewed-by: Stanislaw Gruszka <sgruszka@redhat.com>
-    [reword commit log, use a separate lock]
-    Signed-off-by: Johannes Berg <johannes.berg@intel.com>
-
-commit 80e419de0dff38436b30d363311c625766193f86
-Author: Inbal Hacohen <Inbal.Hacohen@intel.com>
-Date:   Wed Feb 12 09:32:27 2014 +0200
-
-    cfg80211: bugfix in regulatory user hint process
-    
-    After processing hint_user, we would want to schedule the
-    timeout work only if we are actually waiting to CRDA. This happens
-    when the status is not "IGNORE" nor "ALREADY_SET".
-    
-    Signed-off-by: Inbal Hacohen <Inbal.Hacohen@intel.com>
-    Signed-off-by: Johannes Berg <johannes.berg@intel.com>
-
-commit 6514c93afede55284e2cb63359aadedb85884c80
-Author: Jouni Malinen <jouni@qca.qualcomm.com>
-Date:   Tue Feb 18 20:41:08 2014 +0200
-
-    ath9k: Enable U-APSD AP mode support
-    
-    mac80211 handles the actual operations, so ath9k can just indicate
-    support for this. Based on initial tests, this combination seems to
-    work fine.
-    
-    Signed-off-by: Jouni Malinen <jouni@qca.qualcomm.com>
-
-commit a63caf0a357ad5c1f08d6b7827dc76c451445017
-Author: Stanislaw Gruszka <sgruszka@redhat.com>
-Date:   Wed Feb 19 13:15:17 2014 +0100
-
-    ath9k: protect tid->sched check
-    
-    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:
-    
-    [424271.637220] BUG: unable to handle kernel paging request at 00100104
-    [424271.637328] IP: [<f90fc072>] ath_tx_aggr_sleep+0x62/0xe0 [ath9k]
-    ...
-    [424271.639953] Call Trace:
-    [424271.639998]  [<f90f6900>] ? ath9k_get_survey+0x110/0x110 [ath9k]
-    [424271.640083]  [<f90f6942>] ath9k_sta_notify+0x42/0x50 [ath9k]
-    [424271.640177]  [<f809cfef>] sta_ps_start+0x8f/0x1c0 [mac80211]
-    [424271.640258]  [<c10f730e>] ? free_compound_page+0x2e/0x40
-    [424271.640346]  [<f809e915>] ieee80211_rx_handlers+0x9d5/0x2340 [mac80211]
-    [424271.640437]  [<c112f048>] ? kmem_cache_free+0x1d8/0x1f0
-    [424271.640510]  [<c1345a84>] ? kfree_skbmem+0x34/0x90
-    [424271.640578]  [<c10fc23c>] ? put_page+0x2c/0x40
-    [424271.640640]  [<c1345a84>] ? kfree_skbmem+0x34/0x90
-    [424271.640706]  [<c1345a84>] ? kfree_skbmem+0x34/0x90
-    [424271.640787]  [<f809dde3>] ? ieee80211_rx_handlers_result+0x73/0x1d0 [mac80211]
-    [424271.640897]  [<f80a07a0>] ieee80211_prepare_and_rx_handle+0x520/0xad0 [mac80211]
-    [424271.641009]  [<f809e22d>] ? ieee80211_rx_handlers+0x2ed/0x2340 [mac80211]
-    [424271.641104]  [<c13846ce>] ? ip_output+0x7e/0xd0
-    [424271.641182]  [<f80a1057>] ieee80211_rx+0x307/0x7c0 [mac80211]
-    [424271.641266]  [<f90fa6ee>] ath_rx_tasklet+0x88e/0xf70 [ath9k]
-    [424271.641358]  [<f80a0f2c>] ? ieee80211_rx+0x1dc/0x7c0 [mac80211]
-    [424271.641445]  [<f90f82db>] ath9k_tasklet+0xcb/0x130 [ath9k]
-    
-    Bug report:
-    https://bugzilla.kernel.org/show_bug.cgi?id=70551
-    
-    Reported-and-tested-by: Max Sydorenko <maxim.stargazer@gmail.com>
-    Cc: stable@vger.kernel.org
-    Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
-
-commit 82ed9e3ccc02797df2ffe4b78127c4cd5f799a41
-Author: Felix Fietkau <nbd@openwrt.org>
-Date:   Tue Feb 11 15:54:13 2014 +0100
-
-    mac80211: send control port protocol frames to the VO queue
-    
-    Improves reliability of wifi connections with WPA, since authentication
-    frames are prioritized over normal traffic and also typically exempt
-    from aggregation.
-    
-    Cc: stable@vger.kernel.org
-    Signed-off-by: Felix Fietkau <nbd@openwrt.org>
-
-commit d4426800f71e972feaa33e04c5801fc730627bdd
-Author: Stanislaw Gruszka <stf_xl@wp.pl>
-Date:   Mon Feb 10 22:38:28 2014 +0100
-
-    rtl8187: fix regression on MIPS without coherent DMA
-    
-    This patch fixes regression caused by commit a16dad77634 "MIPS: Fix
-    potencial corruption". That commit fixes one corruption scenario in
-    cost of adding another one, which actually start to cause crashes
-    on Yeeloong laptop when rtl8187 driver is used.
-    
-    For correct DMA read operation on machines without DMA coherence, kernel
-    have to invalidate cache, such it will refill later with new data that
-    device wrote to memory, when that data is needed to process. We can only
-    invalidate full cache line. Hence when cache line includes both dma
-    buffer and some other data (written in cache, but not yet in main
-    memory), the other data can not hit memory due to invalidation. That
-    happen on rtl8187 where struct rtl8187_priv fields are located just
-    before and after small buffers that are passed to USB layer and DMA
-    is performed on them.
-    
-    To fix the problem we align buffers and reserve space after them to make
-    them match cache line.
-    
-    This patch does not resolve all possible MIPS problems entirely, for
-    that we have to assure that we always map cache aligned buffers for DMA,
-    what can be complex or even not possible. But patch fixes visible and
-    reproducible regression and seems other possible corruptions do not
-    happen in practice, since Yeeloong laptop works stable without rtl8187
-    driver.
-    
-    Bug report:
-    https://bugzilla.kernel.org/show_bug.cgi?id=54391
-    
-    Reported-by: Petr Pisar <petr.pisar@atlas.cz>
-    Bisected-by: Tom Li <biergaizi2009@gmail.com>
-    Reported-and-tested-by: Tom Li <biergaizi2009@gmail.com>
-    Cc: stable@vger.kernel.org
-    Signed-off-by: Stanislaw Gruszka <stf_xl@wp.pl>
-
-commit e2f141d67ad1e7fe10aaab61811e8a409dfb2442
-Author: Sujith Manoharan <c_manoha@qca.qualcomm.com>
-Date:   Fri Feb 7 10:29:55 2014 +0530
-
-    ath9k: Calculate IQ-CAL median
-    
-    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.
-    
-    Signed-off-by: Sujith Manoharan <c_manoha@qca.qualcomm.com>
-
-commit c52a6fce0820c8d0687443ab86058ae03b478c8f
-Author: Sujith Manoharan <c_manoha@qca.qualcomm.com>
-Date:   Fri Feb 7 10:29:54 2014 +0530
-
-    ath9k: Expand the IQ coefficient array
-    
-    This will be used for storing data for mutiple
-    IQ calibration runs, for AR955x.
-    
-    Signed-off-by: Sujith Manoharan <c_manoha@qca.qualcomm.com>
-
-commit 034969ff5c2b6431d10e07c1938f0b916da85cc3
-Author: Sujith Manoharan <c_manoha@qca.qualcomm.com>
-Date:   Fri Feb 7 10:29:53 2014 +0530
-
-    ath9k: Modify IQ calibration for AR955x
-    
-    IQ calibration post-processing for AR955x is different
-    from other chips - instead of just doing it as part
-    of AGC calibration once, it is triggered 3 times and
-    a median is determined. This patch adds initial support
-    for changing the calibration behavior for AR955x.
-    
-    Also, to simplify things, a helper routine to issue/poll
-    AGC calibration is used.
-    
-    For non-AR955x chips, the iqcal_idx (which will be used
-    in subsequent patches) is set to zero.
-    
-    Signed-off-by: Sujith Manoharan <c_manoha@qca.qualcomm.com>
-
-commit 9b1ed6454e6f3511f24266be99b4e403f243f6a8
-Author: Sujith Manoharan <c_manoha@qca.qualcomm.com>
-Date:   Fri Feb 7 10:29:52 2014 +0530
-
-    ath9k: Fix magnitude/phase calculation
-    
-    Incorrect values are programmed in the registers
-    containing the IQ correction coefficients by the IQ-CAL
-    post-processing code. Fix this.
-    
-    Signed-off-by: Sujith Manoharan <c_manoha@qca.qualcomm.com>
-
-commit 36f93484f96f79171dcecb67c5ef0c3de22531a6
-Author: Sujith Manoharan <c_manoha@qca.qualcomm.com>
-Date:   Fri Feb 7 10:29:51 2014 +0530
-
-    ath9k: Rename ar9003_hw_tx_iqcal_load_avg_2_passes
-    
-    Use ar9003_hw_tx_iq_cal_outlier_detection instead.
-    
-    Signed-off-by: Sujith Manoharan <c_manoha@qca.qualcomm.com>
-
-commit 3af09a7f5d21dd5fd15b973ce6a91a575da30417
-Author: Sujith Manoharan <c_manoha@qca.qualcomm.com>
-Date:   Fri Feb 7 10:29:50 2014 +0530
-
-    ath9k: Check explicitly for IQ calibration
-    
-    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.
-    
-    Signed-off-by: Sujith Manoharan <c_manoha@qca.qualcomm.com>
-
-commit cb4969634b93c4643a32cc3fbd27d2b288b25771
-Author: Sujith Manoharan <c_manoha@qca.qualcomm.com>
-Date:   Fri Feb 7 10:29:49 2014 +0530
-
-    ath9k: Fix IQ cal post processing for SoC
-    
-    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.
-    
-    Signed-off-by: Sujith Manoharan <c_manoha@qca.qualcomm.com>
-
-commit e138e0ef9560c46ce93dbb22a728a57888e94d1c
-Author: Sujith Manoharan <c_manoha@qca.qualcomm.com>
-Date:   Mon Feb 3 13:31:37 2014 +0530
-
-    ath9k: Fix TX power calculation
-    
-    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,
-    they would still be using the wrong TX power. Fix this by assigning
-    a default value in such cases.
-    
-    Cc: Rajkumar Manoharan <rmanohar@qti.qualcomm.com>
-    Signed-off-by: Sujith Manoharan <c_manoha@qca.qualcomm.com>
-
-commit b9f268b5b01331c3c82179abca551429450e9417
-Author: Michal Kazior <michal.kazior@tieto.com>
-Date:   Wed Jan 29 14:22:27 2014 +0100
-
-    cfg80211: consider existing DFS interfaces
-    
-    It was possible to break interface combinations in
-    the following way:
-    
-     combo 1: iftype = AP, num_ifaces = 2, num_chans = 2,
-     combo 2: iftype = AP, num_ifaces = 1, num_chans = 1, radar = HT20
-    
-    With the above interface combinations it was
-    possible to:
-    
-     step 1. start AP on DFS channel by matching combo 2
-     step 2. start AP on non-DFS channel by matching combo 1
-    
-    This was possible beacuse (step 2) did not consider
-    if other interfaces require radar detection.
-    
-    The patch changes how cfg80211 tracks channels -
-    instead of channel itself now a complete chandef
-    is stored.
-    
-    Signed-off-by: Michal Kazior <michal.kazior@tieto.com>
-    Signed-off-by: Johannes Berg <johannes.berg@intel.com>
-
-commit bc9c62f5f511cc395c62dbf4cdd437f23db53b28
-Author: Antonio Quartulli <antonio@open-mesh.com>
-Date:   Wed Jan 29 17:53:43 2014 +0100
-
-    cfg80211: fix channel configuration in IBSS join
-    
-    When receiving an IBSS_JOINED event select the BSS object
-    based on the {bssid, channel} couple rather than the bssid
-    only.
-    With the current approach if another cell having the same
-    BSSID (but using a different channel) exists then cfg80211
-    picks up the wrong BSS object.
-    The result is a mismatching channel configuration between
-    cfg80211 and the driver, that can lead to any sort of
-    problem.
-    
-    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.
-    By passing the channel to cfg80211_get_bss() we can solve
-    this ambiguity and retrieve/create the correct BSS object.
-    All the users of cfg80211_ibss_joined() have been changed
-    accordingly.
-    
-    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
-    cfg80211_ibss_joined() with a zero BSSID on ibss-leave).
-    
-    Cc: Kalle Valo <kvalo@qca.qualcomm.com>
-    Cc: Arend van Spriel <arend@broadcom.com>
-    Cc: Bing Zhao <bzhao@marvell.com>
-    Cc: Jussi Kivilinna <jussi.kivilinna@iki.fi>
-    Cc: libertas-dev@lists.infradead.org
-    Acked-by: Kalle Valo <kvalo@qca.qualcomm.com>
-    Signed-off-by: Antonio Quartulli <antonio@open-mesh.com>
-    [minor code cleanup in ath6kl]
-    Signed-off-by: Johannes Berg <johannes.berg@intel.com>
-
-commit 7e0c41cb41f215aba2c39b1c237bb4d42ec49a85
-Author: Johannes Berg <johannes.berg@intel.com>
-Date:   Fri Jan 24 14:41:44 2014 +0100
-
-    mac80211: fix bufferable MMPDU RX handling
-    
-    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.
-    
-    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 <johannes.berg@intel.com>
-
-commit fc0df6d2343636e3f48a069330d5b972e3d8659d
-Author: Janusz Dziedzic <janusz.dziedzic@tieto.com>
-Date:   Fri Jan 24 14:29:21 2014 +0100
-
-    cfg80211: set preset_chandef after channel switch
-    
-    Set preset_chandef in channel switch notification.
-    In other case we will have old preset_chandef.
-    
-    Signed-off-by: Janusz Dziedzic <janusz.dziedzic@tieto.com>
-    Signed-off-by: Johannes Berg <johannes.berg@intel.com>
-
-commit cdec895e2344987ff171cece96e25d7407a3ebf6
-Author: Simon Wunderlich <simon@open-mesh.com>
-Date:   Fri Jan 24 23:48:29 2014 +0100
-
-    mac80211: send ibss probe responses with noack flag
-    
-    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.
-    
-    Signed-off-by: Simon Wunderlich <simon@open-mesh.com>
-    [fix typo & 'wildcard SSID' in commit log]
-    Signed-off-by: Johannes Berg <johannes.berg@intel.com>
-
-commit 0b865d1e6b9c05052adae9315df7cb195dc60c3b
-Author: Luciano Coelho <luciano.coelho@intel.com>
-Date:   Tue Jan 28 17:09:08 2014 +0200
-
-    mac80211: ibss: remove unnecessary call to release channel
-    
-    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 <luciano.coelho@intel.com>
-    Signed-off-by: Johannes Berg <johannes.berg@intel.com>
-
-commit e1b6c17e971f0a51ff86c2dac2584c63cd999cd7
-Author: Michal Kazior <michal.kazior@tieto.com>
-Date:   Wed Jan 29 07:56:21 2014 +0100
-
-    mac80211: add missing CSA locking
-    
-    The patch adds a missing sdata lock and adds a few
-    lockdeps for easier maintenance.
-    
-    Signed-off-by: Michal Kazior <michal.kazior@tieto.com>
-    Signed-off-by: Johannes Berg <johannes.berg@intel.com>
-
-commit ad17ba7d14d225b109b73c177cd446afb8050598
-Author: Michal Kazior <michal.kazior@tieto.com>
-Date:   Wed Jan 29 07:56:20 2014 +0100
-
-    mac80211: fix sdata->radar_required locking
-    
-    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 <michal.kazior@tieto.com>
-    Signed-off-by: Johannes Berg <johannes.berg@intel.com>
-
-commit 5fcd5f1808813a3d9e502fd756e01bee8a79c85d
-Author: Michal Kazior <michal.kazior@tieto.com>
-Date:   Wed Jan 29 07:56:19 2014 +0100
-
-    mac80211: move csa_active setting in STA CSA
-    
-    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.
-    
-    Signed-off-by: Michal Kazior <michal.kazior@tieto.com>
-    Reviewed-by: Luciano Coelho <luciano.coelho@intel.com>
-    Signed-off-by: Johannes Berg <johannes.berg@intel.com>
-
-commit e486da4b7eed71821c6b4c1bb9ac62ffd3ab13e9
-Author: Michal Kazior <michal.kazior@tieto.com>
-Date:   Wed Jan 29 07:56:18 2014 +0100
-
-    mac80211: fix possible memory leak on AP CSA failure
-    
-    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 <michal.kazior@tieto.com>
-    Reviewed-by: Luciano Coelho <luciano.coelho@intel.com>
-    Signed-off-by: Johannes Berg <johannes.berg@intel.com>
-
-commit 3a77ba08940682bf3d52cf14f980337324af9d4a
-Author: Johannes Berg <johannes.berg@intel.com>
-Date:   Sat Feb 1 00:33:29 2014 +0100
-
-    mac80211: fix fragmentation code, particularly for encryption
-    
-    The "new" fragmentation code (since my rewrite almost 5 years ago)
-    erroneously sets skb->len rather than using skb_trim() to adjust
-    the length of the first fragment after copying out all the others.
-    This leaves the skb tail pointer pointing to after where the data
-    originally ended, and thus causes the encryption MIC to be written
-    at that point, rather than where it belongs: immediately after the
-    data.
-    
-    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
-        verified at the receiver, the MIC is practically guaranteed to
-        be wrong
-     b) we leak up to 8 bytes of plaintext (!) of the packet out into
-        the air
-    
-    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.
-    
-    Fix this by using skb_trim() properly.
-    
-    Cc: stable@vger.kernel.org
-    Fixes: 2de8e0d999b8 ("mac80211: rewrite fragmentation")
-    Reported-by: Jouni Malinen <j@w1.fi>
-    Signed-off-by: Johannes Berg <johannes.berg@intel.com>
-
-commit de5f242e0c10e841017e37eb8c38974a642dbca8
-Author: Sujith Manoharan <c_manoha@qca.qualcomm.com>
-Date:   Tue Jan 28 06:21:59 2014 +0530
-
-    ath9k: Fix build error on ARM
-    
-    Use mdelay instead of udelay to fix this error:
-    
-    ERROR: "__bad_udelay" [drivers/net/wireless/ath/ath9k/ath9k_hw.ko] undefined!
-    make[1]: *** [__modpost] Error 1
-    make: *** [modules] Error 2
-    
-    Reported-by: Josh Boyer <jwboyer@fedoraproject.org>
-    Signed-off-by: Sujith Manoharan <c_manoha@qca.qualcomm.com>
-
-commit 8e3ea7a51dfc61810fcefd947f6edcf61125252a
-Author: Geert Uytterhoeven <geert@linux-m68k.org>
-Date:   Sun Jan 26 11:53:21 2014 +0100
-
-    ath9k: Fix uninitialized variable in ath9k_has_tx_pending()
-    
-    drivers/net/wireless/ath/ath9k/main.c: In function ‘ath9k_has_tx_pending’:
-    drivers/net/wireless/ath/ath9k/main.c:1869: warning: ‘npend’ may be used uninitialized in this function
-    
-    Introduced by commit 10e2318103f5941aa70c318afe34bc41f1b98529 ("ath9k:
-    optimize ath9k_flush").
-    
-    Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>
-
-commit a4a634a6937ebdd827fa58e8fcdb8ca49a3769f6
-Author: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
-Date:   Mon Jan 27 11:07:42 2014 +0200
-
-    mac80211: release the channel in error path in start_ap
-    
-    When the driver cannot start the AP or when the assignement
-    of the beacon goes wrong, we need to unassign the vif.
-    
-    Cc: stable@vger.kernel.org
-    Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
-    Signed-off-by: Johannes Berg <johannes.berg@intel.com>
-
-commit dfb6889a75c601aedb7450b7e606668e77da6679
-Author: Johannes Berg <johannes.berg@intel.com>
-Date:   Wed Jan 22 11:14:19 2014 +0200
-
-    cfg80211: send scan results from work queue
-    
-    Due to the previous commit, when a scan finishes, it is in theory
-    possible to hit the following sequence:
-     1. interface starts being removed
-     2. scan is cancelled by driver and cfg80211 is notified
-     3. scan done work is scheduled
-     4. interface is removed completely, rdev->scan_req is freed,
-        event sent to userspace but scan done work remains pending
-     5. new scan is requested on another virtual interface
-     6. scan done work runs, freeing the still-running scan
-    
-    To fix this situation, hang on to the scan done message and block
-    new scans while that is the case, and only send the message from
-    the work function, regardless of whether the scan_req is already
-    freed from interface removal. This makes step 5 above impossible
-    and changes step 6 to be
-     5. scan done work runs, sending the scan done message
-    
-    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 <johannes.berg@intel.com>
-
-commit 45b7ab41fc08627d9a8428cb413d5d84662a9707
-Author: Johannes Berg <johannes.berg@intel.com>
-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
-    cancelled by the driver. This will make it call cfg80211, which
-    only queues a work struct. If interface/wdev removal is quick
-    enough, this can leave the scan request pending and processed
-    only after the interface is gone, causing a use-after-free.
-    
-    Fix this by making sure the scan request is not pending after
-    the interface is destroyed. We can't flush or cancel the work
-    item due to locking concerns, but when it'll run it shouldn't
-    find anything to do. This leaves a potential issue, if a new
-    scan gets requested before the work runs, it prematurely stops
-    the running scan, potentially causing another crash. I'll fix
-    that in the next patch.
-    
-    This was particularly observed with P2P_DEVICE wdevs, likely
-    because freeing them is quicker than freeing netdevs.
-    
-    Reported-by: Andrei Otcheretianski <andrei.otcheretianski@intel.com>
-    Fixes: 4a58e7c38443 ("cfg80211: don't "leak" uncompleted scans")
-    Signed-off-by: Johannes Berg <johannes.berg@intel.com>
-
-commit ae04fa489ab31b5a10d3cc8399f52761175d4321
-Author: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
-Date:   Thu Jan 23 14:28:16 2014 +0200
-
-    mac80211: avoid deadlock revealed by lockdep
-    
-    sdata->u.ap.request_smps_work can’t be flushed synchronously
-    under wdev_lock(wdev) since ieee80211_request_smps_ap_work
-    itself locks the same lock.
-    While at it, reset the driver_smps_mode when the ap is
-    stopped to its default: OFF.
-    
-    This solves:
-    
-    ======================================================
-    [ 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: [<c105b8d0>] flush_work+0x0/0x90
-    
-    but task is already holding lock:
-      (&wdev->mtx){+.+.+.}, at: [<f9b32626>] cfg80211_stop_ap+0x26/0x230 [cfg80211]
-    
-    which lock already depends on the new lock.
-    
-    the existing dependency chain (in reverse order) is:
-    
-    -> #1 (&wdev->mtx){+.+.+.}:
-            [<c10aefa9>] lock_acquire+0x79/0xe0
-            [<c1607a1a>] mutex_lock_nested+0x4a/0x360
-            [<fb06288b>] ieee80211_request_smps_ap_work+0x2b/0x50 [mac80211]
-            [<c105cdd8>] process_one_work+0x198/0x450
-            [<c105d469>] worker_thread+0xf9/0x320
-            [<c10669ff>] kthread+0x9f/0xb0
-            [<c1613397>] ret_from_kernel_thread+0x1b/0x28
-    
-    -> #0 ((&sdata->u.ap.request_smps_work)){+.+...}:
-            [<c10ae9df>] __lock_acquire+0x183f/0x1910
-            [<c10aefa9>] lock_acquire+0x79/0xe0
-            [<c105b917>] flush_work+0x47/0x90
-            [<c105d867>] __cancel_work_timer+0x67/0xe0
-            [<c105d90f>] cancel_work_sync+0xf/0x20
-            [<fb0765cc>] ieee80211_stop_ap+0x8c/0x340 [mac80211]
-            [<f9b3268c>] cfg80211_stop_ap+0x8c/0x230 [cfg80211]
-            [<f9b0d8f9>] cfg80211_leave+0x79/0x100 [cfg80211]
-            [<f9b0da72>] cfg80211_netdev_notifier_call+0xf2/0x4f0 [cfg80211]
-            [<c160f2c9>] notifier_call_chain+0x59/0x130
-            [<c106c6de>] __raw_notifier_call_chain+0x1e/0x30
-            [<c106c70f>] raw_notifier_call_chain+0x1f/0x30
-            [<c14f8213>] call_netdevice_notifiers_info+0x33/0x70
-            [<c14f8263>] call_netdevice_notifiers+0x13/0x20
-            [<c14f82a4>] __dev_close_many+0x34/0xb0
-            [<c14f83fe>] dev_close_many+0x6e/0xc0
-            [<c14f9c77>] rollback_registered_many+0xa7/0x1f0
-            [<c14f9dd4>] unregister_netdevice_many+0x14/0x60
-            [<fb06f4d9>] ieee80211_remove_interfaces+0xe9/0x170 [mac80211]
-            [<fb055116>] ieee80211_unregister_hw+0x56/0x110 [mac80211]
-            [<fa3e9396>] iwl_op_mode_mvm_stop+0x26/0xe0 [iwlmvm]
-            [<f9b9d8ca>] _iwl_op_mode_stop+0x3a/0x70 [iwlwifi]
-            [<f9b9d96f>] iwl_opmode_deregister+0x6f/0x90 [iwlwifi]
-            [<fa405179>] __exit_compat+0xd/0x19 [iwlmvm]
-            [<c10b8bf9>] SyS_delete_module+0x179/0x2b0
-            [<c1613421>] sysenter_do_call+0x12/0x32
-    
-    Fixes: 687da132234f ("mac80211: implement SMPS for AP")
-    Cc: <stable@vger.kernel.org> [3.13]
-    Reported-by: Ilan Peer <ilan.peer@intel.com>
-    Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
-    Signed-off-by: Johannes Berg <johannes.berg@intel.com>
-
-commit 178b205e96217164fd7c30113464250d0b6f5eca
-Author: Johannes Berg <johannes.berg@intel.com>
-Date:   Thu Jan 23 16:32:29 2014 +0100
-
-    cfg80211: re-enable 5/10 MHz support
-    
-    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 <johannes.berg@intel.com>
-
-commit 110a1c79acda14edc83b7c8dc5af9c7ddd23eb61
-Author: Pontus Fuchs <pontus.fuchs@gmail.com>
-Date:   Thu Jan 16 15:00:40 2014 +0100
-
-    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.
-    
-    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.
-    
-    Cc: stable@vger.kernel.org
-    Fixes: 3713b4e364ef ("nl80211: allow splitting wiphy information in dumps")
-    Signed-off-by: Pontus Fuchs <pontus.fuchs@gmail.com>
-    [avoid the entire workaround when state->split is set]
-    Signed-off-by: Johannes Berg <johannes.berg@intel.com>
-
-commit b4c31b45ffc7ef110fa9ecc34d7878fe7c5b9da4
-Author: Eliad Peller <eliad@wizery.com>
-Date:   Sun Jan 12 11:06:37 2014 +0200
-
-    mac80211: move roc cookie assignment earlier
-    
-    ieee80211_start_roc_work() might add a new roc
-    to existing roc, and tell cfg80211 it has already
-    started.
-    
-    However, this might happen before the roc cookie
-    was set, resulting in REMAIN_ON_CHANNEL (started)
-    event with null cookie. Consequently, it can make
-    wpa_supplicant go out of sync.
-    
-    Fix it by setting the roc cookie earlier.
-    
-    Cc: stable@vger.kernel.org
-    Signed-off-by: Eliad Peller <eliad@wizery.com>
-    Signed-off-by: Johannes Berg <johannes.berg@intel.com>
-
-commit cfdc9157bfd7bcf88ab4dae08873a9907eba984c
-Author: Johannes Berg <johannes.berg@intel.com>
-Date:   Fri Jan 24 14:06:29 2014 +0100
-
-    nl80211: send event when AP operation is stopped
-    
-    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.
-    
-    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 <johannes.berg@intel.com>
-
-commit d5d567eda7704f190379ca852a8f9a4112e3eee3
-Author: Johannes Berg <johannes.berg@intel.com>
-Date:   Thu Jan 23 16:20:29 2014 +0100
-
-    mac80211: add length check in ieee80211_is_robust_mgmt_frame()
-    
-    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 <johannes.berg@intel.com>
-
-commit f8f6d212a047fc65c7d3442dfc038f65517236fc
-Author: Johannes Berg <johannes.berg@intel.com>
-Date:   Fri Jan 24 10:53:53 2014 +0100
-
-    nl80211: fix scheduled scan RSSI matchset attribute confusion
-    
-    The scheduled scan matchsets were intended to be a list of filters,
-    with the found BSS having to pass at least one of them to be passed
-    to the host. When the RSSI attribute was added, however, this was
-    broken and currently wpa_supplicant adds that attribute in its own
-    matchset; however, it doesn't intend that to mean that anything
-    that passes the RSSI filter should be passed to the host, instead
-    it wants it to mean that everything needs to also have higher RSSI.
-    
-    This is semantically problematic because we have a list of filters
-    like [ SSID1, SSID2, SSID3, RSSI ] with no real indication which
-    one should be OR'ed and which one AND'ed.
-    
-    To fix this, move the RSSI filter attribute into each matchset. As
-    we need to stay backward compatible, treat a matchset with only the
-    RSSI attribute as a "default RSSI filter" for all other matchsets,
-    but only if there are other matchsets (an RSSI-only matchset by
-    itself is still desirable.)
-    
-    To make driver implementation easier, keep a global min_rssi_thold
-    for the entire request as well. The only affected driver is ath6kl.
-    
-    I found this when I looked into the code after Raja Mani submitted
-    a patch fixing the n_match_sets calculation to disregard the RSSI,
-    but that patch didn't address the semantic issue.
-    
-    Reported-by: Raja Mani <rmani@qti.qualcomm.com>
-    Acked-by: Luciano Coelho <luciano.coelho@intel.com>
-    Signed-off-by: Johannes Berg <johannes.berg@intel.com>
-
-commit de553e8545e65a6dc4e45f43df7e1443d4291922
-Author: Johannes Berg <johannes.berg@intel.com>
-Date:   Fri Jan 24 10:17:47 2014 +0100
-
-    nl80211: check nla_parse() return values
-    
-    If there's a policy, then nla_parse() return values must be
-    checked, otherwise the policy is useless and there's nothing
-    that ensures the attributes are actually what we expect them
-    to be.
-    
-    Signed-off-by: Johannes Berg <johannes.berg@intel.com>
-
-commit 652204a0733e9e1c54661d6f9d36e2e1e3b22bb1
-Author: Karl Beldan <karl.beldan@rivierawaves.com>
-Date:   Thu Jan 23 20:06:34 2014 +0100
-
-    mac80211: send {ADD,DEL}BA on AC_VO like other mgmt frames, as per spec
-    
-    ATM, {ADD,DEL}BA and BAR frames are sent on the AC matching the TID of
-    the BA parameters. In the discussion [1] about this patch, Johannes
-    recalled that it fixed some races with the DELBA and indeed this
-    behavior was introduced in [2].
-    While [2] is right for the BARs, the part queueing the {ADD,DEL}BAs on
-    their BA params TID AC violates the spec and is more a workaround for
-    some drivers. Helmut expressed some concerns wrt such drivers, in
-    particular DELBAs in rt2x00.
-    
-    ATM, DELBAs are sent after a driver has called (hence "purposely")
-    ieee80211_start_tx_ba_cb_irqsafe and Johannes and Emmanuel gave some
-    details wrt intentions behind the split of the IEEE80211_AMPDU_TX_STOP_*
-    given to the driver ampdu_action supposed to call this function, which
-    could prove handy to people trying to do the right thing in faulty
-    drivers (if their fw/hw don't get in their way).
-    
-    [1] http://mid.gmane.org/1390391564-18481-1-git-send-email-karl.beldan@gmail.com
-    [2] Commit: cf6bb79ad828 ("mac80211: Use appropriate TID for sending BAR, ADDBA and DELBA frames")
-    
-    Signed-off-by: Karl Beldan <karl.beldan@rivierawaves.com>
-    Cc: Helmut Schaa <helmut.schaa@googlemail.com>
-    Cc: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
-    Signed-off-by: Johannes Berg <johannes.berg@intel.com>
---- 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",
- 			   nw_type & ADHOC_CREATOR ? "creator" : "joiner");
--		cfg80211_ibss_joined(vif->ndev, bssid, GFP_KERNEL);
-+		cfg80211_ibss_joined(vif->ndev, bssid, chan, GFP_KERNEL);
- 		cfg80211_put_bss(ar->wiphy, bss);
- 		return;
- 	}
-@@ -861,13 +861,9 @@ void ath6kl_cfg80211_disconnect_event(st
- 	}
- 
- 	if (vif->nw_type & ADHOC_NETWORK) {
--		if (vif->wdev.iftype != NL80211_IFTYPE_ADHOC) {
-+		if (vif->wdev.iftype != NL80211_IFTYPE_ADHOC)
- 			ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
- 				   "%s: ath6k not in ibss mode\n", __func__);
--			return;
--		}
--		memset(bssid, 0, ETH_ALEN);
--		cfg80211_ibss_joined(vif->ndev, bssid, GFP_KERNEL);
- 		return;
- 	}
- 
-@@ -3256,6 +3252,15 @@ static int ath6kl_cfg80211_sscan_start(s
- 	struct ath6kl_vif *vif = netdev_priv(dev);
- 	u16 interval;
- 	int ret, rssi_thold;
-+	int n_match_sets = request->n_match_sets;
-+
-+	/*
-+	 * If there's a matchset w/o an SSID, then assume it's just for
-+	 * the RSSI (nothing else is currently supported) and ignore it.
-+	 * The device only supports a global RSSI filter that we set below.
-+	 */
-+	if (n_match_sets == 1 && !request->match_sets[0].ssid.ssid_len)
-+		n_match_sets = 0;
- 
- 	if (ar->state != ATH6KL_STATE_ON)
- 		return -EIO;
-@@ -3268,11 +3273,11 @@ static int ath6kl_cfg80211_sscan_start(s
- 	ret = ath6kl_set_probed_ssids(ar, vif, request->ssids,
- 				      request->n_ssids,
- 				      request->match_sets,
--				      request->n_match_sets);
-+				      n_match_sets);
- 	if (ret < 0)
- 		return ret;
- 
--	if (!request->n_match_sets) {
-+	if (!n_match_sets) {
- 		ret = ath6kl_wmi_bssfilter_cmd(ar->wmi, vif->fw_vif_idx,
- 					       ALL_BSS_FILTER, 0);
- 		if (ret < 0)
-@@ -3286,12 +3291,12 @@ static int ath6kl_cfg80211_sscan_start(s
- 
- 	if (test_bit(ATH6KL_FW_CAPABILITY_RSSI_SCAN_THOLD,
- 		     ar->fw_capabilities)) {
--		if (request->rssi_thold <= NL80211_SCAN_RSSI_THOLD_OFF)
-+		if (request->min_rssi_thold <= NL80211_SCAN_RSSI_THOLD_OFF)
- 			rssi_thold = 0;
--		else if (request->rssi_thold < -127)
-+		else if (request->min_rssi_thold < -127)
- 			rssi_thold = -127;
- 		else
--			rssi_thold = request->rssi_thold;
-+			rssi_thold = request->min_rssi_thold;
- 
- 		ret = ath6kl_wmi_set_rssi_filter_cmd(ar->wmi, vif->fw_vif_idx,
- 						     rssi_thold);
---- a/drivers/net/wireless/ath/ath9k/hw.c
-+++ b/drivers/net/wireless/ath/ath9k/hw.c
-@@ -1316,7 +1316,7 @@ static bool ath9k_hw_set_reset(struct at
- 	if (AR_SREV_9300_20_OR_LATER(ah))
- 		udelay(50);
- 	else if (AR_SREV_9100(ah))
--		udelay(10000);
-+		mdelay(10);
- 	else
- 		udelay(100);
- 
-@@ -1534,7 +1534,7 @@ EXPORT_SYMBOL(ath9k_hw_check_nav);
- bool ath9k_hw_check_alive(struct ath_hw *ah)
- {
- 	int count = 50;
--	u32 reg;
-+	u32 reg, last_val;
- 
- 	if (AR_SREV_9300(ah))
- 		return !ath9k_hw_detect_mac_hang(ah);
-@@ -1542,9 +1542,14 @@ bool ath9k_hw_check_alive(struct ath_hw 
- 	if (AR_SREV_9285_12_OR_LATER(ah))
- 		return true;
- 
-+	last_val = REG_READ(ah, AR_OBS_BUS_1);
- 	do {
- 		reg = REG_READ(ah, AR_OBS_BUS_1);
-+		if (reg != last_val)
-+			return true;
- 
-+		udelay(1);
-+		last_val = reg;
- 		if ((reg & 0x7E7FFFEF) == 0x00702400)
- 			continue;
- 
-@@ -2051,9 +2056,8 @@ static bool ath9k_hw_set_power_awake(str
- 
- 	REG_SET_BIT(ah, AR_RTC_FORCE_WAKE,
- 		    AR_RTC_FORCE_WAKE_EN);
--
- 	if (AR_SREV_9100(ah))
--		udelay(10000);
-+		mdelay(10);
- 	else
- 		udelay(50);
- 
---- a/drivers/net/wireless/ath/ath9k/main.c
-+++ b/drivers/net/wireless/ath/ath9k/main.c
-@@ -451,7 +451,7 @@ void ath9k_tasklet(unsigned long data)
- 		 * interrupts are enabled in the reset routine.
- 		 */
- 		atomic_inc(&ah->intr_ref_cnt);
--		ath_dbg(common, ANY, "FATAL: Skipping interrupts\n");
-+		ath_dbg(common, RESET, "FATAL: Skipping interrupts\n");
- 		goto out;
- 	}
- 
-@@ -471,7 +471,7 @@ void ath9k_tasklet(unsigned long data)
- 			 * interrupts are enabled in the reset routine.
- 			 */
- 			atomic_inc(&ah->intr_ref_cnt);
--			ath_dbg(common, ANY,
-+			ath_dbg(common, RESET,
- 				"BB_WATCHDOG: Skipping interrupts\n");
- 			goto out;
- 		}
-@@ -484,7 +484,7 @@ void ath9k_tasklet(unsigned long data)
- 			type = RESET_TYPE_TX_GTT;
- 			ath9k_queue_reset(sc, type);
- 			atomic_inc(&ah->intr_ref_cnt);
--			ath_dbg(common, ANY,
-+			ath_dbg(common, RESET,
- 				"GTT: Skipping interrupts\n");
- 			goto out;
- 		}
-@@ -1866,7 +1866,7 @@ static void ath9k_set_coverage_class(str
- 
- static bool ath9k_has_tx_pending(struct ath_softc *sc)
- {
--	int i, npend;
-+	int i, npend = 0;
- 
- 	for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) {
- 		if (!ATH_TXQ_SETUP(sc, i))
---- a/drivers/net/wireless/iwlwifi/mvm/scan.c
-+++ b/drivers/net/wireless/iwlwifi/mvm/scan.c
-@@ -595,6 +595,9 @@ static void iwl_scan_offload_build_ssid(
- 	 * config match list.
- 	 */
- 	for (i = 0; i < req->n_match_sets && i < PROBE_OPTION_MAX; i++) {
-+		/* skip empty SSID matchsets */
-+		if (!req->match_sets[i].ssid.ssid_len)
-+			continue;
- 		scan->direct_scan[i].id = WLAN_EID_SSID;
- 		scan->direct_scan[i].len = req->match_sets[i].ssid.ssid_len;
- 		memcpy(scan->direct_scan[i].ssid, req->match_sets[i].ssid.ssid,
---- a/drivers/net/wireless/rtlwifi/rtl8188ee/trx.c
-+++ b/drivers/net/wireless/rtlwifi/rtl8188ee/trx.c
-@@ -452,7 +452,7 @@ bool rtl88ee_rx_query_desc(struct ieee80
- 			/* During testing, hdr was NULL */
- 			return false;
- 		}
--		if ((ieee80211_is_robust_mgmt_frame(hdr)) &&
-+		if ((_ieee80211_is_robust_mgmt_frame(hdr)) &&
- 		    (ieee80211_has_protected(hdr->frame_control)))
- 			rx_status->flag &= ~RX_FLAG_DECRYPTED;
- 		else
---- a/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c
-+++ b/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c
-@@ -393,7 +393,7 @@ bool rtl92ce_rx_query_desc(struct ieee80
- 			/* In testing, hdr was NULL here */
- 			return false;
- 		}
--		if ((ieee80211_is_robust_mgmt_frame(hdr)) &&
-+		if ((_ieee80211_is_robust_mgmt_frame(hdr)) &&
- 		    (ieee80211_has_protected(hdr->frame_control)))
- 			rx_status->flag &= ~RX_FLAG_DECRYPTED;
- 		else
---- a/drivers/net/wireless/rtlwifi/rtl8192se/trx.c
-+++ b/drivers/net/wireless/rtlwifi/rtl8192se/trx.c
-@@ -310,7 +310,7 @@ bool rtl92se_rx_query_desc(struct ieee80
- 			/* during testing, hdr was NULL here */
- 			return false;
- 		}
--		if ((ieee80211_is_robust_mgmt_frame(hdr)) &&
-+		if ((_ieee80211_is_robust_mgmt_frame(hdr)) &&
- 			(ieee80211_has_protected(hdr->frame_control)))
- 			rx_status->flag &= ~RX_FLAG_DECRYPTED;
- 		else
---- a/drivers/net/wireless/rtlwifi/rtl8723ae/trx.c
-+++ b/drivers/net/wireless/rtlwifi/rtl8723ae/trx.c
-@@ -334,7 +334,7 @@ bool rtl8723ae_rx_query_desc(struct ieee
- 			/* during testing, hdr could be NULL here */
- 			return false;
- 		}
--		if ((ieee80211_is_robust_mgmt_frame(hdr)) &&
-+		if ((_ieee80211_is_robust_mgmt_frame(hdr)) &&
- 			(ieee80211_has_protected(hdr->frame_control)))
- 			rx_status->flag &= ~RX_FLAG_DECRYPTED;
- 		else
---- a/include/linux/ieee80211.h
-+++ b/include/linux/ieee80211.h
-@@ -597,6 +597,20 @@ static inline int ieee80211_is_qos_nullf
- }
- 
- /**
-+ * ieee80211_is_bufferable_mmpdu - check if frame is bufferable MMPDU
-+ * @fc: frame control field in little-endian byteorder
-+ */
-+static inline bool ieee80211_is_bufferable_mmpdu(__le16 fc)
-+{
-+	/* IEEE 802.11-2012, definition of "bufferable management frame";
-+	 * note that this ignores the IBSS special case. */
-+	return ieee80211_is_mgmt(fc) &&
-+	       (ieee80211_is_action(fc) ||
-+		ieee80211_is_disassoc(fc) ||
-+		ieee80211_is_deauth(fc));
-+}
-+
-+/**
-  * ieee80211_is_first_frag - check if IEEE80211_SCTL_FRAG is not set
-  * @seq_ctrl: frame sequence control bytes in little-endian byteorder
-  */
-@@ -2192,10 +2206,10 @@ static inline u8 *ieee80211_get_DA(struc
- }
- 
- /**
-- * 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
-  * @hdr: the frame (buffer must include at least the first octet of payload)
-  */
--static inline bool ieee80211_is_robust_mgmt_frame(struct ieee80211_hdr *hdr)
-+static inline bool _ieee80211_is_robust_mgmt_frame(struct ieee80211_hdr *hdr)
- {
- 	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
-+ */
-+static inline bool ieee80211_is_robust_mgmt_frame(struct sk_buff *skb)
-+{
-+	if (skb->len < 25)
-+		return false;
-+	return _ieee80211_is_robust_mgmt_frame((void *)skb->data);
-+}
-+
-+/**
-  * ieee80211_is_public_action - check if frame is a public action frame
-  * @hdr: the frame
-  * @len: length of the frame
---- a/include/net/cfg80211.h
-+++ b/include/net/cfg80211.h
-@@ -1395,9 +1395,11 @@ struct cfg80211_scan_request {
-  * struct cfg80211_match_set - sets of attributes to match
-  *
-  * @ssid: SSID to be matched
-+ * @rssi_thold: don't report scan results below this threshold (in s32 dBm)
-  */
- struct cfg80211_match_set {
- 	struct cfg80211_ssid ssid;
-+	s32 rssi_thold;
- };
- 
- /**
-@@ -1420,7 +1422,8 @@ struct cfg80211_match_set {
-  * @dev: the interface
-  * @scan_start: start time of the scheduled scan
-  * @channels: channels to scan
-- * @rssi_thold: don't report scan results below this threshold (in s32 dBm)
-+ * @min_rssi_thold: for drivers only supporting a single threshold, this
-+ *	contains the minimum over all matchsets
-  */
- struct cfg80211_sched_scan_request {
- 	struct cfg80211_ssid *ssids;
-@@ -1433,7 +1436,7 @@ struct cfg80211_sched_scan_request {
- 	u32 flags;
- 	struct cfg80211_match_set *match_sets;
- 	int n_match_sets;
--	s32 rssi_thold;
-+	s32 min_rssi_thold;
- 
- 	/* internal */
- 	struct wiphy *wiphy;
-@@ -3130,8 +3133,8 @@ struct cfg80211_cached_keys;
-  * @identifier: (private) Identifier used in nl80211 to identify this
-  *	wireless device if it has no netdev
-  * @current_bss: (private) Used by the internal configuration code
-- * @channel: (private) Used by the internal configuration code to track
-- *	the user-set AP, monitor and WDS channel
-+ * @chandef: (private) Used by the internal configuration code to track
-+ *	the user-set channel definition.
-  * @preset_chandef: (private) Used by the internal configuration code to
-  *	track the channel to be used for AP later
-  * @bssid: (private) Used by the internal configuration code
-@@ -3195,9 +3198,7 @@ struct wireless_dev {
- 
- 	struct cfg80211_internal_bss *current_bss; /* associated / joined */
- 	struct cfg80211_chan_def preset_chandef;
--
--	/* for AP and mesh channel tracking */
--	struct ieee80211_channel *channel;
-+	struct cfg80211_chan_def chandef;
- 
- 	bool ibss_fixed;
- 	bool ibss_dfs_possible;
-@@ -3879,6 +3880,7 @@ void cfg80211_michael_mic_failure(struct
-  *
-  * @dev: network device
-  * @bssid: the BSSID of the IBSS joined
-+ * @channel: the channel of the IBSS joined
-  * @gfp: allocation flags
-  *
-  * This function notifies cfg80211 that the device joined an IBSS or
-@@ -3888,7 +3890,8 @@ void cfg80211_michael_mic_failure(struct
-  * with the locally generated beacon -- this guarantees that there is
-  * always a scan result for this IBSS. cfg80211 will handle the rest.
-  */
--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);
- 
- /**
-  * cfg80211_notify_new_candidate - notify cfg80211 of a new mesh peer candidate
---- a/include/uapi/linux/nl80211.h
-+++ b/include/uapi/linux/nl80211.h
-@@ -2442,9 +2442,15 @@ enum nl80211_reg_rule_attr {
-  * enum nl80211_sched_scan_match_attr - scheduled scan match attributes
-  * @__NL80211_SCHED_SCAN_MATCH_ATTR_INVALID: attribute number 0 is reserved
-  * @NL80211_SCHED_SCAN_MATCH_ATTR_SSID: SSID to be used for matching,
-- * only report BSS with matching SSID.
-+ *	only report BSS with matching SSID.
-  * @NL80211_SCHED_SCAN_MATCH_ATTR_RSSI: RSSI threshold (in dBm) for reporting a
-- *	BSS in scan results. Filtering is turned off if not specified.
-+ *	BSS in scan results. Filtering is turned off if not specified. Note that
-+ *	if this attribute is in a match set of its own, then it is treated as
-+ *	the default value for all matchsets with an SSID, rather than being a
-+ *	matchset of its own without an RSSI filter. This is due to problems with
-+ *	how this API was implemented in the past. Also, due to the same problem,
-+ *	the only way to create a matchset with only an RSSI filter (with this
-+ *	attribute) is if there's only a single matchset with the RSSI attribute.
-  * @NL80211_SCHED_SCAN_MATCH_ATTR_MAX: highest scheduled scan filter
-  *	attribute number currently defined
-  * @__NL80211_SCHED_SCAN_MATCH_ATTR_AFTER_LAST: internal use
---- a/net/mac80211/agg-tx.c
-+++ b/net/mac80211/agg-tx.c
-@@ -107,7 +107,7 @@ static void ieee80211_send_addba_request
- 	mgmt->u.action.u.addba_req.start_seq_num =
- 					cpu_to_le16(start_seq_num << 4);
- 
--	ieee80211_tx_skb_tid(sdata, skb, tid);
-+	ieee80211_tx_skb(sdata, skb);
- }
- 
- void ieee80211_send_bar(struct ieee80211_vif *vif, u8 *ra, u16 tid, u16 ssn)
---- a/net/mac80211/cfg.c
-+++ b/net/mac80211/cfg.c
-@@ -970,9 +970,9 @@ static int ieee80211_start_ap(struct wip
- 	/* TODO: make hostapd tell us what it wants */
- 	sdata->smps_mode = IEEE80211_SMPS_OFF;
- 	sdata->needed_rx_chains = sdata->local->rx_chains;
--	sdata->radar_required = params->radar_required;
- 
- 	mutex_lock(&local->mtx);
-+	sdata->radar_required = params->radar_required;
- 	err = ieee80211_vif_use_channel(sdata, &params->chandef,
- 					IEEE80211_CHANCTX_SHARED);
- 	mutex_unlock(&local->mtx);
-@@ -1021,8 +1021,10 @@ static int ieee80211_start_ap(struct wip
- 					IEEE80211_P2P_OPPPS_ENABLE_BIT;
- 
- 	err = ieee80211_assign_beacon(sdata, &params->beacon);
--	if (err < 0)
-+	if (err < 0) {
-+		ieee80211_vif_release_channel(sdata);
- 		return err;
-+	}
- 	changed |= err;
- 
- 	err = drv_start_ap(sdata->local, sdata);
-@@ -1032,6 +1034,7 @@ static int ieee80211_start_ap(struct wip
- 		if (old)
- 			kfree_rcu(old, rcu_head);
- 		RCU_INIT_POINTER(sdata->u.ap.beacon, NULL);
-+		ieee80211_vif_release_channel(sdata);
- 		return err;
- 	}
- 
-@@ -1053,6 +1056,7 @@ static int ieee80211_change_beacon(struc
- 	int err;
- 
- 	sdata = IEEE80211_DEV_TO_SUB_IF(dev);
-+	sdata_assert_lock(sdata);
- 
- 	/* 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;
- 
-+	sdata_assert_lock(sdata);
-+
- 	old_beacon = sdata_dereference(sdata->u.ap.beacon, sdata);
- 	if (!old_beacon)
- 		return -ENOENT;
-@@ -1090,8 +1096,6 @@ static int ieee80211_stop_ap(struct wiph
- 	kfree(sdata->u.ap.next_beacon);
- 	sdata->u.ap.next_beacon = NULL;
- 
--	cancel_work_sync(&sdata->u.ap.request_smps_work);
--
- 	/* turn off carrier for this interface and dependent VLANs */
- 	list_for_each_entry(vlan, &sdata->u.ap.vlans, u.vlan.list)
- 		netif_carrier_off(vlan->dev);
-@@ -1103,6 +1107,7 @@ static int ieee80211_stop_ap(struct wiph
- 	kfree_rcu(old_beacon, rcu_head);
- 	if (old_probe_resp)
- 		kfree_rcu(old_probe_resp, rcu_head);
-+	sdata->u.ap.driver_smps_mode = IEEE80211_SMPS_OFF;
- 
- 	__sta_info_flush(sdata, true);
- 	ieee80211_free_keys(sdata, true);
-@@ -1988,6 +1993,9 @@ static int ieee80211_change_bss(struct w
- 
- 	band = ieee80211_get_sdata_band(sdata);
- 
-+	if (WARN_ON(!wiphy->bands[band]))
-+		return -EINVAL;
-+
- 	if (params->use_cts_prot >= 0) {
- 		sdata->vif.bss_conf.use_cts_prot = params->use_cts_prot;
- 		changed |= BSS_CHANGED_ERP_CTS_PROT;
-@@ -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);
- 
-+	/*
-+	 * cookie is either the roc cookie (for normal roc)
-+	 * or the SKB (for mgmt TX)
-+	 */
-+	if (!txskb) {
-+		/* local->mtx protects this */
-+		local->roc_cookie_counter++;
-+		roc->cookie = local->roc_cookie_counter;
-+		/* wow, you wrapped 64 bits ... more likely a bug */
-+		if (WARN_ON(roc->cookie == 0)) {
-+			roc->cookie = 1;
-+			local->roc_cookie_counter++;
-+		}
-+		*cookie = roc->cookie;
-+	} else {
-+		*cookie = (unsigned long)txskb;
-+	}
-+
- 	/* if there's one pending or we're scanning, queue this one */
- 	if (!list_empty(&local->roc_list) ||
- 	    local->scanning || local->radar_detect_enabled)
-@@ -2772,24 +2798,6 @@ static int ieee80211_start_roc_work(stru
- 	if (!queued)
- 		list_add_tail(&roc->list, &local->roc_list);
- 
--	/*
--	 * cookie is either the roc cookie (for normal roc)
--	 * or the SKB (for mgmt TX)
--	 */
--	if (!txskb) {
--		/* local->mtx protects this */
--		local->roc_cookie_counter++;
--		roc->cookie = local->roc_cookie_counter;
--		/* wow, you wrapped 64 bits ... more likely a bug */
--		if (WARN_ON(roc->cookie == 0)) {
--			roc->cookie = 1;
--			local->roc_cookie_counter++;
--		}
--		*cookie = roc->cookie;
--	} else {
--		*cookie = (unsigned long)txskb;
--	}
--
- 	return 0;
- }
- 
-@@ -3004,8 +3012,10 @@ void ieee80211_csa_finalize_work(struct 
- 	if (!ieee80211_sdata_running(sdata))
- 		goto unlock;
- 
--	sdata->radar_required = sdata->csa_radar_required;
-+	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))
-@@ -3022,13 +3032,13 @@ void ieee80211_csa_finalize_work(struct 
- 	switch (sdata->vif.type) {
- 	case NL80211_IFTYPE_AP:
- 		err = ieee80211_assign_beacon(sdata, sdata->u.ap.next_beacon);
-+		kfree(sdata->u.ap.next_beacon);
-+		sdata->u.ap.next_beacon = NULL;
-+
- 		if (err < 0)
- 			goto unlock;
- 
- 		changed |= err;
--		kfree(sdata->u.ap.next_beacon);
--		sdata->u.ap.next_beacon = NULL;
--
- 		ieee80211_bss_info_change_notify(sdata, err);
- 		break;
- 	case NL80211_IFTYPE_ADHOC:
-@@ -3066,7 +3076,7 @@ int ieee80211_channel_switch(struct wiph
- 	struct ieee80211_if_mesh __maybe_unused *ifmsh;
- 	int err, num_chanctx;
- 
--	lockdep_assert_held(&sdata->wdev.mtx);
-+	sdata_assert_lock(sdata);
- 
- 	if (!list_empty(&local->roc_list) || local->scanning)
- 		return -EBUSY;
---- a/net/mac80211/ht.c
-+++ b/net/mac80211/ht.c
-@@ -375,7 +375,7 @@ void ieee80211_send_delba(struct ieee802
- 	mgmt->u.action.u.delba.params = cpu_to_le16(params);
- 	mgmt->u.action.u.delba.reason_code = cpu_to_le16(reason_code);
- 
--	ieee80211_tx_skb_tid(sdata, skb, tid);
-+	ieee80211_tx_skb(sdata, skb);
- }
- 
- 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);
- 
- 	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);
- }
- 
---- a/net/mac80211/iface.c
-+++ b/net/mac80211/iface.c
-@@ -770,12 +770,19 @@ static void ieee80211_do_stop(struct iee
- 
- 	ieee80211_roc_purge(local, sdata);
- 
--	if (sdata->vif.type == NL80211_IFTYPE_STATION)
-+	switch (sdata->vif.type) {
-+	case NL80211_IFTYPE_STATION:
- 		ieee80211_mgd_stop(sdata);
--
--	if (sdata->vif.type == NL80211_IFTYPE_ADHOC)
-+		break;
-+	case NL80211_IFTYPE_ADHOC:
- 		ieee80211_ibss_stop(sdata);
--
-+		break;
-+	case NL80211_IFTYPE_AP:
-+		cancel_work_sync(&sdata->u.ap.request_smps_work);
-+		break;
-+	default:
-+		break;
-+	}
- 
- 	/*
- 	 * 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);
- 
- 	cancel_work_sync(&sdata->recalc_smps);
-+	sdata_lock(sdata);
- 	sdata->vif.csa_active = false;
-+	sdata_unlock(sdata);
- 	cancel_work_sync(&sdata->csa_finalize_work);
- 
- 	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
- {
- 	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
- 
--	if (skb->len < 24 || is_multicast_ether_addr(hdr->addr1))
-+	if (is_multicast_ether_addr(hdr->addr1))
- 		return 0;
- 
--	return ieee80211_is_robust_mgmt_frame(hdr);
-+	return ieee80211_is_robust_mgmt_frame(skb);
- }
- 
- 
-@@ -610,10 +610,10 @@ static int ieee80211_is_multicast_robust
- {
- 	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
- 
--	if (skb->len < 24 || !is_multicast_ether_addr(hdr->addr1))
-+	if (!is_multicast_ether_addr(hdr->addr1))
- 		return 0;
- 
--	return ieee80211_is_robust_mgmt_frame(hdr);
-+	return ieee80211_is_robust_mgmt_frame(skb);
- }
- 
- 
-@@ -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;
- 
--	if (!ieee80211_is_robust_mgmt_frame((struct ieee80211_hdr *) hdr))
-+	if (!ieee80211_is_robust_mgmt_frame(skb))
- 		return -1; /* not a robust management frame */
- 
- 	mmie = (struct ieee80211_mmie *)
-@@ -1128,6 +1128,13 @@ static void sta_ps_end(struct sta_info *
- 	       sta->sta.addr, sta->sta.aid);
- 
- 	if (test_sta_flag(sta, WLAN_STA_PS_DRIVER)) {
-+		/*
-+		 * Clear the flag only if the other one is still set
-+		 * so that the TX path won't start TX'ing new frames
-+		 * directly ... In the case that the driver flag isn't
-+		 * set ieee80211_sta_ps_deliver_wakeup() will clear it.
-+		 */
-+		clear_sta_flag(sta, WLAN_STA_PS_STA);
- 		ps_dbg(sta->sdata, "STA %pM aid %d driver-ps-blocked\n",
- 		       sta->sta.addr, sta->sta.aid);
- 		return;
-@@ -1311,18 +1318,15 @@ ieee80211_rx_h_sta_process(struct ieee80
- 	    !ieee80211_has_morefrags(hdr->frame_control) &&
- 	    !(status->rx_flags & IEEE80211_RX_DEFERRED_RELEASE) &&
- 	    (rx->sdata->vif.type == NL80211_IFTYPE_AP ||
--	     rx->sdata->vif.type == NL80211_IFTYPE_AP_VLAN)) {
-+	     rx->sdata->vif.type == NL80211_IFTYPE_AP_VLAN) &&
-+	    /* PM bit is only checked in frames where it isn't reserved,
-+	     * in AP mode it's reserved in non-bufferable management frames
-+	     * (cf. IEEE 802.11-2012 8.2.4.1.7 Power Management field)
-+	     */
-+	    (!ieee80211_is_mgmt(hdr->frame_control) ||
-+	     ieee80211_is_bufferable_mmpdu(hdr->frame_control))) {
- 		if (test_sta_flag(sta, WLAN_STA_PS_STA)) {
--			/*
--			 * Ignore doze->wake transitions that are
--			 * indicated by non-data frames, the standard
--			 * is unclear here, but for example going to
--			 * PS mode and then scanning would cause a
--			 * doze->wake transition for the probe request,
--			 * and that is clearly undesirable.
--			 */
--			if (ieee80211_is_data(hdr->frame_control) &&
--			    !ieee80211_has_pm(hdr->frame_control))
-+			if (!ieee80211_has_pm(hdr->frame_control))
- 				sta_ps_end(sta);
- 		} else {
- 			if (ieee80211_has_pm(hdr->frame_control))
-@@ -1845,8 +1849,7 @@ static int ieee80211_drop_unencrypted_mg
- 		 * having configured keys.
- 		 */
- 		if (unlikely(ieee80211_is_action(fc) && !rx->key &&
--			     ieee80211_is_robust_mgmt_frame(
--				     (struct ieee80211_hdr *) rx->skb->data)))
-+			     ieee80211_is_robust_mgmt_frame(rx->skb)))
- 			return -EACCES;
- 	}
- 
---- a/net/mac80211/tx.c
-+++ b/net/mac80211/tx.c
-@@ -452,8 +452,7 @@ static int ieee80211_use_mfp(__le16 fc, 
- 	if (sta == NULL || !test_sta_flag(sta, WLAN_STA_MFP))
- 		return 0;
- 
--	if (!ieee80211_is_robust_mgmt_frame((struct ieee80211_hdr *)
--					    skb->data))
-+	if (!ieee80211_is_robust_mgmt_frame(skb))
- 		return 0;
- 
- 	return 1;
-@@ -478,6 +477,20 @@ ieee80211_tx_h_unicast_ps_buf(struct iee
- 		       sta->sta.addr, sta->sta.aid, ac);
- 		if (tx->local->total_ps_buffered >= TOTAL_MAX_TX_BUFFER)
- 			purge_old_ps_buffers(tx->local);
-+
-+		/* sync with ieee80211_sta_ps_deliver_wakeup */
-+		spin_lock(&sta->ps_lock);
-+		/*
-+		 * STA woke up the meantime and all the frames on ps_tx_buf have
-+		 * been queued to pending queue. No reordering can happen, go
-+		 * ahead and Tx the packet.
-+		 */
-+		if (!test_sta_flag(sta, WLAN_STA_PS_STA) &&
-+		    !test_sta_flag(sta, WLAN_STA_PS_DRIVER)) {
-+			spin_unlock(&sta->ps_lock);
-+			return TX_CONTINUE;
-+		}
-+
- 		if (skb_queue_len(&sta->ps_tx_buf[ac]) >= STA_MAX_TX_BUFFER) {
- 			struct sk_buff *old = skb_dequeue(&sta->ps_tx_buf[ac]);
- 			ps_dbg(tx->sdata,
-@@ -492,6 +505,7 @@ ieee80211_tx_h_unicast_ps_buf(struct iee
- 		info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING;
- 		info->flags &= ~IEEE80211_TX_TEMPORARY_FLAGS;
- 		skb_queue_tail(&sta->ps_tx_buf[ac], tx->skb);
-+		spin_unlock(&sta->ps_lock);
- 
- 		if (!timer_pending(&local->sta_cleanup))
- 			mod_timer(&local->sta_cleanup,
-@@ -525,9 +539,7 @@ ieee80211_tx_h_ps_buf(struct ieee80211_t
- 
- 	/* only deauth, disassoc and action are bufferable MMPDUs */
- 	if (ieee80211_is_mgmt(hdr->frame_control) &&
--	    !ieee80211_is_deauth(hdr->frame_control) &&
--	    !ieee80211_is_disassoc(hdr->frame_control) &&
--	    !ieee80211_is_action(hdr->frame_control)) {
-+	    !ieee80211_is_bufferable_mmpdu(hdr->frame_control)) {
- 		if (tx->flags & IEEE80211_TX_UNICAST)
- 			info->flags |= IEEE80211_TX_CTL_NO_PS_BUFFER;
- 		return TX_CONTINUE;
-@@ -567,7 +579,7 @@ ieee80211_tx_h_select_key(struct ieee802
- 		tx->key = key;
- 	else if (ieee80211_is_mgmt(hdr->frame_control) &&
- 		 is_multicast_ether_addr(hdr->addr1) &&
--		 ieee80211_is_robust_mgmt_frame(hdr) &&
-+		 ieee80211_is_robust_mgmt_frame(tx->skb) &&
- 		 (key = rcu_dereference(tx->sdata->default_mgmt_key)))
- 		tx->key = key;
- 	else if (is_multicast_ether_addr(hdr->addr1) &&
-@@ -582,12 +594,12 @@ ieee80211_tx_h_select_key(struct ieee802
- 		tx->key = NULL;
- 	else if (tx->skb->protocol == tx->sdata->control_port_protocol)
- 		tx->key = NULL;
--	else if (ieee80211_is_robust_mgmt_frame(hdr) &&
-+	else if (ieee80211_is_robust_mgmt_frame(tx->skb) &&
- 		 !(ieee80211_is_action(hdr->frame_control) &&
- 		   tx->sta && test_sta_flag(tx->sta, WLAN_STA_MFP)))
- 		tx->key = NULL;
- 	else if (ieee80211_is_mgmt(hdr->frame_control) &&
--		 !ieee80211_is_robust_mgmt_frame(hdr))
-+		 !ieee80211_is_robust_mgmt_frame(tx->skb))
- 		tx->key = NULL;
- 	else {
- 		I802_DEBUG_INC(tx->local->tx_handlers_drop_unencrypted);
-@@ -878,7 +890,7 @@ static int ieee80211_fragment(struct iee
- 	}
- 
- 	/* adjust first fragment's length */
--	skb->len = hdrlen + per_fragm;
-+	skb_trim(skb, hdrlen + per_fragm);
- 	return 0;
- }
- 
-@@ -2900,7 +2912,7 @@ ieee80211_get_buffered_bc(struct ieee802
- 				cpu_to_le16(IEEE80211_FCTL_MOREDATA);
- 		}
- 
--		if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
-+		if (sdata->vif.type == NL80211_IFTYPE_AP)
- 			sdata = IEEE80211_DEV_TO_SUB_IF(skb->dev);
- 		if (!ieee80211_tx_prepare(sdata, &tx, skb))
- 			break;
---- a/net/mac80211/wpa.c
-+++ b/net/mac80211/wpa.c
-@@ -499,7 +499,7 @@ ieee80211_crypto_ccmp_decrypt(struct iee
- 	hdrlen = ieee80211_hdrlen(hdr->frame_control);
- 
- 	if (!ieee80211_is_data(hdr->frame_control) &&
--	    !ieee80211_is_robust_mgmt_frame(hdr))
-+	    !ieee80211_is_robust_mgmt_frame(skb))
- 		return RX_CONTINUE;
- 
- 	data_len = skb->len - hdrlen - IEEE80211_CCMP_HDR_LEN -
---- a/net/wireless/ap.c
-+++ b/net/wireless/ap.c
-@@ -27,9 +27,10 @@ static int __cfg80211_stop_ap(struct cfg
- 	err = rdev_stop_ap(rdev, dev);
- 	if (!err) {
- 		wdev->beacon_interval = 0;
--		wdev->channel = NULL;
-+		memset(&wdev->chandef, 0, sizeof(wdev->chandef));
- 		wdev->ssid_len = 0;
- 		rdev_set_qos_map(rdev, dev, NULL);
-+		nl80211_send_ap_stopped(wdev);
- 	}
- 
- 	return err;
---- a/net/wireless/core.c
-+++ b/net/wireless/core.c
-@@ -203,8 +203,11 @@ void cfg80211_stop_p2p_device(struct cfg
- 
- 	rdev->opencount--;
- 
--	WARN_ON(rdev->scan_req && rdev->scan_req->wdev == wdev &&
--		!rdev->scan_req->notified);
-+	if (rdev->scan_req && rdev->scan_req->wdev == wdev) {
-+		if (WARN_ON(!rdev->scan_req->notified))
-+			rdev->scan_req->aborted = true;
-+		___cfg80211_scan_done(rdev, false);
-+	}
- }
- 
- static int cfg80211_rfkill_set_block(void *data, bool blocked)
-@@ -447,9 +450,6 @@ int wiphy_register(struct wiphy *wiphy)
- 	int i;
- 	u16 ifmodes = wiphy->interface_modes;
- 
--	/* support for 5/10 MHz is broken due to nl80211 API mess - disable */
--	wiphy->flags &= ~WIPHY_FLAG_SUPPORTS_5_10_MHZ;
--
- 	/*
- 	 * There are major locking problems in nl80211/mac80211 for CSA,
- 	 * disable for all drivers until this has been reworked.
-@@ -795,8 +795,6 @@ void cfg80211_leave(struct cfg80211_regi
- 	default:
- 		break;
- 	}
--
--	wdev->beacon_interval = 0;
- }
- 
- static int cfg80211_netdev_notifier_call(struct notifier_block *nb,
-@@ -875,8 +873,11 @@ static int cfg80211_netdev_notifier_call
- 		break;
- 	case NETDEV_DOWN:
- 		cfg80211_update_iface_num(rdev, wdev->iftype, -1);
--		WARN_ON(rdev->scan_req && rdev->scan_req->wdev == wdev &&
--			!rdev->scan_req->notified);
-+		if (rdev->scan_req && rdev->scan_req->wdev == wdev) {
-+			if (WARN_ON(!rdev->scan_req->notified))
-+				rdev->scan_req->aborted = true;
-+			___cfg80211_scan_done(rdev, false);
-+		}
- 
- 		if (WARN_ON(rdev->sched_scan_req &&
- 			    rdev->sched_scan_req->dev == wdev->netdev)) {
---- a/net/wireless/core.h
-+++ b/net/wireless/core.h
-@@ -62,6 +62,7 @@ struct cfg80211_registered_device {
- 	struct rb_root bss_tree;
- 	u32 bss_generation;
- 	struct cfg80211_scan_request *scan_req; /* protected by RTNL */
-+	struct sk_buff *scan_msg;
- 	struct cfg80211_sched_scan_request *sched_scan_req;
- 	unsigned long suspend_at;
- 	struct work_struct scan_done_wk;
-@@ -210,6 +211,7 @@ struct cfg80211_event {
- 		} dc;
- 		struct {
- 			u8 bssid[ETH_ALEN];
-+			struct ieee80211_channel *channel;
- 		} ij;
- 	};
- };
-@@ -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,
- 			struct net_device *dev, bool nowext);
--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);
- int cfg80211_ibss_wext_join(struct cfg80211_registered_device *rdev,
- 			    struct wireless_dev *wdev);
- 
-@@ -361,7 +364,8 @@ int cfg80211_validate_key_settings(struc
- 				   struct key_params *params, int key_idx,
- 				   bool pairwise, const u8 *mac_addr);
- void __cfg80211_scan_done(struct work_struct *wk);
--void ___cfg80211_scan_done(struct cfg80211_registered_device *rdev);
-+void ___cfg80211_scan_done(struct cfg80211_registered_device *rdev,
-+			   bool send_message);
- void __cfg80211_sched_scan_results(struct work_struct *wk);
- int __cfg80211_stop_sched_scan(struct cfg80211_registered_device *rdev,
- 			       bool driver_initiated);
-@@ -441,7 +445,8 @@ static inline unsigned int elapsed_jiffi
- void
- cfg80211_get_chan_state(struct wireless_dev *wdev,
- 		        struct ieee80211_channel **chan,
--		        enum cfg80211_chan_mode *chanmode);
-+		        enum cfg80211_chan_mode *chanmode,
-+		        u8 *radar_detect);
- 
- int cfg80211_set_monitor_channel(struct cfg80211_registered_device *rdev,
- 				 struct cfg80211_chan_def *chandef);
---- a/net/wireless/nl80211.c
-+++ b/net/wireless/nl80211.c
-@@ -1723,9 +1723,10 @@ static int nl80211_dump_wiphy(struct sk_
- 				 * We can then retry with the larger buffer.
- 				 */
- 				if ((ret == -ENOBUFS || ret == -EMSGSIZE) &&
--				    !skb->len &&
-+				    !skb->len && !state->split &&
- 				    cb->min_dump_alloc < 4096) {
- 					cb->min_dump_alloc = 4096;
-+					state->split_start = 0;
- 					rtnl_unlock();
- 					return 1;
- 				}
-@@ -2047,10 +2048,12 @@ static int nl80211_set_wiphy(struct sk_b
- 		nla_for_each_nested(nl_txq_params,
- 				    info->attrs[NL80211_ATTR_WIPHY_TXQ_PARAMS],
- 				    rem_txq_params) {
--			nla_parse(tb, NL80211_TXQ_ATTR_MAX,
--				  nla_data(nl_txq_params),
--				  nla_len(nl_txq_params),
--				  txq_params_policy);
-+			result = nla_parse(tb, NL80211_TXQ_ATTR_MAX,
-+					   nla_data(nl_txq_params),
-+					   nla_len(nl_txq_params),
-+					   txq_params_policy);
-+			if (result)
-+				goto bad_res;
- 			result = parse_txq_params(tb, &txq_params);
- 			if (result)
- 				goto bad_res;
-@@ -3289,7 +3292,7 @@ static int nl80211_start_ap(struct sk_bu
- 	if (!err) {
- 		wdev->preset_chandef = params.chandef;
- 		wdev->beacon_interval = params.beacon_interval;
--		wdev->channel = params.chandef.chan;
-+		wdev->chandef = params.chandef;
- 		wdev->ssid_len = params.ssid_len;
- 		memcpy(wdev->ssid, params.ssid, wdev->ssid_len);
- 	}
-@@ -5210,9 +5213,11 @@ static int nl80211_set_reg(struct sk_buf
- 
- 	nla_for_each_nested(nl_reg_rule, info->attrs[NL80211_ATTR_REG_RULES],
- 			    rem_reg_rules) {
--		nla_parse(tb, NL80211_REG_RULE_ATTR_MAX,
--			  nla_data(nl_reg_rule), nla_len(nl_reg_rule),
--			  reg_rule_policy);
-+		r = nla_parse(tb, NL80211_REG_RULE_ATTR_MAX,
-+			      nla_data(nl_reg_rule), nla_len(nl_reg_rule),
-+			      reg_rule_policy);
-+		if (r)
-+			goto bad_reg;
- 		r = parse_reg_rule(tb, &rd->reg_rules[rule_idx]);
- 		if (r)
- 			goto bad_reg;
-@@ -5277,7 +5282,7 @@ static int nl80211_trigger_scan(struct s
- 	if (!rdev->ops->scan)
- 		return -EOPNOTSUPP;
- 
--	if (rdev->scan_req) {
-+	if (rdev->scan_req || rdev->scan_msg) {
- 		err = -EBUSY;
- 		goto unlock;
- 	}
-@@ -5475,6 +5480,7 @@ static int nl80211_start_sched_scan(stru
- 	enum ieee80211_band band;
- 	size_t ie_len;
- 	struct nlattr *tb[NL80211_SCHED_SCAN_MATCH_ATTR_MAX + 1];
-+	s32 default_match_rssi = NL80211_SCAN_RSSI_THOLD_OFF;
- 
- 	if (!(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_SCHED_SCAN) ||
- 	    !rdev->ops->sched_scan_start)
-@@ -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
-+	 * the old implementation, matchsets containing only the RSSI attribute
-+	 * (NL80211_SCHED_SCAN_MATCH_ATTR_RSSI) are considered as the 'default'
-+	 * RSSI for all matchsets, rather than their own matchset for reporting
-+	 * all APs with a strong RSSI. This is needed to be compatible with
-+	 * older userspace that treated a matchset with only the RSSI as the
-+	 * global RSSI for all other matchsets - if there are other matchsets.
-+	 */
-+	if (info->attrs[NL80211_ATTR_SCHED_SCAN_MATCH]) {
- 		nla_for_each_nested(attr,
- 				    info->attrs[NL80211_ATTR_SCHED_SCAN_MATCH],
--				    tmp)
--			n_match_sets++;
-+				    tmp) {
-+			struct nlattr *rssi;
-+
-+			err = nla_parse(tb, NL80211_SCHED_SCAN_MATCH_ATTR_MAX,
-+					nla_data(attr), nla_len(attr),
-+					nl80211_match_policy);
-+			if (err)
-+				return err;
-+			/* add other standalone attributes here */
-+			if (tb[NL80211_SCHED_SCAN_MATCH_ATTR_SSID]) {
-+				n_match_sets++;
-+				continue;
-+			}
-+			rssi = tb[NL80211_SCHED_SCAN_MATCH_ATTR_RSSI];
-+			if (rssi)
-+				default_match_rssi = nla_get_s32(rssi);
-+		}
-+	}
-+
-+	/* 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;
- 
- 	if (n_match_sets > wiphy->max_match_sets)
- 		return -EINVAL;
-@@ -5634,11 +5669,22 @@ static int nl80211_start_sched_scan(stru
- 				    tmp) {
- 			struct nlattr *ssid, *rssi;
- 
--			nla_parse(tb, NL80211_SCHED_SCAN_MATCH_ATTR_MAX,
--				  nla_data(attr), nla_len(attr),
--				  nl80211_match_policy);
-+			err = nla_parse(tb, NL80211_SCHED_SCAN_MATCH_ATTR_MAX,
-+					nla_data(attr), nla_len(attr),
-+					nl80211_match_policy);
-+			if (err)
-+				goto out_free;
- 			ssid = tb[NL80211_SCHED_SCAN_MATCH_ATTR_SSID];
- 			if (ssid) {
-+				if (WARN_ON(i >= n_match_sets)) {
-+					/* this indicates a programming error,
-+					 * the loop above should have verified
-+					 * things properly
-+					 */
-+					err = -EINVAL;
-+					goto out_free;
-+				}
-+
- 				if (nla_len(ssid) > IEEE80211_MAX_SSID_LEN) {
- 					err = -EINVAL;
- 					goto out_free;
-@@ -5647,15 +5693,28 @@ static int nl80211_start_sched_scan(stru
- 				       nla_data(ssid), nla_len(ssid));
- 				request->match_sets[i].ssid.ssid_len =
- 					nla_len(ssid);
-+				/* special attribute - old implemenation w/a */
-+				request->match_sets[i].rssi_thold =
-+					default_match_rssi;
-+				rssi = tb[NL80211_SCHED_SCAN_MATCH_ATTR_RSSI];
-+				if (rssi)
-+					request->match_sets[i].rssi_thold =
-+						nla_get_s32(rssi);
- 			}
--			rssi = tb[NL80211_SCHED_SCAN_MATCH_ATTR_RSSI];
--			if (rssi)
--				request->rssi_thold = nla_get_u32(rssi);
--			else
--				request->rssi_thold =
--						   NL80211_SCAN_RSSI_THOLD_OFF;
- 			i++;
- 		}
-+
-+		/* there was no other matchset, so the RSSI one is alone */
-+		if (i == 0)
-+			request->match_sets[0].rssi_thold = default_match_rssi;
-+
-+		request->min_rssi_thold = INT_MAX;
-+		for (i = 0; i < n_match_sets; i++)
-+			request->min_rssi_thold =
-+				min(request->match_sets[i].rssi_thold,
-+				    request->min_rssi_thold);
-+	} else {
-+		request->min_rssi_thold = NL80211_SCAN_RSSI_THOLD_OFF;
- 	}
- 
- 	if (info->attrs[NL80211_ATTR_IE]) {
-@@ -5751,7 +5810,7 @@ static int nl80211_start_radar_detection
- 
- 	err = rdev->ops->start_radar_detection(&rdev->wiphy, dev, &chandef);
- 	if (!err) {
--		wdev->channel = chandef.chan;
-+		wdev->chandef = chandef;
- 		wdev->cac_started = true;
- 		wdev->cac_start_time = jiffies;
- 	}
-@@ -7502,16 +7561,19 @@ static int nl80211_set_tx_bitrate_mask(s
- 	 * directly to the enum ieee80211_band values used in cfg80211.
- 	 */
- 	BUILD_BUG_ON(NL80211_MAX_SUPP_HT_RATES > IEEE80211_HT_MCS_MASK_LEN * 8);
--	nla_for_each_nested(tx_rates, info->attrs[NL80211_ATTR_TX_RATES], rem)
--	{
-+	nla_for_each_nested(tx_rates, info->attrs[NL80211_ATTR_TX_RATES], rem) {
- 		enum ieee80211_band band = nla_type(tx_rates);
-+		int err;
-+
- 		if (band < 0 || band >= IEEE80211_NUM_BANDS)
- 			return -EINVAL;
- 		sband = rdev->wiphy.bands[band];
- 		if (sband == NULL)
- 			return -EINVAL;
--		nla_parse(tb, NL80211_TXRATE_MAX, nla_data(tx_rates),
--			  nla_len(tx_rates), nl80211_txattr_policy);
-+		err = nla_parse(tb, NL80211_TXRATE_MAX, nla_data(tx_rates),
-+				nla_len(tx_rates), nl80211_txattr_policy);
-+		if (err)
-+			return err;
- 		if (tb[NL80211_TXRATE_LEGACY]) {
- 			mask.control[band].legacy = rateset_to_mask(
- 				sband,
-@@ -10054,40 +10116,31 @@ void nl80211_send_scan_start(struct cfg8
- 				NL80211_MCGRP_SCAN, GFP_KERNEL);
- }
- 
--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,
-+				       struct wireless_dev *wdev, bool aborted)
- {
- 	struct sk_buff *msg;
- 
- 	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
- 	if (!msg)
--		return;
-+		return NULL;
- 
- 	if (nl80211_send_scan_msg(msg, rdev, wdev, 0, 0, 0,
--				  NL80211_CMD_NEW_SCAN_RESULTS) < 0) {
-+				  aborted ? NL80211_CMD_SCAN_ABORTED :
-+					    NL80211_CMD_NEW_SCAN_RESULTS) < 0) {
- 		nlmsg_free(msg);
--		return;
-+		return NULL;
- 	}
- 
--	genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
--				NL80211_MCGRP_SCAN, GFP_KERNEL);
-+	return msg;
- }
- 
--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)
- {
--	struct sk_buff *msg;
--
--	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
- 	if (!msg)
- 		return;
- 
--	if (nl80211_send_scan_msg(msg, rdev, wdev, 0, 0, 0,
--				  NL80211_CMD_SCAN_ABORTED) < 0) {
--		nlmsg_free(msg);
--		return;
--	}
--
- 	genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
- 				NL80211_MCGRP_SCAN, GFP_KERNEL);
- }
-@@ -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;
- 	nl80211_ch_switch_notify(rdev, dev, chandef, GFP_KERNEL);
- }
- EXPORT_SYMBOL(cfg80211_ch_switch_notify);
-@@ -11673,6 +11727,35 @@ void cfg80211_crit_proto_stopped(struct 
- }
- EXPORT_SYMBOL(cfg80211_crit_proto_stopped);
- 
-+void nl80211_send_ap_stopped(struct wireless_dev *wdev)
-+{
-+	struct wiphy *wiphy = wdev->wiphy;
-+	struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
-+	struct sk_buff *msg;
-+	void *hdr;
-+
-+	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
-+	if (!msg)
-+		return;
-+
-+	hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_STOP_AP);
-+	if (!hdr)
-+		goto out;
-+
-+	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;
-+
-+	genlmsg_end(msg, hdr);
-+
-+	genlmsg_multicast_netns(&nl80211_fam, wiphy_net(wiphy), msg, 0,
-+				NL80211_MCGRP_MLME, GFP_KERNEL);
-+	return;
-+ out:
-+	nlmsg_free(msg);
-+}
-+
- /* initialisation/exit functions */
- 
- int nl80211_init(void)
---- a/net/wireless/nl80211.h
-+++ b/net/wireless/nl80211.h
-@@ -8,10 +8,10 @@ void nl80211_exit(void);
- void nl80211_notify_dev_rename(struct cfg80211_registered_device *rdev);
- void nl80211_send_scan_start(struct cfg80211_registered_device *rdev,
- 			     struct wireless_dev *wdev);
--void nl80211_send_scan_done(struct cfg80211_registered_device *rdev,
--			    struct wireless_dev *wdev);
--void nl80211_send_scan_aborted(struct cfg80211_registered_device *rdev,
--			       struct wireless_dev *wdev);
-+struct sk_buff *nl80211_build_scan_msg(struct cfg80211_registered_device *rdev,
-+				       struct wireless_dev *wdev, bool aborted);
-+void nl80211_send_scan_result(struct cfg80211_registered_device *rdev,
-+			      struct sk_buff *msg);
- void nl80211_send_sched_scan(struct cfg80211_registered_device *rdev,
- 			     struct net_device *netdev, u32 cmd);
- void nl80211_send_sched_scan_results(struct cfg80211_registered_device *rdev,
-@@ -74,6 +74,8 @@ nl80211_radar_notify(struct cfg80211_reg
- 		     enum nl80211_radar_event event,
- 		     struct net_device *netdev, gfp_t gfp);
- 
-+void nl80211_send_ap_stopped(struct wireless_dev *wdev);
-+
- void cfg80211_rdev_free_coalesce(struct cfg80211_registered_device *rdev);
- 
- #endif /* __NET_WIRELESS_NL80211_H */
---- a/net/wireless/scan.c
-+++ b/net/wireless/scan.c
-@@ -161,18 +161,25 @@ static void __cfg80211_bss_expire(struct
- 		dev->bss_generation++;
- }
- 
--void ___cfg80211_scan_done(struct cfg80211_registered_device *rdev)
-+void ___cfg80211_scan_done(struct cfg80211_registered_device *rdev,
-+			   bool send_message)
- {
- 	struct cfg80211_scan_request *request;
- 	struct wireless_dev *wdev;
-+	struct sk_buff *msg;
- #ifdef CPTCFG_CFG80211_WEXT
- 	union iwreq_data wrqu;
- #endif
- 
- 	ASSERT_RTNL();
- 
--	request = rdev->scan_req;
-+	if (rdev->scan_msg) {
-+		nl80211_send_scan_result(rdev, rdev->scan_msg);
-+		rdev->scan_msg = NULL;
-+		return;
-+	}
- 
-+	request = rdev->scan_req;
- 	if (!request)
- 		return;
- 
-@@ -186,18 +193,16 @@ void ___cfg80211_scan_done(struct cfg802
- 	if (wdev->netdev)
- 		cfg80211_sme_scan_done(wdev->netdev);
- 
--	if (request->aborted) {
--		nl80211_send_scan_aborted(rdev, wdev);
--	} else {
--		if (request->flags & NL80211_SCAN_FLAG_FLUSH) {
--			/* flush entries from previous scans */
--			spin_lock_bh(&rdev->bss_lock);
--			__cfg80211_bss_expire(rdev, request->scan_start);
--			spin_unlock_bh(&rdev->bss_lock);
--		}
--		nl80211_send_scan_done(rdev, wdev);
-+	if (!request->aborted &&
-+	    request->flags & NL80211_SCAN_FLAG_FLUSH) {
-+		/* flush entries from previous scans */
-+		spin_lock_bh(&rdev->bss_lock);
-+		__cfg80211_bss_expire(rdev, request->scan_start);
-+		spin_unlock_bh(&rdev->bss_lock);
- 	}
- 
-+	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
- 
- 	rdev->scan_req = NULL;
- 	kfree(request);
-+
-+	if (!send_message)
-+		rdev->scan_msg = msg;
-+	else
-+		nl80211_send_scan_result(rdev, msg);
- }
- 
- void __cfg80211_scan_done(struct work_struct *wk)
-@@ -221,7 +231,7 @@ void __cfg80211_scan_done(struct work_st
- 			    scan_done_wk);
- 
- 	rtnl_lock();
--	___cfg80211_scan_done(rdev);
-+	___cfg80211_scan_done(rdev, true);
- 	rtnl_unlock();
- }
- 
-@@ -1079,7 +1089,7 @@ int cfg80211_wext_siwscan(struct net_dev
- 	if (IS_ERR(rdev))
- 		return PTR_ERR(rdev);
- 
--	if (rdev->scan_req) {
-+	if (rdev->scan_req || rdev->scan_msg) {
- 		err = -EBUSY;
- 		goto out;
- 	}
-@@ -1481,7 +1491,7 @@ int cfg80211_wext_giwscan(struct net_dev
- 	if (IS_ERR(rdev))
- 		return PTR_ERR(rdev);
- 
--	if (rdev->scan_req)
-+	if (rdev->scan_req || rdev->scan_msg)
- 		return -EAGAIN;
- 
- 	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);
- 
--	if (rdev->scan_req)
-+	if (rdev->scan_req || rdev->scan_msg)
- 		return -EBUSY;
- 
- 	if (wdev->conn->params.channel)
---- a/net/mac80211/mlme.c
-+++ b/net/mac80211/mlme.c
-@@ -1001,7 +1001,6 @@ ieee80211_sta_process_chanswitch(struct 
- 	}
- 
- 	ifmgd->flags |= IEEE80211_STA_CSA_RECEIVED;
--	sdata->vif.csa_active = true;
- 
- 	mutex_lock(&local->chanctx_mtx);
- 	if (local->use_chanctx) {
-@@ -1039,6 +1038,7 @@ ieee80211_sta_process_chanswitch(struct 
- 	mutex_unlock(&local->chanctx_mtx);
- 
- 	sdata->csa_chandef = csa_ie.chandef;
-+	sdata->vif.csa_active = true;
- 
- 	if (csa_ie.mode)
- 		ieee80211_stop_queues_by_reason(&local->hw,
---- a/net/mac80211/chan.c
-+++ b/net/mac80211/chan.c
-@@ -196,6 +196,8 @@ static bool ieee80211_is_radar_required(
- {
- 	struct ieee80211_sub_if_data *sdata;
- 
-+	lockdep_assert_held(&local->mtx);
-+
- 	rcu_read_lock();
- 	list_for_each_entry_rcu(sdata, &local->interfaces, list) {
- 		if (sdata->radar_required) {
---- a/net/mac80211/ibss.c
-+++ b/net/mac80211/ibss.c
-@@ -294,7 +294,6 @@ static void __ieee80211_sta_join_ibss(st
- 	}
- 
- 	mutex_lock(&local->mtx);
--	ieee80211_vif_release_channel(sdata);
- 	if (ieee80211_vif_use_channel(sdata, &chandef,
- 				      ifibss->fixed_channel ?
- 					IEEE80211_CHANCTX_SHARED :
-@@ -303,6 +302,7 @@ static void __ieee80211_sta_join_ibss(st
- 		mutex_unlock(&local->mtx);
- 		return;
- 	}
-+	sdata->radar_required = radar_required;
- 	mutex_unlock(&local->mtx);
- 
- 	memcpy(ifibss->bssid, bssid, ETH_ALEN);
-@@ -318,7 +318,6 @@ static void __ieee80211_sta_join_ibss(st
- 	rcu_assign_pointer(ifibss->presp, presp);
- 	mgmt = (void *)presp->head;
- 
--	sdata->radar_required = radar_required;
- 	sdata->vif.bss_conf.enable_beacon = true;
- 	sdata->vif.bss_conf.beacon_int = beacon_int;
- 	sdata->vif.bss_conf.basic_rates = basic_rates;
-@@ -386,7 +385,7 @@ static void __ieee80211_sta_join_ibss(st
- 					      presp->head_len, 0, GFP_KERNEL);
- 	cfg80211_put_bss(local->hw.wiphy, bss);
- 	netif_carrier_on(sdata->dev);
--	cfg80211_ibss_joined(sdata->dev, ifibss->bssid, GFP_KERNEL);
-+	cfg80211_ibss_joined(sdata->dev, ifibss->bssid, chan, GFP_KERNEL);
- }
- 
- 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;
- 
-+	sdata_assert_lock(sdata);
-+
- 	sta_flags = IEEE80211_STA_DISABLE_VHT;
- 	switch (ifibss->chandef.width) {
- 	case NL80211_CHAN_WIDTH_5:
-@@ -1471,6 +1472,11 @@ static void ieee80211_rx_mgmt_probe_req(
- 	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;
-+
-+	/* avoid excessive retries for probe request to wildcard SSIDs */
-+	if (pos[1] == 0)
-+		IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_CTL_NO_ACK;
-+
- 	ieee80211_tx_skb(sdata, skb);
- }
- 
---- 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;
- 
-+	sdata_assert_lock(sdata);
-+
- 	sta_flags = IEEE80211_STA_DISABLE_VHT;
- 	switch (sdata->vif.bss_conf.chandef.width) {
- 	case NL80211_CHAN_WIDTH_20_NOHT:
---- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
-+++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
-@@ -4658,6 +4658,7 @@ brcmf_notify_connect_status(struct brcmf
- 	struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
- 	struct net_device *ndev = ifp->ndev;
- 	struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
-+	struct ieee80211_channel *chan;
- 	s32 err = 0;
- 
- 	if (ifp->vif->mode == WL_MODE_AP) {
-@@ -4665,9 +4666,10 @@ brcmf_notify_connect_status(struct brcmf
- 	} else if (brcmf_is_linkup(e)) {
- 		brcmf_dbg(CONN, "Linkup\n");
- 		if (brcmf_is_ibssmode(ifp->vif)) {
-+			chan = ieee80211_get_channel(cfg->wiphy, cfg->channel);
- 			memcpy(profile->bssid, e->addr, ETH_ALEN);
- 			wl_inform_ibss(cfg, ndev, e->addr);
--			cfg80211_ibss_joined(ndev, e->addr, GFP_KERNEL);
-+			cfg80211_ibss_joined(ndev, e->addr, chan, GFP_KERNEL);
- 			clear_bit(BRCMF_VIF_STATUS_CONNECTING,
- 				  &ifp->vif->sme_state);
- 			set_bit(BRCMF_VIF_STATUS_CONNECTED,
---- a/drivers/net/wireless/libertas/cfg.c
-+++ b/drivers/net/wireless/libertas/cfg.c
-@@ -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;
- 
--	cfg80211_ibss_joined(priv->dev, bssid, GFP_KERNEL);
-+	cfg80211_ibss_joined(priv->dev, bssid, params->chandef.chan,
-+			     GFP_KERNEL);
- 
- 	/* TODO: consider doing this at MACREG_INT_CODE_LINK_SENSED time */
- 	priv->connect_status = LBS_CONNECTED;
---- a/drivers/net/wireless/mwifiex/cfg80211.c
-+++ b/drivers/net/wireless/mwifiex/cfg80211.c
-@@ -1881,7 +1881,8 @@ mwifiex_cfg80211_join_ibss(struct wiphy 
- 				     params->privacy);
- done:
- 	if (!ret) {
--		cfg80211_ibss_joined(priv->netdev, priv->cfg_bssid, GFP_KERNEL);
-+		cfg80211_ibss_joined(priv->netdev, priv->cfg_bssid,
-+				     params->chandef.chan, GFP_KERNEL);
- 		dev_dbg(priv->adapter->dev,
- 			"info: joined/created adhoc network with bssid"
- 			" %pM successfully\n", priv->cfg_bssid);
---- a/drivers/net/wireless/rndis_wlan.c
-+++ b/drivers/net/wireless/rndis_wlan.c
-@@ -2835,7 +2835,9 @@ static void rndis_wlan_do_link_up_work(s
- 					bssid, req_ie, req_ie_len,
- 					resp_ie, resp_ie_len, GFP_KERNEL);
- 	} else if (priv->infra_mode == NDIS_80211_INFRA_ADHOC)
--		cfg80211_ibss_joined(usbdev->net, bssid, GFP_KERNEL);
-+		cfg80211_ibss_joined(usbdev->net, bssid,
-+				     get_current_channel(usbdev, NULL),
-+				     GFP_KERNEL);
- 
- 	kfree(info);
- 
---- a/net/wireless/ibss.c
-+++ b/net/wireless/ibss.c
-@@ -14,7 +14,8 @@
- #include "rdev-ops.h"
- 
- 
--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)
- {
- 	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;
- 
--	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);
- 
- 	if (WARN_ON(!bss))
-@@ -54,21 +54,26 @@ void __cfg80211_ibss_joined(struct net_d
- #endif
- }
- 
--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)
- {
- 	struct wireless_dev *wdev = dev->ieee80211_ptr;
- 	struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
- 	struct cfg80211_event *ev;
- 	unsigned long flags;
- 
--	trace_cfg80211_ibss_joined(dev, bssid);
-+	trace_cfg80211_ibss_joined(dev, bssid, channel);
-+
-+	if (WARN_ON(!channel))
-+		return;
- 
- 	ev = kzalloc(sizeof(*ev), gfp);
- 	if (!ev)
- 		return;
- 
- 	ev->type = EVENT_IBSS_JOINED;
--	memcpy(ev->cr.bssid, bssid, ETH_ALEN);
-+	memcpy(ev->ij.bssid, bssid, ETH_ALEN);
-+	ev->ij.channel = channel;
- 
- 	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
- 
- 	wdev->ibss_fixed = params->channel_fixed;
- 	wdev->ibss_dfs_possible = params->userspace_handles_dfs;
-+	wdev->chandef = params->chandef;
- #ifdef CPTCFG_CFG80211_WEXT
- 	wdev->wext.ibss.chandef = params->chandef;
- #endif
-@@ -200,6 +206,7 @@ static void __cfg80211_clear_ibss(struct
- 
- 	wdev->current_bss = NULL;
- 	wdev->ssid_len = 0;
-+	memset(&wdev->chandef, 0, sizeof(wdev->chandef));
- #ifdef CPTCFG_CFG80211_WEXT
- 	if (!nowext)
- 		wdev->wext.ibss.ssid_len = 0;
---- a/net/wireless/trace.h
-+++ b/net/wireless/trace.h
-@@ -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))
- );
- 
--DEFINE_EVENT(cfg80211_rx_evt, cfg80211_ibss_joined,
--	TP_PROTO(struct net_device *netdev, const u8 *addr),
--	TP_ARGS(netdev, addr)
--);
--
- DEFINE_EVENT(cfg80211_rx_evt, cfg80211_rx_spurious_frame,
- 	TP_PROTO(struct net_device *netdev, const u8 *addr),
- 	TP_ARGS(netdev, addr)
-@@ -2293,6 +2288,24 @@ DEFINE_EVENT(cfg80211_rx_evt, cfg80211_r
- 	TP_ARGS(netdev, addr)
- );
- 
-+TRACE_EVENT(cfg80211_ibss_joined,
-+	TP_PROTO(struct net_device *netdev, const u8 *bssid,
-+		 struct ieee80211_channel *channel),
-+	TP_ARGS(netdev, bssid, channel),
-+	TP_STRUCT__entry(
-+		NETDEV_ENTRY
-+		MAC_ENTRY(bssid)
-+		CHAN_ENTRY
-+	),
-+	TP_fast_assign(
-+		NETDEV_ASSIGN;
-+		MAC_ASSIGN(bssid, bssid);
-+		CHAN_ASSIGN(channel);
-+	),
-+	TP_printk(NETDEV_PR_FMT ", bssid: " MAC_PR_FMT ", " CHAN_PR_FMT,
-+		  NETDEV_PR_ARG, MAC_PR_ARG(bssid), CHAN_PR_ARG)
-+);
-+
- TRACE_EVENT(cfg80211_probe_status,
- 	TP_PROTO(struct net_device *netdev, const u8 *addr, u64 cookie,
- 		 bool acked),
---- a/net/wireless/util.c
-+++ b/net/wireless/util.c
-@@ -820,7 +820,8 @@ void cfg80211_process_wdev_events(struct
- 						ev->dc.reason, true);
- 			break;
- 		case EVENT_IBSS_JOINED:
--			__cfg80211_ibss_joined(wdev->netdev, ev->ij.bssid);
-+			__cfg80211_ibss_joined(wdev->netdev, ev->ij.bssid,
-+					       ev->ij.channel);
- 			break;
- 		}
- 		wdev_unlock(wdev);
-@@ -1356,7 +1357,7 @@ int cfg80211_can_use_iftype_chan(struct 
- 		 */
- 		mutex_lock_nested(&wdev_iter->mtx, 1);
- 		__acquire(wdev_iter->mtx);
--		cfg80211_get_chan_state(wdev_iter, &ch, &chmode);
-+		cfg80211_get_chan_state(wdev_iter, &ch, &chmode, &radar_detect);
- 		wdev_unlock(wdev_iter);
- 
- 		switch (chmode) {
---- a/net/wireless/chan.c
-+++ b/net/wireless/chan.c
-@@ -642,7 +642,8 @@ int cfg80211_set_monitor_channel(struct 
- void
- cfg80211_get_chan_state(struct wireless_dev *wdev,
- 		        struct ieee80211_channel **chan,
--		        enum cfg80211_chan_mode *chanmode)
-+		        enum cfg80211_chan_mode *chanmode,
-+		        u8 *radar_detect)
- {
- 	*chan = NULL;
- 	*chanmode = CHAN_MODE_UNDEFINED;
-@@ -660,6 +661,11 @@ cfg80211_get_chan_state(struct wireless_
- 				     !wdev->ibss_dfs_possible)
- 				  ? CHAN_MODE_SHARED
- 				  : CHAN_MODE_EXCLUSIVE;
-+
-+			/* consider worst-case - IBSS can try to return to the
-+			 * original user-specified channel as creator */
-+			if (wdev->ibss_dfs_possible)
-+				*radar_detect |= BIT(wdev->chandef.width);
- 			return;
- 		}
- 		break;
-@@ -674,17 +680,26 @@ cfg80211_get_chan_state(struct wireless_
- 	case NL80211_IFTYPE_AP:
- 	case NL80211_IFTYPE_P2P_GO:
- 		if (wdev->cac_started) {
--			*chan = wdev->channel;
-+			*chan = wdev->chandef.chan;
- 			*chanmode = CHAN_MODE_SHARED;
-+			*radar_detect |= BIT(wdev->chandef.width);
- 		} else if (wdev->beacon_interval) {
--			*chan = wdev->channel;
-+			*chan = wdev->chandef.chan;
- 			*chanmode = CHAN_MODE_SHARED;
-+
-+			if (cfg80211_chandef_dfs_required(wdev->wiphy,
-+							  &wdev->chandef))
-+				*radar_detect |= BIT(wdev->chandef.width);
- 		}
- 		return;
- 	case NL80211_IFTYPE_MESH_POINT:
- 		if (wdev->mesh_id_len) {
--			*chan = wdev->channel;
-+			*chan = wdev->chandef.chan;
- 			*chanmode = CHAN_MODE_SHARED;
-+
-+			if (cfg80211_chandef_dfs_required(wdev->wiphy,
-+							  &wdev->chandef))
-+				*radar_detect |= BIT(wdev->chandef.width);
- 		}
- 		return;
- 	case NL80211_IFTYPE_MONITOR:
---- a/net/wireless/mesh.c
-+++ b/net/wireless/mesh.c
-@@ -195,7 +195,7 @@ int __cfg80211_join_mesh(struct cfg80211
- 	if (!err) {
- 		memcpy(wdev->ssid, setup->mesh_id, setup->mesh_id_len);
- 		wdev->mesh_id_len = setup->mesh_id_len;
--		wdev->channel = setup->chandef.chan;
-+		wdev->chandef = setup->chandef;
- 	}
- 
- 	return err;
-@@ -244,7 +244,7 @@ int cfg80211_set_mesh_channel(struct cfg
- 		err = rdev_libertas_set_mesh_channel(rdev, wdev->netdev,
- 						     chandef->chan);
- 		if (!err)
--			wdev->channel = chandef->chan;
-+			wdev->chandef = *chandef;
- 
- 		return err;
- 	}
-@@ -276,7 +276,7 @@ static int __cfg80211_leave_mesh(struct 
- 	err = rdev_leave_mesh(rdev, dev);
- 	if (!err) {
- 		wdev->mesh_id_len = 0;
--		wdev->channel = NULL;
-+		memset(&wdev->chandef, 0, sizeof(wdev->chandef));
- 		rdev_set_qos_map(rdev, dev, NULL);
- 	}
- 
---- 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;
- 
--	if (WARN_ON(!wdev->channel))
-+	if (WARN_ON(!wdev->chandef.chan))
- 		return;
- 
- 	switch (event) {
---- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
-+++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
-@@ -5065,6 +5065,10 @@ static u16 ar9003_hw_get_max_edge_power(
- 			break;
- 		}
- 	}
-+
-+	if (is2GHz && !twiceMaxEdgePower)
-+		twiceMaxEdgePower = 60;
-+
- 	return twiceMaxEdgePower;
- }
- 
---- a/drivers/net/wireless/ath/ath9k/ar9003_calib.c
-+++ b/drivers/net/wireless/ath/ath9k/ar9003_calib.c
-@@ -23,10 +23,11 @@
- #define MAX_MEASUREMENT	MAX_IQCAL_MEASUREMENT
- #define MAX_MAG_DELTA	11
- #define MAX_PHS_DELTA	10
-+#define MAXIQCAL        3
- 
- struct coeff {
--	int mag_coeff[AR9300_MAX_CHAINS][MAX_MEASUREMENT];
--	int phs_coeff[AR9300_MAX_CHAINS][MAX_MEASUREMENT];
-+	int mag_coeff[AR9300_MAX_CHAINS][MAX_MEASUREMENT][MAXIQCAL];
-+	int phs_coeff[AR9300_MAX_CHAINS][MAX_MEASUREMENT][MAXIQCAL];
- 	int iqc_coeff[2];
- };
- 
-@@ -800,7 +801,7 @@ static bool ar9003_hw_calc_iq_corr(struc
- 	if (q_q_coff > 63)
- 		q_q_coff = 63;
- 
--	iqc_coeff[0] = (q_q_coff * 128) + q_i_coff;
-+	iqc_coeff[0] = (q_q_coff * 128) + (0x7f & q_i_coff);
- 
- 	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;
- 
--	iqc_coeff[1] = (q_q_coff * 128) + q_i_coff;
-+	iqc_coeff[1] = (q_q_coff * 128) + (0x7f & q_i_coff);
- 
- 	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;
- }
- 
--static void ar9003_hw_detect_outlier(int *mp_coeff, int nmeasurement,
-+static void ar9003_hw_detect_outlier(int mp_coeff[][MAXIQCAL],
-+				     int nmeasurement,
- 				     int max_delta)
- {
- 	int mp_max = -64, max_idx = 0;
-@@ -848,20 +850,20 @@ static void ar9003_hw_detect_outlier(int
- 
- 	/* find min/max mismatch across all calibrated gains */
- 	for (i = 0; i < nmeasurement; i++) {
--		if (mp_coeff[i] > mp_max) {
--			mp_max = mp_coeff[i];
-+		if (mp_coeff[i][0] > mp_max) {
-+			mp_max = mp_coeff[i][0];
- 			max_idx = i;
--		} else if (mp_coeff[i] < mp_min) {
--			mp_min = mp_coeff[i];
-+		} else if (mp_coeff[i][0] < mp_min) {
-+			mp_min = mp_coeff[i][0];
- 			min_idx = i;
- 		}
- 	}
- 
- 	/* find average (exclude max abs value) */
- 	for (i = 0; i < nmeasurement; i++) {
--		if ((abs(mp_coeff[i]) < abs(mp_max)) ||
--		    (abs(mp_coeff[i]) < abs(mp_min))) {
--			mp_avg += mp_coeff[i];
-+		if ((abs(mp_coeff[i][0]) < abs(mp_max)) ||
-+		    (abs(mp_coeff[i][0]) < abs(mp_min))) {
-+			mp_avg += mp_coeff[i][0];
- 			mp_count++;
- 		}
- 	}
-@@ -873,7 +875,7 @@ static void ar9003_hw_detect_outlier(int
- 	if (mp_count)
- 		mp_avg /= mp_count;
- 	else
--		mp_avg = mp_coeff[nmeasurement - 1];
-+		mp_avg = mp_coeff[nmeasurement - 1][0];
- 
- 	/* detect outlier */
- 	if (abs(mp_max - mp_min) > max_delta) {
-@@ -882,15 +884,16 @@ static void ar9003_hw_detect_outlier(int
- 		else
- 			outlier_idx = min_idx;
- 
--		mp_coeff[outlier_idx] = mp_avg;
-+		mp_coeff[outlier_idx][0] = mp_avg;
- 	}
- }
- 
--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)
- {
- 	int i, im, nmeasurement;
-+	int magnitude, phase;
- 	u32 tx_corr_coeff[MAX_MEASUREMENT][AR9300_MAX_CHAINS];
- 	struct ath9k_hw_cal_data *caldata = ah->caldata;
- 
-@@ -920,21 +923,30 @@ static void ar9003_hw_tx_iqcal_load_avg_
- 		if (nmeasurement > MAX_MEASUREMENT)
- 			nmeasurement = MAX_MEASUREMENT;
- 
--		/* detect outlier only if nmeasurement > 1 */
--		if (nmeasurement > 1) {
--			/* Detect magnitude outlier */
--			ar9003_hw_detect_outlier(coeff->mag_coeff[i],
--					nmeasurement, MAX_MAG_DELTA);
--
--			/* Detect phase outlier */
--			ar9003_hw_detect_outlier(coeff->phs_coeff[i],
--					nmeasurement, MAX_PHS_DELTA);
-+		/*
-+		 * Skip normal outlier detection for AR9550.
-+		 */
-+		if (!AR_SREV_9550(ah)) {
-+			/* detect outlier only if nmeasurement > 1 */
-+			if (nmeasurement > 1) {
-+				/* Detect magnitude outlier */
-+				ar9003_hw_detect_outlier(coeff->mag_coeff[i],
-+							 nmeasurement,
-+							 MAX_MAG_DELTA);
-+
-+				/* Detect phase outlier */
-+				ar9003_hw_detect_outlier(coeff->phs_coeff[i],
-+							 nmeasurement,
-+							 MAX_PHS_DELTA);
-+			}
- 		}
- 
- 		for (im = 0; im < nmeasurement; im++) {
-+			magnitude = coeff->mag_coeff[i][im][0];
-+			phase = coeff->phs_coeff[i][im][0];
- 
--			coeff->iqc_coeff[0] = (coeff->mag_coeff[i][im] & 0x7f) |
--				((coeff->phs_coeff[i][im] & 0x7f) << 7);
-+			coeff->iqc_coeff[0] =
-+				(phase & 0x7f) | ((magnitude & 0x7f) << 7);
- 
- 			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;
- }
- 
--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)
-+{
-+	struct ath_common *common = ath9k_hw_common(ah);
-+	int im, ix, iy, temp;
-+
-+	for (im = 0; im < nmeasurement; im++) {
-+		for (ix = 0; ix < MAXIQCAL - 1; ix++) {
-+			for (iy = ix + 1; iy <= MAXIQCAL - 1; iy++) {
-+				if (coeff->mag_coeff[i][im][iy] <
-+				    coeff->mag_coeff[i][im][ix]) {
-+					temp = coeff->mag_coeff[i][im][ix];
-+					coeff->mag_coeff[i][im][ix] =
-+						coeff->mag_coeff[i][im][iy];
-+					coeff->mag_coeff[i][im][iy] = temp;
-+				}
-+				if (coeff->phs_coeff[i][im][iy] <
-+				    coeff->phs_coeff[i][im][ix]) {
-+					temp = coeff->phs_coeff[i][im][ix];
-+					coeff->phs_coeff[i][im][ix] =
-+						coeff->phs_coeff[i][im][iy];
-+					coeff->phs_coeff[i][im][iy] = temp;
-+				}
-+			}
-+		}
-+		coeff->mag_coeff[i][im][0] = coeff->mag_coeff[i][im][MAXIQCAL / 2];
-+		coeff->phs_coeff[i][im][0] = coeff->phs_coeff[i][im][MAXIQCAL / 2];
-+
-+		ath_dbg(common, CALIBRATE,
-+			"IQCAL: Median [ch%d][gain%d]: mag = %d phase = %d\n",
-+			i, im,
-+			coeff->mag_coeff[i][im][0],
-+			coeff->phs_coeff[i][im][0]);
-+	}
-+}
-+
-+static bool ar955x_tx_iq_cal_median(struct ath_hw *ah,
-+				    struct coeff *coeff,
-+				    int iqcal_idx,
-+				    int nmeasurement)
-+{
-+	int i;
-+
-+	if ((iqcal_idx + 1) != MAXIQCAL)
-+		return false;
-+
-+	for (i = 0; i < AR9300_MAX_CHAINS; i++) {
-+		__ar955x_tx_iq_cal_sort(ah, coeff, i, nmeasurement);
-+	}
-+
-+	return true;
-+}
-+
-+static void ar9003_hw_tx_iq_cal_post_proc(struct ath_hw *ah,
-+					  int iqcal_idx,
-+					  bool is_reusable)
- {
- 	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
- 		AR_PHY_CHAN_INFO_TAB_1,
- 		AR_PHY_CHAN_INFO_TAB_2,
- 	};
--	struct coeff coeff;
-+	static struct coeff coeff;
- 	s32 iq_res[6];
- 	int i, im, j;
--	int nmeasurement;
-+	int nmeasurement = 0;
-+	bool outlier_detect = true;
- 
- 	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;
- 			}
- 
--			coeff.mag_coeff[i][im] = coeff.iqc_coeff[0] & 0x7f;
--			coeff.phs_coeff[i][im] =
-+			coeff.phs_coeff[i][im][iqcal_idx] =
-+				coeff.iqc_coeff[0] & 0x7f;
-+			coeff.mag_coeff[i][im][iqcal_idx] =
- 				(coeff.iqc_coeff[0] >> 7) & 0x7f;
- 
--			if (coeff.mag_coeff[i][im] > 63)
--				coeff.mag_coeff[i][im] -= 128;
--			if (coeff.phs_coeff[i][im] > 63)
--				coeff.phs_coeff[i][im] -= 128;
-+			if (coeff.mag_coeff[i][im][iqcal_idx] > 63)
-+				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;
- 		}
- 	}
--	ar9003_hw_tx_iqcal_load_avg_2_passes(ah, &coeff, is_reusable);
-+
-+	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;
- 
-@@ -1409,7 +1484,7 @@ skip_tx_iqcal:
- 	}
- 
- 	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);
- 
-@@ -1455,14 +1530,38 @@ skip_tx_iqcal:
- 	return true;
- }
- 
-+static bool do_ar9003_agc_cal(struct ath_hw *ah)
-+{
-+	struct ath_common *common = ath9k_hw_common(ah);
-+	bool status;
-+
-+	REG_WRITE(ah, AR_PHY_AGC_CONTROL,
-+		  REG_READ(ah, AR_PHY_AGC_CONTROL) |
-+		  AR_PHY_AGC_CONTROL_CAL);
-+
-+	status = ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL,
-+			       AR_PHY_AGC_CONTROL_CAL,
-+			       0, AH_WAIT_TIMEOUT);
-+	if (!status) {
-+		ath_dbg(common, CALIBRATE,
-+			"offset calibration failed to complete in %d ms,"
-+			"noisy environment?\n",
-+			AH_WAIT_TIMEOUT / 1000);
-+		return false;
-+	}
-+
-+	return true;
-+}
-+
- static bool ar9003_hw_init_cal_soc(struct ath_hw *ah,
- 				   struct ath9k_channel *chan)
- {
- 	struct ath_common *common = ath9k_hw_common(ah);
- 	struct ath9k_hw_cal_data *caldata = ah->caldata;
- 	bool txiqcal_done = false;
--	bool is_reusable = true, status = true;
-+	bool status = true;
- 	bool run_agc_cal = false, sep_iq_cal = false;
-+	int i = 0;
- 
- 	/* 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.
- 	 */
- 	if (ah->enabled_cals & TX_IQ_ON_AGC_CAL) {
--		txiqcal_done = true;
-+		if (REG_READ_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_0,
-+				   AR_PHY_TX_IQCAL_CONTROL_0_ENABLE_TXIQ_CAL)) {
-+				txiqcal_done = true;
-+		} else {
-+			txiqcal_done = false;
-+		}
- 		run_agc_cal = true;
- 	} else {
- 		sep_iq_cal = true;
-@@ -1512,27 +1616,37 @@ skip_tx_iqcal:
- 		if (AR_SREV_9330_11(ah))
- 			ar9003_hw_manual_peak_cal(ah, 0, IS_CHAN_2GHZ(chan));
- 
--		/* Calibrate the AGC */
--		REG_WRITE(ah, AR_PHY_AGC_CONTROL,
--			  REG_READ(ah, AR_PHY_AGC_CONTROL) |
--			  AR_PHY_AGC_CONTROL_CAL);
--
--		/* Poll for offset calibration complete */
--		status = ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL,
--				       AR_PHY_AGC_CONTROL_CAL,
--				       0, AH_WAIT_TIMEOUT);
--	}
-+		/*
-+		 * For non-AR9550 chips, we just trigger AGC calibration
-+		 * in the HW, poll for completion and then process
-+		 * the results.
-+		 *
-+		 * For AR955x, we run it multiple times and use
-+		 * median IQ correction.
-+		 */
-+		if (!AR_SREV_9550(ah)) {
-+			status = do_ar9003_agc_cal(ah);
-+			if (!status)
-+				return false;
- 
--	if (!status) {
--		ath_dbg(common, CALIBRATE,
--			"offset calibration failed to complete in %d ms; noisy environment?\n",
--			AH_WAIT_TIMEOUT / 1000);
--		return false;
-+			if (txiqcal_done)
-+				ar9003_hw_tx_iq_cal_post_proc(ah, 0, false);
-+		} else {
-+			if (!txiqcal_done) {
-+				status = do_ar9003_agc_cal(ah);
-+				if (!status)
-+					return false;
-+			} else {
-+				for (i = 0; i < MAXIQCAL; i++) {
-+					status = do_ar9003_agc_cal(ah);
-+					if (!status)
-+						return false;
-+					ar9003_hw_tx_iq_cal_post_proc(ah, i, false);
-+				}
-+			}
-+		}
- 	}
- 
--	if (txiqcal_done)
--		ar9003_hw_tx_iq_cal_post_proc(ah, is_reusable);
--
- 	/* Revert chainmask to runtime parameters */
- 	ar9003_hw_set_chain_masks(ah, ah->rxchainmask, ah->txchainmask);
- 
---- 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 <linux/cache.h>
-+
- #include "rtl818x.h"
- #include "leds.h"
- 
-@@ -139,7 +141,10 @@ struct rtl8187_priv {
- 	u8 aifsn[4];
- 	u8 rfkill_mask;
- 	struct {
--		__le64 buf;
-+		union {
-+			__le64 buf;
-+			u8 dummy1[L1_CACHE_BYTES];
-+		} ____cacheline_aligned;
- 		struct sk_buff_head queue;
- 	} b_tx_status; /* This queue is used by both -b and non-b devices */
- 	struct mutex io_mutex;
-@@ -147,7 +152,8 @@ struct rtl8187_priv {
- 		u8 bits8;
- 		__le16 bits16;
- 		__le32 bits32;
--	} *io_dmabuf;
-+		u8 dummy2[L1_CACHE_BYTES];
-+	} *io_dmabuf ____cacheline_aligned;
- 	bool rfkill_off;
- 	u16 seqno;
- };
---- a/net/mac80211/wme.c
-+++ b/net/mac80211/wme.c
-@@ -154,6 +154,11 @@ u16 ieee80211_select_queue(struct ieee80
- 		return IEEE80211_AC_BE;
- 	}
- 
-+	if (skb->protocol == sdata->control_port_protocol) {
-+		skb->priority = 7;
-+		return ieee80211_downgrade_queue(sdata, skb);
-+	}
-+
- 	/* use the data classifier to determine what 802.1d tag the
- 	 * data frame has */
- 	rcu_read_lock();
---- a/drivers/net/wireless/ath/ath9k/xmit.c
-+++ b/drivers/net/wireless/ath/ath9k/xmit.c
-@@ -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 (!tid->sched)
--			continue;
--
- 		ac = tid->ac;
- 		txq = ac->txq;
- 
- 		ath_txq_lock(sc, txq);
- 
-+		if (!tid->sched) {
-+			ath_txq_unlock(sc, txq);
-+			continue;
-+		}
-+
- 		buffered = ath_tid_has_buffered(tid);
- 
- 		tid->sched = false;
-@@ -1696,7 +1698,7 @@ int ath_cabq_update(struct ath_softc *sc
- 
- 	ath9k_hw_get_txq_props(sc->sc_ah, qnum, &qi);
- 
--	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);
- 
-@@ -2061,7 +2063,7 @@ static struct ath_buf *ath_tx_setup_buff
- 
- 	ATH_TXBUF_RESET(bf);
- 
--	if (tid) {
-+	if (tid && ieee80211_is_data_present(hdr->frame_control)) {
- 		fragno = le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_FRAG;
- 		seqno = tid->seq_next;
- 		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;
- 	}
- 
-+	if (txctl->an && ieee80211_is_data_present(hdr->frame_control))
-+		tid = ath_get_skb_tid(sc, txctl->an, skb);
-+
- 	if (info->flags & IEEE80211_TX_CTL_PS_RESPONSE) {
- 		ath_txq_unlock(sc, txq);
- 		txq = sc->tx.uapsdq;
- 		ath_txq_lock(sc, txq);
- 	} else if (txctl->an &&
- 		   ieee80211_is_data_present(hdr->frame_control)) {
--		tid = ath_get_skb_tid(sc, txctl->an, skb);
--
- 		WARN_ON(tid->ac->txq != txctl->txq);
- 
- 		if (info->flags & IEEE80211_TX_CTL_CLEAR_PS_FILT)
---- 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;
- 	hw->wiphy->flags |= WIPHY_FLAG_HAS_CHANNEL_SWITCH;
-+	hw->wiphy->flags |= WIPHY_FLAG_AP_UAPSD;
- 
- 	hw->queues = 4;
- 	hw->max_rates = 4;
---- a/net/mac80211/ieee80211_i.h
-+++ b/net/mac80211/ieee80211_i.h
-@@ -1700,14 +1700,8 @@ void ieee80211_stop_queue_by_reason(stru
- void ieee80211_propagate_queue_wake(struct ieee80211_local *local, int queue);
- void ieee80211_add_pending_skb(struct ieee80211_local *local,
- 			       struct sk_buff *skb);
--void ieee80211_add_pending_skbs_fn(struct ieee80211_local *local,
--				   struct sk_buff_head *skbs,
--				   void (*fn)(void *data), void *data);
--static inline void ieee80211_add_pending_skbs(struct ieee80211_local *local,
--					      struct sk_buff_head *skbs)
--{
--	ieee80211_add_pending_skbs_fn(local, skbs, NULL, NULL);
--}
-+void ieee80211_add_pending_skbs(struct ieee80211_local *local,
-+				struct sk_buff_head *skbs);
- void ieee80211_flush_queues(struct ieee80211_local *local,
- 			    struct ieee80211_sub_if_data *sdata);
- 
---- a/net/mac80211/sta_info.c
-+++ 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)
- {
- 	int ac, i;
- 	struct tid_ampdu_tx *tid_tx;
-@@ -99,7 +99,8 @@ static void cleanup_single_sta(struct st
- 	struct ieee80211_local *local = sdata->local;
- 	struct ps_data *ps;
- 
--	if (test_sta_flag(sta, WLAN_STA_PS_STA)) {
-+	if (test_sta_flag(sta, WLAN_STA_PS_STA) ||
-+	    test_sta_flag(sta, WLAN_STA_PS_DRIVER)) {
- 		if (sta->sdata->vif.type == NL80211_IFTYPE_AP ||
- 		    sta->sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
- 			ps = &sdata->bss->ps;
-@@ -109,6 +110,7 @@ static void cleanup_single_sta(struct st
- 			return;
- 
- 		clear_sta_flag(sta, WLAN_STA_PS_STA);
-+		clear_sta_flag(sta, WLAN_STA_PS_DRIVER);
- 
- 		atomic_dec(&ps->num_sta_ps);
- 		sta_info_recalc_tim(sta);
-@@ -139,7 +141,14 @@ static void cleanup_single_sta(struct st
- 		ieee80211_purge_tx_queue(&local->hw, &tid_tx->pending);
- 		kfree(tid_tx);
- 	}
-+}
- 
-+static void cleanup_single_sta(struct sta_info *sta)
-+{
-+	struct ieee80211_sub_if_data *sdata = sta->sdata;
-+	struct ieee80211_local *local = sdata->local;
-+
-+	__cleanup_single_sta(sta);
- 	sta_info_free(local, sta);
- }
- 
-@@ -330,6 +339,7 @@ struct sta_info *sta_info_alloc(struct i
- 	rcu_read_unlock();
- 
- 	spin_lock_init(&sta->lock);
-+	spin_lock_init(&sta->ps_lock);
- 	INIT_WORK(&sta->drv_unblock_wk, sta_unblock);
- 	INIT_WORK(&sta->ampdu_mlme.work, ieee80211_ba_session_work);
- 	mutex_init(&sta->ampdu_mlme.mtx);
-@@ -487,21 +497,26 @@ static int sta_info_insert_finish(struct
- 		goto out_err;
- 	}
- 
--	/* notify driver */
--	err = sta_info_insert_drv_state(local, sdata, sta);
--	if (err)
--		goto out_err;
--
- 	local->num_sta++;
- 	local->sta_generation++;
- 	smp_mb();
- 
-+	/* simplify things and don't accept BA sessions yet */
-+	set_sta_flag(sta, WLAN_STA_BLOCK_BA);
-+
- 	/* make the station visible */
- 	sta_info_hash_add(local, sta);
- 
- 	list_add_rcu(&sta->list, &local->sta_list);
- 
-+	/* notify driver */
-+	err = sta_info_insert_drv_state(local, sdata, sta);
-+	if (err)
-+		goto out_remove;
-+
- 	set_sta_flag(sta, WLAN_STA_INSERTED);
-+	/* accept BA sessions now */
-+	clear_sta_flag(sta, WLAN_STA_BLOCK_BA);
- 
- 	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;
-+ out_remove:
-+	sta_info_hash_del(local, sta);
-+	list_del_rcu(&sta->list);
-+	local->num_sta--;
-+	synchronize_net();
-+	__cleanup_single_sta(sta);
-  out_err:
- 	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)
- {
--	struct sta_info *sta = _sta;
- 	struct ieee80211_sub_if_data *sdata = sta->sdata;
-+	struct ieee80211_local *local = sdata->local;
-+	struct sk_buff_head pending;
-+	int filtered = 0, buffered = 0, ac;
-+	unsigned long flags;
- 	struct ps_data *ps;
- 
- 	if (sdata->vif.type == NL80211_IFTYPE_AP ||
-@@ -1085,20 +1110,6 @@ static void clear_sta_ps_flags(void *_st
- 	else
- 		return;
- 
--	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);
--}
--
--/* powersave support code */
--void ieee80211_sta_ps_deliver_wakeup(struct sta_info *sta)
--{
--	struct ieee80211_sub_if_data *sdata = sta->sdata;
--	struct ieee80211_local *local = sdata->local;
--	struct sk_buff_head pending;
--	int filtered = 0, buffered = 0, ac;
--	unsigned long flags;
--
- 	clear_sta_flag(sta, WLAN_STA_SP);
- 
- 	BUILD_BUG_ON(BITS_TO_LONGS(IEEE80211_NUM_TIDS) > 1);
-@@ -1109,6 +1120,8 @@ void ieee80211_sta_ps_deliver_wakeup(str
- 
- 	skb_queue_head_init(&pending);
- 
-+	/* sync with ieee80211_tx_h_unicast_ps_buf */
-+	spin_lock(&sta->ps_lock);
- 	/* Send all buffered frames to the station */
- 	for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) {
- 		int count = skb_queue_len(&pending), tmp;
-@@ -1127,7 +1140,12 @@ void ieee80211_sta_ps_deliver_wakeup(str
- 		buffered += tmp - count;
- 	}
- 
--	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);
-+
-+	atomic_dec(&ps->num_sta_ps);
- 
- 	/* This station just woke up and isn't aware of our SMPS state */
- 	if (!ieee80211_smps_is_restrictive(sta->known_smps_mode,
---- a/net/mac80211/sta_info.h
-+++ b/net/mac80211/sta_info.h
-@@ -267,6 +267,7 @@ struct ieee80211_tx_latency_stat {
-  * @drv_unblock_wk: used for driver PS unblocking
-  * @listen_interval: listen interval of this station, when we're acting as AP
-  * @_flags: STA flags, see &enum ieee80211_sta_info_flags, do not use directly
-+ * @ps_lock: used for powersave (when mac80211 is the AP) related locking
-  * @ps_tx_buf: buffers (per AC) of frames to transmit to this station
-  *	when it leaves power saving state or polls
-  * @tx_filtered: buffers (per AC) of frames we already tried to
-@@ -356,10 +357,8 @@ struct sta_info {
- 	/* use the accessors defined below */
- 	unsigned long _flags;
- 
--	/*
--	 * STA powersave frame queues, no more than the internal
--	 * locking required.
--	 */
-+	/* STA powersave lock and frame queues */
-+	spinlock_t ps_lock;
- 	struct sk_buff_head ps_tx_buf[IEEE80211_NUM_ACS];
- 	struct sk_buff_head tx_filtered[IEEE80211_NUM_ACS];
- 	unsigned long driver_buffered_tids;
---- a/net/mac80211/util.c
-+++ b/net/mac80211/util.c
-@@ -435,9 +435,8 @@ void ieee80211_add_pending_skb(struct ie
- 	spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
- }
- 
--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)
- {
- 	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 (fn)
--		fn(data);
--
- 	for (i = 0; i < hw->queues; i++)
- 		__ieee80211_wake_queue(hw, i,
- 			IEEE80211_QUEUE_STOP_REASON_SKB_ADD);
---- a/net/wireless/reg.c
-+++ b/net/wireless/reg.c
-@@ -1700,7 +1700,7 @@ static void reg_process_hint(struct regu
- 		return;
- 	case NL80211_REGDOM_SET_BY_USER:
- 		treatment = reg_process_hint_user(reg_request);
--		if (treatment == REG_REQ_OK ||
-+		if (treatment == REG_REQ_IGNORE ||
- 		    treatment == REG_REQ_ALREADY_SET)
- 			return;
- 		schedule_delayed_work(&reg_timeout, msecs_to_jiffies(3142));
---- a/drivers/net/wireless/ath/ath9k/debug.c
-+++ b/drivers/net/wireless/ath/ath9k/debug.c
-@@ -138,43 +138,41 @@ static ssize_t read_file_ani(struct file
- 	unsigned int len = 0, size = 1024;
- 	ssize_t retval = 0;
- 	char *buf;
-+	int i;
-+	struct {
-+		const char *name;
-+		unsigned int val;
-+	} ani_info[] = {
-+		{ "ANI RESET", ah->stats.ast_ani_reset },
-+		{ "OFDM LEVEL", ah->ani.ofdmNoiseImmunityLevel },
-+		{ "CCK LEVEL", ah->ani.cckNoiseImmunityLevel },
-+		{ "SPUR UP", ah->stats.ast_ani_spurup },
-+		{ "SPUR DOWN", ah->stats.ast_ani_spurup },
-+		{ "OFDM WS-DET ON", ah->stats.ast_ani_ofdmon },
-+		{ "OFDM WS-DET OFF", ah->stats.ast_ani_ofdmoff },
-+		{ "MRC-CCK ON", ah->stats.ast_ani_ccklow },
-+		{ "MRC-CCK OFF", ah->stats.ast_ani_cckhigh },
-+		{ "FIR-STEP UP", ah->stats.ast_ani_stepup },
-+		{ "FIR-STEP DOWN", ah->stats.ast_ani_stepdown },
-+		{ "INV LISTENTIME", ah->stats.ast_ani_lneg_or_lzero },
-+		{ "OFDM ERRORS", ah->stats.ast_ani_ofdmerrs },
-+		{ "CCK ERRORS", ah->stats.ast_ani_cckerrs },
-+	};
- 
- 	buf = kzalloc(size, GFP_KERNEL);
- 	if (buf == NULL)
- 		return -ENOMEM;
- 
--	if (common->disable_ani) {
--		len += scnprintf(buf + len, size - len, "%s: %s\n",
--				 "ANI", "DISABLED");
-+	len += scnprintf(buf + len, size - len, "%15s: %s\n", "ANI",
-+			 common->disable_ani ? "DISABLED" : "ENABLED");
-+
-+	if (common->disable_ani)
- 		goto exit;
--	}
- 
--	len += scnprintf(buf + len, size - len, "%15s: %s\n",
--			 "ANI", "ENABLED");
--	len += scnprintf(buf + len, size - len, "%15s: %u\n",
--			 "ANI RESET", ah->stats.ast_ani_reset);
--	len += scnprintf(buf + len, size - len, "%15s: %u\n",
--			 "SPUR UP", ah->stats.ast_ani_spurup);
--	len += scnprintf(buf + len, size - len, "%15s: %u\n",
--			 "SPUR DOWN", ah->stats.ast_ani_spurup);
--	len += scnprintf(buf + len, size - len, "%15s: %u\n",
--			 "OFDM WS-DET ON", ah->stats.ast_ani_ofdmon);
--	len += scnprintf(buf + len, size - len, "%15s: %u\n",
--			 "OFDM WS-DET OFF", ah->stats.ast_ani_ofdmoff);
--	len += scnprintf(buf + len, size - len, "%15s: %u\n",
--			 "MRC-CCK ON", ah->stats.ast_ani_ccklow);
--	len += scnprintf(buf + len, size - len, "%15s: %u\n",
--			 "MRC-CCK OFF", ah->stats.ast_ani_cckhigh);
--	len += scnprintf(buf + len, size - len, "%15s: %u\n",
--			 "FIR-STEP UP", ah->stats.ast_ani_stepup);
--	len += scnprintf(buf + len, size - len, "%15s: %u\n",
--			 "FIR-STEP DOWN", ah->stats.ast_ani_stepdown);
--	len += scnprintf(buf + len, size - len, "%15s: %u\n",
--			 "INV LISTENTIME", ah->stats.ast_ani_lneg_or_lzero);
--	len += scnprintf(buf + len, size - len, "%15s: %u\n",
--			 "OFDM ERRORS", ah->stats.ast_ani_ofdmerrs);
--	len += scnprintf(buf + len, size - len, "%15s: %u\n",
--			 "CCK ERRORS", ah->stats.ast_ani_cckerrs);
-+	for (i = 0; i < ARRAY_SIZE(ani_info); i++)
-+		len += scnprintf(buf + len, size - len, "%15s: %u\n",
-+				 ani_info[i].name, ani_info[i].val);
-+
- exit:
- 	if (len > size)
- 		len = size;
-@@ -866,6 +864,12 @@ static ssize_t read_file_reset(struct fi
- 			 "%17s: %2d\n", "PLL RX Hang",
- 			 sc->debug.stats.reset[RESET_TYPE_PLL_HANG]);
- 	len += scnprintf(buf + len, sizeof(buf) - len,
-+			 "%17s: %2d\n", "MAC Hang",
-+			 sc->debug.stats.reset[RESET_TYPE_MAC_HANG]);
-+	len += scnprintf(buf + len, sizeof(buf) - len,
-+			 "%17s: %2d\n", "Stuck Beacon",
-+			 sc->debug.stats.reset[RESET_TYPE_BEACON_STUCK]);
-+	len += scnprintf(buf + len, sizeof(buf) - len,
- 			 "%17s: %2d\n", "MCI Reset",
- 			 sc->debug.stats.reset[RESET_TYPE_MCI]);
- 
---- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c
-+++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
-@@ -868,10 +868,6 @@ static void ar9003_hw_set_rfmode(struct 
- 
- 	if (IS_CHAN_A_FAST_CLOCK(ah, chan))
- 		rfMode |= (AR_PHY_MODE_DYNAMIC | AR_PHY_MODE_DYN_CCK_DISABLE);
--	if (IS_CHAN_QUARTER_RATE(chan))
--		rfMode |= AR_PHY_MODE_QUARTER;
--	if (IS_CHAN_HALF_RATE(chan))
--		rfMode |= AR_PHY_MODE_HALF;
- 
- 	if (rfMode & (AR_PHY_MODE_QUARTER | AR_PHY_MODE_HALF))
- 		REG_RMW_FIELD(ah, AR_PHY_FRAME_CTL,
---- a/drivers/net/wireless/ath/ath5k/mac80211-ops.c
-+++ b/drivers/net/wireless/ath/ath5k/mac80211-ops.c
-@@ -706,6 +706,7 @@ ath5k_get_survey(struct ieee80211_hw *hw
- 	survey->channel = conf->chandef.chan;
- 	survey->noise = ah->ah_noise_floor;
- 	survey->filled = SURVEY_INFO_NOISE_DBM |
-+			SURVEY_INFO_IN_USE |
- 			SURVEY_INFO_CHANNEL_TIME |
- 			SURVEY_INFO_CHANNEL_TIME_BUSY |
- 			SURVEY_INFO_CHANNEL_TIME_RX |
---- a/drivers/net/wireless/ath/ath9k/recv.c
-+++ b/drivers/net/wireless/ath/ath9k/recv.c
-@@ -732,11 +732,18 @@ static struct ath_rxbuf *ath_get_next_rx
- 			return NULL;
- 
- 		/*
--		 * mark descriptor as zero-length and set the 'more'
--		 * flag to ensure that both buffers get discarded
-+		 * Re-check previous descriptor, in case it has been filled
-+		 * in the mean time.
- 		 */
--		rs->rs_datalen = 0;
--		rs->rs_more = true;
-+		ret = ath9k_hw_rxprocdesc(ah, ds, rs);
-+		if (ret == -EINPROGRESS) {
-+			/*
-+			 * mark descriptor as zero-length and set the 'more'
-+			 * flag to ensure that both buffers get discarded
-+			 */
-+			rs->rs_datalen = 0;
-+			rs->rs_more = true;
-+		}
- 	}
- 
- 	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;
- 
- 	/*
- 	 * Discard corrupt descriptors which are marked in
- 	 * ath_get_next_rx_buf().
- 	 */
--	sc->rx.discard_next = rx_stats->rs_more;
- 	if (discard_current)
--		return -EINVAL;
-+		goto corrupt;
-+
-+	sc->rx.discard_next = false;
- 
- 	/*
- 	 * Discard zero-length packets.
- 	 */
- 	if (!rx_stats->rs_datalen) {
- 		RX_STAT_INC(rx_len_err);
--		return -EINVAL;
-+		goto corrupt;
- 	}
- 
--        /*
--         * rs_status follows rs_datalen so if rs_datalen is too large
--         * we can take a hint that hardware corrupted it, so ignore
--         * those frames.
--         */
-+	/*
-+	 * rs_status follows rs_datalen so if rs_datalen is too large
-+	 * we can take a hint that hardware corrupted it, so ignore
-+	 * those frames.
-+	 */
- 	if (rx_stats->rs_datalen > (common->rx_bufsize - ah->caps.rx_status_len)) {
- 		RX_STAT_INC(rx_len_err);
--		return -EINVAL;
-+		goto corrupt;
- 	}
- 
- 	/* 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
- 	 * condition handled above.
- 	 */
--	if (rx_stats->rs_status & ATH9K_RXERR_CORRUPT_DESC) {
--		ret = -EINVAL;
--		goto exit;
--	}
-+	if (rx_stats->rs_status & ATH9K_RXERR_CORRUPT_DESC)
-+		goto corrupt;
- 
- 	hdr = (struct ieee80211_hdr *) (skb->data + ah->caps.rx_status_len);
- 
-@@ -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);
- 
--		ret = -EINVAL;
--		goto exit;
-+		return -EINVAL;
- 	}
- 
- 	/*
- 	 * everything but the rate is checked here, the rate check is done
- 	 * separately to avoid doing two lookups for a rate for each frame.
- 	 */
--	if (!ath9k_rx_accept(common, hdr, rx_status, rx_stats, decrypt_error)) {
--		ret = -EINVAL;
--		goto exit;
--	}
-+	if (!ath9k_rx_accept(common, hdr, rx_status, rx_stats, decrypt_error))
-+		return -EINVAL;
- 
- 	if (ath_is_mybeacon(common, hdr)) {
- 		RX_STAT_INC(rx_beacons);
-@@ -1064,15 +1066,11 @@ static int ath9k_rx_skb_preprocess(struc
- 	/*
- 	 * This shouldn't happen, but have a safety check anyway.
- 	 */
--	if (WARN_ON(!ah->curchan)) {
--		ret = -EINVAL;
--		goto exit;
--	}
-+	if (WARN_ON(!ah->curchan))
-+		return -EINVAL;
- 
--	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;
- 
- 	ath9k_process_rssi(common, hw, rx_stats, rx_status);
- 
-@@ -1087,9 +1085,11 @@ static int ath9k_rx_skb_preprocess(struc
- 		sc->rx.num_pkts++;
- #endif
- 
--exit:
--	sc->rx.discard_next = false;
--	return ret;
-+	return 0;
-+
-+corrupt:
-+	sc->rx.discard_next = rx_stats->rs_more;
-+	return -EINVAL;
- }
- 
- 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
-@@ -176,16 +176,26 @@ static void ath9k_hw_set_ofdm_nil(struct
- 	if (ah->opmode == NL80211_IFTYPE_STATION &&
- 	    BEACON_RSSI(ah) <= ATH9K_ANI_RSSI_THR_HIGH)
- 		weak_sig = true;
--
- 	/*
--	 * OFDM Weak signal detection is always enabled for AP mode.
-+	 * Newer chipsets are better at dealing with high PHY error counts -
-+	 * keep weak signal detection enabled when no RSSI threshold is
-+	 * available to determine if it is needed (mode != STA)
- 	 */
--	if (ah->opmode != NL80211_IFTYPE_AP &&
--	    aniState->ofdmWeakSigDetect != weak_sig) {
--		ath9k_hw_ani_control(ah,
--				     ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION,
--				     entry_ofdm->ofdm_weak_signal_on);
--	}
-+	else if (AR_SREV_9300_20_OR_LATER(ah) &&
-+		 ah->opmode != NL80211_IFTYPE_STATION)
-+		weak_sig = true;
-+
-+	/* Older chipsets are more sensitive to high PHY error counts */
-+	else if (!AR_SREV_9300_20_OR_LATER(ah) &&
-+		 aniState->ofdmNoiseImmunityLevel >= 8)
-+		weak_sig = false;
-+
-+	if (aniState->ofdmWeakSigDetect != weak_sig)
-+		ath9k_hw_ani_control(ah, ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION,
-+				     weak_sig);
-+
-+	if (!AR_SREV_9300_20_OR_LATER(ah))
-+		return;
- 
- 	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, 
- 	BUG_ON(aniState == NULL);
- 	ah->stats.ast_ani_reset++;
- 
--	/* only allow a subset of functions in AP mode */
--	if (ah->opmode == NL80211_IFTYPE_AP) {
--		if (IS_CHAN_2GHZ(chan)) {
--			ah->ani_function = (ATH9K_ANI_SPUR_IMMUNITY_LEVEL |
--					    ATH9K_ANI_FIRSTEP_LEVEL);
--			if (AR_SREV_9300_20_OR_LATER(ah))
--				ah->ani_function |= ATH9K_ANI_MRC_CCK;
--		} else
--			ah->ani_function = 0;
--	}
--
- 	ofdm_nil = max_t(int, ATH9K_ANI_OFDM_DEF_LEVEL,
- 			 aniState->ofdmNoiseImmunityLevel);
- 	cck_nil = max_t(int, ATH9K_ANI_CCK_DEF_LEVEL,
-@@ -483,10 +482,17 @@ void ath9k_hw_ani_init(struct ath_hw *ah
- 
- 	ath_dbg(common, ANI, "Initialize ANI\n");
- 
--	ah->config.ofdm_trig_high = ATH9K_ANI_OFDM_TRIG_HIGH;
--	ah->config.ofdm_trig_low = ATH9K_ANI_OFDM_TRIG_LOW;
--	ah->config.cck_trig_high = ATH9K_ANI_CCK_TRIG_HIGH;
--	ah->config.cck_trig_low = ATH9K_ANI_CCK_TRIG_LOW;
-+	if (AR_SREV_9300_20_OR_LATER(ah)) {
-+		ah->config.ofdm_trig_high = ATH9K_ANI_OFDM_TRIG_HIGH;
-+		ah->config.ofdm_trig_low = ATH9K_ANI_OFDM_TRIG_LOW;
-+		ah->config.cck_trig_high = ATH9K_ANI_CCK_TRIG_HIGH;
-+		ah->config.cck_trig_low = ATH9K_ANI_CCK_TRIG_LOW;
-+	} else {
-+		ah->config.ofdm_trig_high = ATH9K_ANI_OFDM_TRIG_HIGH_OLD;
-+		ah->config.ofdm_trig_low = ATH9K_ANI_OFDM_TRIG_LOW_OLD;
-+		ah->config.cck_trig_high = ATH9K_ANI_CCK_TRIG_HIGH_OLD;
-+		ah->config.cck_trig_low = ATH9K_ANI_CCK_TRIG_LOW_OLD;
-+	}
- 
- 	ani->spurImmunityLevel = ATH9K_ANI_SPUR_IMMUNE_LVL;
- 	ani->firstepLevel = ATH9K_ANI_FIRSTEP_LVL;
---- a/drivers/net/wireless/ath/ath9k/ani.h
-+++ b/drivers/net/wireless/ath/ath9k/ani.h
-@@ -22,12 +22,16 @@
- /* units are errors per second */
- #define ATH9K_ANI_OFDM_TRIG_HIGH           3500
- #define ATH9K_ANI_OFDM_TRIG_HIGH_BELOW_INI 1000
-+#define ATH9K_ANI_OFDM_TRIG_HIGH_OLD       500
- 
- #define ATH9K_ANI_OFDM_TRIG_LOW           400
- #define ATH9K_ANI_OFDM_TRIG_LOW_ABOVE_INI 900
-+#define ATH9K_ANI_OFDM_TRIG_LOW_OLD       200
- 
- #define ATH9K_ANI_CCK_TRIG_HIGH           600
-+#define ATH9K_ANI_CCK_TRIG_HIGH_OLD       200
- #define ATH9K_ANI_CCK_TRIG_LOW            300
-+#define ATH9K_ANI_CCK_TRIG_LOW_OLD        100
- 
- #define ATH9K_ANI_SPUR_IMMUNE_LVL         3
- #define ATH9K_ANI_FIRSTEP_LVL             2
---- a/drivers/net/wireless/ath/ath9k/ar5008_phy.c
-+++ b/drivers/net/wireless/ath/ath9k/ar5008_phy.c
-@@ -26,10 +26,6 @@ static const int firstep_table[] =
- /* level:  0   1   2   3   4   5   6   7   8  */
- 	{ -4, -2,  0,  2,  4,  6,  8, 10, 12 }; /* lvl 0-8, default 2 */
- 
--static const int cycpwrThr1_table[] =
--/* level:  0   1   2   3   4   5   6   7   8  */
--	{ -6, -4, -2,  0,  2,  4,  6,  8 };     /* lvl 0-7, default 3 */
--
- /*
-  * register values to turn OFDM weak signal detection OFF
-  */
-@@ -921,7 +917,7 @@ static bool ar5008_hw_ani_control_new(st
- 	struct ath_common *common = ath9k_hw_common(ah);
- 	struct ath9k_channel *chan = ah->curchan;
- 	struct ar5416AniState *aniState = &ah->ani;
--	s32 value, value2;
-+	s32 value;
- 
- 	switch (cmd & ah->ani_function) {
- 	case ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION:{
-@@ -1008,42 +1004,11 @@ static bool ar5008_hw_ani_control_new(st
- 	case ATH9K_ANI_FIRSTEP_LEVEL:{
- 		u32 level = param;
- 
--		if (level >= ARRAY_SIZE(firstep_table)) {
--			ath_dbg(common, ANI,
--				"ATH9K_ANI_FIRSTEP_LEVEL: level out of range (%u > %zu)\n",
--				level, ARRAY_SIZE(firstep_table));
--			return false;
--		}
--
--		/*
--		 * make register setting relative to default
--		 * from INI file & cap value
--		 */
--		value = firstep_table[level] -
--			firstep_table[ATH9K_ANI_FIRSTEP_LVL] +
--			aniState->iniDef.firstep;
--		if (value < ATH9K_SIG_FIRSTEP_SETTING_MIN)
--			value = ATH9K_SIG_FIRSTEP_SETTING_MIN;
--		if (value > ATH9K_SIG_FIRSTEP_SETTING_MAX)
--			value = ATH9K_SIG_FIRSTEP_SETTING_MAX;
-+		value = level * 2;
- 		REG_RMW_FIELD(ah, AR_PHY_FIND_SIG,
--			      AR_PHY_FIND_SIG_FIRSTEP,
--			      value);
--		/*
--		 * we need to set first step low register too
--		 * make register setting relative to default
--		 * from INI file & cap value
--		 */
--		value2 = firstep_table[level] -
--			 firstep_table[ATH9K_ANI_FIRSTEP_LVL] +
--			 aniState->iniDef.firstepLow;
--		if (value2 < ATH9K_SIG_FIRSTEP_SETTING_MIN)
--			value2 = ATH9K_SIG_FIRSTEP_SETTING_MIN;
--		if (value2 > ATH9K_SIG_FIRSTEP_SETTING_MAX)
--			value2 = ATH9K_SIG_FIRSTEP_SETTING_MAX;
--
-+			      AR_PHY_FIND_SIG_FIRSTEP, value);
- 		REG_RMW_FIELD(ah, AR_PHY_FIND_SIG_LOW,
--			      AR_PHY_FIND_SIG_FIRSTEP_LOW, value2);
-+			      AR_PHY_FIND_SIG_FIRSTEP_LOW, value);
- 
- 		if (level != aniState->firstepLevel) {
- 			ath_dbg(common, ANI,
-@@ -1060,7 +1025,7 @@ static bool ar5008_hw_ani_control_new(st
- 				aniState->firstepLevel,
- 				level,
- 				ATH9K_ANI_FIRSTEP_LVL,
--				value2,
-+				value,
- 				aniState->iniDef.firstepLow);
- 			if (level > aniState->firstepLevel)
- 				ah->stats.ast_ani_stepup++;
-@@ -1073,41 +1038,13 @@ static bool ar5008_hw_ani_control_new(st
- 	case ATH9K_ANI_SPUR_IMMUNITY_LEVEL:{
- 		u32 level = param;
- 
--		if (level >= ARRAY_SIZE(cycpwrThr1_table)) {
--			ath_dbg(common, ANI,
--				"ATH9K_ANI_SPUR_IMMUNITY_LEVEL: level out of range (%u > %zu)\n",
--				level, ARRAY_SIZE(cycpwrThr1_table));
--			return false;
--		}
--		/*
--		 * make register setting relative to default
--		 * from INI file & cap value
--		 */
--		value = cycpwrThr1_table[level] -
--			cycpwrThr1_table[ATH9K_ANI_SPUR_IMMUNE_LVL] +
--			aniState->iniDef.cycpwrThr1;
--		if (value < ATH9K_SIG_SPUR_IMM_SETTING_MIN)
--			value = ATH9K_SIG_SPUR_IMM_SETTING_MIN;
--		if (value > ATH9K_SIG_SPUR_IMM_SETTING_MAX)
--			value = ATH9K_SIG_SPUR_IMM_SETTING_MAX;
-+		value = (level + 1) * 2;
- 		REG_RMW_FIELD(ah, AR_PHY_TIMING5,
--			      AR_PHY_TIMING5_CYCPWR_THR1,
--			      value);
-+			      AR_PHY_TIMING5_CYCPWR_THR1, value);
- 
--		/*
--		 * set AR_PHY_EXT_CCA for extension channel
--		 * make register setting relative to default
--		 * from INI file & cap value
--		 */
--		value2 = cycpwrThr1_table[level] -
--			 cycpwrThr1_table[ATH9K_ANI_SPUR_IMMUNE_LVL] +
--			 aniState->iniDef.cycpwrThr1Ext;
--		if (value2 < ATH9K_SIG_SPUR_IMM_SETTING_MIN)
--			value2 = ATH9K_SIG_SPUR_IMM_SETTING_MIN;
--		if (value2 > ATH9K_SIG_SPUR_IMM_SETTING_MAX)
--			value2 = ATH9K_SIG_SPUR_IMM_SETTING_MAX;
--		REG_RMW_FIELD(ah, AR_PHY_EXT_CCA,
--			      AR_PHY_EXT_TIMING5_CYCPWR_THR1, value2);
-+		if (IS_CHAN_HT40(ah->curchan))
-+			REG_RMW_FIELD(ah, AR_PHY_EXT_CCA,
-+				      AR_PHY_EXT_TIMING5_CYCPWR_THR1, value);
- 
- 		if (level != aniState->spurImmunityLevel) {
- 			ath_dbg(common, ANI,
-@@ -1124,7 +1061,7 @@ static bool ar5008_hw_ani_control_new(st
- 				aniState->spurImmunityLevel,
- 				level,
- 				ATH9K_ANI_SPUR_IMMUNE_LVL,
--				value2,
-+				value,
- 				aniState->iniDef.cycpwrThr1Ext);
- 			if (level > aniState->spurImmunityLevel)
- 				ah->stats.ast_ani_spurup++;
diff --git a/package/kernel/mac80211/patches/310-ap_scan.patch b/package/kernel/mac80211/patches/310-ap_scan.patch
index 389a00370d..87f165a5e0 100644
--- a/package/kernel/mac80211/patches/310-ap_scan.patch
+++ b/package/kernel/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 *
  		 * the  frames sent while scanning on other channel will be
  		 * lost)
  		 */
diff --git a/package/kernel/mac80211/patches/400-ath_move_debug_code.patch b/package/kernel/mac80211/patches/400-ath_move_debug_code.patch
index 0dba7ac125..4cc77afa1b 100644
--- a/package/kernel/mac80211/patches/400-ath_move_debug_code.patch
+++ b/package/kernel/mac80211/patches/400-ath_move_debug_code.patch
@@ -12,7 +12,7 @@
  ccflags-y += -D__CHECK_ENDIAN__
 --- a/drivers/net/wireless/ath/ath.h
 +++ b/drivers/net/wireless/ath/ath.h
-@@ -282,13 +282,6 @@ void _ath_dbg(struct ath_common *common,
+@@ -295,13 +295,6 @@ void _ath_dbg(struct ath_common *common,
  #endif /* CPTCFG_ATH_DEBUG */
  
  /** Returns string describing opmode, or NULL if unknown mode. */
diff --git a/package/kernel/mac80211/patches/402-ath9k-fix-invalid-mac-address-handling.patch b/package/kernel/mac80211/patches/402-ath9k-fix-invalid-mac-address-handling.patch
index 63ab0dba6e..acaa317f76 100644
--- a/package/kernel/mac80211/patches/402-ath9k-fix-invalid-mac-address-handling.patch
+++ b/package/kernel/mac80211/patches/402-ath9k-fix-invalid-mac-address-handling.patch
@@ -8,7 +8,7 @@
  #include <asm/unaligned.h>
  
  #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/kernel/mac80211/patches/403-ath_regd_optional.patch b/package/kernel/mac80211/patches/403-ath_regd_optional.patch
index 07c54ccf81..4a9b7e48fc 100644
--- a/package/kernel/mac80211/patches/403-ath_regd_optional.patch
+++ b/package/kernel/mac80211/patches/403-ath_regd_optional.patch
@@ -58,7 +58,7 @@
  	---help---
 --- a/.local-symbols
 +++ b/.local-symbols
-@@ -119,6 +119,7 @@ RTL8187_LEDS=
+@@ -120,6 +120,7 @@ RTL8187_LEDS=
  ATH_COMMON=
  ATH_CARDS=
  ATH_DEBUG=
diff --git a/package/kernel/mac80211/patches/405-regd_no_assoc_hints.patch b/package/kernel/mac80211/patches/405-regd_no_assoc_hints.patch
index 6ad4fda272..4fa611f206 100644
--- a/package/kernel/mac80211/patches/405-regd_no_assoc_hints.patch
+++ b/package/kernel/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
  	enum environment_cap env = ENVIRON_ANY;
  	struct regulatory_request *request = NULL, *lr;
  
@@ -9,7 +9,7 @@
  	/* IE len must be evenly divisible by 2 */
  	if (country_ie_len & 0x01)
  		return;
-@@ -2072,6 +2074,7 @@ static void restore_regulatory_settings(
+@@ -2194,6 +2196,7 @@ static void restore_regulatory_settings(
  
  void regulatory_hint_disconnect(void)
  {
diff --git a/package/kernel/mac80211/patches/410-ath9k_allow_adhoc_and_ap.patch b/package/kernel/mac80211/patches/410-ath9k_allow_adhoc_and_ap.patch
index 1f71e0b8aa..909a5f104d 100644
--- a/package/kernel/mac80211/patches/410-ath9k_allow_adhoc_and_ap.patch
+++ b/package/kernel/mac80211/patches/410-ath9k_allow_adhoc_and_ap.patch
@@ -1,6 +1,6 @@
 --- 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) |
  				 BIT(NL80211_IFTYPE_P2P_GO) },
diff --git a/package/kernel/mac80211/patches/411-ath5k_allow_adhoc_and_ap.patch b/package/kernel/mac80211/patches/411-ath5k_allow_adhoc_and_ap.patch
index 3487ab26f2..1f069946cd 100644
--- a/package/kernel/mac80211/patches/411-ath5k_allow_adhoc_and_ap.patch
+++ b/package/kernel/mac80211/patches/411-ath5k_allow_adhoc_and_ap.patch
@@ -18,7 +18,7 @@
  		goto end;
 --- a/drivers/net/wireless/ath/ath5k/base.c
 +++ b/drivers/net/wireless/ath/ath5k/base.c
-@@ -1934,7 +1934,7 @@ ath5k_beacon_send(struct ath5k_hw *ah)
+@@ -1937,7 +1937,7 @@ ath5k_beacon_send(struct ath5k_hw *ah)
  	}
  
  	if ((ah->opmode == NL80211_IFTYPE_AP && ah->num_ap_vifs +
@@ -27,7 +27,7 @@
  			ah->opmode == NL80211_IFTYPE_MESH_POINT) {
  		u64 tsf = ath5k_hw_get_tsf64(ah);
  		u32 tsftu = TSF_TO_TU(tsf);
-@@ -2020,7 +2020,7 @@ ath5k_beacon_update_timers(struct ath5k_
+@@ -2023,7 +2023,7 @@ ath5k_beacon_update_timers(struct ath5k_
  
  	intval = ah->bintval & AR5K_BEACON_PERIOD;
  	if (ah->opmode == NL80211_IFTYPE_AP && ah->num_ap_vifs
@@ -36,7 +36,7 @@
  		intval /= ATH_BCBUF;	/* staggered multi-bss beacons */
  		if (intval < 15)
  			ATH5K_WARN(ah, "intval %u is too low, min 15\n",
-@@ -2487,6 +2487,7 @@ static const struct ieee80211_iface_limi
+@@ -2490,6 +2490,7 @@ static const struct ieee80211_iface_limi
  				 BIT(NL80211_IFTYPE_MESH_POINT) |
  #endif
  				 BIT(NL80211_IFTYPE_AP) },
diff --git a/package/kernel/mac80211/patches/500-ath9k_eeprom_debugfs.patch b/package/kernel/mac80211/patches/500-ath9k_eeprom_debugfs.patch
index 664cf45175..36e01511ad 100644
--- a/package/kernel/mac80211/patches/500-ath9k_eeprom_debugfs.patch
+++ b/package/kernel/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
  	ath9k_spectral_deinit_debug(sc);
  }
  
@@ -54,7 +54,7 @@
  int ath9k_init_debug(struct ath_hw *ah)
  {
  	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)
  	ath9k_tx99_init_debug(sc);
  	ath9k_spectral_init_debug(sc);
  
diff --git a/package/kernel/mac80211/patches/501-ath9k-eeprom_endianess.patch b/package/kernel/mac80211/patches/501-ath9k-eeprom_endianess.patch
index 96e7c6d8cc..169eb9ae0c 100644
--- a/package/kernel/mac80211/patches/501-ath9k-eeprom_endianess.patch
+++ b/package/kernel/mac80211/patches/501-ath9k-eeprom_endianess.patch
@@ -81,7 +81,7 @@
  	struct ath_ops reg_ops;
 --- a/drivers/net/wireless/ath/ath9k/init.c
 +++ b/drivers/net/wireless/ath/ath9k/init.c
-@@ -722,6 +722,8 @@ static int ath9k_init_softc(u16 devid, s
+@@ -518,6 +518,8 @@ static int ath9k_init_softc(u16 devid, s
  		ah->is_clk_25mhz = pdata->is_clk_25mhz;
  		ah->get_mac_revision = pdata->get_mac_revision;
  		ah->external_reset = pdata->external_reset;
diff --git a/package/kernel/mac80211/patches/502-ath9k_ahb_init.patch b/package/kernel/mac80211/patches/502-ath9k_ahb_init.patch
index 4edc63bede..43c3260b80 100644
--- a/package/kernel/mac80211/patches/502-ath9k_ahb_init.patch
+++ b/package/kernel/mac80211/patches/502-ath9k_ahb_init.patch
@@ -1,15 +1,15 @@
 --- a/drivers/net/wireless/ath/ath9k/init.c
 +++ b/drivers/net/wireless/ath/ath9k/init.c
-@@ -1112,23 +1112,23 @@ static int __init ath9k_init(void)
- 		goto err_out;
- 	}
+@@ -892,23 +892,23 @@ static int __init ath9k_init(void)
+ {
+ 	int error;
  
 -	error = ath_pci_init();
 +	error = ath_ahb_init();
  	if (error < 0) {
 -		pr_err("No PCI devices found, driver not installed\n");
  		error = -ENODEV;
- 		goto err_rate_unregister;
+ 		goto err_out;
  	}
  
 -	error = ath_ahb_init();
@@ -27,6 +27,6 @@
 -	ath_pci_exit();
 + err_ahb_exit:
 +	ath_ahb_exit();
- 
-  err_rate_unregister:
- 	ath_rate_control_unregister();
+  err_out:
+ 	return error;
+ }
diff --git a/package/kernel/mac80211/patches/510-ath9k_intr_mitigation_tweak.patch b/package/kernel/mac80211/patches/510-ath9k_intr_mitigation_tweak.patch
index d7478ff590..c8189333d2 100644
--- a/package/kernel/mac80211/patches/510-ath9k_intr_mitigation_tweak.patch
+++ b/package/kernel/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/kernel/mac80211/patches/511-ath9k_reduce_rxbuf.patch b/package/kernel/mac80211/patches/511-ath9k_reduce_rxbuf.patch
index ef0b9a1e2a..e457267654 100644
--- a/package/kernel/mac80211/patches/511-ath9k_reduce_rxbuf.patch
+++ b/package/kernel/mac80211/patches/511-ath9k_reduce_rxbuf.patch
@@ -1,6 +1,6 @@
 --- a/drivers/net/wireless/ath/ath9k/ath9k.h
 +++ b/drivers/net/wireless/ath/ath9k/ath9k.h
-@@ -90,7 +90,7 @@ int ath_descdma_setup(struct ath_softc *
+@@ -89,7 +89,7 @@ int ath_descdma_setup(struct ath_softc *
  		(_l) &= ((_sz) - 1);		\
  	} while (0)
  
diff --git a/package/kernel/mac80211/patches/512-ath9k_channelbw_debugfs.patch b/package/kernel/mac80211/patches/512-ath9k_channelbw_debugfs.patch
index 8f3cc03043..665d8aa64d 100644
--- a/package/kernel/mac80211/patches/512-ath9k_channelbw_debugfs.patch
+++ b/package/kernel/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
  	.owner = THIS_MODULE
  };
  
@@ -35,7 +35,7 @@
 +		return -EINVAL;
 +
 +	common->chan_bw = chan_bw;
-+	if (!test_bit(SC_OP_INVALID, &sc->sc_flags))
++	if (!test_bit(ATH_OP_INVALID, &common->op_flags))
 +		ath9k_ops.config(sc->hw, IEEE80211_CONF_CHANGE_CHANNEL);
 +
 +	return count;
@@ -53,7 +53,7 @@
  int ath9k_init_debug(struct ath_hw *ah)
  {
  	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)
  
  	debugfs_create_file("eeprom", S_IRUSR, sc->debug.debugfs_phy, sc,
  			    &fops_eeprom);
@@ -64,17 +64,17 @@
  	debugfs_create_file("interrupt", S_IRUSR, sc->debug.debugfs_phy, sc,
 --- a/drivers/net/wireless/ath/ath.h
 +++ b/drivers/net/wireless/ath/ath.h
-@@ -130,6 +130,7 @@ struct ath_common {
- 	struct ieee80211_hw *hw;
+@@ -140,6 +140,7 @@ struct ath_common {
  	int debug_mask;
  	enum ath_device_state state;
+ 	unsigned long op_flags;
 +	u32 chan_bw;
  
  	struct ath_ani ani;
  
 --- a/drivers/net/wireless/ath/ath9k/common.c
 +++ b/drivers/net/wireless/ath/ath9k/common.c
-@@ -52,11 +52,13 @@ EXPORT_SYMBOL(ath9k_cmn_get_hw_crypto_ke
+@@ -296,11 +296,13 @@ EXPORT_SYMBOL(ath9k_cmn_get_hw_crypto_ke
  /*
   * Update internal channel flags.
   */
@@ -89,7 +89,7 @@
  
  	ichan->channel = chan->center_freq;
  	ichan->chan = chan;
-@@ -64,7 +66,19 @@ static void ath9k_cmn_update_ichannel(st
+@@ -308,7 +310,19 @@ static void ath9k_cmn_update_ichannel(st
  	if (chan->band == IEEE80211_BAND_5GHZ)
  		flags |= CHANNEL_5GHZ;
  
@@ -110,7 +110,7 @@
  	case NL80211_CHAN_WIDTH_5:
  		flags |= CHANNEL_QUARTER;
  		break;
-@@ -97,10 +111,11 @@ struct ath9k_channel *ath9k_cmn_get_chan
+@@ -341,10 +355,11 @@ struct ath9k_channel *ath9k_cmn_get_chan
  					    struct cfg80211_chan_def *chandef)
  {
  	struct ieee80211_channel *curchan = chandef->chan;
diff --git a/package/kernel/mac80211/patches/513-ath9k_add_pci_ids.patch b/package/kernel/mac80211/patches/513-ath9k_add_pci_ids.patch
index db4e6a1238..540198f01c 100644
--- a/package/kernel/mac80211/patches/513-ath9k_add_pci_ids.patch
+++ b/package/kernel/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/kernel/mac80211/patches/520-mac80211_cur_txpower.patch b/package/kernel/mac80211/patches/520-mac80211_cur_txpower.patch
index 6df95bceae..aa460a81c4 100644
--- a/package/kernel/mac80211/patches/520-mac80211_cur_txpower.patch
+++ b/package/kernel/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 {
  	u8 max_tx_aggregation_subframes;
  	u8 offchannel_tx_hw_queue;
  	u8 radiotap_mcs_details;
@@ -10,7 +10,7 @@
  	u8 uapsd_queues;
 --- 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
  	struct ieee80211_local *local = wiphy_priv(wiphy);
  	struct ieee80211_sub_if_data *sdata = IEEE80211_WDEV_TO_SUB_IF(wdev);
  
diff --git a/package/kernel/mac80211/patches/521-ath9k_cur_txpower.patch b/package/kernel/mac80211/patches/521-ath9k_cur_txpower.patch
index 0d6c360d38..24bc0626ed 100644
--- a/package/kernel/mac80211/patches/521-ath9k_cur_txpower.patch
+++ b/package/kernel/mac80211/patches/521-ath9k_cur_txpower.patch
@@ -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
  		sc->config.txpowlimit = 2 * conf->power_level;
  		ath9k_cmn_update_txpow(ah, sc->curtxpow,
  				       sc->config.txpowlimit, &sc->curtxpow);
diff --git a/package/kernel/mac80211/patches/522-mac80211_configure_antenna_gain.patch b/package/kernel/mac80211/patches/522-mac80211_configure_antenna_gain.patch
index 8f2adc9d0f..f131f56c1e 100644
--- a/package/kernel/mac80211/patches/522-mac80211_configure_antenna_gain.patch
+++ b/package/kernel/mac80211/patches/522-mac80211_configure_antenna_gain.patch
@@ -1,6 +1,6 @@
 --- a/include/net/cfg80211.h
 +++ b/include/net/cfg80211.h
-@@ -2156,6 +2156,7 @@ struct cfg80211_qos_map {
+@@ -2167,6 +2167,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
@@ -8,7 +8,7 @@
   *
   * @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 {
  				enum nl80211_tx_power_setting type, int mbm);
  	int	(*get_tx_power)(struct wiphy *wiphy, struct wireless_dev *wdev,
  				int *dbm);
@@ -18,7 +18,7 @@
  				const u8 *addr);
 --- a/include/net/mac80211.h
 +++ b/include/net/mac80211.h
-@@ -1033,6 +1033,7 @@ enum ieee80211_smps_mode {
+@@ -1032,6 +1032,7 @@ enum ieee80211_smps_mode {
   *
   * @power_level: requested transmit power (in dBm), backward compatibility
   *	value only that is set to the minimum of all interfaces
@@ -26,7 +26,7 @@
   *
   * @chandef: the channel definition to tune to
   * @radar_enabled: whether radar detection is enabled
-@@ -1054,6 +1055,7 @@ struct ieee80211_conf {
+@@ -1053,6 +1054,7 @@ struct ieee80211_conf {
  	u32 flags;
  	int power_level, dynamic_ps_timeout;
  	int max_sleep_period;
@@ -36,9 +36,9 @@
  	u8 ps_dtim_period;
 --- a/include/uapi/linux/nl80211.h
 +++ b/include/uapi/linux/nl80211.h
-@@ -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.
   *
 + * @NL80211_ATTR_WIPHY_ANTENNA_GAIN: Configured antenna gain. Used to reduce
 + *	transmit power to stay within regulatory limits. u32, dBi.
@@ -46,9 +46,9 @@
   * @NL80211_ATTR_MAX: highest attribute number currently defined
   * @__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,
  
 +	NL80211_ATTR_WIPHY_ANTENNA_GAIN,
 +
@@ -57,7 +57,7 @@
  	__NL80211_ATTR_AFTER_LAST,
 --- 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
  	return 0;
  }
  
@@ -77,7 +77,7 @@
  static int ieee80211_set_wds_peer(struct wiphy *wiphy, struct net_device *dev,
  				  const u8 *addr)
  {
-@@ -3924,6 +3937,7 @@ struct cfg80211_ops mac80211_config_ops
+@@ -4000,6 +4013,7 @@ const struct cfg80211_ops mac80211_confi
  	.set_wiphy_params = ieee80211_set_wiphy_params,
  	.set_tx_power = ieee80211_set_tx_power,
  	.get_tx_power = ieee80211_get_tx_power,
@@ -87,7 +87,7 @@
  	CFG80211_TESTMODE_CMD(ieee80211_testmode_cmd)
 --- a/net/mac80211/ieee80211_i.h
 +++ b/net/mac80211/ieee80211_i.h
-@@ -1221,6 +1221,7 @@ struct ieee80211_local {
+@@ -1225,6 +1225,7 @@ struct ieee80211_local {
  	int dynamic_ps_forced_timeout;
  
  	int user_power_level; /* in dBm, for all interfaces */
@@ -139,34 +139,32 @@
  	local->user_power_level = IEEE80211_UNSET_POWER_LEVEL;
 --- a/net/wireless/nl80211.c
 +++ b/net/wireless/nl80211.c
-@@ -384,6 +384,7 @@ static const struct nla_policy nl80211_p
- 	[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 },
+ 	[NL80211_ATTR_TDLS_PEER_CAPABILITY] = { .type = NLA_U32 },
 +	[NL80211_ATTR_WIPHY_ANTENNA_GAIN] = { .type = NLA_U32 },
  };
  
  /* policy for the key attributes */
-@@ -2104,6 +2105,22 @@ static int nl80211_set_wiphy(struct sk_b
- 		if (result)
- 			goto bad_res;
+@@ -2116,6 +2117,20 @@ static int nl80211_set_wiphy(struct sk_b
+ 			return result;
  	}
-+
+ 
 +	if (info->attrs[NL80211_ATTR_WIPHY_ANTENNA_GAIN]) {
 +		int idx, dbi = 0;
 +
-+		if (!rdev->ops->set_antenna_gain) {
-+			result = -EOPNOTSUPP;
-+			goto bad_res;
-+		}
++		if (!rdev->ops->set_antenna_gain)
++			return -EOPNOTSUPP;
 +
 +		idx = NL80211_ATTR_WIPHY_ANTENNA_GAIN;
 +		dbi = nla_get_u32(info->attrs[idx]);
 +
 +		result = rdev->ops->set_antenna_gain(&rdev->wiphy, dbi);
 +		if (result)
-+			goto bad_res;
++			return result;
 +	}
- 
++
  	if (info->attrs[NL80211_ATTR_WIPHY_ANTENNA_TX] &&
  	    info->attrs[NL80211_ATTR_WIPHY_ANTENNA_RX]) {
+ 		u32 tx_ant, rx_ant;
diff --git a/package/kernel/mac80211/patches/523-ath9k_use_configured_antenna_gain.patch b/package/kernel/mac80211/patches/523-ath9k_use_configured_antenna_gain.patch
index 30aa9ee187..b84a99134a 100644
--- a/package/kernel/mac80211/patches/523-ath9k_use_configured_antenna_gain.patch
+++ b/package/kernel/mac80211/patches/523-ath9k_use_configured_antenna_gain.patch
@@ -1,6 +1,6 @@
 --- a/drivers/net/wireless/ath/ath.h
 +++ b/drivers/net/wireless/ath/ath.h
-@@ -74,6 +74,7 @@ struct ath_regulatory {
+@@ -83,6 +83,7 @@ struct ath_regulatory {
  	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
  	}
  
  	if (changed & IEEE80211_CONF_CHANGE_POWER) {
diff --git a/package/kernel/mac80211/patches/530-ath9k_extra_leds.patch b/package/kernel/mac80211/patches/530-ath9k_extra_leds.patch
index 59f78d9dfa..5502f02ccc 100644
--- a/package/kernel/mac80211/patches/530-ath9k_extra_leds.patch
+++ b/package/kernel/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
+@@ -555,6 +555,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 {
+@@ -693,6 +696,13 @@ void ath_ant_comb_scan(struct ath_softc 
  #define PS_BEACON_SYNC            BIT(4)
  #define PS_WAIT_FOR_ANI           BIT(5)
  
@@ -24,8 +24,8 @@
  struct ath_softc {
  	struct ieee80211_hw *hw;
  	struct device *dev;
-@@ -751,9 +761,8 @@ struct ath_softc {
- 	struct ieee80211_supported_band sbands[IEEE80211_NUM_BANDS];
+@@ -732,9 +742,8 @@ struct ath_softc {
+ 	struct ath_beacon beacon;
  
  #ifdef CPTCFG_MAC80211_LEDS
 -	bool led_registered;
@@ -162,7 +162,7 @@
  void ath_fill_led_pin(struct ath_softc *sc)
 --- 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 
+@@ -806,7 +806,7 @@ int ath9k_init_device(u16 devid, struct 
  
  #ifdef CPTCFG_MAC80211_LEDS
  	/* must be initialized before ieee80211_register_hw */
@@ -173,7 +173,7 @@
  #endif
 --- 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
  	.llseek = default_llseek,
  };
  
@@ -235,7 +235,7 @@
  
  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)
  			    &fops_eeprom);
  	debugfs_create_file("chanbw", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy,
  			    sc, &fops_chanbw);
diff --git a/package/kernel/mac80211/patches/542-ath9k_debugfs_diag.patch b/package/kernel/mac80211/patches/542-ath9k_debugfs_diag.patch
index e1b6ff17e8..44aa905649 100644
--- a/package/kernel/mac80211/patches/542-ath9k_debugfs_diag.patch
+++ b/package/kernel/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
  #endif
  
  
@@ -51,7 +51,7 @@
  int ath9k_init_debug(struct ath_hw *ah)
  {
  	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)
  	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)
  	ath9k_debug_sync_cause(sc, sync_cause);
  	status &= ah->imask;	/* discard unasked-for bits */
  
diff --git a/package/kernel/mac80211/patches/543-ath9k-allow-to-disable-bands-via-platform-data.patch b/package/kernel/mac80211/patches/543-ath9k-allow-to-disable-bands-via-platform-data.patch
index d26a5af865..e2e18c91a2 100644
--- a/package/kernel/mac80211/patches/543-ath9k-allow-to-disable-bands-via-platform-data.patch
+++ b/package/kernel/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
 +++ b/drivers/net/wireless/ath/ath9k/init.c
-@@ -722,6 +722,8 @@ static int ath9k_init_softc(u16 devid, s
+@@ -518,6 +518,8 @@ static int ath9k_init_softc(u16 devid, s
  		ah->is_clk_25mhz = pdata->is_clk_25mhz;
  		ah->get_mac_revision = pdata->get_mac_revision;
  		ah->external_reset = pdata->external_reset;
diff --git a/package/kernel/mac80211/patches/550-ath9k_entropy_from_adc.patch b/package/kernel/mac80211/patches/550-ath9k_entropy_from_adc.patch
index d126fd4e94..d3c17cdeb6 100644
--- a/package/kernel/mac80211/patches/550-ath9k_entropy_from_adc.patch
+++ b/package/kernel/mac80211/patches/550-ath9k_entropy_from_adc.patch
@@ -55,7 +55,7 @@
  	ops->spectral_scan_config = ar9003_hw_spectral_scan_config;
 --- 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
  	if (ah->caps.hw_caps & ATH9K_HW_CAP_5GHZ)
  		ath9k_init_band_txpower(sc, IEEE80211_BAND_5GHZ);
  
@@ -64,8 +64,8 @@
 +		ah->curchan = curchan;
  }
  
- 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[] = {
+@@ -768,6 +769,18 @@ static void ath9k_set_hw_capab(struct at
  	SET_IEEE80211_PERM_ADDR(hw, common->macaddr);
  }
  
@@ -84,7 +84,7 @@
  int ath9k_init_device(u16 devid, struct ath_softc *sc,
  		    const struct ath_bus_ops *bus_ops)
  {
-@@ -1025,6 +1038,8 @@ int ath9k_init_device(u16 devid, struct 
+@@ -813,6 +826,8 @@ int ath9k_init_device(u16 devid, struct 
  		ARRAY_SIZE(ath9k_tpt_blink));
  #endif
  
@@ -110,7 +110,7 @@
  static inline void ath9k_hw_set_bt_ant_diversity(struct ath_hw *ah, bool enable)
 --- a/drivers/net/wireless/ath/ath9k/link.c
 +++ b/drivers/net/wireless/ath/ath9k/link.c
-@@ -307,6 +307,11 @@ void ath_ani_calibrate(unsigned long dat
+@@ -308,6 +308,11 @@ void ath_ani_calibrate(unsigned long dat
  	unsigned int timestamp = jiffies_to_msecs(jiffies);
  	u32 cal_interval, short_cal_interval, long_cal_interval;
  	unsigned long flags;
diff --git a/package/kernel/mac80211/patches/551-ath9k_p2p_ifcomb.patch b/package/kernel/mac80211/patches/551-ath9k_p2p_ifcomb.patch
index ffffe0cbe8..579a633077 100644
--- a/package/kernel/mac80211/patches/551-ath9k_p2p_ifcomb.patch
+++ b/package/kernel/mac80211/patches/551-ath9k_p2p_ifcomb.patch
@@ -12,7 +12,7 @@ Signed-off-by: Felix Fietkau <nbd@openwrt.org>
 
 --- 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) |
diff --git a/package/kernel/mac80211/patches/552-ath9k_p2p_ps_support.patch b/package/kernel/mac80211/patches/552-ath9k_p2p_ps_support.patch
index 4a61db3f9a..fbe5396e6d 100644
--- a/package/kernel/mac80211/patches/552-ath9k_p2p_ps_support.patch
+++ b/package/kernel/mac80211/patches/552-ath9k_p2p_ps_support.patch
@@ -27,7 +27,7 @@ Signed-off-by: Felix Fietkau <nbd@openwrt.org>
  	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 <nbd@openwrt.org>
  	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 <nbd@openwrt.org>
  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 <nbd@openwrt.org>
  	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 <nbd@openwrt.org>
 +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 <nbd@openwrt.org>
 +
 +	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,
-@@ -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 <nbd@openwrt.org>
  
 --- 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 <nbd@openwrt.org>
  #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
+@@ -367,11 +370,15 @@ void ath9k_release_buffered_frames(struc
  /********/
  
  struct ath_vif {
@@ -192,7 +194,7 @@ Signed-off-by: Felix Fietkau <nbd@openwrt.org>
  };
  
  struct ath9k_vif_iter_data {
-@@ -472,6 +479,8 @@ int ath_update_survey_stats(struct ath_s
+@@ -464,6 +471,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 <nbd@openwrt.org>
  
  /**********/
  /* BTCOEX */
-@@ -741,6 +750,9 @@ struct ath_softc {
+@@ -724,6 +733,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;
 +
- 	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
-@@ -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 <nbd@openwrt.org>
  	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
+@@ -870,6 +873,9 @@ static void ath9k_deinit_softc(struct at
  {
  	int i = 0;
  
diff --git a/package/kernel/mac80211/patches/566-ath9k-ar933x-usb-hang-workaround.patch b/package/kernel/mac80211/patches/566-ath9k-ar933x-usb-hang-workaround.patch
index af94c9e312..eddbc6c06e 100644
--- a/package/kernel/mac80211/patches/566-ath9k-ar933x-usb-hang-workaround.patch
+++ b/package/kernel/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
-@@ -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 */
  /******************/
-@@ -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;
  }
  
-@@ -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;
  }
  
-@@ -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;
  }
  
-@@ -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/kernel/mac80211/patches/603-rt2x00-introduce-rt2x00eeprom.patch b/package/kernel/mac80211/patches/603-rt2x00-introduce-rt2x00eeprom.patch
index 2bbc6f162a..3d7a94514b 100644
--- a/package/kernel/mac80211/patches/603-rt2x00-introduce-rt2x00eeprom.patch
+++ b/package/kernel/mac80211/patches/603-rt2x00-introduce-rt2x00eeprom.patch
@@ -1,6 +1,6 @@
 --- a/.local-symbols
 +++ b/.local-symbols
-@@ -279,6 +279,7 @@ RT2X00_LIB_FIRMWARE=
+@@ -280,6 +280,7 @@ RT2X00_LIB_FIRMWARE=
  RT2X00_LIB_CRYPTO=
  RT2X00_LIB_LEDS=
  RT2X00_LIB_DEBUGFS=
diff --git a/package/kernel/mac80211/patches/611-rt2x00-rf_vals-rt3352-xtal20.patch b/package/kernel/mac80211/patches/611-rt2x00-rf_vals-rt3352-xtal20.patch
index 478a0f277e..7137834aa7 100644
--- a/package/kernel/mac80211/patches/611-rt2x00-rf_vals-rt3352-xtal20.patch
+++ b/package/kernel/mac80211/patches/611-rt2x00-rf_vals-rt3352-xtal20.patch
@@ -28,7 +28,7 @@
  static int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
  {
  	struct hw_mode_spec *spec = &rt2x00dev->spec;
-@@ -7579,7 +7600,10 @@ static int rt2800_probe_hw_mode(struct r
+@@ -7578,7 +7599,10 @@ static int rt2800_probe_hw_mode(struct r
  	case RF5390:
  	case RF5392:
  		spec->num_channels = 14;
@@ -40,7 +40,7 @@
  		break;
  
  	case RF3052:
-@@ -7755,6 +7779,19 @@ static int rt2800_probe_rt(struct rt2x00
+@@ -7754,6 +7778,19 @@ static int rt2800_probe_rt(struct rt2x00
  	return 0;
  }
  
@@ -60,7 +60,7 @@
  int rt2800_probe_hw(struct rt2x00_dev *rt2x00dev)
  {
  	int retval;
-@@ -7784,6 +7821,15 @@ int rt2800_probe_hw(struct rt2x00_dev *r
+@@ -7783,6 +7820,15 @@ int rt2800_probe_hw(struct rt2x00_dev *r
  	rt2800_register_write(rt2x00dev, GPIO_CTRL, reg);
  
  	/*
diff --git a/package/kernel/mac80211/patches/615-rt2x00-fix_20mhz_clk.patch b/package/kernel/mac80211/patches/615-rt2x00-fix_20mhz_clk.patch
index d843b7ab53..e95487395d 100644
--- a/package/kernel/mac80211/patches/615-rt2x00-fix_20mhz_clk.patch
+++ b/package/kernel/mac80211/patches/615-rt2x00-fix_20mhz_clk.patch
@@ -8,7 +8,7 @@
  
  #include "rt2x00.h"
  #include "rt2800lib.h"
-@@ -7781,13 +7782,14 @@ static int rt2800_probe_rt(struct rt2x00
+@@ -7780,13 +7781,14 @@ static int rt2800_probe_rt(struct rt2x00
  
  int rt2800_probe_clk(struct rt2x00_dev *rt2x00dev)
  {
diff --git a/package/kernel/mac80211/patches/616-rt2x00-support-rt5350.patch b/package/kernel/mac80211/patches/616-rt2x00-support-rt5350.patch
index 8d3fcd245a..a62ad157ed 100644
--- a/package/kernel/mac80211/patches/616-rt2x00-support-rt5350.patch
+++ b/package/kernel/mac80211/patches/616-rt2x00-support-rt5350.patch
@@ -240,7 +240,7 @@
  	case RF5360:
  	case RF5370:
  	case RF5372:
-@@ -7595,6 +7706,7 @@ static int rt2800_probe_hw_mode(struct r
+@@ -7594,6 +7705,7 @@ static int rt2800_probe_hw_mode(struct r
  	case RF3290:
  	case RF3320:
  	case RF3322:
@@ -248,7 +248,7 @@
  	case RF5360:
  	case RF5370:
  	case RF5372:
-@@ -7727,6 +7839,7 @@ static int rt2800_probe_hw_mode(struct r
+@@ -7726,6 +7838,7 @@ static int rt2800_probe_hw_mode(struct r
  	case RF3053:
  	case RF3070:
  	case RF3290:
@@ -256,7 +256,7 @@
  	case RF5360:
  	case RF5370:
  	case RF5372:
-@@ -7765,6 +7878,7 @@ static int rt2800_probe_rt(struct rt2x00
+@@ -7764,6 +7877,7 @@ static int rt2800_probe_rt(struct rt2x00
  	case RT3390:
  	case RT3572:
  	case RT3593:
diff --git a/package/kernel/mac80211/patches/700-mwl8k-missing-pci-id-for-WNR854T.patch b/package/kernel/mac80211/patches/700-mwl8k-missing-pci-id-for-WNR854T.patch
index 484c075893..752fb0eec9 100644
--- a/package/kernel/mac80211/patches/700-mwl8k-missing-pci-id-for-WNR854T.patch
+++ b/package/kernel/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")
  MODULE_FIRMWARE(MWL8K_8366_AP_FW(MWL8K_8366_AP_FW_API));
  
  static DEFINE_PCI_DEVICE_TABLE(mwl8k_pci_id_table) = {
diff --git a/package/kernel/mac80211/patches/919-wl18xx-align-event-mailbox-with-current-fw.patch b/package/kernel/mac80211/patches/901-wl18xx-align-event-mailbox-with-current-fw.patch
similarity index 89%
rename from package/kernel/mac80211/patches/919-wl18xx-align-event-mailbox-with-current-fw.patch
rename to package/kernel/mac80211/patches/901-wl18xx-align-event-mailbox-with-current-fw.patch
index 95db58f0f4..77647bbcf6 100644
--- a/package/kernel/mac80211/patches/919-wl18xx-align-event-mailbox-with-current-fw.patch
+++ b/package/kernel/mac80211/patches/901-wl18xx-align-event-mailbox-with-current-fw.patch
@@ -16,8 +16,6 @@ Signed-off-by: Eliad Peller <eliad@wizery.com>
  drivers/net/wireless/ti/wl18xx/event.h | 20 ++++++++++++++++++++
  1 file changed, 20 insertions(+)
 
-diff --git a/drivers/net/wireless/ti/wl18xx/event.h b/drivers/net/wireless/ti/wl18xx/event.h
-index 398f3d2..a76e98e 100644
 --- a/drivers/net/wireless/ti/wl18xx/event.h
 +++ b/drivers/net/wireless/ti/wl18xx/event.h
 @@ -68,6 +68,26 @@ struct wl18xx_event_mailbox {
@@ -47,6 +45,3 @@ index 398f3d2..a76e98e 100644
  } __packed;
  
  int wl18xx_wait_for_event(struct wl1271 *wl, enum wlcore_wait_event event,
--- 
-1.8.5.2.229.g4448466.dirty
-
diff --git a/package/kernel/mac80211/patches/901-wlcore-memset-wl--rx_filter_enabled-to-zero-after-recovery.patch b/package/kernel/mac80211/patches/901-wlcore-memset-wl--rx_filter_enabled-to-zero-after-recovery.patch
deleted file mode 100644
index df2a6e9448..0000000000
--- a/package/kernel/mac80211/patches/901-wlcore-memset-wl--rx_filter_enabled-to-zero-after-recovery.patch
+++ /dev/null
@@ -1,73 +0,0 @@
-zero rx_filter_enabled array after recovery to avoid
-cases were the driver will keep trying to clear a
-filter which is not configured in FW.
-
-Such case will cause consecutive recoveries due to
-command execution failures.
-
-While on it, convert rx_filter_enabled to bitmap,
-to save some memory and make sparse happy (it
-doesn't like sizeof(bool array)).
-
-Signed-off-by: Nadim Zubidat <nadimz@ti.com>
-Signed-off-by: Eliad Peller <eliad@wizery.com>
-
----
-drivers/net/wireless/ti/wlcore/main.c   | 1 +
- drivers/net/wireless/ti/wlcore/rx.c     | 9 ++++++---
- drivers/net/wireless/ti/wlcore/wlcore.h | 2 +-
- 3 files changed, 8 insertions(+), 4 deletions(-)
-
---- a/drivers/net/wireless/ti/wlcore/main.c
-+++ b/drivers/net/wireless/ti/wlcore/main.c
-@@ -1914,6 +1914,7 @@ static void wlcore_op_stop_locked(struct
- 	memset(wl->links_map, 0, sizeof(wl->links_map));
- 	memset(wl->roc_map, 0, sizeof(wl->roc_map));
- 	memset(wl->session_ids, 0, sizeof(wl->session_ids));
-+	memset(wl->rx_filter_enabled, 0, sizeof(wl->rx_filter_enabled));
- 	wl->active_sta_count = 0;
- 	wl->active_link_count = 0;
- 
---- a/drivers/net/wireless/ti/wlcore/rx.c
-+++ b/drivers/net/wireless/ti/wlcore/rx.c
-@@ -302,7 +302,7 @@ int wl1271_rx_filter_enable(struct wl127
- {
- 	int ret;
- 
--	if (wl->rx_filter_enabled[index] == enable) {
-+	if (!!test_bit(index, wl->rx_filter_enabled) == enable) {
- 		wl1271_warning("Request to enable an already "
- 			     "enabled rx filter %d", index);
- 		return 0;
-@@ -316,7 +316,10 @@ int wl1271_rx_filter_enable(struct wl127
- 		return ret;
- 	}
- 
--	wl->rx_filter_enabled[index] = enable;
-+	if (enable)
-+		__set_bit(index, wl->rx_filter_enabled);
-+	else
-+		__clear_bit(index, wl->rx_filter_enabled);
- 
- 	return 0;
- }
-@@ -326,7 +329,7 @@ int wl1271_rx_filter_clear_all(struct wl
- 	int i, ret = 0;
- 
- 	for (i = 0; i < WL1271_MAX_RX_FILTERS; i++) {
--		if (!wl->rx_filter_enabled[i])
-+		if (!test_bit(i, wl->rx_filter_enabled))
- 			continue;
- 		ret = wl1271_rx_filter_enable(wl, i, 0, NULL);
- 		if (ret)
---- a/drivers/net/wireless/ti/wlcore/wlcore.h
-+++ b/drivers/net/wireless/ti/wlcore/wlcore.h
-@@ -453,7 +453,7 @@ struct wl1271 {
- 	size_t fw_status_priv_len;
- 
- 	/* RX Data filter rule state - enabled/disabled */
--	bool rx_filter_enabled[WL1271_MAX_RX_FILTERS];
-+	unsigned long rx_filter_enabled[BITS_TO_LONGS(WL1271_MAX_RX_FILTERS)];
- 
- 	/* size of the private static data */
- 	size_t static_data_priv_len;
diff --git a/package/kernel/mac80211/patches/902-wlcore-cancel-Tx-watchdog-on-~-and-rearm-on-first-Tx-after.patch b/package/kernel/mac80211/patches/902-wlcore-cancel-Tx-watchdog-on-~-and-rearm-on-first-Tx-after.patch
deleted file mode 100644
index 497227d474..0000000000
--- a/package/kernel/mac80211/patches/902-wlcore-cancel-Tx-watchdog-on-~-and-rearm-on-first-Tx-after.patch
+++ /dev/null
@@ -1,73 +0,0 @@
-Sometimes a tx_flush during suspend fails, but the FW manages to flush
-out the packets during the time when the host is supsended. Cancel
-the Tx-watchdog on suspend to not cause a spurious recovery on resume
-for that case. Set a flag to reinit the watchdog on the first Tx after
-resume, so we'll still recover if the FW is not empty and there's
-indeed a problem.
-
-Signed-off-by: Arik Nemtsov <arik@wizery.com>
-Signed-off-by: Eliad Peller <eliad@wizery.com>
-
----
-drivers/net/wireless/ti/wlcore/main.c     | 13 +++++++++++++
- drivers/net/wireless/ti/wlcore/tx.c       |  9 +++++++--
- drivers/net/wireless/ti/wlcore/wlcore_i.h |  1 +
- 3 files changed, 21 insertions(+), 2 deletions(-)
-
---- a/drivers/net/wireless/ti/wlcore/main.c
-+++ b/drivers/net/wireless/ti/wlcore/main.c
-@@ -1767,6 +1767,12 @@ static int wl1271_op_suspend(struct ieee
- 	flush_work(&wl->tx_work);
- 	flush_delayed_work(&wl->elp_work);
- 
-+	/*
-+	 * Cancel the watchdog even if above tx_flush failed. We will detect
-+	 * it on resume anyway.
-+	 */
-+	cancel_delayed_work(&wl->tx_watchdog_work);
-+
- 	return 0;
- }
- 
-@@ -1824,6 +1830,13 @@ static int wl1271_op_resume(struct ieee8
- 
- out:
- 	wl->wow_enabled = false;
-+
-+	/*
-+	 * Set a flag to re-init the watchdog on the first Tx after resume.
-+	 * That way we avoid possible conditions where Tx-complete interrupts
-+	 * fail to arrive and we perform a spurious recovery.
-+	 */
-+	set_bit(WL1271_FLAG_REINIT_TX_WDOG, &wl->flags);
- 	mutex_unlock(&wl->mutex);
- 
- 	return 0;
---- a/drivers/net/wireless/ti/wlcore/tx.c
-+++ b/drivers/net/wireless/ti/wlcore/tx.c
-@@ -234,8 +234,13 @@ static int wl1271_tx_allocate(struct wl1
- 		wl->tx_blocks_available -= total_blocks;
- 		wl->tx_allocated_blocks += total_blocks;
- 
--		/* If the FW was empty before, arm the Tx watchdog */
--		if (wl->tx_allocated_blocks == total_blocks)
-+		/*
-+		 * If the FW was empty before, arm the Tx watchdog. Also do
-+		 * this on the first Tx after resume, as we always cancel the
-+		 * watchdog on suspend.
-+		 */
-+		if (wl->tx_allocated_blocks == total_blocks ||
-+		    test_and_clear_bit(WL1271_FLAG_REINIT_TX_WDOG, &wl->flags))
- 			wl12xx_rearm_tx_watchdog_locked(wl);
- 
- 		ac = wl1271_tx_get_queue(skb_get_queue_mapping(skb));
---- a/drivers/net/wireless/ti/wlcore/wlcore_i.h
-+++ b/drivers/net/wireless/ti/wlcore/wlcore_i.h
-@@ -240,6 +240,7 @@ enum wl12xx_flags {
- 	WL1271_FLAG_VIF_CHANGE_IN_PROGRESS,
- 	WL1271_FLAG_INTENDED_FW_RECOVERY,
- 	WL1271_FLAG_IO_FAILED,
-+	WL1271_FLAG_REINIT_TX_WDOG,
- };
- 
- enum wl12xx_vif_flags {
diff --git a/package/kernel/mac80211/patches/920-wlcore-don-t-switch-channels-on-disconnected-STA-vif.patch b/package/kernel/mac80211/patches/902-wlcore-don-t-switch-channels-on-disconnected-STA-vif.patch
similarity index 89%
rename from package/kernel/mac80211/patches/920-wlcore-don-t-switch-channels-on-disconnected-STA-vif.patch
rename to package/kernel/mac80211/patches/902-wlcore-don-t-switch-channels-on-disconnected-STA-vif.patch
index d15e9eb6a3..3d501b2fab 100644
--- a/package/kernel/mac80211/patches/920-wlcore-don-t-switch-channels-on-disconnected-STA-vif.patch
+++ b/package/kernel/mac80211/patches/902-wlcore-don-t-switch-channels-on-disconnected-STA-vif.patch
@@ -13,7 +13,7 @@ Signed-off-by: Arik Nemtsov <arik@wizery.com>
 
 --- a/drivers/net/wireless/ti/wlcore/main.c
 +++ b/drivers/net/wireless/ti/wlcore/main.c
-@@ -5179,6 +5179,10 @@ static void wl12xx_op_channel_switch(str
+@@ -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);
@@ -24,7 +24,7 @@ Signed-off-by: Arik Nemtsov <arik@wizery.com>
  			ieee80211_chswitch_done(vif, false);
  		}
  		goto out;
-@@ -5194,6 +5198,9 @@ static void wl12xx_op_channel_switch(str
+@@ -5196,6 +5200,9 @@ static void wl12xx_op_channel_switch(str
  	wl12xx_for_each_wlvif_sta(wl, wlvif) {
  		unsigned long delay_usec;
  
diff --git a/package/kernel/mac80211/patches/903-wlcore-block-read-writes-to-FW-during-ELP.patch b/package/kernel/mac80211/patches/903-wlcore-block-read-writes-to-FW-during-ELP.patch
deleted file mode 100644
index 1aafb32968..0000000000
--- a/package/kernel/mac80211/patches/903-wlcore-block-read-writes-to-FW-during-ELP.patch
+++ /dev/null
@@ -1,36 +0,0 @@
-When the chip is in ELP mode read/write to FW is invalid and may cause
-the lower layers to get stuck. The reads/writes concerning ELP wakeup
-are the exception here and are checked for. In addition to blocking the
-IO, produce a warning.
-
-Signed-off-by: Barak Bercovitz <barak@wizery.com>
-Signed-off-by: Eliad Peller <eliad@wizery.com>
-
----
-drivers/net/wireless/ti/wlcore/io.h | 8 ++++++--
- 1 file changed, 6 insertions(+), 2 deletions(-)
-
---- a/drivers/net/wireless/ti/wlcore/io.h
-+++ b/drivers/net/wireless/ti/wlcore/io.h
-@@ -60,7 +60,9 @@ static inline int __must_check wlcore_ra
- {
- 	int ret;
- 
--	if (test_bit(WL1271_FLAG_IO_FAILED, &wl->flags))
-+	if (test_bit(WL1271_FLAG_IO_FAILED, &wl->flags) ||
-+	    WARN_ON((test_bit(WL1271_FLAG_IN_ELP, &wl->flags) &&
-+		     addr != HW_ACCESS_ELP_CTRL_REG)))
- 		return -EIO;
- 
- 	ret = wl->if_ops->write(wl->dev, addr, buf, len, fixed);
-@@ -76,7 +78,9 @@ static inline int __must_check wlcore_ra
- {
- 	int ret;
- 
--	if (test_bit(WL1271_FLAG_IO_FAILED, &wl->flags))
-+	if (test_bit(WL1271_FLAG_IO_FAILED, &wl->flags) ||
-+	    WARN_ON((test_bit(WL1271_FLAG_IN_ELP, &wl->flags) &&
-+		     addr != HW_ACCESS_ELP_CTRL_REG)))
- 		return -EIO;
- 
- 	ret = wl->if_ops->read(wl->dev, addr, buf, len, fixed);
diff --git a/package/kernel/mac80211/patches/904-wlcore-AP-don-t-start-mac80211-PS-on-non-peer-HLIDs.patch b/package/kernel/mac80211/patches/904-wlcore-AP-don-t-start-mac80211-PS-on-non-peer-HLIDs.patch
deleted file mode 100644
index 3942f1e5a1..0000000000
--- a/package/kernel/mac80211/patches/904-wlcore-AP-don-t-start-mac80211-PS-on-non-peer-HLIDs.patch
+++ /dev/null
@@ -1,28 +0,0 @@
-It seems the wl18xx FW sometimes sends spurious changes on the PSM state
-of the broadcast HLID. This causes us to search for a station on a
-non-peer link and fail, causing warnings in our log.
-
-Prevent the driver from considering PSM changes for any non-peer HLIDs.
-
-Signed-off-by: Arik Nemtsov <arik@wizery.com>
-Signed-off-by: Eliad Peller <eliad@wizery.com>
-
----
-drivers/net/wireless/ti/wlcore/ps.c | 6 +++++-
- 1 file changed, 5 insertions(+), 1 deletion(-)
-
---- a/drivers/net/wireless/ti/wlcore/ps.c
-+++ b/drivers/net/wireless/ti/wlcore/ps.c
-@@ -280,7 +280,11 @@ void wl12xx_ps_link_start(struct wl1271
- 	struct ieee80211_sta *sta;
- 	struct ieee80211_vif *vif = wl12xx_wlvif_to_vif(wlvif);
- 
--	if (test_bit(hlid, &wl->ap_ps_map))
-+	if (WARN_ON_ONCE(wlvif->bss_type != BSS_TYPE_AP_BSS))
-+		return;
-+
-+	if (!test_bit(hlid, wlvif->ap.sta_hlid_map) ||
-+	    test_bit(hlid, &wl->ap_ps_map))
- 		return;
- 
- 	wl1271_debug(DEBUG_PSM, "start mac80211 PSM on hlid %d pkts %d "
diff --git a/package/kernel/mac80211/patches/905-wlcore-wl12xx-wl18xx-simplify-fw_status-handling.patch b/package/kernel/mac80211/patches/905-wlcore-wl12xx-wl18xx-simplify-fw_status-handling.patch
deleted file mode 100644
index c669797ef3..0000000000
--- a/package/kernel/mac80211/patches/905-wlcore-wl12xx-wl18xx-simplify-fw_status-handling.patch
+++ /dev/null
@@ -1,731 +0,0 @@
-Instead of splitting the fw_status into 2 and using some
-complex calculations, read the fw status and let each low-level
-driver (wl12xx/wl18xx) convert it into a common struct.
-
-This is required for the upcoming fw api changes, which
-break the current logic anyway.
-
-Signed-off-by: Eliad Peller <eliad@wizery.com>
-
----
-drivers/net/wireless/ti/wl12xx/main.c     | 35 ++++++++++-
- drivers/net/wireless/ti/wl12xx/wl12xx.h   | 50 ++++++++++++++++
- drivers/net/wireless/ti/wl18xx/main.c     | 39 ++++++++++++-
- drivers/net/wireless/ti/wl18xx/tx.c       |  4 +-
- drivers/net/wireless/ti/wl18xx/wl18xx.h   | 53 +++++++++++++++++
- drivers/net/wireless/ti/wlcore/cmd.c      | 11 +++-
- drivers/net/wireless/ti/wlcore/hw_ops.h   |  9 +++
- drivers/net/wireless/ti/wlcore/main.c     | 96 +++++++++++++++----------------
- drivers/net/wireless/ti/wlcore/rx.c       |  2 +-
- drivers/net/wireless/ti/wlcore/rx.h       |  2 +-
- drivers/net/wireless/ti/wlcore/wlcore.h   |  7 ++-
- drivers/net/wireless/ti/wlcore/wlcore_i.h | 72 ++++++++++-------------
- 12 files changed, 277 insertions(+), 103 deletions(-)
-
---- a/drivers/net/wireless/ti/wl12xx/main.c
-+++ b/drivers/net/wireless/ti/wl12xx/main.c
-@@ -1378,7 +1378,7 @@ static u32 wl12xx_get_rx_packet_len(stru
- 
- static int wl12xx_tx_delayed_compl(struct wl1271 *wl)
- {
--	if (wl->fw_status_1->tx_results_counter ==
-+	if (wl->fw_status->tx_results_counter ==
- 	    (wl->tx_results_count & 0xff))
- 		return 0;
- 
-@@ -1438,6 +1438,37 @@ out:
- 	return ret;
- }
- 
-+static void wl12xx_convert_fw_status(struct wl1271 *wl, void *raw_fw_status,
-+				     struct wl_fw_status *fw_status)
-+{
-+	struct wl12xx_fw_status *int_fw_status = raw_fw_status;
-+
-+	fw_status->intr = le32_to_cpu(int_fw_status->intr);
-+	fw_status->fw_rx_counter = int_fw_status->fw_rx_counter;
-+	fw_status->drv_rx_counter = int_fw_status->drv_rx_counter;
-+	fw_status->tx_results_counter = int_fw_status->tx_results_counter;
-+	fw_status->rx_pkt_descs = int_fw_status->rx_pkt_descs;
-+
-+	fw_status->fw_localtime = le32_to_cpu(int_fw_status->fw_localtime);
-+	fw_status->link_ps_bitmap = le32_to_cpu(int_fw_status->link_ps_bitmap);
-+	fw_status->link_fast_bitmap =
-+			le32_to_cpu(int_fw_status->link_fast_bitmap);
-+	fw_status->total_released_blks =
-+			le32_to_cpu(int_fw_status->total_released_blks);
-+	fw_status->tx_total = le32_to_cpu(int_fw_status->tx_total);
-+
-+	fw_status->counters.tx_released_pkts =
-+			int_fw_status->counters.tx_released_pkts;
-+	fw_status->counters.tx_lnk_free_pkts =
-+			int_fw_status->counters.tx_lnk_free_pkts;
-+	fw_status->counters.tx_voice_released_blks =
-+			int_fw_status->counters.tx_voice_released_blks;
-+	fw_status->counters.tx_last_rate =
-+			int_fw_status->counters.tx_last_rate;
-+
-+	fw_status->log_start_addr = le32_to_cpu(int_fw_status->log_start_addr);
-+}
-+
- static u32 wl12xx_sta_get_ap_rate_mask(struct wl1271 *wl,
- 				       struct wl12xx_vif *wlvif)
- {
-@@ -1677,6 +1708,7 @@ static struct wlcore_ops wl12xx_ops = {
- 	.tx_delayed_compl	= wl12xx_tx_delayed_compl,
- 	.hw_init		= wl12xx_hw_init,
- 	.init_vif		= NULL,
-+	.convert_fw_status	= wl12xx_convert_fw_status,
- 	.sta_get_ap_rate_mask	= wl12xx_sta_get_ap_rate_mask,
- 	.get_pg_ver		= wl12xx_get_pg_ver,
- 	.get_mac		= wl12xx_get_mac,
-@@ -1725,6 +1757,7 @@ static int wl12xx_setup(struct wl1271 *w
- 	wl->band_rate_to_idx = wl12xx_band_rate_to_idx;
- 	wl->hw_tx_rate_tbl_size = WL12XX_CONF_HW_RXTX_RATE_MAX;
- 	wl->hw_min_ht_rate = WL12XX_CONF_HW_RXTX_RATE_MCS0;
-+	wl->fw_status_len = sizeof(struct wl12xx_fw_status);
- 	wl->fw_status_priv_len = 0;
- 	wl->stats.fw_stats_len = sizeof(struct wl12xx_acx_statistics);
- 	wlcore_set_ht_cap(wl, IEEE80211_BAND_2GHZ, &wl12xx_ht_cap);
---- a/drivers/net/wireless/ti/wl12xx/wl12xx.h
-+++ b/drivers/net/wireless/ti/wl12xx/wl12xx.h
-@@ -79,4 +79,54 @@ struct wl12xx_priv {
- 	struct wl127x_rx_mem_pool_addr *rx_mem_addr;
- };
- 
-+struct wl12xx_fw_packet_counters {
-+	/* Cumulative counter of released packets per AC */
-+	u8 tx_released_pkts[NUM_TX_QUEUES];
-+
-+	/* Cumulative counter of freed packets per HLID */
-+	u8 tx_lnk_free_pkts[WL12XX_MAX_LINKS];
-+
-+	/* Cumulative counter of released Voice memory blocks */
-+	u8 tx_voice_released_blks;
-+
-+	/* Tx rate of the last transmitted packet */
-+	u8 tx_last_rate;
-+
-+	u8 padding[2];
-+} __packed;
-+
-+/* FW status registers */
-+struct wl12xx_fw_status {
-+	__le32 intr;
-+	u8  fw_rx_counter;
-+	u8  drv_rx_counter;
-+	u8  reserved;
-+	u8  tx_results_counter;
-+	__le32 rx_pkt_descs[WL12XX_NUM_RX_DESCRIPTORS];
-+
-+	__le32 fw_localtime;
-+
-+	/*
-+	 * A bitmap (where each bit represents a single HLID)
-+	 * to indicate if the station is in PS mode.
-+	 */
-+	__le32 link_ps_bitmap;
-+
-+	/*
-+	 * A bitmap (where each bit represents a single HLID) to indicate
-+	 * if the station is in Fast mode
-+	 */
-+	__le32 link_fast_bitmap;
-+
-+	/* Cumulative counter of total released mem blocks since FW-reset */
-+	__le32 total_released_blks;
-+
-+	/* Size (in Memory Blocks) of TX pool */
-+	__le32 tx_total;
-+
-+	struct wl12xx_fw_packet_counters counters;
-+
-+	__le32 log_start_addr;
-+} __packed;
-+
- #endif /* __WL12XX_PRIV_H__ */
---- a/drivers/net/wireless/ti/wl18xx/main.c
-+++ b/drivers/net/wireless/ti/wl18xx/main.c
-@@ -1133,6 +1133,39 @@ static int wl18xx_hw_init(struct wl1271
- 	return ret;
- }
- 
-+static void wl18xx_convert_fw_status(struct wl1271 *wl, void *raw_fw_status,
-+				     struct wl_fw_status *fw_status)
-+{
-+	struct wl18xx_fw_status *int_fw_status = raw_fw_status;
-+
-+	fw_status->intr = le32_to_cpu(int_fw_status->intr);
-+	fw_status->fw_rx_counter = int_fw_status->fw_rx_counter;
-+	fw_status->drv_rx_counter = int_fw_status->drv_rx_counter;
-+	fw_status->tx_results_counter = int_fw_status->tx_results_counter;
-+	fw_status->rx_pkt_descs = int_fw_status->rx_pkt_descs;
-+
-+	fw_status->fw_localtime = le32_to_cpu(int_fw_status->fw_localtime);
-+	fw_status->link_ps_bitmap = le32_to_cpu(int_fw_status->link_ps_bitmap);
-+	fw_status->link_fast_bitmap =
-+			le32_to_cpu(int_fw_status->link_fast_bitmap);
-+	fw_status->total_released_blks =
-+			le32_to_cpu(int_fw_status->total_released_blks);
-+	fw_status->tx_total = le32_to_cpu(int_fw_status->tx_total);
-+
-+	fw_status->counters.tx_released_pkts =
-+			int_fw_status->counters.tx_released_pkts;
-+	fw_status->counters.tx_lnk_free_pkts =
-+			int_fw_status->counters.tx_lnk_free_pkts;
-+	fw_status->counters.tx_voice_released_blks =
-+			int_fw_status->counters.tx_voice_released_blks;
-+	fw_status->counters.tx_last_rate =
-+			int_fw_status->counters.tx_last_rate;
-+
-+	fw_status->log_start_addr = le32_to_cpu(int_fw_status->log_start_addr);
-+
-+	fw_status->priv = &int_fw_status->priv;
-+}
-+
- static void wl18xx_set_tx_desc_csum(struct wl1271 *wl,
- 				    struct wl1271_tx_hw_descr *desc,
- 				    struct sk_buff *skb)
-@@ -1572,7 +1605,7 @@ static bool wl18xx_lnk_high_prio(struct
- {
- 	u8 thold;
- 	struct wl18xx_fw_status_priv *status_priv =
--		(struct wl18xx_fw_status_priv *)wl->fw_status_2->priv;
-+		(struct wl18xx_fw_status_priv *)wl->fw_status->priv;
- 	u32 suspend_bitmap = le32_to_cpu(status_priv->link_suspend_bitmap);
- 
- 	/* suspended links are never high priority */
-@@ -1594,7 +1627,7 @@ static bool wl18xx_lnk_low_prio(struct w
- {
- 	u8 thold;
- 	struct wl18xx_fw_status_priv *status_priv =
--		(struct wl18xx_fw_status_priv *)wl->fw_status_2->priv;
-+		(struct wl18xx_fw_status_priv *)wl->fw_status->priv;
- 	u32 suspend_bitmap = le32_to_cpu(status_priv->link_suspend_bitmap);
- 
- 	if (test_bit(hlid, (unsigned long *)&suspend_bitmap))
-@@ -1632,6 +1665,7 @@ static struct wlcore_ops wl18xx_ops = {
- 	.tx_immediate_compl = wl18xx_tx_immediate_completion,
- 	.tx_delayed_compl = NULL,
- 	.hw_init	= wl18xx_hw_init,
-+	.convert_fw_status = wl18xx_convert_fw_status,
- 	.set_tx_desc_csum = wl18xx_set_tx_desc_csum,
- 	.get_pg_ver	= wl18xx_get_pg_ver,
- 	.set_rx_csum = wl18xx_set_rx_csum,
-@@ -1726,6 +1760,7 @@ static int wl18xx_setup(struct wl1271 *w
- 	wl->band_rate_to_idx = wl18xx_band_rate_to_idx;
- 	wl->hw_tx_rate_tbl_size = WL18XX_CONF_HW_RXTX_RATE_MAX;
- 	wl->hw_min_ht_rate = WL18XX_CONF_HW_RXTX_RATE_MCS0;
-+	wl->fw_status_len = sizeof(struct wl18xx_fw_status);
- 	wl->fw_status_priv_len = sizeof(struct wl18xx_fw_status_priv);
- 	wl->stats.fw_stats_len = sizeof(struct wl18xx_acx_statistics);
- 	wl->static_data_priv_len = sizeof(struct wl18xx_static_data_priv);
---- a/drivers/net/wireless/ti/wl18xx/tx.c
-+++ b/drivers/net/wireless/ti/wl18xx/tx.c
-@@ -32,7 +32,7 @@ static
- void wl18xx_get_last_tx_rate(struct wl1271 *wl, struct ieee80211_vif *vif,
- 			     struct ieee80211_tx_rate *rate)
- {
--	u8 fw_rate = wl->fw_status_2->counters.tx_last_rate;
-+	u8 fw_rate = wl->fw_status->counters.tx_last_rate;
- 
- 	if (fw_rate > CONF_HW_RATE_INDEX_MAX) {
- 		wl1271_error("last Tx rate invalid: %d", fw_rate);
-@@ -139,7 +139,7 @@ static void wl18xx_tx_complete_packet(st
- void wl18xx_tx_immediate_complete(struct wl1271 *wl)
- {
- 	struct wl18xx_fw_status_priv *status_priv =
--		(struct wl18xx_fw_status_priv *)wl->fw_status_2->priv;
-+		(struct wl18xx_fw_status_priv *)wl->fw_status->priv;
- 	struct wl18xx_priv *priv = wl->priv;
- 	u8 i;
- 
---- a/drivers/net/wireless/ti/wl18xx/wl18xx.h
-+++ b/drivers/net/wireless/ti/wl18xx/wl18xx.h
-@@ -109,6 +109,59 @@ struct wl18xx_fw_status_priv {
- 	u8 padding[3];
- };
- 
-+struct wl18xx_fw_packet_counters {
-+	/* Cumulative counter of released packets per AC */
-+	u8 tx_released_pkts[NUM_TX_QUEUES];
-+
-+	/* Cumulative counter of freed packets per HLID */
-+	u8 tx_lnk_free_pkts[WL12XX_MAX_LINKS];
-+
-+	/* Cumulative counter of released Voice memory blocks */
-+	u8 tx_voice_released_blks;
-+
-+	/* Tx rate of the last transmitted packet */
-+	u8 tx_last_rate;
-+
-+	u8 padding[2];
-+} __packed;
-+
-+/* FW status registers */
-+struct wl18xx_fw_status {
-+	__le32 intr;
-+	u8  fw_rx_counter;
-+	u8  drv_rx_counter;
-+	u8  reserved;
-+	u8  tx_results_counter;
-+	__le32 rx_pkt_descs[WL18XX_NUM_RX_DESCRIPTORS];
-+
-+	__le32 fw_localtime;
-+
-+	/*
-+	 * A bitmap (where each bit represents a single HLID)
-+	 * to indicate if the station is in PS mode.
-+	 */
-+	__le32 link_ps_bitmap;
-+
-+	/*
-+	 * A bitmap (where each bit represents a single HLID) to indicate
-+	 * if the station is in Fast mode
-+	 */
-+	__le32 link_fast_bitmap;
-+
-+	/* Cumulative counter of total released mem blocks since FW-reset */
-+	__le32 total_released_blks;
-+
-+	/* Size (in Memory Blocks) of TX pool */
-+	__le32 tx_total;
-+
-+	struct wl18xx_fw_packet_counters counters;
-+
-+	__le32 log_start_addr;
-+
-+	/* Private status to be used by the lower drivers */
-+	struct wl18xx_fw_status_priv priv;
-+} __packed;
-+
- #define WL18XX_PHY_VERSION_MAX_LEN 20
- 
- struct wl18xx_static_data_priv {
---- a/drivers/net/wireless/ti/wlcore/cmd.c
-+++ b/drivers/net/wireless/ti/wlcore/cmd.c
-@@ -324,9 +324,14 @@ int wl12xx_allocate_link(struct wl1271 *
- 	__set_bit(link, wlvif->links_map);
- 	spin_unlock_irqrestore(&wl->wl_lock, flags);
- 
--	/* take the last "freed packets" value from the current FW status */
--	wl->links[link].prev_freed_pkts =
--			wl->fw_status_2->counters.tx_lnk_free_pkts[link];
-+	/*
-+	 * take the last "freed packets" value from the current FW status.
-+	 * on recovery, we might not have fw_status yet, and
-+	 * tx_lnk_free_pkts will be NULL. check for it.
-+	 */
-+	if (wl->fw_status->counters.tx_lnk_free_pkts)
-+		wl->links[link].prev_freed_pkts =
-+			wl->fw_status->counters.tx_lnk_free_pkts[link];
- 	wl->links[link].wlvif = wlvif;
- 
- 	/*
---- a/drivers/net/wireless/ti/wlcore/hw_ops.h
-+++ b/drivers/net/wireless/ti/wlcore/hw_ops.h
-@@ -106,6 +106,15 @@ wlcore_hw_init_vif(struct wl1271 *wl, st
- 	return 0;
- }
- 
-+static inline void
-+wlcore_hw_convert_fw_status(struct wl1271 *wl, void *raw_fw_status,
-+			    struct wl_fw_status *fw_status)
-+{
-+	BUG_ON(!wl->ops->convert_fw_status);
-+
-+	wl->ops->convert_fw_status(wl, raw_fw_status, fw_status);
-+}
-+
- static inline u32
- wlcore_hw_sta_get_ap_rate_mask(struct wl1271 *wl, struct wl12xx_vif *wlvif)
- {
---- a/drivers/net/wireless/ti/wlcore/main.c
-+++ b/drivers/net/wireless/ti/wlcore/main.c
-@@ -357,12 +357,12 @@ static void wl12xx_irq_ps_regulate_link(
- 
- static void wl12xx_irq_update_links_status(struct wl1271 *wl,
- 					   struct wl12xx_vif *wlvif,
--					   struct wl_fw_status_2 *status)
-+					   struct wl_fw_status *status)
- {
- 	u32 cur_fw_ps_map;
- 	u8 hlid;
- 
--	cur_fw_ps_map = le32_to_cpu(status->link_ps_bitmap);
-+	cur_fw_ps_map = status->link_ps_bitmap;
- 	if (wl->ap_fw_ps_map != cur_fw_ps_map) {
- 		wl1271_debug(DEBUG_PSM,
- 			     "link ps prev 0x%x cur 0x%x changed 0x%x",
-@@ -377,41 +377,38 @@ static void wl12xx_irq_update_links_stat
- 					    wl->links[hlid].allocated_pkts);
- }
- 
--static int wlcore_fw_status(struct wl1271 *wl,
--			    struct wl_fw_status_1 *status_1,
--			    struct wl_fw_status_2 *status_2)
-+static int wlcore_fw_status(struct wl1271 *wl, struct wl_fw_status *status)
- {
- 	struct wl12xx_vif *wlvif;
- 	struct timespec ts;
- 	u32 old_tx_blk_count = wl->tx_blocks_available;
- 	int avail, freed_blocks;
- 	int i;
--	size_t status_len;
- 	int ret;
- 	struct wl1271_link *lnk;
- 
--	status_len = WLCORE_FW_STATUS_1_LEN(wl->num_rx_desc) +
--		sizeof(*status_2) + wl->fw_status_priv_len;
--
--	ret = wlcore_raw_read_data(wl, REG_RAW_FW_STATUS_ADDR, status_1,
--				   status_len, false);
-+	ret = wlcore_raw_read_data(wl, REG_RAW_FW_STATUS_ADDR,
-+				   wl->raw_fw_status,
-+				   wl->fw_status_len, false);
- 	if (ret < 0)
- 		return ret;
- 
-+	wlcore_hw_convert_fw_status(wl, wl->raw_fw_status, wl->fw_status);
-+
- 	wl1271_debug(DEBUG_IRQ, "intr: 0x%x (fw_rx_counter = %d, "
- 		     "drv_rx_counter = %d, tx_results_counter = %d)",
--		     status_1->intr,
--		     status_1->fw_rx_counter,
--		     status_1->drv_rx_counter,
--		     status_1->tx_results_counter);
-+		     status->intr,
-+		     status->fw_rx_counter,
-+		     status->drv_rx_counter,
-+		     status->tx_results_counter);
- 
- 	for (i = 0; i < NUM_TX_QUEUES; i++) {
- 		/* prevent wrap-around in freed-packets counter */
- 		wl->tx_allocated_pkts[i] -=
--				(status_2->counters.tx_released_pkts[i] -
-+				(status->counters.tx_released_pkts[i] -
- 				wl->tx_pkts_freed[i]) & 0xff;
- 
--		wl->tx_pkts_freed[i] = status_2->counters.tx_released_pkts[i];
-+		wl->tx_pkts_freed[i] = status->counters.tx_released_pkts[i];
- 	}
- 
- 
-@@ -420,29 +417,28 @@ static int wlcore_fw_status(struct wl127
- 		lnk = &wl->links[i];
- 
- 		/* prevent wrap-around in freed-packets counter */
--		diff = (status_2->counters.tx_lnk_free_pkts[i] -
-+		diff = (status->counters.tx_lnk_free_pkts[i] -
- 		       lnk->prev_freed_pkts) & 0xff;
- 
- 		if (diff == 0)
- 			continue;
- 
- 		lnk->allocated_pkts -= diff;
--		lnk->prev_freed_pkts = status_2->counters.tx_lnk_free_pkts[i];
-+		lnk->prev_freed_pkts = status->counters.tx_lnk_free_pkts[i];
- 
- 		/* accumulate the prev_freed_pkts counter */
- 		lnk->total_freed_pkts += diff;
- 	}
- 
- 	/* prevent wrap-around in total blocks counter */
--	if (likely(wl->tx_blocks_freed <=
--		   le32_to_cpu(status_2->total_released_blks)))
--		freed_blocks = le32_to_cpu(status_2->total_released_blks) -
-+	if (likely(wl->tx_blocks_freed <= status->total_released_blks))
-+		freed_blocks = status->total_released_blks -
- 			       wl->tx_blocks_freed;
- 	else
- 		freed_blocks = 0x100000000LL - wl->tx_blocks_freed +
--			       le32_to_cpu(status_2->total_released_blks);
-+			       status->total_released_blks;
- 
--	wl->tx_blocks_freed = le32_to_cpu(status_2->total_released_blks);
-+	wl->tx_blocks_freed = status->total_released_blks;
- 
- 	wl->tx_allocated_blocks -= freed_blocks;
- 
-@@ -458,7 +454,7 @@ static int wlcore_fw_status(struct wl127
- 			cancel_delayed_work(&wl->tx_watchdog_work);
- 	}
- 
--	avail = le32_to_cpu(status_2->tx_total) - wl->tx_allocated_blocks;
-+	avail = status->tx_total - wl->tx_allocated_blocks;
- 
- 	/*
- 	 * The FW might change the total number of TX memblocks before
-@@ -477,15 +473,15 @@ static int wlcore_fw_status(struct wl127
- 
- 	/* for AP update num of allocated TX blocks per link and ps status */
- 	wl12xx_for_each_wlvif_ap(wl, wlvif) {
--		wl12xx_irq_update_links_status(wl, wlvif, status_2);
-+		wl12xx_irq_update_links_status(wl, wlvif, status);
- 	}
- 
- 	/* update the host-chipset time offset */
- 	getnstimeofday(&ts);
- 	wl->time_offset = (timespec_to_ns(&ts) >> 10) -
--		(s64)le32_to_cpu(status_2->fw_localtime);
-+		(s64)(status->fw_localtime);
- 
--	wl->fw_fast_lnk_map = le32_to_cpu(status_2->link_fast_bitmap);
-+	wl->fw_fast_lnk_map = status->link_fast_bitmap;
- 
- 	return 0;
- }
-@@ -549,13 +545,13 @@ static int wlcore_irq_locked(struct wl12
- 		clear_bit(WL1271_FLAG_IRQ_RUNNING, &wl->flags);
- 		smp_mb__after_clear_bit();
- 
--		ret = wlcore_fw_status(wl, wl->fw_status_1, wl->fw_status_2);
-+		ret = wlcore_fw_status(wl, wl->fw_status);
- 		if (ret < 0)
- 			goto out;
- 
- 		wlcore_hw_tx_immediate_compl(wl);
- 
--		intr = le32_to_cpu(wl->fw_status_1->intr);
-+		intr = wl->fw_status->intr;
- 		intr &= WLCORE_ALL_INTR_MASK;
- 		if (!intr) {
- 			done = true;
-@@ -584,7 +580,7 @@ static int wlcore_irq_locked(struct wl12
- 		if (likely(intr & WL1271_ACX_INTR_DATA)) {
- 			wl1271_debug(DEBUG_IRQ, "WL1271_ACX_INTR_DATA");
- 
--			ret = wlcore_rx(wl, wl->fw_status_1);
-+			ret = wlcore_rx(wl, wl->fw_status);
- 			if (ret < 0)
- 				goto out;
- 
-@@ -843,11 +839,11 @@ static void wl12xx_read_fwlog_panic(stru
- 		wl12xx_cmd_stop_fwlog(wl);
- 
- 	/* Read the first memory block address */
--	ret = wlcore_fw_status(wl, wl->fw_status_1, wl->fw_status_2);
-+	ret = wlcore_fw_status(wl, wl->fw_status);
- 	if (ret < 0)
- 		goto out;
- 
--	addr = le32_to_cpu(wl->fw_status_2->log_start_addr);
-+	addr = wl->fw_status->log_start_addr;
- 	if (!addr)
- 		goto out;
- 
-@@ -990,23 +986,23 @@ static int wlcore_fw_wakeup(struct wl127
- 
- static int wl1271_setup(struct wl1271 *wl)
- {
--	wl->fw_status_1 = kzalloc(WLCORE_FW_STATUS_1_LEN(wl->num_rx_desc) +
--				  sizeof(*wl->fw_status_2) +
--				  wl->fw_status_priv_len, GFP_KERNEL);
--	if (!wl->fw_status_1)
--		return -ENOMEM;
-+	wl->raw_fw_status = kzalloc(wl->fw_status_len, GFP_KERNEL);
-+	if (!wl->raw_fw_status)
-+		goto err;
- 
--	wl->fw_status_2 = (struct wl_fw_status_2 *)
--				(((u8 *) wl->fw_status_1) +
--				WLCORE_FW_STATUS_1_LEN(wl->num_rx_desc));
-+	wl->fw_status = kzalloc(sizeof(*wl->fw_status), GFP_KERNEL);
-+	if (!wl->fw_status)
-+		goto err;
- 
- 	wl->tx_res_if = kzalloc(sizeof(*wl->tx_res_if), GFP_KERNEL);
--	if (!wl->tx_res_if) {
--		kfree(wl->fw_status_1);
--		return -ENOMEM;
--	}
-+	if (!wl->tx_res_if)
-+		goto err;
- 
- 	return 0;
-+err:
-+	kfree(wl->fw_status);
-+	kfree(wl->raw_fw_status);
-+	return -ENOMEM;
- }
- 
- static int wl12xx_set_power_on(struct wl1271 *wl)
-@@ -1952,9 +1948,10 @@ static void wlcore_op_stop_locked(struct
- 
- 	wl1271_debugfs_reset(wl);
- 
--	kfree(wl->fw_status_1);
--	wl->fw_status_1 = NULL;
--	wl->fw_status_2 = NULL;
-+	kfree(wl->raw_fw_status);
-+	wl->raw_fw_status = NULL;
-+	kfree(wl->fw_status);
-+	wl->fw_status = NULL;
- 	kfree(wl->tx_res_if);
- 	wl->tx_res_if = NULL;
- 	kfree(wl->target_mem_map);
-@@ -6058,7 +6055,8 @@ int wlcore_free_hw(struct wl1271 *wl)
- 	kfree(wl->nvs);
- 	wl->nvs = NULL;
- 
--	kfree(wl->fw_status_1);
-+	kfree(wl->raw_fw_status);
-+	kfree(wl->fw_status);
- 	kfree(wl->tx_res_if);
- 	destroy_workqueue(wl->freezable_wq);
- 
---- a/drivers/net/wireless/ti/wlcore/rx.c
-+++ b/drivers/net/wireless/ti/wlcore/rx.c
-@@ -203,7 +203,7 @@ static int wl1271_rx_handle_data(struct
- 	return is_data;
- }
- 
--int wlcore_rx(struct wl1271 *wl, struct wl_fw_status_1 *status)
-+int wlcore_rx(struct wl1271 *wl, struct wl_fw_status *status)
- {
- 	unsigned long active_hlids[BITS_TO_LONGS(WL12XX_MAX_LINKS)] = {0};
- 	u32 buf_size;
---- a/drivers/net/wireless/ti/wlcore/rx.h
-+++ b/drivers/net/wireless/ti/wlcore/rx.h
-@@ -142,7 +142,7 @@ struct wl1271_rx_descriptor {
- 	u8  reserved;
- } __packed;
- 
--int wlcore_rx(struct wl1271 *wl, struct wl_fw_status_1 *status);
-+int wlcore_rx(struct wl1271 *wl, struct wl_fw_status *status);
- u8 wl1271_rate_to_idx(int rate, enum ieee80211_band band);
- int wl1271_rx_filter_enable(struct wl1271 *wl,
- 			    int index, bool enable,
---- a/drivers/net/wireless/ti/wlcore/wlcore.h
-+++ b/drivers/net/wireless/ti/wlcore/wlcore.h
-@@ -73,6 +73,8 @@ struct wlcore_ops {
- 	void (*tx_immediate_compl)(struct wl1271 *wl);
- 	int (*hw_init)(struct wl1271 *wl);
- 	int (*init_vif)(struct wl1271 *wl, struct wl12xx_vif *wlvif);
-+	void (*convert_fw_status)(struct wl1271 *wl, void *raw_fw_status,
-+				  struct wl_fw_status *fw_status);
- 	u32 (*sta_get_ap_rate_mask)(struct wl1271 *wl,
- 				    struct wl12xx_vif *wlvif);
- 	int (*get_pg_ver)(struct wl1271 *wl, s8 *ver);
-@@ -348,8 +350,8 @@ struct wl1271 {
- 	u32 buffer_cmd;
- 	u32 buffer_busyword[WL1271_BUSY_WORD_CNT];
- 
--	struct wl_fw_status_1 *fw_status_1;
--	struct wl_fw_status_2 *fw_status_2;
-+	void *raw_fw_status;
-+	struct wl_fw_status *fw_status;
- 	struct wl1271_tx_hw_res_if *tx_res_if;
- 
- 	/* Current chipset configuration */
-@@ -450,6 +452,7 @@ struct wl1271 {
- 	struct ieee80211_sta_ht_cap ht_cap[WLCORE_NUM_BANDS];
- 
- 	/* size of the private FW status data */
-+	size_t fw_status_len;
- 	size_t fw_status_priv_len;
- 
- 	/* RX Data filter rule state - enabled/disabled */
---- a/drivers/net/wireless/ti/wlcore/wlcore_i.h
-+++ b/drivers/net/wireless/ti/wlcore/wlcore_i.h
-@@ -120,70 +120,58 @@ struct wl1271_chip {
- 
- #define AP_MAX_STATIONS            8
- 
--struct wl_fw_packet_counters {
--	/* Cumulative counter of released packets per AC */
--	u8 tx_released_pkts[NUM_TX_QUEUES];
--
--	/* Cumulative counter of freed packets per HLID */
--	u8 tx_lnk_free_pkts[WL12XX_MAX_LINKS];
--
--	/* Cumulative counter of released Voice memory blocks */
--	u8 tx_voice_released_blks;
--
--	/* Tx rate of the last transmitted packet */
--	u8 tx_last_rate;
--
--	u8 padding[2];
--} __packed;
--
--/* FW status registers */
--struct wl_fw_status_1 {
--	__le32 intr;
-+struct wl_fw_status {
-+	u32 intr;
- 	u8  fw_rx_counter;
- 	u8  drv_rx_counter;
--	u8  reserved;
- 	u8  tx_results_counter;
--	__le32 rx_pkt_descs[0];
--} __packed;
--
--/*
-- * Each HW arch has a different number of Rx descriptors.
-- * The length of the status depends on it, since it holds an array
-- * of descriptors.
-- */
--#define WLCORE_FW_STATUS_1_LEN(num_rx_desc) \
--		(sizeof(struct wl_fw_status_1) + \
--		(sizeof(((struct wl_fw_status_1 *)0)->rx_pkt_descs[0])) * \
--		num_rx_desc)
-+	__le32 *rx_pkt_descs;
- 
--struct wl_fw_status_2 {
--	__le32 fw_localtime;
-+	u32 fw_localtime;
- 
- 	/*
- 	 * A bitmap (where each bit represents a single HLID)
- 	 * to indicate if the station is in PS mode.
- 	 */
--	__le32 link_ps_bitmap;
-+	u32 link_ps_bitmap;
- 
- 	/*
- 	 * A bitmap (where each bit represents a single HLID) to indicate
- 	 * if the station is in Fast mode
- 	 */
--	__le32 link_fast_bitmap;
-+	u32 link_fast_bitmap;
- 
- 	/* Cumulative counter of total released mem blocks since FW-reset */
--	__le32 total_released_blks;
-+	u32 total_released_blks;
- 
- 	/* Size (in Memory Blocks) of TX pool */
--	__le32 tx_total;
-+	u32 tx_total;
- 
--	struct wl_fw_packet_counters counters;
-+	struct {
-+		/*
-+		 * Cumulative counter of released packets per AC
-+		 * (length of the array is NUM_TX_QUEUES)
-+		 */
-+		u8 *tx_released_pkts;
-+
-+		/*
-+		 * Cumulative counter of freed packets per HLID
-+		 * (length of the array is WL12XX_MAX_LINKS)
-+		 */
-+		u8 *tx_lnk_free_pkts;
-+
-+		/* Cumulative counter of released Voice memory blocks */
-+		u8 tx_voice_released_blks;
-+
-+		/* Tx rate of the last transmitted packet */
-+		u8 tx_last_rate;
-+	} counters;
- 
--	__le32 log_start_addr;
-+	u32 log_start_addr;
- 
- 	/* Private status to be used by the lower drivers */
--	u8 priv[0];
--} __packed;
-+	void *priv;
-+};
- 
- #define WL1271_MAX_CHANNELS 64
- struct wl1271_scan {
diff --git a/package/kernel/mac80211/patches/906-wlcore-wl12xx-wl18xx-configure-num_links-per-hw.patch b/package/kernel/mac80211/patches/906-wlcore-wl12xx-wl18xx-configure-num_links-per-hw.patch
deleted file mode 100644
index 5c342f5e1d..0000000000
--- a/package/kernel/mac80211/patches/906-wlcore-wl12xx-wl18xx-configure-num_links-per-hw.patch
+++ /dev/null
@@ -1,345 +0,0 @@
-Upcoming fw versions will have different max links support
-(according to the hw). Get ready for it by configuring
-wl->num_links per-hw, instead of using the const WL12XX_MAX_LINKS.
-
-However, continue using WLCORE_MAX_LINKS in order to simplify
-structs declarations (we use it in multiple bitmaps, and converting
-them to dynamic arrays is just cumbersome).
-
-Signed-off-by: Eliad Peller <eliad@wizery.com>
-
----
-drivers/net/wireless/ti/wl12xx/main.c     |  3 +++
- drivers/net/wireless/ti/wl12xx/wl12xx.h   |  2 ++
- drivers/net/wireless/ti/wl18xx/main.c     |  3 +++
- drivers/net/wireless/ti/wl18xx/wl18xx.h   |  4 +++-
- drivers/net/wireless/ti/wlcore/cmd.c      |  4 ++--
- drivers/net/wireless/ti/wlcore/event.c    |  4 ++--
- drivers/net/wireless/ti/wlcore/main.c     | 12 ++++++++----
- drivers/net/wireless/ti/wlcore/rx.c       |  8 ++++----
- drivers/net/wireless/ti/wlcore/tx.c       | 20 ++++++++++----------
- drivers/net/wireless/ti/wlcore/wlcore.h   |  8 +++++---
- drivers/net/wireless/ti/wlcore/wlcore_i.h | 13 +++++++++----
- 11 files changed, 51 insertions(+), 30 deletions(-)
-
---- a/drivers/net/wireless/ti/wl12xx/main.c
-+++ b/drivers/net/wireless/ti/wl12xx/main.c
-@@ -1749,9 +1749,12 @@ static int wl12xx_setup(struct wl1271 *w
- 	struct wlcore_platdev_data *pdev_data = dev_get_platdata(&wl->pdev->dev);
- 	struct wl12xx_platform_data *pdata = pdev_data->pdata;
- 
-+	BUILD_BUG_ON(WL12XX_MAX_LINKS > WLCORE_MAX_LINKS);
-+
- 	wl->rtable = wl12xx_rtable;
- 	wl->num_tx_desc = WL12XX_NUM_TX_DESCRIPTORS;
- 	wl->num_rx_desc = WL12XX_NUM_RX_DESCRIPTORS;
-+	wl->num_links = WL12XX_MAX_LINKS;
- 	wl->num_channels = 1;
- 	wl->num_mac_addr = WL12XX_NUM_MAC_ADDRESSES;
- 	wl->band_rate_to_idx = wl12xx_band_rate_to_idx;
---- a/drivers/net/wireless/ti/wl12xx/wl12xx.h
-+++ b/drivers/net/wireless/ti/wl12xx/wl12xx.h
-@@ -65,6 +65,8 @@
- 
- #define WL12XX_RX_BA_MAX_SESSIONS 3
- 
-+#define WL12XX_MAX_LINKS 12
-+
- struct wl127x_rx_mem_pool_addr {
- 	u32 addr;
- 	u32 addr_extra;
---- a/drivers/net/wireless/ti/wl18xx/main.c
-+++ b/drivers/net/wireless/ti/wl18xx/main.c
-@@ -1752,9 +1752,12 @@ static int wl18xx_setup(struct wl1271 *w
- 	struct wl18xx_priv *priv = wl->priv;
- 	int ret;
- 
-+	BUILD_BUG_ON(WL18XX_MAX_LINKS > WLCORE_MAX_LINKS);
-+
- 	wl->rtable = wl18xx_rtable;
- 	wl->num_tx_desc = WL18XX_NUM_TX_DESCRIPTORS;
- 	wl->num_rx_desc = WL18XX_NUM_RX_DESCRIPTORS;
-+	wl->num_links = WL18XX_MAX_LINKS;
- 	wl->num_channels = 2;
- 	wl->num_mac_addr = WL18XX_NUM_MAC_ADDRESSES;
- 	wl->band_rate_to_idx = wl18xx_band_rate_to_idx;
---- a/drivers/net/wireless/ti/wl18xx/wl18xx.h
-+++ b/drivers/net/wireless/ti/wl18xx/wl18xx.h
-@@ -42,6 +42,8 @@
- 
- #define WL18XX_RX_BA_MAX_SESSIONS 5
- 
-+#define WL18XX_MAX_LINKS 12
-+
- struct wl18xx_priv {
- 	/* buffer for sending commands to FW */
- 	u8 cmd_buf[WL18XX_CMD_MAX_SIZE];
-@@ -114,7 +116,7 @@ struct wl18xx_fw_packet_counters {
- 	u8 tx_released_pkts[NUM_TX_QUEUES];
- 
- 	/* Cumulative counter of freed packets per HLID */
--	u8 tx_lnk_free_pkts[WL12XX_MAX_LINKS];
-+	u8 tx_lnk_free_pkts[WL18XX_MAX_LINKS];
- 
- 	/* Cumulative counter of released Voice memory blocks */
- 	u8 tx_voice_released_blks;
---- a/drivers/net/wireless/ti/wlcore/cmd.c
-+++ b/drivers/net/wireless/ti/wlcore/cmd.c
-@@ -312,8 +312,8 @@ static int wlcore_get_new_session_id(str
- int wl12xx_allocate_link(struct wl1271 *wl, struct wl12xx_vif *wlvif, u8 *hlid)
- {
- 	unsigned long flags;
--	u8 link = find_first_zero_bit(wl->links_map, WL12XX_MAX_LINKS);
--	if (link >= WL12XX_MAX_LINKS)
-+	u8 link = find_first_zero_bit(wl->links_map, wl->num_links);
-+	if (link >= wl->num_links)
- 		return -EBUSY;
- 
- 	wl->session_ids[link] = wlcore_get_new_session_id(wl, link);
---- a/drivers/net/wireless/ti/wlcore/event.c
-+++ b/drivers/net/wireless/ti/wlcore/event.c
-@@ -68,7 +68,7 @@ static void wl1271_stop_ba_event(struct
- 		u8 hlid;
- 		struct wl1271_link *lnk;
- 		for_each_set_bit(hlid, wlvif->ap.sta_hlid_map,
--				 WL12XX_MAX_LINKS) {
-+				 wl->num_links) {
- 			lnk = &wl->links[hlid];
- 			if (!lnk->ba_bitmap)
- 				continue;
-@@ -173,7 +173,7 @@ static void wlcore_disconnect_sta(struct
- 	const u8 *addr;
- 	int h;
- 
--	for_each_set_bit(h, &sta_bitmap, WL12XX_MAX_LINKS) {
-+	for_each_set_bit(h, &sta_bitmap, wl->num_links) {
- 		bool found = false;
- 		/* find the ap vif connected to this sta */
- 		wl12xx_for_each_wlvif_ap(wl, wlvif) {
---- a/drivers/net/wireless/ti/wlcore/main.c
-+++ b/drivers/net/wireless/ti/wlcore/main.c
-@@ -372,7 +372,7 @@ static void wl12xx_irq_update_links_stat
- 		wl->ap_fw_ps_map = cur_fw_ps_map;
- 	}
- 
--	for_each_set_bit(hlid, wlvif->ap.sta_hlid_map, WL12XX_MAX_LINKS)
-+	for_each_set_bit(hlid, wlvif->ap.sta_hlid_map, wl->num_links)
- 		wl12xx_irq_ps_regulate_link(wl, wlvif, hlid,
- 					    wl->links[hlid].allocated_pkts);
- }
-@@ -412,7 +412,7 @@ static int wlcore_fw_status(struct wl127
- 	}
- 
- 
--	for_each_set_bit(i, wl->links_map, WL12XX_MAX_LINKS) {
-+	for_each_set_bit(i, wl->links_map, wl->num_links) {
- 		u8 diff;
- 		lnk = &wl->links[i];
- 
-@@ -5888,7 +5888,7 @@ struct ieee80211_hw *wlcore_alloc_hw(siz
- 	int i, j, ret;
- 	unsigned int order;
- 
--	BUILD_BUG_ON(AP_MAX_STATIONS > WL12XX_MAX_LINKS);
-+	BUILD_BUG_ON(AP_MAX_STATIONS > WLCORE_MAX_LINKS);
- 
- 	hw = ieee80211_alloc_hw(sizeof(*wl), &wl1271_ops);
- 	if (!hw) {
-@@ -5911,8 +5911,12 @@ struct ieee80211_hw *wlcore_alloc_hw(siz
- 
- 	wl->hw = hw;
- 
-+	/*
-+	 * wl->num_links is not configured yet, so just use WLCORE_MAX_LINKS.
-+	 * we don't allocate any additional resource here, so that's fine.
-+	 */
- 	for (i = 0; i < NUM_TX_QUEUES; i++)
--		for (j = 0; j < WL12XX_MAX_LINKS; j++)
-+		for (j = 0; j < WLCORE_MAX_LINKS; j++)
- 			skb_queue_head_init(&wl->links[j].tx_queue[i]);
- 
- 	skb_queue_head_init(&wl->deferred_rx_queue);
---- a/drivers/net/wireless/ti/wlcore/rx.c
-+++ b/drivers/net/wireless/ti/wlcore/rx.c
-@@ -205,7 +205,7 @@ static int wl1271_rx_handle_data(struct
- 
- int wlcore_rx(struct wl1271 *wl, struct wl_fw_status *status)
- {
--	unsigned long active_hlids[BITS_TO_LONGS(WL12XX_MAX_LINKS)] = {0};
-+	unsigned long active_hlids[BITS_TO_LONGS(WLCORE_MAX_LINKS)] = {0};
- 	u32 buf_size;
- 	u32 fw_rx_counter = status->fw_rx_counter % wl->num_rx_desc;
- 	u32 drv_rx_counter = wl->rx_counter % wl->num_rx_desc;
-@@ -263,12 +263,12 @@ int wlcore_rx(struct wl1271 *wl, struct
- 						  wl->aggr_buf + pkt_offset,
- 						  pkt_len, rx_align,
- 						  &hlid) == 1) {
--				if (hlid < WL12XX_MAX_LINKS)
-+				if (hlid < wl->num_links)
- 					__set_bit(hlid, active_hlids);
- 				else
- 					WARN(1,
--					     "hlid exceeded WL12XX_MAX_LINKS "
--					     "(%d)\n", hlid);
-+					     "hlid (%d) exceeded MAX_LINKS\n",
-+					     hlid);
- 			}
- 
- 			wl->rx_counter++;
---- a/drivers/net/wireless/ti/wlcore/tx.c
-+++ b/drivers/net/wireless/ti/wlcore/tx.c
-@@ -565,11 +565,11 @@ static struct sk_buff *wlcore_vif_dequeu
- 	int i, h, start_hlid;
- 
- 	/* start from the link after the last one */
--	start_hlid = (wlvif->last_tx_hlid + 1) % WL12XX_MAX_LINKS;
-+	start_hlid = (wlvif->last_tx_hlid + 1) % wl->num_links;
- 
- 	/* dequeue according to AC, round robin on each link */
--	for (i = 0; i < WL12XX_MAX_LINKS; i++) {
--		h = (start_hlid + i) % WL12XX_MAX_LINKS;
-+	for (i = 0; i < wl->num_links; i++) {
-+		h = (start_hlid + i) % wl->num_links;
- 
- 		/* only consider connected stations */
- 		if (!test_bit(h, wlvif->links_map))
-@@ -693,8 +693,8 @@ static void wl1271_skb_queue_head(struct
- 		skb_queue_head(&wl->links[hlid].tx_queue[q], skb);
- 
- 		/* make sure we dequeue the same packet next time */
--		wlvif->last_tx_hlid = (hlid + WL12XX_MAX_LINKS - 1) %
--				      WL12XX_MAX_LINKS;
-+		wlvif->last_tx_hlid = (hlid + wl->num_links - 1) %
-+				      wl->num_links;
- 	}
- 
- 	spin_lock_irqsave(&wl->wl_lock, flags);
-@@ -727,7 +727,7 @@ void wl12xx_rearm_rx_streaming(struct wl
- 	timeout = wl->conf.rx_streaming.duration;
- 	wl12xx_for_each_wlvif_sta(wl, wlvif) {
- 		bool found = false;
--		for_each_set_bit(hlid, active_hlids, WL12XX_MAX_LINKS) {
-+		for_each_set_bit(hlid, active_hlids, wl->num_links) {
- 			if (test_bit(hlid, wlvif->links_map)) {
- 				found  = true;
- 				break;
-@@ -764,7 +764,7 @@ int wlcore_tx_work_locked(struct wl1271
- 	struct wl1271_tx_hw_descr *desc;
- 	u32 buf_offset = 0, last_len = 0;
- 	bool sent_packets = false;
--	unsigned long active_hlids[BITS_TO_LONGS(WL12XX_MAX_LINKS)] = {0};
-+	unsigned long active_hlids[BITS_TO_LONGS(WLCORE_MAX_LINKS)] = {0};
- 	int ret = 0;
- 	int bus_ret = 0;
- 	u8 hlid;
-@@ -1066,7 +1066,7 @@ void wl12xx_tx_reset_wlvif(struct wl1271
- 	int i;
- 
- 	/* TX failure */
--	for_each_set_bit(i, wlvif->links_map, WL12XX_MAX_LINKS) {
-+	for_each_set_bit(i, wlvif->links_map, wl->num_links) {
- 		if (wlvif->bss_type == BSS_TYPE_AP_BSS &&
- 		    i != wlvif->ap.bcast_hlid && i != wlvif->ap.global_hlid) {
- 			/* this calls wl12xx_free_link */
-@@ -1090,7 +1090,7 @@ void wl12xx_tx_reset(struct wl1271 *wl)
- 
- 	/* only reset the queues if something bad happened */
- 	if (wl1271_tx_total_queue_count(wl) != 0) {
--		for (i = 0; i < WL12XX_MAX_LINKS; i++)
-+		for (i = 0; i < wl->num_links; i++)
- 			wl1271_tx_reset_link_queues(wl, i);
- 
- 		for (i = 0; i < NUM_TX_QUEUES; i++)
-@@ -1183,7 +1183,7 @@ void wl1271_tx_flush(struct wl1271 *wl)
- 		       WL1271_TX_FLUSH_TIMEOUT / 1000);
- 
- 	/* forcibly flush all Tx buffers on our queues */
--	for (i = 0; i < WL12XX_MAX_LINKS; i++)
-+	for (i = 0; i < wl->num_links; i++)
- 		wl1271_tx_reset_link_queues(wl, i);
- 
- out_wake:
---- a/drivers/net/wireless/ti/wlcore/wlcore.h
-+++ b/drivers/net/wireless/ti/wlcore/wlcore.h
-@@ -224,7 +224,7 @@ struct wl1271 {
- 	int channel;
- 	u8 system_hlid;
- 
--	unsigned long links_map[BITS_TO_LONGS(WL12XX_MAX_LINKS)];
-+	unsigned long links_map[BITS_TO_LONGS(WLCORE_MAX_LINKS)];
- 	unsigned long roles_map[BITS_TO_LONGS(WL12XX_MAX_ROLES)];
- 	unsigned long roc_map[BITS_TO_LONGS(WL12XX_MAX_ROLES)];
- 	unsigned long rate_policies_map[
-@@ -232,7 +232,7 @@ struct wl1271 {
- 	unsigned long klv_templates_map[
- 			BITS_TO_LONGS(WLCORE_MAX_KLV_TEMPLATES)];
- 
--	u8 session_ids[WL12XX_MAX_LINKS];
-+	u8 session_ids[WLCORE_MAX_LINKS];
- 
- 	struct list_head wlvif_list;
- 
-@@ -380,7 +380,7 @@ struct wl1271 {
- 	 * AP-mode - links indexed by HLID. The global and broadcast links
- 	 * are always active.
- 	 */
--	struct wl1271_link links[WL12XX_MAX_LINKS];
-+	struct wl1271_link links[WLCORE_MAX_LINKS];
- 
- 	/* number of currently active links */
- 	int active_link_count;
-@@ -438,6 +438,8 @@ struct wl1271 {
- 	u32 num_tx_desc;
- 	/* number of RX descriptors the HW supports. */
- 	u32 num_rx_desc;
-+	/* number of links the HW supports */
-+	u8 num_links;
- 
- 	/* translate HW Tx rates to standard rate-indices */
- 	const u8 **band_rate_to_idx;
---- a/drivers/net/wireless/ti/wlcore/wlcore_i.h
-+++ b/drivers/net/wireless/ti/wlcore/wlcore_i.h
-@@ -58,10 +58,15 @@
- #define WL1271_DEFAULT_DTIM_PERIOD 1
- 
- #define WL12XX_MAX_ROLES           4
--#define WL12XX_MAX_LINKS           12
- #define WL12XX_INVALID_ROLE_ID     0xff
- #define WL12XX_INVALID_LINK_ID     0xff
- 
-+/*
-+ * max number of links allowed by all HWs.
-+ * this is NOT the actual max links supported by the current hw.
-+ */
-+#define WLCORE_MAX_LINKS 12
-+
- /* the driver supports the 2.4Ghz and 5Ghz bands */
- #define WLCORE_NUM_BANDS           2
- 
-@@ -156,7 +161,7 @@ struct wl_fw_status {
- 
- 		/*
- 		 * Cumulative counter of freed packets per HLID
--		 * (length of the array is WL12XX_MAX_LINKS)
-+		 * (length of the array is wl->num_links)
- 		 */
- 		u8 *tx_lnk_free_pkts;
- 
-@@ -357,7 +362,7 @@ struct wl12xx_vif {
- 
- 			/* HLIDs bitmap of associated stations */
- 			unsigned long sta_hlid_map[BITS_TO_LONGS(
--							WL12XX_MAX_LINKS)];
-+							WLCORE_MAX_LINKS)];
- 
- 			/* recoreded keys - set here before AP startup */
- 			struct wl1271_ap_key *recorded_keys[MAX_NUM_KEYS];
-@@ -374,7 +379,7 @@ struct wl12xx_vif {
- 	/* counters of packets per AC, across all links in the vif */
- 	int tx_queue_count[NUM_TX_QUEUES];
- 
--	unsigned long links_map[BITS_TO_LONGS(WL12XX_MAX_LINKS)];
-+	unsigned long links_map[BITS_TO_LONGS(WLCORE_MAX_LINKS)];
- 
- 	u8 ssid[IEEE80211_MAX_SSID_LEN + 1];
- 	u8 ssid_len;
diff --git a/package/kernel/mac80211/patches/907-wlcore-wl12xx-wl18xx-configure-max_stations-per-hw.patch b/package/kernel/mac80211/patches/907-wlcore-wl12xx-wl18xx-configure-max_stations-per-hw.patch
deleted file mode 100644
index 66fd7dde1b..0000000000
--- a/package/kernel/mac80211/patches/907-wlcore-wl12xx-wl18xx-configure-max_stations-per-hw.patch
+++ /dev/null
@@ -1,110 +0,0 @@
-Each hw supports a different max stations (connected to the
-same ap). add a new wl->max_ap_stations and use it instead
-of the current common AP_MAX_STATIONS.
-
-Signed-off-by: Eliad Peller <eliad@wizery.com>
-
----
-drivers/net/wireless/ti/wl12xx/main.c     | 2 ++
- drivers/net/wireless/ti/wl12xx/wl12xx.h   | 1 +
- drivers/net/wireless/ti/wl18xx/main.c     | 2 ++
- drivers/net/wireless/ti/wl18xx/wl18xx.h   | 1 +
- drivers/net/wireless/ti/wlcore/main.c     | 4 +---
- drivers/net/wireless/ti/wlcore/wlcore.h   | 2 ++
- drivers/net/wireless/ti/wlcore/wlcore_i.h | 2 --
- 7 files changed, 9 insertions(+), 5 deletions(-)
-
---- a/drivers/net/wireless/ti/wl12xx/main.c
-+++ b/drivers/net/wireless/ti/wl12xx/main.c
-@@ -1750,11 +1750,13 @@ static int wl12xx_setup(struct wl1271 *w
- 	struct wl12xx_platform_data *pdata = pdev_data->pdata;
- 
- 	BUILD_BUG_ON(WL12XX_MAX_LINKS > WLCORE_MAX_LINKS);
-+	BUILD_BUG_ON(WL12XX_MAX_AP_STATIONS > WL12XX_MAX_LINKS);
- 
- 	wl->rtable = wl12xx_rtable;
- 	wl->num_tx_desc = WL12XX_NUM_TX_DESCRIPTORS;
- 	wl->num_rx_desc = WL12XX_NUM_RX_DESCRIPTORS;
- 	wl->num_links = WL12XX_MAX_LINKS;
-+	wl->max_ap_stations = WL12XX_MAX_AP_STATIONS;
- 	wl->num_channels = 1;
- 	wl->num_mac_addr = WL12XX_NUM_MAC_ADDRESSES;
- 	wl->band_rate_to_idx = wl12xx_band_rate_to_idx;
---- a/drivers/net/wireless/ti/wl12xx/wl12xx.h
-+++ b/drivers/net/wireless/ti/wl12xx/wl12xx.h
-@@ -65,6 +65,7 @@
- 
- #define WL12XX_RX_BA_MAX_SESSIONS 3
- 
-+#define WL12XX_MAX_AP_STATIONS 8
- #define WL12XX_MAX_LINKS 12
- 
- struct wl127x_rx_mem_pool_addr {
---- a/drivers/net/wireless/ti/wl18xx/main.c
-+++ b/drivers/net/wireless/ti/wl18xx/main.c
-@@ -1753,11 +1753,13 @@ static int wl18xx_setup(struct wl1271 *w
- 	int ret;
- 
- 	BUILD_BUG_ON(WL18XX_MAX_LINKS > WLCORE_MAX_LINKS);
-+	BUILD_BUG_ON(WL18XX_MAX_AP_STATIONS > WL18XX_MAX_LINKS);
- 
- 	wl->rtable = wl18xx_rtable;
- 	wl->num_tx_desc = WL18XX_NUM_TX_DESCRIPTORS;
- 	wl->num_rx_desc = WL18XX_NUM_RX_DESCRIPTORS;
- 	wl->num_links = WL18XX_MAX_LINKS;
-+	wl->max_ap_stations = WL18XX_MAX_AP_STATIONS;
- 	wl->num_channels = 2;
- 	wl->num_mac_addr = WL18XX_NUM_MAC_ADDRESSES;
- 	wl->band_rate_to_idx = wl18xx_band_rate_to_idx;
---- a/drivers/net/wireless/ti/wl18xx/wl18xx.h
-+++ b/drivers/net/wireless/ti/wl18xx/wl18xx.h
-@@ -42,6 +42,7 @@
- 
- #define WL18XX_RX_BA_MAX_SESSIONS 5
- 
-+#define WL18XX_MAX_AP_STATIONS 8
- #define WL18XX_MAX_LINKS 12
- 
- struct wl18xx_priv {
---- a/drivers/net/wireless/ti/wlcore/main.c
-+++ b/drivers/net/wireless/ti/wlcore/main.c
-@@ -4695,7 +4695,7 @@ static int wl1271_allocate_sta(struct wl
- 	int ret;
- 
- 
--	if (wl->active_sta_count >= AP_MAX_STATIONS) {
-+	if (wl->active_sta_count >= wl->max_ap_stations) {
- 		wl1271_warning("could not allocate HLID - too much stations");
- 		return -EBUSY;
- 	}
-@@ -5888,8 +5888,6 @@ struct ieee80211_hw *wlcore_alloc_hw(siz
- 	int i, j, ret;
- 	unsigned int order;
- 
--	BUILD_BUG_ON(AP_MAX_STATIONS > WLCORE_MAX_LINKS);
--
- 	hw = ieee80211_alloc_hw(sizeof(*wl), &wl1271_ops);
- 	if (!hw) {
- 		wl1271_error("could not alloc ieee80211_hw");
---- a/drivers/net/wireless/ti/wlcore/wlcore.h
-+++ b/drivers/net/wireless/ti/wlcore/wlcore.h
-@@ -440,6 +440,8 @@ struct wl1271 {
- 	u32 num_rx_desc;
- 	/* number of links the HW supports */
- 	u8 num_links;
-+	/* max stations a single AP can support */
-+	u8 max_ap_stations;
- 
- 	/* translate HW Tx rates to standard rate-indices */
- 	const u8 **band_rate_to_idx;
---- a/drivers/net/wireless/ti/wlcore/wlcore_i.h
-+++ b/drivers/net/wireless/ti/wlcore/wlcore_i.h
-@@ -123,8 +123,6 @@ struct wl1271_chip {
- 
- #define NUM_TX_QUEUES              4
- 
--#define AP_MAX_STATIONS            8
--
- struct wl_fw_status {
- 	u32 intr;
- 	u8  fw_rx_counter;
diff --git a/package/kernel/mac80211/patches/908-wlcore-wl12xx-wl18xx-configure-iface_combinations-per-hw.patch b/package/kernel/mac80211/patches/908-wlcore-wl12xx-wl18xx-configure-iface_combinations-per-hw.patch
deleted file mode 100644
index eb00a50a0e..0000000000
--- a/package/kernel/mac80211/patches/908-wlcore-wl12xx-wl18xx-configure-iface_combinations-per-hw.patch
+++ /dev/null
@@ -1,176 +0,0 @@
-Each hw supports a different iface combinations.
-Define the supported combinations in each driver,
-and save it in wl->iface_combinations.
-
-Since each driver defines its own combinations now,
-it can also define its max supported channels, so
-we no longer need to save and set it explicitly
-in wlcore.
-
-Update wl18xx interface combinations to allow
-multiple APs.
-
-Signed-off-by: Eliad Peller <eliad@wizery.com>
-
----
-drivers/net/wireless/ti/wl12xx/main.c   | 26 +++++++++++++++++++++-
- drivers/net/wireless/ti/wl18xx/main.c   | 39 ++++++++++++++++++++++++++++++++-
- drivers/net/wireless/ti/wlcore/main.c   | 28 ++---------------------
- drivers/net/wireless/ti/wlcore/wlcore.h |  5 +++--
- 4 files changed, 68 insertions(+), 30 deletions(-)
-
---- a/drivers/net/wireless/ti/wl12xx/main.c
-+++ b/drivers/net/wireless/ti/wl12xx/main.c
-@@ -1743,6 +1743,29 @@ static struct ieee80211_sta_ht_cap wl12x
- 		},
- };
- 
-+static const struct ieee80211_iface_limit wl12xx_iface_limits[] = {
-+	{
-+		.max = 3,
-+		.types = BIT(NL80211_IFTYPE_STATION),
-+	},
-+	{
-+		.max = 1,
-+		.types = BIT(NL80211_IFTYPE_AP) |
-+			 BIT(NL80211_IFTYPE_P2P_GO) |
-+			 BIT(NL80211_IFTYPE_P2P_CLIENT),
-+	},
-+};
-+
-+static const struct ieee80211_iface_combination
-+wl12xx_iface_combinations[] = {
-+	{
-+		.max_interfaces = 3,
-+		.limits = wl12xx_iface_limits,
-+		.n_limits = ARRAY_SIZE(wl12xx_iface_limits),
-+		.num_different_channels = 1,
-+	},
-+};
-+
- static int wl12xx_setup(struct wl1271 *wl)
- {
- 	struct wl12xx_priv *priv = wl->priv;
-@@ -1757,7 +1780,8 @@ static int wl12xx_setup(struct wl1271 *w
- 	wl->num_rx_desc = WL12XX_NUM_RX_DESCRIPTORS;
- 	wl->num_links = WL12XX_MAX_LINKS;
- 	wl->max_ap_stations = WL12XX_MAX_AP_STATIONS;
--	wl->num_channels = 1;
-+	wl->iface_combinations = wl12xx_iface_combinations;
-+	wl->n_iface_combinations = ARRAY_SIZE(wl12xx_iface_combinations);
- 	wl->num_mac_addr = WL12XX_NUM_MAC_ADDRESSES;
- 	wl->band_rate_to_idx = wl12xx_band_rate_to_idx;
- 	wl->hw_tx_rate_tbl_size = WL12XX_CONF_HW_RXTX_RATE_MAX;
---- a/drivers/net/wireless/ti/wl18xx/main.c
-+++ b/drivers/net/wireless/ti/wl18xx/main.c
-@@ -1747,6 +1747,42 @@ static struct ieee80211_sta_ht_cap wl18x
- 		},
- };
- 
-+static const struct ieee80211_iface_limit wl18xx_iface_limits[] = {
-+	{
-+		.max = 3,
-+		.types = BIT(NL80211_IFTYPE_STATION),
-+	},
-+	{
-+		.max = 1,
-+		.types = BIT(NL80211_IFTYPE_AP) |
-+			 BIT(NL80211_IFTYPE_P2P_GO) |
-+			 BIT(NL80211_IFTYPE_P2P_CLIENT),
-+	},
-+};
-+
-+static const struct ieee80211_iface_limit wl18xx_iface_ap_limits[] = {
-+	{
-+		.max = 2,
-+		.types = BIT(NL80211_IFTYPE_AP),
-+	},
-+};
-+
-+static const struct ieee80211_iface_combination
-+wl18xx_iface_combinations[] = {
-+	{
-+		.max_interfaces = 3,
-+		.limits = wl18xx_iface_limits,
-+		.n_limits = ARRAY_SIZE(wl18xx_iface_limits),
-+		.num_different_channels = 2,
-+	},
-+	{
-+		.max_interfaces = 2,
-+		.limits = wl18xx_iface_ap_limits,
-+		.n_limits = ARRAY_SIZE(wl18xx_iface_ap_limits),
-+		.num_different_channels = 1,
-+	}
-+};
-+
- static int wl18xx_setup(struct wl1271 *wl)
- {
- 	struct wl18xx_priv *priv = wl->priv;
-@@ -1760,7 +1796,8 @@ static int wl18xx_setup(struct wl1271 *w
- 	wl->num_rx_desc = WL18XX_NUM_RX_DESCRIPTORS;
- 	wl->num_links = WL18XX_MAX_LINKS;
- 	wl->max_ap_stations = WL18XX_MAX_AP_STATIONS;
--	wl->num_channels = 2;
-+	wl->iface_combinations = wl18xx_iface_combinations;
-+	wl->n_iface_combinations = ARRAY_SIZE(wl18xx_iface_combinations);
- 	wl->num_mac_addr = WL18XX_NUM_MAC_ADDRESSES;
- 	wl->band_rate_to_idx = wl18xx_band_rate_to_idx;
- 	wl->hw_tx_rate_tbl_size = WL18XX_CONF_HW_RXTX_RATE_MAX;
---- a/drivers/net/wireless/ti/wlcore/main.c
-+++ b/drivers/net/wireless/ti/wlcore/main.c
-@@ -5723,28 +5723,6 @@ static void wl1271_unregister_hw(struct
- 
- }
- 
--static const struct ieee80211_iface_limit wlcore_iface_limits[] = {
--	{
--		.max = 3,
--		.types = BIT(NL80211_IFTYPE_STATION),
--	},
--	{
--		.max = 1,
--		.types = BIT(NL80211_IFTYPE_AP) |
--			 BIT(NL80211_IFTYPE_P2P_GO) |
--			 BIT(NL80211_IFTYPE_P2P_CLIENT),
--	},
--};
--
--static struct ieee80211_iface_combination
--wlcore_iface_combinations[] = {
--	{
--	  .max_interfaces = 3,
--	  .limits = wlcore_iface_limits,
--	  .n_limits = ARRAY_SIZE(wlcore_iface_limits),
--	},
--};
--
- static int wl1271_init_ieee80211(struct wl1271 *wl)
- {
- 	int i;
-@@ -5865,10 +5843,8 @@ static int wl1271_init_ieee80211(struct
- 		NL80211_PROBE_RESP_OFFLOAD_SUPPORT_P2P;
- 
- 	/* allowed interface combinations */
--	wlcore_iface_combinations[0].num_different_channels = wl->num_channels;
--	wl->hw->wiphy->iface_combinations = wlcore_iface_combinations;
--	wl->hw->wiphy->n_iface_combinations =
--		ARRAY_SIZE(wlcore_iface_combinations);
-+	wl->hw->wiphy->iface_combinations = wl->iface_combinations;
-+	wl->hw->wiphy->n_iface_combinations = wl->n_iface_combinations;
- 
- 	SET_IEEE80211_DEV(wl->hw, wl->dev);
- 
---- a/drivers/net/wireless/ti/wlcore/wlcore.h
-+++ b/drivers/net/wireless/ti/wlcore/wlcore.h
-@@ -485,8 +485,9 @@ struct wl1271 {
- 
- 	struct completion nvs_loading_complete;
- 
--	/* number of concurrent channels the HW supports */
--	u32 num_channels;
-+	/* interface combinations supported by the hw */
-+	const struct ieee80211_iface_combination *iface_combinations;
-+	u8 n_iface_combinations;
- };
- 
- int wlcore_probe(struct wl1271 *wl, struct platform_device *pdev);
diff --git a/package/kernel/mac80211/patches/909-wl18xx-move-to-new-firmware-wl18xx-fw-3.bin.patch b/package/kernel/mac80211/patches/909-wl18xx-move-to-new-firmware-wl18xx-fw-3.bin.patch
deleted file mode 100644
index 85214c1037..0000000000
--- a/package/kernel/mac80211/patches/909-wl18xx-move-to-new-firmware-wl18xx-fw-3.bin.patch
+++ /dev/null
@@ -1,200 +0,0 @@
-Bump the min wl18xx fw version to 8.8.0.0.13
-
-This fw is not backward compatible with older
-firmware (due to api changes), so use bump
-the firmware name as well.
-
-Some modifications were done to the driver-fw api
-in order to support multiple APs.
-
-Additionally, some of the consts (such as max stations,
-max links and max RX BA sessions) were changed.
-
-Signed-off-by: Arik Nemtsov <arik@wizery.com>
-Signed-off-by: Eliad Peller <eliad@wizery.com>
-
----
-drivers/net/wireless/ti/wl18xx/main.c     |  2 +-
- drivers/net/wireless/ti/wl18xx/wl18xx.h   | 10 +++++-----
- drivers/net/wireless/ti/wlcore/acx.c      |  4 +++-
- drivers/net/wireless/ti/wlcore/acx.h      |  6 ++++--
- drivers/net/wireless/ti/wlcore/cmd.c      |  5 ++++-
- drivers/net/wireless/ti/wlcore/cmd.h      |  7 +++++--
- drivers/net/wireless/ti/wlcore/main.c     |  2 +-
- drivers/net/wireless/ti/wlcore/tx.c       |  2 +-
- drivers/net/wireless/ti/wlcore/wlcore_i.h |  2 +-
- 9 files changed, 25 insertions(+), 15 deletions(-)
-
---- a/drivers/net/wireless/ti/wl18xx/main.c
-+++ b/drivers/net/wireless/ti/wl18xx/main.c
-@@ -648,7 +648,7 @@ static const struct wl18xx_clk_cfg wl18x
- };
- 
- /* TODO: maybe move to a new header file? */
--#define WL18XX_FW_NAME "ti-connectivity/wl18xx-fw-2.bin"
-+#define WL18XX_FW_NAME "ti-connectivity/wl18xx-fw-3.bin"
- 
- static int wl18xx_identify_chip(struct wl1271 *wl)
- {
---- a/drivers/net/wireless/ti/wl18xx/wl18xx.h
-+++ b/drivers/net/wireless/ti/wl18xx/wl18xx.h
-@@ -26,10 +26,10 @@
- 
- /* minimum FW required for driver */
- #define WL18XX_CHIP_VER		8
--#define WL18XX_IFTYPE_VER	5
-+#define WL18XX_IFTYPE_VER	8
- #define WL18XX_MAJOR_VER	WLCORE_FW_VER_IGNORE
- #define WL18XX_SUBTYPE_VER	WLCORE_FW_VER_IGNORE
--#define WL18XX_MINOR_VER	39
-+#define WL18XX_MINOR_VER	13
- 
- #define WL18XX_CMD_MAX_SIZE          740
- 
-@@ -40,10 +40,10 @@
- 
- #define WL18XX_NUM_MAC_ADDRESSES 3
- 
--#define WL18XX_RX_BA_MAX_SESSIONS 5
-+#define WL18XX_RX_BA_MAX_SESSIONS 13
- 
--#define WL18XX_MAX_AP_STATIONS 8
--#define WL18XX_MAX_LINKS 12
-+#define WL18XX_MAX_AP_STATIONS 10
-+#define WL18XX_MAX_LINKS 16
- 
- struct wl18xx_priv {
- 	/* buffer for sending commands to FW */
---- a/drivers/net/wireless/ti/wlcore/acx.c
-+++ b/drivers/net/wireless/ti/wlcore/acx.c
-@@ -1591,7 +1591,8 @@ out:
- 	return ret;
- }
- 
--int wl1271_acx_set_inconnection_sta(struct wl1271 *wl, u8 *addr)
-+int wl1271_acx_set_inconnection_sta(struct wl1271 *wl,
-+				    struct wl12xx_vif *wlvif, u8 *addr)
- {
- 	struct wl1271_acx_inconnection_sta *acx = NULL;
- 	int ret;
-@@ -1603,6 +1604,7 @@ int wl1271_acx_set_inconnection_sta(stru
- 		return -ENOMEM;
- 
- 	memcpy(acx->addr, addr, ETH_ALEN);
-+	acx->role_id = wlvif->role_id;
- 
- 	ret = wl1271_cmd_configure(wl, ACX_UPDATE_INCONNECTION_STA_LIST,
- 				   acx, sizeof(*acx));
---- a/drivers/net/wireless/ti/wlcore/acx.h
-+++ b/drivers/net/wireless/ti/wlcore/acx.h
-@@ -824,7 +824,8 @@ struct wl1271_acx_inconnection_sta {
- 	struct acx_header header;
- 
- 	u8 addr[ETH_ALEN];
--	u8 padding1[2];
-+	u8 role_id;
-+	u8 padding;
- } __packed;
- 
- /*
-@@ -1118,7 +1119,8 @@ int wl1271_acx_ps_rx_streaming(struct wl
- 			       bool enable);
- int wl1271_acx_ap_max_tx_retry(struct wl1271 *wl, struct wl12xx_vif *wlvif);
- int wl12xx_acx_config_ps(struct wl1271 *wl, struct wl12xx_vif *wlvif);
--int wl1271_acx_set_inconnection_sta(struct wl1271 *wl, u8 *addr);
-+int wl1271_acx_set_inconnection_sta(struct wl1271 *wl,
-+				    struct wl12xx_vif *wlvif, u8 *addr);
- int wl1271_acx_fm_coex(struct wl1271 *wl);
- int wl12xx_acx_set_rate_mgmt_params(struct wl1271 *wl);
- int wl12xx_acx_config_hangover(struct wl1271 *wl);
---- a/drivers/net/wireless/ti/wlcore/cmd.c
-+++ b/drivers/net/wireless/ti/wlcore/cmd.c
-@@ -1532,6 +1532,7 @@ int wl12xx_cmd_add_peer(struct wl1271 *w
- 	cmd->sp_len = sta->max_sp;
- 	cmd->wmm = sta->wme ? 1 : 0;
- 	cmd->session_id = wl->session_ids[hlid];
-+	cmd->role_id = wlvif->role_id;
- 
- 	for (i = 0; i < NUM_ACCESS_CATEGORIES_COPY; i++)
- 		if (sta->wme && (sta->uapsd_queues & BIT(i)))
-@@ -1568,7 +1569,8 @@ out:
- 	return ret;
- }
- 
--int wl12xx_cmd_remove_peer(struct wl1271 *wl, u8 hlid)
-+int wl12xx_cmd_remove_peer(struct wl1271 *wl, struct wl12xx_vif *wlvif,
-+			   u8 hlid)
- {
- 	struct wl12xx_cmd_remove_peer *cmd;
- 	int ret;
-@@ -1586,6 +1588,7 @@ int wl12xx_cmd_remove_peer(struct wl1271
- 	/* We never send a deauth, mac80211 is in charge of this */
- 	cmd->reason_opcode = 0;
- 	cmd->send_deauth_flag = 0;
-+	cmd->role_id = wlvif->role_id;
- 
- 	ret = wl1271_cmd_send(wl, CMD_REMOVE_PEER, cmd, sizeof(*cmd), 0);
- 	if (ret < 0) {
---- a/drivers/net/wireless/ti/wlcore/cmd.h
-+++ b/drivers/net/wireless/ti/wlcore/cmd.h
-@@ -88,7 +88,8 @@ int wl12xx_roc(struct wl1271 *wl, struct
- int wl12xx_croc(struct wl1271 *wl, u8 role_id);
- int wl12xx_cmd_add_peer(struct wl1271 *wl, struct wl12xx_vif *wlvif,
- 			struct ieee80211_sta *sta, u8 hlid);
--int wl12xx_cmd_remove_peer(struct wl1271 *wl, u8 hlid);
-+int wl12xx_cmd_remove_peer(struct wl1271 *wl, struct wl12xx_vif *wlvif,
-+			   u8 hlid);
- void wlcore_set_pending_regdomain_ch(struct wl1271 *wl, u16 channel,
- 				     enum ieee80211_band band);
- int wlcore_cmd_regdomain_config_locked(struct wl1271 *wl);
-@@ -594,6 +595,8 @@ struct wl12xx_cmd_add_peer {
- 	u8 sp_len;
- 	u8 wmm;
- 	u8 session_id;
-+	u8 role_id;
-+	u8 padding[3];
- } __packed;
- 
- struct wl12xx_cmd_remove_peer {
-@@ -602,7 +605,7 @@ struct wl12xx_cmd_remove_peer {
- 	u8 hlid;
- 	u8 reason_opcode;
- 	u8 send_deauth_flag;
--	u8 padding1;
-+	u8 role_id;
- } __packed;
- 
- /*
---- a/drivers/net/wireless/ti/wlcore/main.c
-+++ b/drivers/net/wireless/ti/wlcore/main.c
-@@ -4798,7 +4798,7 @@ static int wl12xx_sta_remove(struct wl12
- 	if (WARN_ON(!test_bit(id, wlvif->ap.sta_hlid_map)))
- 		return -EINVAL;
- 
--	ret = wl12xx_cmd_remove_peer(wl, wl_sta->hlid);
-+	ret = wl12xx_cmd_remove_peer(wl, wlvif, wl_sta->hlid);
- 	if (ret < 0)
- 		return ret;
- 
---- a/drivers/net/wireless/ti/wlcore/tx.c
-+++ b/drivers/net/wireless/ti/wlcore/tx.c
-@@ -101,7 +101,7 @@ static void wl1271_tx_ap_update_inconnec
- 	 * authentication response. this way it won't get de-authed by FW
- 	 * when transmitting too soon.
- 	 */
--	wl1271_acx_set_inconnection_sta(wl, hdr->addr1);
-+	wl1271_acx_set_inconnection_sta(wl, wlvif, hdr->addr1);
- 
- 	/*
- 	 * ROC for 1 second on the AP channel for completing the connection.
---- a/drivers/net/wireless/ti/wlcore/wlcore_i.h
-+++ b/drivers/net/wireless/ti/wlcore/wlcore_i.h
-@@ -65,7 +65,7 @@
-  * max number of links allowed by all HWs.
-  * this is NOT the actual max links supported by the current hw.
-  */
--#define WLCORE_MAX_LINKS 12
-+#define WLCORE_MAX_LINKS 16
- 
- /* the driver supports the 2.4Ghz and 5Ghz bands */
- #define WLCORE_NUM_BANDS           2
diff --git a/package/kernel/mac80211/patches/910-wlcore-send-EAPOL-frames-with-voice-priority.patch b/package/kernel/mac80211/patches/910-wlcore-send-EAPOL-frames-with-voice-priority.patch
deleted file mode 100644
index 6f6b22a090..0000000000
--- a/package/kernel/mac80211/patches/910-wlcore-send-EAPOL-frames-with-voice-priority.patch
+++ /dev/null
@@ -1,37 +0,0 @@
-Send EAPOL frames with voice priority by setting (the new)
-TX_HW_ATTR_EAPOL_FRAME bit in tx attribute.
-
-Sending EAPOL with voice priority fixes re-key
-timeout issues during heavy traffic.
-
-Signed-off-by: Igal Chernobelsky <igalc@ti.com>
-Signed-off-by: Eliad Peller <eliad@wizery.com>
-
----
-drivers/net/wireless/ti/wlcore/tx.c | 4 ++++
- drivers/net/wireless/ti/wlcore/tx.h | 1 +
- 2 files changed, 5 insertions(+)
-
---- a/drivers/net/wireless/ti/wlcore/tx.c
-+++ b/drivers/net/wireless/ti/wlcore/tx.c
-@@ -362,6 +362,10 @@ static void wl1271_tx_fill_hdr(struct wl
- 	    ieee80211_has_protected(frame_control))
- 		tx_attr |= TX_HW_ATTR_HOST_ENCRYPT;
- 
-+	/* send EAPOL frames as voice */
-+	if (control->control.flags & IEEE80211_TX_CTRL_PORT_CTRL_PROTO)
-+		tx_attr |= TX_HW_ATTR_EAPOL_FRAME;
-+
- 	desc->tx_attr = cpu_to_le16(tx_attr);
- 
- 	wlcore_hw_set_tx_desc_csum(wl, desc, skb);
---- a/drivers/net/wireless/ti/wlcore/tx.h
-+++ b/drivers/net/wireless/ti/wlcore/tx.h
-@@ -37,6 +37,7 @@
- #define TX_HW_ATTR_TX_CMPLT_REQ          BIT(12)
- #define TX_HW_ATTR_TX_DUMMY_REQ          BIT(13)
- #define TX_HW_ATTR_HOST_ENCRYPT          BIT(14)
-+#define TX_HW_ATTR_EAPOL_FRAME           BIT(15)
- 
- #define TX_HW_ATTR_OFST_SAVE_RETRIES     0
- #define TX_HW_ATTR_OFST_HEADER_PAD       1
diff --git a/package/kernel/mac80211/patches/911-wlcore-don-t-stop-sched_scan-on-interface-removal.patch b/package/kernel/mac80211/patches/911-wlcore-don-t-stop-sched_scan-on-interface-removal.patch
deleted file mode 100644
index 91269d22fc..0000000000
--- a/package/kernel/mac80211/patches/911-wlcore-don-t-stop-sched_scan-on-interface-removal.patch
+++ /dev/null
@@ -1,25 +0,0 @@
-Stopping sched scan on interface removal (during recovery)
-is no longer needed, as sched scanning is automatically
-restarted by mac80211.
-
-Signed-off-by: Barak Bercovitz <barak@wizery.com>
-Signed-off-by: Eliad Peller <eliad@wizery.com>
-
----
-drivers/net/wireless/ti/wlcore/main.c | 4 +---
- 1 file changed, 1 insertion(+), 3 deletions(-)
-
---- a/drivers/net/wireless/ti/wlcore/main.c
-+++ b/drivers/net/wireless/ti/wlcore/main.c
-@@ -2582,10 +2582,8 @@ static void __wl1271_op_remove_interface
- 		ieee80211_scan_completed(wl->hw, true);
- 	}
- 
--	if (wl->sched_vif == wlvif) {
--		ieee80211_sched_scan_stopped(wl->hw);
-+	if (wl->sched_vif == wlvif)
- 		wl->sched_vif = NULL;
--	}
- 
- 	if (wl->roc_vif == vif) {
- 		wl->roc_vif = NULL;
diff --git a/package/kernel/mac80211/patches/912-wlcore-wl18xx-allow-CCK-rates-for-AP-mode.patch b/package/kernel/mac80211/patches/912-wlcore-wl18xx-allow-CCK-rates-for-AP-mode.patch
deleted file mode 100644
index c957b9c04e..0000000000
--- a/package/kernel/mac80211/patches/912-wlcore-wl18xx-allow-CCK-rates-for-AP-mode.patch
+++ /dev/null
@@ -1,47 +0,0 @@
-12xx chips allow only OFDM rates in AP mode for BT-Coex purposes. This
-is no longer required in 18xx chips, starting with FW 8.6.0.0.8.
-
-Update the min allowed FW version in 18xx to support this functionality.
-
-Signed-off-by: Arik Nemtsov <arik@wizery.com>
-Signed-off-by: Eliad Peller <eliad@wizery.com>
-
----
-drivers/net/wireless/ti/wl12xx/main.c   | 1 +
- drivers/net/wireless/ti/wlcore/init.c   | 2 +-
- drivers/net/wireless/ti/wlcore/wlcore.h | 3 +++
- 3 files changed, 5 insertions(+), 1 deletion(-)
-
---- a/drivers/net/wireless/ti/wl12xx/main.c
-+++ b/drivers/net/wireless/ti/wl12xx/main.c
-@@ -1789,6 +1789,7 @@ static int wl12xx_setup(struct wl1271 *w
- 	wl->fw_status_len = sizeof(struct wl12xx_fw_status);
- 	wl->fw_status_priv_len = 0;
- 	wl->stats.fw_stats_len = sizeof(struct wl12xx_acx_statistics);
-+	wl->ofdm_only_ap = true;
- 	wlcore_set_ht_cap(wl, IEEE80211_BAND_2GHZ, &wl12xx_ht_cap);
- 	wlcore_set_ht_cap(wl, IEEE80211_BAND_5GHZ, &wl12xx_ht_cap);
- 	wl12xx_conf_init(wl);
---- a/drivers/net/wireless/ti/wlcore/init.c
-+++ b/drivers/net/wireless/ti/wlcore/init.c
-@@ -462,7 +462,7 @@ int wl1271_init_ap_rates(struct wl1271 *
- 	 * If the basic rates contain OFDM rates, use OFDM only
- 	 * rates for unicast TX as well. Else use all supported rates.
- 	 */
--	if ((wlvif->basic_rate_set & CONF_TX_OFDM_RATES))
-+	if (wl->ofdm_only_ap && (wlvif->basic_rate_set & CONF_TX_OFDM_RATES))
- 		supported_rates = CONF_TX_OFDM_RATES;
- 	else
- 		supported_rates = CONF_TX_ENABLED_RATES;
---- a/drivers/net/wireless/ti/wlcore/wlcore.h
-+++ b/drivers/net/wireless/ti/wlcore/wlcore.h
-@@ -409,6 +409,9 @@ struct wl1271 {
- 	/* AP-mode - number of currently connected stations */
- 	int active_sta_count;
- 
-+	/* Flag determining whether AP should broadcast OFDM-only rates */
-+	bool ofdm_only_ap;
-+
- 	/* last wlvif we transmitted from */
- 	struct wl12xx_vif *last_wlvif;
- 
diff --git a/package/kernel/mac80211/patches/913-wlcore-don-t-handle-unsetting-of-default-wep-key.patch b/package/kernel/mac80211/patches/913-wlcore-don-t-handle-unsetting-of-default-wep-key.patch
deleted file mode 100644
index 69621c59fe..0000000000
--- a/package/kernel/mac80211/patches/913-wlcore-don-t-handle-unsetting-of-default-wep-key.patch
+++ /dev/null
@@ -1,28 +0,0 @@
-mac80211 unsets the default wep key on disassoc.
-The fw doesn't support this notification, so simply
-ignore it.
-
-The actual flow actually triggers fw recovery in some
-cases, as mac80211 unsets the default key only after
-disassoc, when wlvif->sta.hlid, resulting in invalid
-hlid being passed to the fw.
-
-Signed-off-by: Eliad Peller <eliad@wizery.com>
-
----
-drivers/net/wireless/ti/wlcore/main.c | 4 ++++
- 1 file changed, 4 insertions(+)
-
---- a/drivers/net/wireless/ti/wlcore/main.c
-+++ b/drivers/net/wireless/ti/wlcore/main.c
-@@ -3505,6 +3505,10 @@ static void wl1271_op_set_default_key_id
- 	wl1271_debug(DEBUG_MAC80211, "mac80211 set default key idx %d",
- 		     key_idx);
- 
-+	/* we don't handle unsetting of default key */
-+	if (key_idx == -1)
-+		return;
-+
- 	mutex_lock(&wl->mutex);
- 
- 	if (unlikely(wl->state != WLCORE_STATE_ON)) {
diff --git a/package/kernel/mac80211/patches/914-wlcore-consider-multiple-APs-when-checking-active_link_count.patch b/package/kernel/mac80211/patches/914-wlcore-consider-multiple-APs-when-checking-active_link_count.patch
deleted file mode 100644
index 9e9eba7417..0000000000
--- a/package/kernel/mac80211/patches/914-wlcore-consider-multiple-APs-when-checking-active_link_count.patch
+++ /dev/null
@@ -1,51 +0,0 @@
-Each AP has its own global and broadcast links, so when
-checking for active sta count (according to the active_link_count)
-we must take them all into account.
-
-Signed-off-by: Eliad Peller <eliad@wizery.com>
-
----
-drivers/net/wireless/ti/wlcore/main.c | 10 +++++-----
- drivers/net/wireless/ti/wlcore/tx.c   | 10 +++++-----
- 2 files changed, 10 insertions(+), 10 deletions(-)
-
---- a/drivers/net/wireless/ti/wlcore/main.c
-+++ b/drivers/net/wireless/ti/wlcore/main.c
-@@ -345,12 +345,12 @@ static void wl12xx_irq_ps_regulate_link(
- 	 * Start high-level PS if the STA is asleep with enough blocks in FW.
- 	 * Make an exception if this is the only connected link. In this
- 	 * case FW-memory congestion is less of a problem.
--	 * Note that a single connected STA means 3 active links, since we must
--	 * account for the global and broadcast AP links. The "fw_ps" check
--	 * assures us the third link is a STA connected to the AP. Otherwise
--	 * the FW would not set the PSM bit.
-+	 * Note that a single connected STA means 2*ap_count + 1 active links,
-+	 * since we must account for the global and broadcast AP links
-+	 * for each AP. The "fw_ps" check assures us the other link is a STA
-+	 * connected to the AP. Otherwise the FW would not set the PSM bit.
- 	 */
--	else if (wl->active_link_count > 3 && fw_ps &&
-+	else if (wl->active_link_count > (wl->ap_count*2 + 1) && fw_ps &&
- 		 tx_pkts >= WL1271_PS_STA_MAX_PACKETS)
- 		wl12xx_ps_link_start(wl, wlvif, hlid, true);
- }
---- a/drivers/net/wireless/ti/wlcore/tx.c
-+++ b/drivers/net/wireless/ti/wlcore/tx.c
-@@ -134,12 +134,12 @@ static void wl1271_tx_regulate_link(stru
- 	 * into high-level PS and clean out its TX queues.
- 	 * Make an exception if this is the only connected link. In this
- 	 * case FW-memory congestion is less of a problem.
--	 * Note that a single connected STA means 3 active links, since we must
--	 * account for the global and broadcast AP links. The "fw_ps" check
--	 * assures us the third link is a STA connected to the AP. Otherwise
--	 * the FW would not set the PSM bit.
-+	 * Note that a single connected STA means 2*ap_count + 1 active links,
-+	 * since we must account for the global and broadcast AP links
-+	 * for each AP. The "fw_ps" check assures us the other link is a STA
-+	 * connected to the AP. Otherwise the FW would not set the PSM bit.
- 	 */
--	if (wl->active_link_count > 3 && fw_ps &&
-+	if (wl->active_link_count > (wl->ap_count*2 + 1) && fw_ps &&
- 	    tx_pkts >= WL1271_PS_STA_MAX_PACKETS)
- 		wl12xx_ps_link_start(wl, wlvif, hlid, true);
- }
diff --git a/package/kernel/mac80211/patches/915-wlcore-decrease-warning-verbosity-during-recovery.patch b/package/kernel/mac80211/patches/915-wlcore-decrease-warning-verbosity-during-recovery.patch
deleted file mode 100644
index be2de10ccf..0000000000
--- a/package/kernel/mac80211/patches/915-wlcore-decrease-warning-verbosity-during-recovery.patch
+++ /dev/null
@@ -1,42 +0,0 @@
-Silently ignore repetitive scheduling of recovery work and commands
-being passed to the bus when the HW is not available. This can happen
-many times during recovery and slow it down. It also spams the kernel
-logs.
-
-Signed-off-by: Arik Nemtsov <arik@wizery.com>
-Signed-off-by: Eliad Peller <eliad@wizery.com>
-
----
-drivers/net/wireless/ti/wlcore/cmd.c  | 4 ++--
- drivers/net/wireless/ti/wlcore/main.c | 5 +++--
- 2 files changed, 5 insertions(+), 4 deletions(-)
-
---- a/drivers/net/wireless/ti/wlcore/cmd.c
-+++ b/drivers/net/wireless/ti/wlcore/cmd.c
-@@ -60,8 +60,8 @@ static int __wlcore_cmd_send(struct wl12
- 	u16 status;
- 	u16 poll_count = 0;
- 
--	if (WARN_ON(wl->state == WLCORE_STATE_RESTARTING &&
--		    id != CMD_STOP_FWLOGGER))
-+	if (unlikely(wl->state == WLCORE_STATE_RESTARTING &&
-+		     id != CMD_STOP_FWLOGGER))
- 		return -EIO;
- 
- 	cmd = buf;
---- a/drivers/net/wireless/ti/wlcore/main.c
-+++ b/drivers/net/wireless/ti/wlcore/main.c
-@@ -782,10 +782,11 @@ out:
- 
- void wl12xx_queue_recovery_work(struct wl1271 *wl)
- {
--	WARN_ON(!test_bit(WL1271_FLAG_INTENDED_FW_RECOVERY, &wl->flags));
--
- 	/* Avoid a recursive recovery */
- 	if (wl->state == WLCORE_STATE_ON) {
-+		WARN_ON(!test_bit(WL1271_FLAG_INTENDED_FW_RECOVERY,
-+				  &wl->flags));
-+
- 		wl->state = WLCORE_STATE_RESTARTING;
- 		set_bit(WL1271_FLAG_RECOVERY_IN_PROGRESS, &wl->flags);
- 		wl1271_ps_elp_wakeup(wl);
diff --git a/package/kernel/mac80211/patches/916-wlcore-increase-timeout-to-5000-msecs.patch b/package/kernel/mac80211/patches/916-wlcore-increase-timeout-to-5000-msecs.patch
deleted file mode 100644
index eb490e43c8..0000000000
--- a/package/kernel/mac80211/patches/916-wlcore-increase-timeout-to-5000-msecs.patch
+++ /dev/null
@@ -1,21 +0,0 @@
-dfs configuration command might take longer than
-the current timeout. increase it to 5 seconds.
-
-Signed-off-by: Yaniv Machani <yanivma@ti.com>
-Signed-off-by: Eliad Peller <eliad@wizery.com>
-
----
-drivers/net/wireless/ti/wlcore/cmd.h | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/net/wireless/ti/wlcore/cmd.h
-+++ b/drivers/net/wireless/ti/wlcore/cmd.h
-@@ -207,7 +207,7 @@ enum cmd_templ {
- #define WL1271_COMMAND_TIMEOUT     2000
- #define WL1271_CMD_TEMPL_DFLT_SIZE 252
- #define WL1271_CMD_TEMPL_MAX_SIZE  512
--#define WL1271_EVENT_TIMEOUT       1500
-+#define WL1271_EVENT_TIMEOUT       5000
- 
- struct wl1271_cmd_header {
- 	__le16 id;
diff --git a/package/kernel/mac80211/patches/917-wlcore-enable-beacon-filtering-only-after-receiving-a-beacon.patch b/package/kernel/mac80211/patches/917-wlcore-enable-beacon-filtering-only-after-receiving-a-beacon.patch
deleted file mode 100644
index 5dbad9494e..0000000000
--- a/package/kernel/mac80211/patches/917-wlcore-enable-beacon-filtering-only-after-receiving-a-beacon.patch
+++ /dev/null
@@ -1,71 +0,0 @@
-Enabling beacon filtering before receving a beacon
-might result in not having a beacon at all for the
-current connected AP, which prevents the station
-from entering power-save.
-
-Replace the current approach (of starting beacon
-filtering on init) and configure beacon filering
-only after bss_conf->dtimper is set (which means
-mac80211 already parsed a beacon).
-
-Signed-off-by: Eliad Peller <eliad@wizery.com>
-
----
-drivers/net/wireless/ti/wlcore/acx.c  |  3 ++-
- drivers/net/wireless/ti/wlcore/init.c |  4 ++--
- drivers/net/wireless/ti/wlcore/main.c | 12 ++++++++++++
- 3 files changed, 16 insertions(+), 3 deletions(-)
-
---- a/drivers/net/wireless/ti/wlcore/acx.c
-+++ b/drivers/net/wireless/ti/wlcore/acx.c
-@@ -358,7 +358,8 @@ int wl1271_acx_beacon_filter_opt(struct
- 	struct acx_beacon_filter_option *beacon_filter = NULL;
- 	int ret = 0;
- 
--	wl1271_debug(DEBUG_ACX, "acx beacon filter opt");
-+	wl1271_debug(DEBUG_ACX, "acx beacon filter opt enable=%d",
-+		     enable_filter);
- 
- 	if (enable_filter &&
- 	    wl->conf.conn.bcn_filt_mode == CONF_BCN_FILT_MODE_DISABLED)
---- a/drivers/net/wireless/ti/wlcore/init.c
-+++ b/drivers/net/wireless/ti/wlcore/init.c
-@@ -287,8 +287,8 @@ static int wl1271_init_sta_beacon_filter
- 	if (ret < 0)
- 		return ret;
- 
--	/* enable beacon filtering */
--	ret = wl1271_acx_beacon_filter_opt(wl, wlvif, true);
-+	/* disable beacon filtering until we get the first beacon */
-+	ret = wl1271_acx_beacon_filter_opt(wl, wlvif, false);
- 	if (ret < 0)
- 		return ret;
- 
---- a/drivers/net/wireless/ti/wlcore/main.c
-+++ b/drivers/net/wireless/ti/wlcore/main.c
-@@ -2941,6 +2941,11 @@ static int wlcore_unset_assoc(struct wl1
- 		ret = wl1271_acx_keep_alive_mode(wl, wlvif, false);
- 		if (ret < 0)
- 			return ret;
-+
-+		/* disable beacon filtering */
-+		ret = wl1271_acx_beacon_filter_opt(wl, wlvif, false);
-+		if (ret < 0)
-+			return ret;
- 	}
- 
- 	if (test_and_clear_bit(WLVIF_FLAG_CS_PROGRESS, &wlvif->flags)) {
-@@ -4345,6 +4350,13 @@ static void wl1271_bss_info_changed_sta(
- 		}
- 	}
- 
-+	if ((changed & BSS_CHANGED_BEACON_INFO) && bss_conf->dtim_period) {
-+		/* enable beacon filtering */
-+		ret = wl1271_acx_beacon_filter_opt(wl, wlvif, true);
-+		if (ret < 0)
-+			goto out;
-+	}
-+
- 	ret = wl1271_bss_erp_info_changed(wl, vif, bss_conf, changed);
- 	if (ret < 0)
- 		goto out;
diff --git a/package/kernel/mac80211/patches/918-wlcore-add-support-for-STA-CSA-with-chan-contexts.patch b/package/kernel/mac80211/patches/918-wlcore-add-support-for-STA-CSA-with-chan-contexts.patch
deleted file mode 100644
index c33535d049..0000000000
--- a/package/kernel/mac80211/patches/918-wlcore-add-support-for-STA-CSA-with-chan-contexts.patch
+++ /dev/null
@@ -1,22 +0,0 @@
-TI wl12xx/wl18xx cards support channel switch via a driver specific
-switch_channel op while operating with channel contexts.
-
-Signed-off-by: Arik Nemtsov <arik@wizery.com>
-Signed-off-by: Eliad Peller <eliad@wizery.com>
-
----
-drivers/net/wireless/ti/wlcore/main.c | 3 ++-
- 1 file changed, 2 insertions(+), 1 deletion(-)
-
---- a/drivers/net/wireless/ti/wlcore/main.c
-+++ b/drivers/net/wireless/ti/wlcore/main.c
-@@ -5770,7 +5770,8 @@ static int wl1271_init_ieee80211(struct
- 		IEEE80211_HW_AP_LINK_PS |
- 		IEEE80211_HW_AMPDU_AGGREGATION |
- 		IEEE80211_HW_TX_AMPDU_SETUP_IN_HW |
--		IEEE80211_HW_QUEUE_CONTROL;
-+		IEEE80211_HW_QUEUE_CONTROL |
-+		IEEE80211_HW_CHANCTX_STA_CSA;
- 
- 	wl->hw->wiphy->cipher_suites = cipher_suites;
- 	wl->hw->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);
-- 
2.30.2