ソースを参照

Update OpenWrt

This also removes our mac80211 backport for now, as the version found in
Attitude Adjustment is up-to-date.
Matthias Schiffer 10 年 前
コミット
303f69668b

+ 1 - 1
modules

@@ -1,7 +1,7 @@
 GLUON_FEEDS='openwrt gluon routing luci'
 
 OPENWRT_REPO=git://git.openwrt.org/12.09/openwrt.git
-OPENWRT_COMMIT=5180b2c94cd0b270b7290e84607877db76855b49
+OPENWRT_COMMIT=595ebf6f0d39394e5518869d4fc436cfd27e4d3c
 
 PACKAGES_OPENWRT_REPO=git://git.openwrt.org/12.09/packages.git
 PACKAGES_OPENWRT_COMMIT=381bbea65989b63e30f43ab87e51b042325bbff3

+ 0 - 15067
patches/openwrt/0018-Backport-mac80211-from-Barrier-Breaker-r41113.patch

@@ -1,15067 +0,0 @@
-From: Matthias Schiffer <mschiffer@universe-factory.net>
-Date: Mon, 19 May 2014 15:59:37 +0200
-Subject: Backport mac80211 from Barrier Breaker (r41113)
-
-diff --git a/package/mac80211/Makefile b/package/mac80211/Makefile
-index 9a7093c..c286b0f 100644
---- a/package/mac80211/Makefile
-+++ b/package/mac80211/Makefile
-@@ -1,5 +1,5 @@
- #
--# Copyright (C) 2007-2013 OpenWrt.org
-+# Copyright (C) 2007-2014 OpenWrt.org
- #
- # This is free software, licensed under the GNU General Public License v2.
- # See /LICENSE for more information.
-@@ -10,11 +10,11 @@ include $(INCLUDE_DIR)/kernel.mk
- 
- PKG_NAME:=mac80211
- 
--PKG_VERSION:=2014-01-23.1
-+PKG_VERSION:=2014-05-22
- PKG_RELEASE:=1
- PKG_SOURCE_URL:=http://mirror2.openwrt.org/sources
- PKG_BACKPORT_VERSION:=
--PKG_MD5SUM:=8db16edbdaf4abc2e9c2f3b6c86736a6
-+PKG_MD5SUM:=367937d4f8c05cb36ca989ee26abc3df
- 
- PKG_SOURCE:=compat-wireless-$(PKG_VERSION)$(PKG_BACKPORT_VERSION).tar.bz2
- PKG_BUILD_DIR:=$(KERNEL_BUILD_DIR)/compat-wireless-$(PKG_VERSION)
-@@ -105,12 +105,12 @@ Generic IEEE 802.11 Networking Stack (mac80211)
- endef
- 
- PKG_LINUX_FIRMWARE_NAME:=linux-firmware
--PKG_LINUX_FIRMWARE_VERSION:=7d0c7a8cfd78388d90cc784a185b19dcbdbce824
-+PKG_LINUX_FIRMWARE_VERSION:=f8c22c692bdee57a20b092e647464ff6176df3ed
- PKG_LINUX_FIRMWARE_SOURCE:=$(PKG_LINUX_FIRMWARE_NAME)-$(PKG_LINUX_FIRMWARE_VERSION).tar.bz2
- PKG_LINUX_FIRMWARE_PROTO:=git
- PKG_LINUX_FIRMWARE_SOURCE_URL:=git://git.kernel.org/pub/scm/linux/kernel/git/firmware/linux-firmware.git
- PKG_LINUX_FIRMWARE_SUBDIR:=$(PKG_LINUX_FIRMWARE_NAME)-$(PKG_LINUX_FIRMWARE_VERSION)
--PKG_LINUX_FIRMWARE_MIRROR_MD5SUM:=837a1a9456c1ec8b428cc0b2b08a331b
-+PKG_LINUX_FIRMWARE_MIRROR_MD5SUM:=e219333f01835c6e556875a9e0deb3f9
- 
- define Download/linux-firmware
-   FILE:=$(PKG_LINUX_FIRMWARE_SOURCE)
-@@ -124,7 +124,7 @@ endef
- $(eval $(call Download,linux-firmware))
- 
- PKG_ATH10K_LINUX_FIRMWARE_NAME:=ath10k-firmware
--PKG_ATH10K_LINUX_FIRMWARE_VERSION:=d86e78e5c6be34329936c8bd73a212700437be2e
-+PKG_ATH10K_LINUX_FIRMWARE_VERSION:=38eeda3ae6f90fde5546bdd48ee4ff3090f238c0
- PKG_ATH10K_LINUX_FIRMWARE_SOURCE:=$(PKG_ATH10K_LINUX_FIRMWARE_NAME)-$(PKG_ATH10K_LINUX_FIRMWARE_VERSION).tar.bz2
- PKG_ATH10K_LINUX_FIRMWARE_PROTO:=git
- PKG_ATH10K_LINUX_FIRMWARE_SOURCE_URL:=https://github.com/kvalo/ath10k-firmware.git
-@@ -363,8 +363,8 @@ define KernelPackage/rtl8180
-   $(call KernelPackage/rtl818x/Default)
-   DEPENDS+= @PCI_SUPPORT
-   TITLE+= (RTL8180 PCI)
--  FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/rtl818x/rtl8180/rtl8180.ko
--  AUTOLOAD:=$(call AutoLoad,27,rtl8180)
-+  FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/rtl818x/rtl8180/rtl818x_pci.ko
-+  AUTOLOAD:=$(call AutoLoad,27,rtl818x_pci)
- endef
- 
- define KernelPackage/rtl8187
-@@ -606,6 +606,19 @@ Atheros IEEE 802.11ac family of chipsets. For now only
- PCI is supported.
- endef
- 
-+define KernelPackage/ath10k/config
-+  if PACKAGE_kmod-ath10k
-+
-+	config ATH10K_STA_FW
-+		bool "Firmware optimized for STA operation"
-+		default n
-+		help
-+		  Use the ath10k firmware optimized for wireless client instead
-+		  of access point operation.
-+
-+  endif
-+endef
-+
- define KernelPackage/carl9170
-   $(call KernelPackage/mac80211/Default)
-   TITLE:=Driver for Atheros AR9170 USB sticks
-@@ -844,6 +857,13 @@ define KernelPackage/iwlagn/config
- 		  Download and install firmware for:
- 		    Intel Centrino Advanced-N 6230, Wireless-N 1030, Wireless-N 130 and Advanced-N 6235
- 
-+	config IWL7260_FW
-+		bool "Intel 7260 Firmware"
-+		default y
-+		help
-+		  Download and install firmware for:
-+		    Intel Dual Band Wireless-N 7260 and Intel Dual Band Wireless-AC 7260
-+
- 	config IWL100_FW
- 		bool "Intel 100 Firmware"
- 		default y
-@@ -1639,8 +1659,7 @@ define KernelPackage/wl18xx/install
- 	$(INSTALL_DIR) $(1)/lib/firmware/ti-connectivity
- 	$(INSTALL_DATA) \
- 		$(PKG_BUILD_DIR)/$(PKG_LINUX_FIRMWARE_SUBDIR)/ti-connectivity/wl18xx-conf.bin \
--		$(PKG_BUILD_DIR)/$(PKG_LINUX_FIRMWARE_SUBDIR)/ti-connectivity/wl18xx-fw.bin \
--		$(PKG_BUILD_DIR)/$(PKG_LINUX_FIRMWARE_SUBDIR)/ti-connectivity/wl18xx-fw-2.bin \
-+		$(PKG_BUILD_DIR)/$(PKG_LINUX_FIRMWARE_SUBDIR)/ti-connectivity/wl18xx-fw-3.bin \
- 		$(1)/lib/firmware/ti-connectivity
- endef
- 
-@@ -1664,10 +1683,19 @@ endef
- 
- define KernelPackage/ath10k/install
- 	$(INSTALL_DIR) $(1)/lib/firmware/ath10k/QCA988X/hw2.0
-+ifeq ($(CONFIG_ATH10K_STA_FW),y)
-+	$(INSTALL_DATA) \
-+		$(PKG_BUILD_DIR)/$(PKG_ATH10K_LINUX_FIRMWARE_SUBDIR)/ath10k/QCA988X/hw2.0/board.bin \
-+		$(1)/lib/firmware/ath10k/QCA988X/hw2.0/
-+	$(INSTALL_DATA) \
-+		$(PKG_BUILD_DIR)/$(PKG_ATH10K_LINUX_FIRMWARE_SUBDIR)/main/firmware-2.bin_999.999.0.636 \
-+		$(1)/lib/firmware/ath10k/QCA988X/hw2.0/firmware-2.bin
-+else
- 	$(INSTALL_DATA) \
- 		$(PKG_BUILD_DIR)/$(PKG_ATH10K_LINUX_FIRMWARE_SUBDIR)/ath10k/QCA988X/hw2.0/board.bin \
- 		$(PKG_BUILD_DIR)/$(PKG_ATH10K_LINUX_FIRMWARE_SUBDIR)/ath10k/QCA988X/hw2.0/firmware-2.bin \
- 		$(1)/lib/firmware/ath10k/QCA988X/hw2.0/
-+endif
- endef
- 
- define KernelPackage/mwl8k/install
-@@ -1714,6 +1742,9 @@ endif
- ifneq ($(CONFIG_IWL6030_FW),)
- 	$(INSTALL_DATA) $(PKG_BUILD_DIR)/$(PKG_LINUX_FIRMWARE_SUBDIR)/iwlwifi-6000g2b-6.ucode $(1)/lib/firmware
- endif
-+ifneq ($(CONFIG_IWL7260_FW),)
-+	$(INSTALL_DATA) $(PKG_BUILD_DIR)/$(PKG_LINUX_FIRMWARE_SUBDIR)/iwlwifi-7260-7.ucode $(1)/lib/firmware
-+endif
- ifneq ($(CONFIG_IWL100_FW),)
- 	$(INSTALL_DATA) $(PKG_BUILD_DIR)/$(PKG_LINUX_FIRMWARE_SUBDIR)/iwlwifi-100-5.ucode $(1)/lib/firmware
- endif
-diff --git a/package/mac80211/files/regdb.txt b/package/mac80211/files/regdb.txt
-index 2badb21..fcab208 100644
---- a/package/mac80211/files/regdb.txt
-+++ b/package/mac80211/files/regdb.txt
-@@ -1,211 +1,216 @@
- # This is the world regulatory domain
- country 00:
--	(2402 - 2472 @ 40), (3, 20)
-+	(2402 - 2472 @ 40), (20)
- 	# Channel 12 - 13.
--	(2457 - 2482 @ 40), (3, 20), PASSIVE-SCAN, NO-IBSS
-+	(2457 - 2482 @ 40), (20), NO-IR
- 	# Channel 14. Only JP enables this and for 802.11b only
--	(2474 - 2494 @ 20), (3, 20), PASSIVE-SCAN, NO-IBSS, NO-OFDM
-+	(2474 - 2494 @ 20), (20), NO-IR
- 	# Channel 36 - 48
--	(5170 - 5250 @ 80), (3, 20)
-+	(5170 - 5250 @ 80), (20), NO-IR
- 	# NB: 5260 MHz - 5700 MHz requies DFS
- 	# Channel 149 - 165
--	(5735 - 5835 @ 80), (3, 20), PASSIVE-SCAN, NO-IBSS
-+	(5735 - 5835 @ 80), (20), NO-IR
- 	# IEEE 802.11ad (60GHz), channels 1..3
--	(57240 - 63720 @ 2160), (N/A, 0)
-+	(57240 - 63720 @ 2160), (0)
- 
- 
- country AD:
- 	# 60 gHz band channels 1-4, ref: Etsi En 302 567
--	(57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR
--
--country AE:
--	(2402 - 2482 @ 40), (N/A, 20)
--	(5170 - 5250 @ 80), (3, 17)
--	(5250 - 5330 @ 80), (3, 24), DFS
--	(5490 - 5710 @ 80), (3, 24), DFS
--	(5735 - 5835 @ 80), (3, 30)
--
--country AL:
--	(2402 - 2482 @ 20), (N/A, 20)
--
--country AM:
--	(2402 - 2482 @ 40), (N/A, 20)
--	(5170 - 5250 @ 20), (N/A, 18)
--	(5250 - 5330 @ 20), (N/A, 18), DFS
--
--country AN:
--	(2402 - 2482 @ 40), (N/A, 20)
--	(5170 - 5250 @ 40), (N/A, 20)
--	(5250 - 5330 @ 40), (N/A, 20), DFS
--	(5490 - 5710 @ 40), (N/A, 27), DFS
--
--country AR:
--	(2402 - 2482 @ 40), (N/A, 20)
--	(5170 - 5250 @ 80), (3, 17)
--	(5250 - 5330 @ 80), (3, 24), DFS
--	(5490 - 5710 @ 80), (3, 24), DFS
--	(5735 - 5835 @ 80), (3, 30)
-+	(57240 - 65880 @ 2160), (40), NO-OUTDOOR
-+
-+country AE: DFS-FCC
-+	(2402 - 2482 @ 40), (20)
-+	(5170 - 5250 @ 80), (17)
-+	(5250 - 5330 @ 80), (24), DFS
-+	(5490 - 5730 @ 80), (24), DFS
-+	(5735 - 5835 @ 80), (30)
-+
-+country AL: DFS-ETSI
-+	(2402 - 2482 @ 40), (20)
-+	(5170 - 5250 @ 80), (20.00)
-+	(5250 - 5330 @ 80), (20.00), DFS
-+	(5490 - 5710 @ 80), (27.00), DFS
-+
-+country AM: DFS-ETSI
-+	(2402 - 2482 @ 40), (20)
-+	(5170 - 5250 @ 80), (18)
-+	(5250 - 5330 @ 80), (18), DFS
-+
-+country AN: DFS-ETSI
-+	(2402 - 2482 @ 40), (20)
-+	(5170 - 5250 @ 80), (20)
-+	(5250 - 5330 @ 80), (20), DFS
-+	(5490 - 5710 @ 80), (27), DFS
-+
-+country AR: DFS-FCC
-+	(2402 - 2482 @ 40), (20)
-+	(5170 - 5250 @ 80), (17)
-+	(5250 - 5330 @ 80), (24), DFS
-+	(5490 - 5730 @ 80), (24), DFS
-+	(5735 - 5835 @ 80), (30)
- 
- country AT: DFS-ETSI
--	(2402 - 2482 @ 40), (N/A, 20)
--	(5170 - 5250 @ 80), (N/A, 20)
--	(5250 - 5330 @ 80), (N/A, 20), DFS
--	(5490 - 5710 @ 80), (N/A, 27), DFS
-+	(2402 - 2482 @ 40), (20)
-+	(5170 - 5250 @ 80), (20)
-+	(5250 - 5330 @ 80), (20), DFS
-+	(5490 - 5710 @ 80), (27), DFS
- 	# 60 gHz band channels 1-4, ref: Etsi En 302 567
--	(57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR
-+	(57240 - 65880 @ 2160), (40), NO-OUTDOOR
- 
- country AU:
--	(2402 - 2482 @ 40), (N/A, 20)
--	(5170 - 5250 @ 80), (3, 17)
--	(5250 - 5330 @ 80), (3, 24), DFS
--	(5490 - 5710 @ 80), (3, 24), DFS
--	(5735 - 5835 @ 80), (3, 30)
--
--country AW:
--	(2402 - 2482 @ 40), (N/A, 20)
--	(5170 - 5250 @ 40), (N/A, 20)
--	(5250 - 5330 @ 40), (N/A, 20), DFS
--	(5490 - 5710 @ 40), (N/A, 27), DFS
--
--country AZ:
--	(2402 - 2482 @ 40), (N/A, 20)
--	(5170 - 5250 @ 40), (N/A, 18)
--	(5250 - 5330 @ 40), (N/A, 18), DFS
-+	(2402 - 2482 @ 40), (20)
-+	(5170 - 5250 @ 80), (17)
-+	(5250 - 5330 @ 80), (24), DFS
-+	(5490 - 5710 @ 80), (24), DFS
-+	(5735 - 5835 @ 80), (30)
-+
-+country AW: DFS-ETSI
-+	(2402 - 2482 @ 40), (20)
-+	(5170 - 5250 @ 80), (20)
-+	(5250 - 5330 @ 80), (20), DFS
-+	(5490 - 5710 @ 80), (27), DFS
-+
-+country AZ: DFS-ETSI
-+	(2402 - 2482 @ 40), (20)
-+	(5170 - 5250 @ 80), (18)
-+	(5250 - 5330 @ 80), (18), DFS
- 
- country BA: DFS-ETSI
--	(2402 - 2482 @ 40), (N/A, 20)
--	(5170 - 5250 @ 40), (N/A, 20)
--	(5250 - 5330 @ 40), (N/A, 20), DFS
--	(5490 - 5710 @ 40), (N/A, 27), DFS
-+	(2402 - 2482 @ 40), (20)
-+	(5170 - 5250 @ 80), (20)
-+	(5250 - 5330 @ 80), (20), DFS
-+	(5490 - 5710 @ 80), (27), DFS
- 	# 60 gHz band channels 1-4, ref: Etsi En 302 567
--	(57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR
-+	(57240 - 65880 @ 2160), (40), NO-OUTDOOR
- 
--country BB:
--	(2402 - 2482 @ 40), (N/A, 20)
--	(5170 - 5250 @ 40), (3, 23)
--	(5250 - 5330 @ 40), (3, 23), DFS
--	(5735 - 5835 @ 40), (3, 30)
-+country BB: DFS-FCC
-+	(2402 - 2482 @ 40), (20)
-+	(5170 - 5250 @ 80), (23)
-+	(5250 - 5330 @ 80), (23), DFS
-+	(5735 - 5835 @ 80), (30)
- 
--country BD:
--	(2402 - 2482 @ 40), (N/A, 20)
-+country BD: DFS-JP
-+	(2402 - 2482 @ 40), (20)
-+	(5735 - 5835 @ 80), (30)
- 
- country BE: DFS-ETSI
--	(2402 - 2482 @ 40), (N/A, 20)
--	(5170 - 5250 @ 80), (N/A, 20)
--	(5250 - 5330 @ 80), (N/A, 20), DFS
--	(5490 - 5710 @ 80), (N/A, 27), DFS
-+	(2402 - 2482 @ 40), (20)
-+	(5170 - 5250 @ 80), (20)
-+	(5250 - 5330 @ 80), (20), DFS
-+	(5490 - 5710 @ 80), (27), DFS
- 	# 60 gHz band channels 1-4, ref: Etsi En 302 567
--	(57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR
-+	(57240 - 65880 @ 2160), (40), NO-OUTDOOR
- 
- country BG: DFS-ETSI
--	(2402 - 2482 @ 40), (N/A, 20)
--	(5170 - 5250 @ 40), (N/A, 23)
--	(5250 - 5290 @ 40), (N/A, 23), DFS
--	(5490 - 5710 @ 40), (N/A, 30), DFS
-+	(2402 - 2482 @ 40), (20)
-+	(5170 - 5250 @ 80), (20)
-+	(5250 - 5330 @ 80), (20), DFS
- 	# 60 gHz band channels 1-4, ref: Etsi En 302 567
--	(57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR
-+	(57240 - 65880 @ 2160), (40), NO-OUTDOOR
- 
--country BH:
--	(2402 - 2482 @ 40), (N/A, 20)
--	(5170 - 5250 @ 20), (N/A, 20)
--	(5250 - 5330 @ 20), (N/A, 20), DFS
--	(5735 - 5835 @ 20), (N/A, 20)
-+country BH: DFS-JP
-+	(2402 - 2482 @ 40), (20)
-+	(5170 - 5250 @ 80), (20)
-+	(5250 - 5330 @ 80), (20), DFS
-+	(5735 - 5835 @ 80), (20)
- 
- country BL:
--	(2402 - 2482 @ 40), (N/A, 20)
--	(5170 - 5250 @ 40), (N/A, 18)
--	(5250 - 5330 @ 40), (N/A, 18), DFS
--
--country BN:
--	(2402 - 2482 @ 40), (N/A, 20)
--	(5170 - 5250 @ 40), (N/A, 20)
--	(5250 - 5330 @ 40), (N/A, 20), DFS
--	(5735 - 5835 @ 40), (N/A, 30)
--
--country BO:
--	(2402 - 2482 @ 40), (N/A, 30)
--	(5735 - 5835 @ 40), (N/A, 30)
--
--country BR:
--	(2402 - 2482 @ 40), (N/A, 20)
--	(5170 - 5250 @ 80), (3, 17)
--	(5250 - 5330 @ 80), (3, 24), DFS
--	(5490 - 5710 @ 80), (3, 24), DFS
--	(5735 - 5835 @ 80), (3, 30)
--
--country BY:
--	(2402 - 2482 @ 40), (N/A, 20)
--	(5170 - 5250 @ 40), (N/A, 20)
--	(5250 - 5330 @ 40), (N/A, 20), DFS
--	(5490 - 5710 @ 40), (N/A, 27), DFS
--
--country BZ:
--	(2402 - 2482 @ 40), (N/A, 30)
--	(5735 - 5835 @ 40), (N/A, 30)
--
--country CA:
--	(2402 - 2472 @ 40), (3, 27)
--	(5170 - 5250 @ 80), (3, 17)
--	(5250 - 5330 @ 80), (3, 24), DFS
--	(5490 - 5710 @ 80), (3, 24), DFS
--	(5735 - 5835 @ 80), (3, 30)
-+	(2402 - 2482 @ 40), (20)
-+	(5170 - 5250 @ 40), (18)
-+	(5250 - 5330 @ 40), (18), DFS
-+
-+country BN: DFS-JP
-+	(2402 - 2482 @ 40), (20)
-+	(5170 - 5250 @ 80), (20)
-+	(5250 - 5330 @ 80), (20), DFS
-+	(5735 - 5835 @ 80), (20)
-+
-+country BO: DFS-JP
-+	(2402 - 2482 @ 40), (30)
-+	(5735 - 5835 @ 80), (30)
-+
-+country BR: DFS-FCC
-+	(2402 - 2482 @ 40), (20)
-+	(5170 - 5250 @ 80), (17)
-+	(5250 - 5330 @ 80), (24), DFS
-+	(5490 - 5730 @ 80), (24), DFS
-+	(5735 - 5835 @ 80), (30)
-+
-+country BY: DFS-ETSI
-+	(2402 - 2482 @ 40), (20)
-+	(5170 - 5250 @ 80), (20)
-+	(5250 - 5330 @ 80), (20), DFS
-+	(5490 - 5710 @ 80), (27), DFS
-+
-+country BZ: DFS-JP
-+	(2402 - 2482 @ 40), (30)
-+	(5735 - 5835 @ 80), (30)
-+
-+country CA: DFS-FCC
-+	(2402 - 2472 @ 40), (30)
-+	(5170 - 5250 @ 80), (17)
-+	(5250 - 5330 @ 80), (24), DFS
-+	(5490 - 5730 @ 80), (24), DFS
-+	(5735 - 5835 @ 80), (30)
- 
- country CH: DFS-ETSI
--	(2402 - 2482 @ 40), (N/A, 20)
--	(5170 - 5250 @ 80), (N/A, 20)
--	(5250 - 5330 @ 80), (N/A, 20), DFS
--	(5490 - 5710 @ 80), (N/A, 27), DFS
--	# 60 gHz band channels 1-4, ref: Etsi En 302 567
--	(57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR
--
--country CL:
--	(2402 - 2482 @ 40), (N/A, 20)
--	(5170 - 5250 @ 40), (N/A, 20)
--	(5250 - 5330 @ 40), (N/A, 20), DFS
--	(5735 - 5835 @ 40), (N/A, 20)
--
--country CN:
--	(2402 - 2482 @ 40), (N/A, 20)
--	(5735 - 5835 @ 80), (N/A, 30)
-+	(2402 - 2482 @ 40), (20)
-+	(5170 - 5250 @ 80), (20)
-+	(5250 - 5330 @ 80), (20), DFS
-+	(5490 - 5710 @ 80), (27), DFS
-+	# 60 gHz band channels 1-4, ref: Etsi En 302 567
-+	(57240 - 65880 @ 2160), (40), NO-OUTDOOR
-+
-+country CL: DFS-JP
-+	(2402 - 2482 @ 40), (20)
-+	(5170 - 5250 @ 80), (20)
-+	(5250 - 5330 @ 80), (20), DFS
-+	(5735 - 5835 @ 80), (20)
-+
-+country CN: DFS-FCC
-+	(2402 - 2482 @ 40), (20)
-+	(5170 - 5250 @ 80), (23)
-+	(5250 - 5330 @ 80), (23), DFS
-+	(5735 - 5835 @ 80), (30)
- 	# 60 gHz band channels 1,4: 28dBm, channels 2,3: 44dBm
- 	# ref: http://www.miit.gov.cn/n11293472/n11505629/n11506593/n11960250/n11960606/n11960700/n12330791.files/n12330790.pdf
--	(57240 - 59400 @ 2160), (N/A, 28)
--	(59400 - 63720 @ 2160), (N/A, 44)
--	(63720 - 65880 @ 2160), (N/A, 28)
--
--country CO:
--	(2402 - 2472 @ 40), (3, 27)
--	(5170 - 5250 @ 80), (3, 17)
--	(5250 - 5330 @ 80), (3, 24), DFS
--	(5490 - 5710 @ 80), (3, 24), DFS
--	(5735 - 5835 @ 80), (3, 30)
--
--country CR:
--	(2402 - 2482 @ 40), (N/A, 20)
--	(5170 - 5250 @ 80), (3, 17)
--	(5250 - 5330 @ 80), (3, 24), DFS
--	(5490 - 5710 @ 80), (3, 24), DFS
--	(5735 - 5835 @ 80), (3, 30)
-+	(57240 - 59400 @ 2160), (28)
-+	(59400 - 63720 @ 2160), (44)
-+	(63720 - 65880 @ 2160), (28)
-+
-+country CO: DFS-FCC
-+	(2402 - 2482 @ 40), (20)
-+	(5170 - 5250 @ 80), (17)
-+	(5250 - 5330 @ 80), (24), DFS
-+	(5490 - 5730 @ 80), (24), DFS
-+	(5735 - 5835 @ 80), (30)
-+
-+country CR: DFS-FCC
-+	(2402 - 2482 @ 40), (20)
-+	(5170 - 5250 @ 80), (17)
-+	(5250 - 5330 @ 80), (24), DFS
-+	(5490 - 5730 @ 80), (24), DFS
-+	(5735 - 5835 @ 80), (30)
- 
- country CY: DFS-ETSI
--	(2402 - 2482 @ 40), (N/A, 20)
--	(5170 - 5250 @ 40), (N/A, 20)
--	(5250 - 5330 @ 40), (N/A, 20), DFS
--	(5490 - 5710 @ 40), (N/A, 27), DFS
-+	(2402 - 2482 @ 40), (20)
-+	(5170 - 5250 @ 80), (20)
-+	(5250 - 5330 @ 80), (20), DFS
-+	(5490 - 5710 @ 80), (27), DFS
- 	# 60 gHz band channels 1-4, ref: Etsi En 302 567
--	(57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR
-+	(57240 - 65880 @ 2160), (40), NO-OUTDOOR
- 
- # Data from http://www.ctu.eu/164/download/VOR/VOR-12-08-2005-34.pdf
- # and http://www.ctu.eu/164/download/VOR/VOR-12-05-2007-6-AN.pdf
- # Power at 5250 - 5350 MHz and 5470 - 5725 MHz can be doubled if TPC is
- # implemented.
- country CZ: DFS-ETSI
--	(2400 - 2483.5 @ 40), (N/A, 100 mW)
--	(5150 - 5250 @ 80), (N/A, 200 mW), NO-OUTDOOR
--	(5250 - 5350 @ 80), (N/A, 100 mW), NO-OUTDOOR, DFS
--	(5470 - 5725 @ 80), (N/A, 500 mW), DFS
-+	(2400 - 2483.5 @ 40), (100 mW)
-+	(5150 - 5250 @ 80), (200 mW), NO-OUTDOOR
-+	(5250 - 5350 @ 80), (100 mW), NO-OUTDOOR
-+	(5470 - 5725 @ 80), (500 mW), DFS
- 	# 60 gHz band channels 1-4, ref: Etsi En 302 567
--	(57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR
-+	(57240 - 65880 @ 2160), (40), NO-OUTDOOR
- 
- # Data from "Frequenznutzungsplan" (as published in April 2008), downloaded from
- # http://www.bundesnetzagentur.de/cae/servlet/contentblob/38448/publicationFile/2659/Frequenznutzungsplan2008_Id17448pdf.pdf
-@@ -221,542 +226,555 @@ country CZ: DFS-ETSI
- 
- country DE: DFS-ETSI
- 	# entries 279004 and 280006
--	(2400 - 2483.5 @ 40), (N/A, 100 mW)
--	# entry 303005
--	(5150 - 5250 @ 80), (N/A, 100 mW), NO-OUTDOOR
--	# entries 304002 and 305002
--	(5250 - 5350 @ 80), (N/A, 100 mW), NO-OUTDOOR, DFS
-+	(2400 - 2483.5 @ 40), (100 mW)
-+	# entry 303005, 304002 and 305002
-+	(5150 - 5350 @ 80), (100 mW), NO-OUTDOOR
- 	# entries 308002, 309001 and 310003
--	(5470 - 5725 @ 80), (N/A, 500 mW), DFS
-+	(5470 - 5725 @ 80), (500 mW), DFS
- 	# 60 gHz band channels 1-4, ref: Etsi En 302 567
--	(57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR
-+	(57240 - 65880 @ 2160), (40), NO-OUTDOOR
- 
- country DK: DFS-ETSI
--	(2402 - 2482 @ 40), (N/A, 20)
--	(5170 - 5250 @ 80), (N/A, 20)
--	(5250 - 5330 @ 80), (N/A, 20), DFS
--	(5490 - 5710 @ 80), (N/A, 27), DFS
--	# 60 gHz band channels 1-4, ref: Etsi En 302 567
--	(57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR
--
--country DO:
--	(2402 - 2472 @ 40), (3, 27)
--	(5170 - 5250 @ 40), (3, 17)
--	(5250 - 5330 @ 40), (3, 23), DFS
--	(5735 - 5835 @ 40), (3, 30)
--
--country DZ:
--	(2402 - 2482 @ 40), (N/A, 20)
--
--country EC:
--	(2402 - 2482 @ 40), (N/A, 20)
--	(5170 - 5250 @ 80), (3, 17)
--	(5250 - 5330 @ 80), (3, 24), DFS
--	(5490 - 5710 @ 80), (3, 24), DFS
--	(5735 - 5835 @ 80), (3, 30)
-+	(2402 - 2482 @ 40), (20)
-+	(5170 - 5250 @ 80), (20)
-+	(5250 - 5330 @ 80), (20), DFS
-+	(5490 - 5710 @ 80), (27), DFS
-+	# 60 gHz band channels 1-4, ref: Etsi En 302 567
-+	(57240 - 65880 @ 2160), (40), NO-OUTDOOR
-+
-+country DO: DFS-FCC
-+	(2402 - 2472 @ 40), (30)
-+	(5170 - 5250 @ 80), (17)
-+	(5250 - 5330 @ 80), (23), DFS
-+	(5735 - 5835 @ 80), (30)
-+
-+country DZ: DFS-JP
-+	(2402 - 2482 @ 40), (20)
-+	(5170.000 - 5250.000 @ 80.000), (23.00)
-+	(5250.000 - 5330.000 @ 80.000), (23.00), DFS
-+	(5490.000 - 5670.000 @ 80.000), (23.00), DFS
-+
-+country EC: DFS-FCC
-+	(2402 - 2482 @ 40), (20)
-+	(5170 - 5250 @ 80), (17)
-+	(5250 - 5330 @ 80), (24), DFS
-+	(5490 - 5730 @ 80), (24), DFS
-+	(5735 - 5835 @ 80), (30)
- 
- country EE: DFS-ETSI
--	(2402 - 2482 @ 40), (N/A, 20)
--	(5170 - 5250 @ 40), (N/A, 20)
--	(5250 - 5330 @ 40), (N/A, 20), DFS
--	(5490 - 5710 @ 40), (N/A, 27), DFS
-+	(2402 - 2482 @ 40), (20)
-+	(5170 - 5250 @ 80), (20)
-+	(5250 - 5330 @ 80), (20), DFS
-+	(5490 - 5710 @ 80), (27), DFS
- 	# 60 gHz band channels 1-4, ref: Etsi En 302 567
--	(57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR
-+	(57240 - 65880 @ 2160), (40), NO-OUTDOOR
- 
--country EG:
--	(2402 - 2482 @ 40), (N/A, 20)
--	(5170 - 5250 @ 20), (N/A, 20)
--	(5250 - 5330 @ 20), (N/A, 20), DFS
-+country EG: DFS-ETSI
-+	(2402 - 2482 @ 40), (20)
-+	(5170 - 5250 @ 80), (20)
-+	(5250 - 5330 @ 80), (20), DFS
- 
- country ES: DFS-ETSI
--	(2400 - 2483.5 @ 40), (N/A, 100 mW)
--	(5150 - 5250 @ 80), (N/A, 100 mW), NO-OUTDOOR
--	(5250 - 5350 @ 80), (N/A, 100 mW), NO-OUTDOOR, DFS
--	(5470 - 5725 @ 80), (N/A, 500 mW), DFS
-+	(2400 - 2483.5 @ 40), (100 mW)
-+	(5150 - 5250 @ 80), (100 mW), NO-OUTDOOR
-+	(5250 - 5350 @ 80), (100 mW), NO-OUTDOOR
-+	(5470 - 5725 @ 80), (500 mW), DFS
- 	# 60 gHz band channels 1-4, ref: Etsi En 302 567
--	(57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR
-+	(57240 - 65880 @ 2160), (40), NO-OUTDOOR
- 
- country FI: DFS-ETSI
--	(2402 - 2482 @ 40), (N/A, 20)
--	(5170 - 5250 @ 80), (N/A, 20)
--	(5250 - 5330 @ 80), (N/A, 20), DFS
--	(5490 - 5710 @ 80), (N/A, 27), DFS
-+	(2402 - 2482 @ 40), (20)
-+	(5170 - 5250 @ 80), (20)
-+	(5250 - 5330 @ 80), (20), DFS
-+	(5490 - 5710 @ 80), (27), DFS
- 	# 60 gHz band channels 1-4, ref: Etsi En 302 567
--	(57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR
-+	(57240 - 65880 @ 2160), (40), NO-OUTDOOR
- 
- country FR: DFS-ETSI
--	(2402 - 2482 @ 40), (N/A, 20)
--	(5170 - 5250 @ 80), (N/A, 20)
--	(5250 - 5330 @ 80), (N/A, 20), DFS
--	(5490 - 5710 @ 80), (N/A, 27), DFS
-+	(2402 - 2482 @ 40), (20)
-+	(5170 - 5250 @ 80), (20)
-+	(5250 - 5330 @ 80), (20), DFS
-+	(5490 - 5710 @ 80), (27), DFS
- 	# 60 gHz band channels 1-4, ref: Etsi En 302 567
--	(57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR
-+	(57240 - 65880 @ 2160), (40), NO-OUTDOOR
- 
--country GE:
--	(2402 - 2482 @ 40), (N/A, 20)
--	(5170 - 5250 @ 40), (N/A, 18)
--	(5250 - 5330 @ 40), (N/A, 18), DFS
-+country GE: DFS-ETSI
-+	(2402 - 2482 @ 40), (20)
-+	(5170 - 5250 @ 80), (18)
-+	(5250 - 5330 @ 80), (18), DFS
- 	# 60 gHz band channels 1-4, ref: Etsi En 302 567
--	(57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR
-+	(57240 - 65880 @ 2160), (40), NO-OUTDOOR
- 
- country GB: DFS-ETSI
--	(2402 - 2482 @ 40), (N/A, 20)
--	(5170 - 5250 @ 80), (N/A, 20)
--	(5250 - 5330 @ 80), (N/A, 20), DFS
--	(5490 - 5710 @ 80), (N/A, 27), DFS
-+	(2402 - 2482 @ 40), (20)
-+	(5170 - 5250 @ 80), (20)
-+	(5250 - 5330 @ 80), (20), DFS
-+	(5490 - 5710 @ 80), (27), DFS
- 	# 60 gHz band channels 1-4, ref: Etsi En 302 567
--	(57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR
-+	(57240 - 65880 @ 2160), (40), NO-OUTDOOR
- 
--country GD:
--	(2402 - 2472 @ 40), (3, 27)
--	(5170 - 5250 @ 40), (3, 17)
--	(5250 - 5330 @ 40), (3, 20), DFS
--	(5490 - 5710 @ 40), (3, 20), DFS
--	(5735 - 5835 @ 40), (3, 30)
-+country GD: DFS-FCC
-+	(2402 - 2472 @ 40), (30)
-+	(5170 - 5250 @ 80), (17)
-+	(5250 - 5330 @ 80), (24), DFS
-+	(5490 - 5730 @ 80), (24), DFS
-+	(5735 - 5835 @ 80), (30)
- 
- country GR: DFS-ETSI
--	(2402 - 2482 @ 40), (N/A, 20)
--	(5170 - 5250 @ 80), (N/A, 20)
--	(5250 - 5330 @ 80), (N/A, 20), DFS
--	(5490 - 5710 @ 80), (N/A, 27), DFS
-+	(2402 - 2482 @ 40), (20)
-+	(5170 - 5250 @ 80), (20)
-+	(5250 - 5330 @ 80), (20), DFS
-+	(5490 - 5710 @ 80), (27), DFS
- 	# 60 gHz band channels 1-4, ref: Etsi En 302 567
--	(57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR
-+	(57240 - 65880 @ 2160), (40), NO-OUTDOOR
- 
- country GL: DFS-ETSI
--	(2402 - 2482 @ 40), (N/A, 20)
--	(5170 - 5250 @ 20), (N/A, 20)
--	(5250 - 5330 @ 20), (N/A, 20), DFS
--	(5490 - 5710 @ 20), (N/A, 27), DFS
--
--country GT:
--	(2402 - 2472 @ 40), (3, 27)
--	(5170 - 5250 @ 40), (3, 17)
--	(5250 - 5330 @ 40), (3, 23), DFS
--	(5735 - 5835 @ 40), (3, 30)
--
--country GU:
--	(2402 - 2472 @ 40), (3, 27)
--	(5170 - 5250 @ 80), (3, 17)
--	(5250 - 5330 @ 80), (3, 24), DFS
--	(5490 - 5710 @ 80), (3, 24), DFS
--	(5735 - 5835 @ 80), (3, 30)
--
--country HN:
--	(2402 - 2482 @ 40), (N/A, 20)
--	(5170 - 5250 @ 40), (3, 17)
--	(5250 - 5330 @ 40), (3, 20), DFS
--	(5490 - 5710 @ 40), (3, 20), DFS
--	(5735 - 5835 @ 40), (3, 30)
-+	(2402 - 2482 @ 40), (20)
-+	(5170 - 5250 @ 80), (20)
-+	(5250 - 5330 @ 80), (20), DFS
-+	(5490 - 5710 @ 80), (27), DFS
-+
-+country GT: DFS-FCC
-+	(2402 - 2472 @ 40), (30)
-+	(5170 - 5250 @ 80), (17)
-+	(5250 - 5330 @ 80), (23), DFS
-+	(5735 - 5835 @ 80), (30)
-+
-+country GU: DFS-FCC
-+	(2402 - 2472 @ 40), (30)
-+	(5170 - 5250 @ 80), (17)
-+	(5250 - 5330 @ 80), (24), DFS
-+	(5490 - 5730 @ 80), (24), DFS
-+	(5735 - 5835 @ 80), (30)
-+
-+country HN: DFS-FCC
-+	(2402 - 2482 @ 40), (20)
-+	(5170 - 5250 @ 80), (17)
-+	(5250 - 5330 @ 80), (24), DFS
-+	(5490 - 5730 @ 80), (24), DFS
-+	(5735 - 5835 @ 80), (30)
- 
- country HK:
--	(2402 - 2482 @ 40), (N/A, 20)
--	(5170 - 5250 @ 80), (3, 17)
--	(5250 - 5330 @ 80), (3, 24), DFS
--	(5490 - 5710 @ 80), (3, 24), DFS
--	(5735 - 5835 @ 80), (3, 30)
-+	(2402 - 2482 @ 40), (20)
-+	(5170 - 5250 @ 80), (17)
-+	(5250 - 5330 @ 80), (24), DFS
-+	(5490 - 5710 @ 80), (24), DFS
-+	(5735 - 5835 @ 80), (30)
- 
- country HR: DFS-ETSI
--	(2402 - 2482 @ 40), (N/A, 20)
--	(5170 - 5250 @ 40), (N/A, 20)
--	(5250 - 5330 @ 40), (N/A, 20), DFS
--	(5490 - 5710 @ 40), (N/A, 27), DFS
-+	(2402 - 2482 @ 40), (20)
-+	(5170 - 5250 @ 80), (20)
-+	(5250 - 5330 @ 80), (20), DFS
-+	(5490 - 5710 @ 80), (27), DFS
- 	# 60 gHz band channels 1-4, ref: Etsi En 302 567
--	(57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR
-+	(57240 - 65880 @ 2160), (40), NO-OUTDOOR
- 
--country HT:
--	(2402 - 2482 @ 40), (N/A, 20)
--	(5170 - 5250 @ 40), (N/A, 20)
--	(5250 - 5330 @ 40), (N/A, 20), DFS
--	(5490 - 5710 @ 40), (N/A, 27), DFS
-+country HT: DFS-ETSI
-+	(2402 - 2482 @ 40), (20)
-+	(5170 - 5250 @ 80), (20)
-+	(5250 - 5330 @ 80), (20), DFS
-+	(5490 - 5710 @ 80), (27), DFS
- 
- country HU: DFS-ETSI
--	(2402 - 2482 @ 40), (N/A, 20)
--	(5170 - 5250 @ 40), (N/A, 20)
--	(5250 - 5330 @ 40), (N/A, 20), DFS
--	(5490 - 5710 @ 40), (N/A, 27), DFS
-+	(2402 - 2482 @ 40), (20)
-+	(5170 - 5250 @ 80), (20)
-+	(5250 - 5330 @ 80), (20), DFS
-+	(5490 - 5710 @ 80), (27), DFS
- 	# 60 gHz band channels 1-4, ref: Etsi En 302 567
--	(57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR
-+	(57240 - 65880 @ 2160), (40), NO-OUTDOOR
- 
--country ID:
-+country ID: DFS-JP
- 	# ref: http://www.postel.go.id/content/ID/regulasi/standardisasi/kepdir/bwa%205,8%20ghz.pdf
--	(2402 - 2482 @ 40), (N/A, 20)
--	(5735 - 5815 @ 80), (N/A, 20)
-+	(2402 - 2482 @ 40), (20)
-+	(5735 - 5815 @ 80), (23)
- 
- country IE: DFS-ETSI
--	(2402 - 2482 @ 40), (N/A, 20)
--	(5170 - 5250 @ 80), (N/A, 20)
--	(5250 - 5330 @ 80), (N/A, 20), DFS
--	(5490 - 5710 @ 80), (N/A, 27), DFS
-+	(2402 - 2482 @ 40), (20)
-+	(5170 - 5250 @ 80), (20)
-+	(5250 - 5330 @ 80), (20), DFS
-+	(5490 - 5710 @ 80), (27), DFS
- 	# 60 gHz band channels 1-4, ref: Etsi En 302 567
--	(57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR
-+	(57240 - 65880 @ 2160), (40), NO-OUTDOOR
- 
--country IL:
--	(2402 - 2482 @ 40), (N/A, 20)
--	(5150 - 5250 @ 80), (N/A, 200 mW), NO-OUTDOOR
--	(5250 - 5350 @ 80), (N/A, 200 mW), NO-OUTDOOR, DFS
-+country IL: DFS-ETSI
-+	(2402 - 2482 @ 40), (20)
-+	(5150 - 5350 @ 80), (200 mW), NO-OUTDOOR
- 
--country IN:
--	(2402 - 2482 @ 40), (N/A, 20)
--	(5170 - 5250 @ 40), (N/A, 20)
--	(5250 - 5330 @ 40), (N/A, 20), DFS
--	(5735 - 5835 @ 40), (N/A, 20)
-+country IN: DFS-JP
-+	(2402 - 2482 @ 40), (20)
-+	(5170 - 5250 @ 80), (20)
-+	(5250 - 5330 @ 80), (20), DFS
-+	(5735 - 5835 @ 80), (20)
- 
- country IS: DFS-ETSI
--	(2402 - 2482 @ 40), (N/A, 20)
--	(5170 - 5250 @ 40), (N/A, 20)
--	(5250 - 5330 @ 40), (N/A, 20), DFS
--	(5490 - 5710 @ 40), (N/A, 27), DFS
-+	(2402 - 2482 @ 40), (20)
-+	(5170 - 5250 @ 80), (20)
-+	(5250 - 5330 @ 80), (20), DFS
-+	(5490 - 5710 @ 80), (27), DFS
- 	# 60 gHz band channels 1-4, ref: Etsi En 302 567
--	(57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR
-+	(57240 - 65880 @ 2160), (40), NO-OUTDOOR
- 
--country IR:
--	(2402 - 2482 @ 40), (N/A, 20)
--	(5735 - 5835 @ 40), (N/A, 30)
-+country IR: DFS-JP
-+	(2402 - 2482 @ 40), (20)
-+	(5735 - 5835 @ 80), (30)
- 
- country IT: DFS-ETSI
--	(2402 - 2482 @ 40), (N/A, 20)
--	(5170 - 5250 @ 80), (N/A, 20)
--	(5250 - 5330 @ 80), (N/A, 20), DFS
--	(5490 - 5710 @ 80), (N/A, 27), DFS
--	# 60 gHz band channels 1-4, ref: Etsi En 302 567
--	(57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR
--
--country JM:
--	(2402 - 2482 @ 40), (N/A, 20)
--	(5170 - 5250 @ 40), (3, 17)
--	(5250 - 5330 @ 40), (3, 20), DFS
--	(5490 - 5710 @ 40), (3, 20), DFS
--	(5735 - 5835 @ 40), (3, 30)
--
--country JP:
--	(2402 - 2482 @ 40), (N/A, 20)
--	(2474 - 2494 @ 20), (N/A, 20), NO-OFDM
--	(4910 - 4990 @ 40), (N/A, 23)
--	(5030 - 5090 @ 40), (N/A, 23)
--	(5170 - 5250 @ 80), (N/A, 20)
--	(5250 - 5330 @ 80), (N/A, 20), DFS
--	(5490 - 5710 @ 160), (N/A, 23), DFS
--
--country JO:
--	(2402 - 2482 @ 40), (N/A, 20)
--	(5170 - 5250 @ 40), (N/A, 18)
--
--country KE:
--	(2402 - 2482 @ 40), (N/A, 20)
--	(5735 - 5835 @ 40), (N/A, 30)
--
--country KH:
--	(2402 - 2482 @ 40), (N/A, 20)
--	(5170 - 5250 @ 40), (N/A, 20)
--	(5250 - 5330 @ 40), (N/A, 20), DFS
--	(5490 - 5710 @ 40), (N/A, 27), DFS
--
--country KP:
--	(2402 - 2482 @ 40), (N/A, 20)
--	(5170 - 5330 @ 40), (3, 20)
--	(5160 - 5250 @ 40), (3, 20), DFS
--	(5490 - 5630 @ 40), (3, 30), DFS
--	(5735 - 5815 @ 40), (3, 30)
--
--country KR:
--	(2402 - 2482 @ 20), (N/A, 20)
--	(5170 - 5250 @ 80), (3, 20)
--	(5250 - 5330 @ 80), (3, 20), DFS
--	(5490 - 5630 @ 80), (3, 30), DFS
--	(5735 - 5815 @ 80), (3, 30)
--
--country KW:
--	(2402 - 2482 @ 40), (N/A, 20)
--	(5170 - 5250 @ 80), (N/A, 20)
--	(5250 - 5330 @ 80), (N/A, 20), DFS
-+	(2402 - 2482 @ 40), (20)
-+	(5170 - 5250 @ 80), (20)
-+	(5250 - 5330 @ 80), (20), DFS
-+	(5490 - 5710 @ 80), (27), DFS
-+	# 60 gHz band channels 1-4, ref: Etsi En 302 567
-+	(57240 - 65880 @ 2160), (40), NO-OUTDOOR
-+
-+country JM: DFS-FCC
-+	(2402 - 2482 @ 40), (20)
-+	(5170 - 5250 @ 80), (17)
-+	(5250 - 5330 @ 80), (24), DFS
-+	(5490 - 5730 @ 80), (24), DFS
-+	(5735 - 5835 @ 80), (30)
-+
-+country JP: DFS-JP
-+	(2402 - 2482 @ 40), (20)
-+	(2474 - 2494 @ 20), (20), NO-OFDM
-+	(4910 - 4990 @ 40), (23)
-+	(5030 - 5090 @ 40), (23)
-+	(5170 - 5250 @ 80), (20)
-+	(5250 - 5330 @ 80), (20), DFS
-+	(5490 - 5710 @ 160), (23), DFS
-+
-+country JO: DFS-JP
-+	(2402 - 2482 @ 40), (20)
-+	(5170 - 5250 @ 80), (23)
-+	(5735 - 5835 @ 80), (23)
-+
-+country KE: DFS-JP
-+	(2402 - 2482 @ 40), (20)
-+	(5170 - 5250 @ 80), (23)
-+	(5490 - 5570 @ 80), (30), DFS
-+	(5735 - 5775 @ 40), (23)
-+
-+country KH: DFS-ETSI
-+	(2402 - 2482 @ 40), (20)
-+	(5170 - 5250 @ 80), (20)
-+	(5250 - 5330 @ 80), (20), DFS
-+	(5490 - 5710 @ 80), (27), DFS
-+
-+country KP: DFS-JP
-+	(2402 - 2482 @ 40), (20)
-+	(5170 - 5250 @ 80), (20)
-+	(5250 - 5330 @ 80), (20), DFS
-+	(5490 - 5630 @ 80), (30), DFS
-+	(5735 - 5815 @ 80), (30)
-+
-+country KR: DFS-JP
-+	(2402 - 2482 @ 20), (20)
-+	(2402 - 2482 @ 40), (20)
-+	(5170 - 5250 @ 80), (20)
-+	(5250 - 5330 @ 80), (20), DFS
-+	(5490 - 5710 @ 80), (30), DFS
-+	(5735 - 5815 @ 80), (30)
-+
-+country KW: DFS-ETSI
-+	(2402 - 2482 @ 40), (20)
-+	(5170 - 5250 @ 80), (20)
-+	(5250 - 5330 @ 80), (20), DFS
- 
- country KZ:
--	(2402 - 2482 @ 40), (N/A, 20)
-+	(2402 - 2482 @ 40), (20)
- 
--country LB:
--	(2402 - 2482 @ 40), (N/A, 20)
--	(5735 - 5835 @ 40), (N/A, 30)
-+country LB: DFS-FCC
-+	(2402 - 2482 @ 40), (20)
-+	(5170 - 5250 @ 80), (17)
-+	(5250 - 5330 @ 80), (24), DFS
-+	(5490 - 5730 @ 80), (24), DFS
-+	(5735 - 5835 @ 80), (30)
- 
- country LI: DFS-ETSI
--	(2402 - 2482 @ 40), (N/A, 20)
--	(5170 - 5250 @ 40), (N/A, 20)
--	(5250 - 5330 @ 40), (N/A, 20), DFS
--	(5490 - 5710 @ 40), (N/A, 27), DFS
--
--country LK:
--	(2402 - 2482 @ 40), (N/A, 20)
--	(5170 - 5250 @ 20), (3, 17)
--	(5250 - 5330 @ 20), (3, 20), DFS
--	(5490 - 5710 @ 20), (3, 20), DFS
--	(5735 - 5835 @ 20), (3, 30)
-+	(2402 - 2482 @ 40), (20)
-+	(5170 - 5250 @ 80), (20)
-+	(5250 - 5330 @ 80), (20), DFS
-+	(5490 - 5710 @ 80), (27), DFS
-+
-+country LK: DFS-FCC
-+	(2402 - 2482 @ 40), (20)
-+	(5170 - 5250 @ 80), (17)
-+	(5250 - 5330 @ 80), (24), DFS
-+	(5490 - 5730 @ 80), (24), DFS
-+	(5735 - 5835 @ 80), (30)
- 
- country LT: DFS-ETSI
--	(2402 - 2482 @ 40), (N/A, 20)
--	(5170 - 5250 @ 40), (N/A, 20)
--	(5250 - 5330 @ 40), (N/A, 20), DFS
--	(5490 - 5710 @ 40), (N/A, 27), DFS
-+	(2402 - 2482 @ 40), (20)
-+	(5170 - 5250 @ 80), (20)
-+	(5250 - 5330 @ 80), (20), DFS
-+	(5490 - 5710 @ 80), (27), DFS
- 	# 60 gHz band channels 1-4, ref: Etsi En 302 567
--	(57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR
-+	(57240 - 65880 @ 2160), (40), NO-OUTDOOR
- 
- country LU: DFS-ETSI
--	(2402 - 2482 @ 40), (N/A, 20)
--	(5170 - 5250 @ 80), (N/A, 20)
--	(5250 - 5330 @ 80), (N/A, 20), DFS
--	(5490 - 5710 @ 80), (N/A, 27), DFS
-+	(2402 - 2482 @ 40), (20)
-+	(5170 - 5250 @ 80), (20)
-+	(5250 - 5330 @ 80), (20), DFS
-+	(5490 - 5710 @ 80), (27), DFS
- 	# 60 gHz band channels 1-4, ref: Etsi En 302 567
--	(57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR
-+	(57240 - 65880 @ 2160), (40), NO-OUTDOOR
- 
- country LV: DFS-ETSI
--	(2402 - 2482 @ 40), (N/A, 20)
--	(5170 - 5250 @ 40), (N/A, 20)
--	(5250 - 5330 @ 40), (N/A, 20), DFS
--	(5490 - 5710 @ 40), (N/A, 27), DFS
-+	(2402 - 2482 @ 40), (20)
-+	(5170 - 5250 @ 80), (20)
-+	(5250 - 5330 @ 80), (20), DFS
-+	(5490 - 5710 @ 80), (27), DFS
- 	# 60 gHz band channels 1-4, ref: Etsi En 302 567
--	(57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR
-+	(57240 - 65880 @ 2160), (40), NO-OUTDOOR
- 
- country MC: DFS-ETSI
--	(2402 - 2482 @ 40), (N/A, 20)
--	(5170 - 5250 @ 40), (N/A, 18)
--	(5250 - 5330 @ 40), (N/A, 18), DFS
-+	(2402 - 2482 @ 40), (20)
-+	(5170 - 5250 @ 80), (20)
-+	(5250 - 5330 @ 80), (20), DFS
-+	(5490 - 5710 @ 80), (27), DFS
- 
--country MA:
--	(2402 - 2482 @ 40), (N/A, 20)
--	(5170 - 5250 @ 80), (N/A, 23)
--	(5735 - 5835 @ 80), (N/A, 23)
-+country MA: DFS-ETSI
-+	(2402 - 2482 @ 40), (20)
-+	(5170 - 5250 @ 80), (20)
-+	(5250 - 5330 @ 80), (20), DFS
- 
- country MO:
--	(2402 - 2482 @ 40), (N/A, 20)
--	(5170 - 5250 @ 40), (3, 23)
--	(5250 - 5330 @ 40), (3, 23), DFS
--	(5735 - 5835 @ 40), (3, 30)
-+	(2402 - 2482 @ 40), (20)
-+	(5170 - 5250 @ 40), (23)
-+	(5250 - 5330 @ 40), (23), DFS
-+	(5735 - 5835 @ 40), (30)
- 
- country MK: DFS-ETSI
--	(2402 - 2482 @ 40), (N/A, 20)
--	(5170 - 5250 @ 40), (N/A, 20)
--	(5250 - 5330 @ 40), (N/A, 20), DFS
--	(5490 - 5710 @ 40), (N/A, 27), DFS
-+	(2402 - 2482 @ 40), (20)
-+	(5170 - 5250 @ 80), (20)
-+	(5250 - 5330 @ 80), (20), DFS
-+	(5490 - 5710 @ 80), (27), DFS
- 	# 60 gHz band channels 1-4, ref: Etsi En 302 567
--	(57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR
-+	(57240 - 65880 @ 2160), (40), NO-OUTDOOR
- 
- country MT: DFS-ETSI
--	(2402 - 2482 @ 40), (N/A, 20)
--	(5170 - 5250 @ 40), (N/A, 20)
--	(5250 - 5330 @ 40), (N/A, 20), DFS
--	(5490 - 5710 @ 40), (N/A, 27), DFS
--	# 60 gHz band channels 1-4, ref: Etsi En 302 567
--	(57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR
--
--country MY:
--	(2402 - 2482 @ 40), (N/A, 20)
--	(5170 - 5250 @ 80), (N/A, 17)
--	(5250 - 5330 @ 80), (N/A, 23), DFS
--	(5735 - 5835 @ 80), (N/A, 30)
--
--country MX:
--	(2402 - 2472 @ 40), (3, 27)
--	(5170 - 5250 @ 80), (3, 17)
--	(5250 - 5330 @ 80), (3, 24), DFS
--	(5490 - 5710 @ 80), (3, 24), DFS
--	(5735 - 5835 @ 80), (3, 30)
-+	(2402 - 2482 @ 40), (20)
-+	(5170 - 5250 @ 80), (20)
-+	(5250 - 5330 @ 80), (20), DFS
-+	(5490 - 5710 @ 80), (27), DFS
-+	# 60 gHz band channels 1-4, ref: Etsi En 302 567
-+	(57240 - 65880 @ 2160), (40), NO-OUTDOOR
-+
-+country MY: DFS-FCC
-+	(2402 - 2482 @ 40), (20)
-+	(5170 - 5250 @ 80), (17)
-+	(5250 - 5330 @ 80), (23), DFS
-+	(5735 - 5835 @ 80), (30)
-+
-+country MX: DFS-FCC
-+	(2402 - 2482 @ 40), (20)
-+	(5170 - 5250 @ 80), (17)
-+	(5250 - 5330 @ 80), (24), DFS
-+	(5490 - 5730 @ 80), (24), DFS
-+	(5735 - 5835 @ 80), (30)
- 
- country NL: DFS-ETSI
--	(2402 - 2482 @ 40), (N/A, 20)
--	(5170 - 5250 @ 80), (N/A, 20), NO-OUTDOOR
--	(5250 - 5330 @ 80), (N/A, 20), NO-OUTDOOR, DFS
--	(5490 - 5710 @ 80), (N/A, 27), DFS
-+	(2402 - 2482 @ 40), (20)
-+	(5170 - 5330 @ 80), (20), NO-OUTDOOR
-+	(5490 - 5710 @ 80), (27), DFS
- 	# 60 gHz band channels 1-4, ref: Etsi En 302 567
--	(57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR
-+	(57240 - 65880 @ 2160), (40), NO-OUTDOOR
- 
- country NO: DFS-ETSI
--	(2402 - 2482 @ 40), (N/A, 20)
--	(5170 - 5250 @ 40), (N/A, 20)
--	(5250 - 5330 @ 40), (N/A, 20), DFS
--	(5490 - 5710 @ 40), (N/A, 27), DFS
--	# 60 gHz band channels 1-4, ref: Etsi En 302 567
--	(57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR
--
--country NP:
--	(2402 - 2482 @ 40), (N/A, 20)
--	(5735 - 5835 @ 40), (N/A, 30)
--
--country NZ:
--	(2402 - 2482 @ 40), (N/A, 30)
--	(5170 - 5250 @ 80), (3, 17)
--	(5250 - 5330 @ 80), (3, 24), DFS
--	(5490 - 5710 @ 80), (3, 24), DFS
--	(5735 - 5835 @ 80), (3, 30)
--
--country OM:
--	(2402 - 2482 @ 40), (N/A, 20)
--	(5170 - 5250 @ 40), (3, 17)
--	(5250 - 5330 @ 40), (3, 20), DFS
--	(5490 - 5710 @ 40), (3, 20), DFS
--	(5735 - 5835 @ 40), (3, 30)
--
--country PA:
--	(2402 - 2472 @ 40), (3, 27)
--	(5170 - 5250 @ 40), (3, 17)
--	(5250 - 5330 @ 40), (3, 23), DFS
--	(5735 - 5835 @ 40), (3, 30)
--
--country PE:
--	(2402 - 2482 @ 40), (N/A, 20)
--	(5170 - 5250 @ 80), (3, 17)
--	(5250 - 5330 @ 80), (3, 24), DFS
--	(5490 - 5710 @ 80), (3, 24), DFS
--	(5735 - 5835 @ 80), (3, 30)
--
--country PG:
--	(2402 - 2482 @ 40), (N/A, 20)
--	(5170 - 5250 @ 40), (3, 17)
--	(5250 - 5330 @ 40), (3, 23), DFS
--	(5735 - 5835 @ 40), (3, 30)
--
--country PH:
--	(2402 - 2482 @ 40), (N/A, 20)
--	(5170 - 5250 @ 80), (3, 17)
--	(5250 - 5330 @ 80), (3, 24), DFS
--	(5490 - 5710 @ 80), (3, 24), DFS
--	(5735 - 5835 @ 80), (3, 30)
--
--country PK:
--	(2402 - 2482 @ 40), (N/A, 20)
--	(5735 - 5835 @ 40), (N/A, 30)
-+	(2402 - 2482 @ 40), (20)
-+	(5170 - 5250 @ 80), (20)
-+	(5250 - 5330 @ 80), (20), DFS
-+	(5490 - 5710 @ 80), (27), DFS
-+	# 60 gHz band channels 1-4, ref: Etsi En 302 567
-+	(57240 - 65880 @ 2160), (40), NO-OUTDOOR
-+
-+country NP: DFS-JP
-+	(2402 - 2482 @ 40), (20)
-+	(5170 - 5250 @ 80), (20)
-+	(5250 - 5330 @ 80), (20), DFS
-+	(5735 - 5835 @ 80), (20)
-+
-+country NZ: DFS-FCC
-+	(2402 - 2482 @ 40), (30)
-+	(5170 - 5250 @ 80), (17)
-+	(5250 - 5330 @ 80), (24), DFS
-+	(5490 - 5730 @ 80), (24), DFS
-+	(5735 - 5835 @ 80), (30)
-+
-+country OM: DFS-ETSI
-+	(2402 - 2482 @ 40), (20)
-+	(5170 - 5250 @ 80), (20)
-+	(5250 - 5330 @ 80), (20), DFS
-+	(5490 - 5710 @ 80), (27), DFS
-+
-+country PA: DFS-FCC
-+	(2402 - 2472 @ 40), (30)
-+	(5170 - 5250 @ 80), (17)
-+	(5250 - 5330 @ 80), (23), DFS
-+	(5735 - 5835 @ 80), (30)
-+
-+country PE: DFS-FCC
-+	(2402 - 2482 @ 40), (20)
-+	(5170 - 5250 @ 80), (17)
-+	(5250 - 5330 @ 80), (24), DFS
-+	(5490 - 5730 @ 80), (24), DFS
-+	(5735 - 5835 @ 80), (30)
-+
-+country PG: DFS-FCC
-+	(2402 - 2482 @ 40), (20)
-+	(5170 - 5250 @ 80), (17)
-+	(5250 - 5330 @ 80), (24), DFS
-+	(5490 - 5730 @ 80), (24), DFS
-+	(5735 - 5835 @ 80), (30)
-+
-+country PH: DFS-FCC
-+	(2402 - 2482 @ 40), (20)
-+	(5170 - 5250 @ 80), (17)
-+	(5250 - 5330 @ 80), (24), DFS
-+	(5490 - 5730 @ 80), (24), DFS
-+	(5735 - 5835 @ 80), (30)
-+
-+country PK: DFS-JP
-+	(2402 - 2482 @ 40), (20)
-+	(5735 - 5835 @ 80), (30)
- 
- country PL: DFS-ETSI
--	(2402 - 2482 @ 40), (N/A, 20)
--	(5170 - 5250 @ 80), (N/A, 20)
--	(5250 - 5330 @ 80), (N/A, 20), DFS
--	(5490 - 5710 @ 80), (N/A, 27), DFS
-+	(2402 - 2482 @ 40), (20)
-+	(5170 - 5250 @ 80), (20)
-+	(5250 - 5330 @ 80), (20), DFS
-+	(5490 - 5710 @ 80), (27), DFS
- 	# 60 gHz band channels 1-4, ref: Etsi En 302 567
--	(57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR
-+	(57240 - 65880 @ 2160), (40), NO-OUTDOOR
- 
- country PT: DFS-ETSI
--	(2402 - 2482 @ 40), (N/A, 20)
--	(5170 - 5250 @ 80), (N/A, 20)
--	(5250 - 5330 @ 80), (N/A, 20), DFS
--	(5490 - 5710 @ 80), (N/A, 27), DFS
-+	(2402 - 2482 @ 40), (20)
-+	(5170 - 5250 @ 80), (20)
-+	(5250 - 5330 @ 80), (20), DFS
-+	(5490 - 5710 @ 80), (27), DFS
- 	# 60 gHz band channels 1-4, ref: Etsi En 302 567
--	(57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR
-+	(57240 - 65880 @ 2160), (40), NO-OUTDOOR
- 
--country PR:
--	(2402 - 2472 @ 40), (3, 27)
--	(5170 - 5250 @ 80), (3, 17)
--	(5250 - 5330 @ 80), (3, 24), DFS
--	(5490 - 5710 @ 80), (3, 24), DFS
--	(5735 - 5835 @ 80), (3, 30)
-+country PR: DFS-FCC
-+	(2402 - 2472 @ 40), (30)
-+	(5170 - 5250 @ 80), (17)
-+	(5250 - 5330 @ 80), (24), DFS
-+	(5490 - 5730 @ 80), (24), DFS
-+	(5735 - 5835 @ 80), (30)
- 
--country QA:
--	(2402 - 2482 @ 40), (N/A, 20)
--	(5735 - 5835 @ 40), (N/A, 30)
-+country QA: DFS-JP
-+	(2402 - 2482 @ 40), (20)
-+	(5735 - 5835 @ 80), (30)
- 
- country RO: DFS-ETSI
--	(2402 - 2482 @ 40), (N/A, 20)
--	(5170 - 5250 @ 40), (N/A, 20)
--	(5250 - 5330 @ 40), (N/A, 20), DFS
--	(5490 - 5710 @ 40), (N/A, 27), DFS
-+	(2402 - 2482 @ 40), (20)
-+	(5170 - 5250 @ 80), (20)
-+	(5250 - 5330 @ 80), (20), DFS
-+	(5490 - 5710 @ 80), (27), DFS
- 	# 60 gHz band channels 1-4, ref: Etsi En 302 567
--	(57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR
-+	(57240 - 65880 @ 2160), (40), NO-OUTDOOR
- 
- 
- # Source:
- # http://www.ratel.rs/upload/documents/Plan_namene/Plan_namene-sl_glasnik.pdf
--country RS:
--	(2400 - 2483.5 @ 40), (N/A, 100 mW)
--	(5150 - 5350 @ 40), (N/A, 200 mW), NO-OUTDOOR
--	(5470 - 5725 @ 20), (3, 1000 mW), DFS
--	# 60 gHz band channels 1-4, ref: Etsi En 302 567
--	(57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR
--
--country RU:
--	(2402 - 2482 @ 40), (N/A, 20)
--	(5170 - 5330 @ 40), (N/A, 20)
--	(5650 - 5710 @ 40), (N/A, 30)
--	(5735 - 5835 @ 40), (N/A, 30)
--
--country RW:
--	(2402 - 2482 @ 40), (N/A, 20)
--	(5735 - 5835 @ 40), (N/A, 30)
--
--country SA:
--	(2402 - 2482 @ 40), (N/A, 20)
--	(5170 - 5250 @ 80), (3, 17)
--	(5250 - 5330 @ 80), (3, 24), DFS
--	(5490 - 5710 @ 80), (3, 24), DFS
--	(5735 - 5835 @ 80), (3, 30)
-+country RS: DFS-ETSI
-+	(2400 - 2483.5 @ 40), (100 mW)
-+	(5150 - 5350 @ 40), (200 mW), NO-OUTDOOR
-+	(5470 - 5725 @ 20), (1000 mW), DFS
-+	# 60 gHz band channels 1-4, ref: Etsi En 302 567
-+	(57240 - 65880 @ 2160), (40), NO-OUTDOOR
-+
-+country RU: DFS-ETSI
-+	(2402 - 2482 @ 40), (20)
-+	(5170 - 5250 @ 80), (20)
-+	(5250 - 5330 @ 80), (20), DFS
-+	(5650 - 5730 @ 80), (30), DFS
-+	(5735 - 5835 @ 80), (30)
-+
-+country RW: DFS-FCC
-+	(2402 - 2482 @ 40), (20)
-+	(5170 - 5250 @ 80), (17)
-+	(5250 - 5330 @ 80), (24), DFS
-+	(5490 - 5730 @ 80), (24), DFS
-+	(5735 - 5835 @ 80), (30)
-+
-+country SA: DFS-ETSI
-+	(2402 - 2482 @ 40), (20)
-+	(5170 - 5250 @ 80), (20)
-+	(5250 - 5330 @ 80), (20), DFS
-+	(5490 - 5710 @ 80), (27), DFS
- 
- country SE: DFS-ETSI
--	(2402 - 2482 @ 40), (N/A, 20)
--	(5170 - 5250 @ 80), (N/A, 20)
--	(5250 - 5330 @ 80), (N/A, 20), DFS
--	(5490 - 5710 @ 80), (N/A, 27), DFS
-+	(2402 - 2482 @ 40), (20)
-+	(5170 - 5250 @ 80), (20)
-+	(5250 - 5330 @ 80), (20), DFS
-+	(5490 - 5710 @ 80), (27), DFS
- 	# 60 gHz band channels 1-4, ref: Etsi En 302 567
--	(57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR
-+	(57240 - 65880 @ 2160), (40), NO-OUTDOOR
- 
--country SG:
--	(2402 - 2482 @ 40), (N/A, 20)
--	(5170 - 5250 @ 80), (3, 17)
--	(5250 - 5330 @ 80), (3, 24), DFS
--	(5490 - 5710 @ 80), (3, 24), DFS
--	(5735 - 5835 @ 80), (3, 30)
-+country SG: DFS-FCC
-+	(2402 - 2482 @ 40), (20)
-+	(5170 - 5250 @ 80), (17)
-+	(5250 - 5330 @ 80), (24), DFS
-+	(5490 - 5730 @ 80), (24), DFS
-+	(5735 - 5835 @ 80), (30)
- 
- country SI: DFS-ETSI
--	(2402 - 2482 @ 40), (N/A, 20)
--	(5170 - 5250 @ 40), (N/A, 20)
--	(5250 - 5330 @ 40), (N/A, 20), DFS
--	(5490 - 5710 @ 40), (N/A, 27), DFS
-+	(2402 - 2482 @ 40), (20)
-+	(5170 - 5250 @ 80), (20)
-+	(5250 - 5330 @ 80), (20), DFS
-+	(5490 - 5710 @ 80), (27), DFS
- 	# 60 gHz band channels 1-4, ref: Etsi En 302 567
--	(57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR
-+	(57240 - 65880 @ 2160), (40), NO-OUTDOOR
- 
- country SK: DFS-ETSI
--	(2402 - 2482 @ 40), (N/A, 20)
--	(5170 - 5250 @ 80), (N/A, 20)
--	(5250 - 5330 @ 80), (N/A, 20), DFS
--	(5490 - 5710 @ 80), (N/A, 27), DFS
-+	(2402 - 2482 @ 40), (20)
-+	(5170 - 5250 @ 80), (20)
-+	(5250 - 5330 @ 80), (20), DFS
-+	(5490 - 5710 @ 80), (27), DFS
- 	# 60 gHz band channels 1-4, ref: Etsi En 302 567
--	(57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR
-+	(57240 - 65880 @ 2160), (40), NO-OUTDOOR
- 
--country SV:
--	(2402 - 2482 @ 40), (N/A, 20)
--	(5170 - 5250 @ 20), (3, 17)
--	(5250 - 5330 @ 20), (3, 23), DFS
--	(5735 - 5835 @ 20), (3, 30)
-+country SV: DFS-FCC
-+	(2402 - 2482 @ 40), (20)
-+	(5170 - 5250 @ 80), (17)
-+	(5250 - 5330 @ 80), (23), DFS
-+	(5735 - 5835 @ 80), (30)
- 
- country SY:
--	(2402 - 2482 @ 40), (N/A, 20)
--
--country TW:
--	(2402 - 2472 @ 40), (3, 27)
--	(5270 - 5330 @ 40), (3, 17), DFS
--	(5490 - 5710 @ 80), (3, 30), DFS
--	(5735 - 5815 @ 80), (3, 30)
--
--country TH:
--	(2402 - 2482 @ 40), (N/A, 20)
--	(5170 - 5250 @ 80), (3, 17)
--	(5250 - 5330 @ 80), (3, 24), DFS
--	(5490 - 5710 @ 80), (3, 24), DFS
--	(5735 - 5835 @ 80), (3, 30)
--
--country TT:
--	(2402 - 2482 @ 40), (N/A, 20)
--	(5170 - 5250 @ 40), (3, 17)
--	(5250 - 5330 @ 40), (3, 20), DFS
--	(5490 - 5710 @ 40), (3, 20), DFS
--	(5735 - 5835 @ 40), (3, 30)
--
--country TN:
--	(2402 - 2482 @ 40), (N/A, 20)
--	(5170 - 5250 @ 20), (N/A, 20)
--	(5250 - 5330 @ 20), (N/A, 20), DFS
-+	(2402 - 2482 @ 40), (20)
-+
-+country TW: DFS-JP
-+	(2402 - 2472 @ 40), (30)
-+	(5270 - 5330 @ 40), (17), DFS
-+	(5490 - 5590 @ 80), (30), DFS
-+	(5650 - 5710 @ 40), (30), DFS
-+	(5735 - 5835 @ 80), (30)
-+
-+country TH: DFS-FCC
-+	(2402 - 2482 @ 40), (20)
-+	(5170 - 5250 @ 80), (17)
-+	(5250 - 5330 @ 80), (24), DFS
-+	(5490 - 5730 @ 80), (24), DFS
-+	(5735 - 5835 @ 80), (30)
-+
-+country TT: DFS-FCC
-+	(2402 - 2482 @ 40), (20)
-+	(5170 - 5250 @ 80), (17)
-+	(5250 - 5330 @ 80), (24), DFS
-+	(5490 - 5730 @ 80), (24), DFS
-+	(5735 - 5835 @ 80), (30)
-+
-+country TN: DFS-ETSI
-+	(2402 - 2482 @ 40), (20)
-+	(5170 - 5250 @ 80), (20)
-+	(5250 - 5330 @ 80), (20), DFS
- 
- country TR: DFS-ETSI
--	(2402 - 2482 @ 40), (N/A, 20)
--	(5170 - 5250 @ 80), (N/A, 20)
--	(5250 - 5330 @ 80), (N/A, 20), DFS
--	(5490 - 5710 @ 80), (N/A, 27), DFS
-+	(2402 - 2482 @ 40), (20)
-+	(5170 - 5250 @ 80), (20)
-+	(5250 - 5330 @ 80), (20), DFS
-+	(5490 - 5710 @ 80), (27), DFS
- 	# 60 gHz band channels 1-4, ref: Etsi En 302 567
--	(57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR
-+	(57240 - 65880 @ 2160), (40), NO-OUTDOOR
-  
- # Source:
- # #914 / 06 Sep 2007: http://www.ucrf.gov.ua/uk/doc/nkrz/1196068874
-@@ -765,59 +783,63 @@ country TR: DFS-ETSI
- # Listed 5GHz range is a lowest common denominator for all related
- # rules in the referenced laws. Such a range is used because of
- # disputable definitions there.
--country UA:
--	(2400 - 2483.5 @ 40), (N/A, 20), NO-OUTDOOR
--	(5150 - 5350 @ 40), (N/A, 20), NO-OUTDOOR
-+country UA: DFS-ETSI
-+	(2400 - 2483.5 @ 40), (20), NO-OUTDOOR
-+	(5150 - 5350 @ 40), (20), NO-OUTDOOR
-+	(5490 - 5670 @ 80), (20), DFS
-+	(5735 - 5835 @ 80), (20)
- 	# 60 gHz band channels 1-4, ref: Etsi En 302 567
--	(57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR
-+	(57240 - 65880 @ 2160), (40), NO-OUTDOOR
- 
- country US: DFS-FCC
--	(2402 - 2472 @ 40), (3, 27)
--	(5170 - 5250 @ 80), (3, 17)
--	(5250 - 5330 @ 80), (3, 24), DFS
--	(5490 - 5600 @ 80), (3, 24), DFS
--	(5650 - 5710 @ 40), (3, 24), DFS
--	(5735 - 5835 @ 80), (3, 30)
-+	(2402 - 2472 @ 40), (30)
-+	(5170 - 5250 @ 80), (17)
-+	(5250 - 5330 @ 80), (23), DFS
-+	(5735 - 5835 @ 80), (30)
- 	# 60g band
- 	# reference: http://cfr.regstoday.com/47cfr15.aspx#47_CFR_15p255
- 	# channels 1,2,3, EIRP=40dBm(43dBm peak)
--	(57240 - 63720 @ 2160), (N/A, 40)
--
--country UY:
--	(2402 - 2482 @ 40), (N/A, 20)
--	(5170 - 5250 @ 40), (3, 17)
--	(5250 - 5330 @ 40), (3, 20), DFS
--	(5490 - 5710 @ 40), (3, 20), DFS
--	(5735 - 5835 @ 40), (3, 30)
--
--country UZ:
--	(2402 - 2472 @ 40), (3, 27)
--	(5170 - 5250 @ 40), (3, 17)
--	(5250 - 5330 @ 40), (3, 20), DFS
--	(5490 - 5710 @ 40), (3, 20), DFS
--	(5735 - 5835 @ 40), (3, 30)
--
--country VE:
--	(2402 - 2482 @ 40), (N/A, 20)
--	(5735 - 5815 @ 40), (N/A, 23)
--
--country VN:
--	(2402 - 2482 @ 40), (N/A, 20)
--	(5170 - 5250 @ 80), (3, 17)
--	(5250 - 5330 @ 80), (3, 24), DFS
--	(5490 - 5710 @ 80), (3, 24), DFS
--	(5735 - 5835 @ 80), (3, 30)
-+	(57240 - 63720 @ 2160), (40)
-+
-+country UY: DFS-FCC
-+	(2402 - 2482 @ 40), (20)
-+	(5170 - 5250 @ 80), (17)
-+	(5250 - 5330 @ 80), (24), DFS
-+	(5490 - 5730 @ 80), (24), DFS
-+	(5735 - 5835 @ 80), (30)
-+
-+country UZ: DFS-FCC
-+	(2402 - 2472 @ 40), (30)
-+	(5170 - 5250 @ 80), (17)
-+	(5250 - 5330 @ 80), (24), DFS
-+	(5490 - 5730 @ 80), (24), DFS
-+	(5735 - 5835 @ 80), (30)
-+
-+country VE: DFS-FCC
-+	(2402 - 2482 @ 40), (20)
-+	(5170 - 5250 @ 80), (17)
-+	(5250 - 5330 @ 80), (23), DFS
-+	(5735 - 5835 @ 80), (30)
-+
-+country VN: DFS-FCC
-+	(2402 - 2482 @ 40), (20)
-+	(5170 - 5250 @ 80), (17)
-+	(5250 - 5330 @ 80), (24), DFS
-+	(5490 - 5730 @ 80), (24), DFS
-+	(5735 - 5835 @ 80), (30)
- 
- country YE:
--	(2402 - 2482 @ 40), (N/A, 20)
--
--country ZA:
--	(2402 - 2482 @ 40), (N/A, 20)
--	(5170 - 5250 @ 80), (3, 17)
--	(5250 - 5330 @ 80), (3, 24), DFS
--	(5490 - 5710 @ 80), (3, 24), DFS
--	(5735 - 5835 @ 80), (3, 30)
--
--country ZW:
--	(2402 - 2482 @ 40), (N/A, 20)
-+	(2402 - 2482 @ 40), (20)
-+
-+country ZA: DFS-ETSI
-+	(2402 - 2482 @ 40), (20)
-+	(5170 - 5250 @ 80), (20)
-+	(5250 - 5330 @ 80), (20), DFS
-+	(5490 - 5710 @ 80), (27), DFS
-+
-+country ZW: DFS-ETSI
-+	(2402 - 2482 @ 40), (20)
-+	(5170 - 5250 @ 80), (20)
-+	(5250 - 5330 @ 80), (20), DFS
-+	(5490 - 5710 @ 80), (27), DFS
- 
-diff --git a/package/mac80211/patches/001-fix_build.patch b/package/mac80211/patches/001-fix_build.patch
-index 26b327a..99ef50e 100644
---- a/package/mac80211/patches/001-fix_build.patch
-+++ b/package/mac80211/patches/001-fix_build.patch
-@@ -131,7 +131,7 @@
-  .PHONY: defconfig-help
- --- a/Makefile.real
- +++ b/Makefile.real
--@@ -54,7 +54,7 @@ defconfig-%::
-+@@ -59,7 +59,7 @@ defconfig-%::
-  
-  backport-include/backport/autoconf.h: .config Kconfig.versions Kconfig.kernel
-  	@$(MAKE) oldconfig
-@@ -140,7 +140,7 @@
-  	@grep -f .local-symbols .config | (				\
-  		echo "#ifndef COMPAT_AUTOCONF_INCLUDED"			;\
-  		echo "#define COMPAT_AUTOCONF_INCLUDED"			;\
--@@ -75,7 +75,12 @@ backport-include/backport/autoconf.h: .c
-+@@ -80,7 +80,12 @@ backport-include/backport/autoconf.h: .c
-  			esac						;\
-  		done							;\
-  		echo "#endif /* COMPAT_AUTOCONF_INCLUDED */"		;\
-diff --git a/package/mac80211/patches/003-remove_bogus_modparams.patch b/package/mac80211/patches/003-remove_bogus_modparams.patch
-index c969b19..ffb730b 100644
---- a/package/mac80211/patches/003-remove_bogus_modparams.patch
-+++ b/package/mac80211/patches/003-remove_bogus_modparams.patch
-@@ -1,6 +1,6 @@
- --- a/compat/main.c
- +++ b/compat/main.c
--@@ -21,31 +21,6 @@ MODULE_LICENSE("GPL");
-+@@ -20,31 +20,6 @@ MODULE_LICENSE("GPL");
-  #error "You need a BACKPORTS_VERSION"
-  #endif
-  
-diff --git a/package/mac80211/patches/004-backports-add-led_trigger_blink-_oneshot.patch b/package/mac80211/patches/004-backports-add-led_trigger_blink-_oneshot.patch
-index 584fb05..8d97224 100644
---- a/package/mac80211/patches/004-backports-add-led_trigger_blink-_oneshot.patch
-+++ b/package/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/mac80211/patches/005-make-genregdb.awk-skip-antenna-gain.patch b/package/mac80211/patches/005-make-genregdb.awk-skip-antenna-gain.patch
-new file mode 100644
-index 0000000..55bffbc
---- /dev/null
-+++ b/package/mac80211/patches/005-make-genregdb.awk-skip-antenna-gain.patch
-@@ -0,0 +1,44 @@
-+From: Luis R. Rodriguez <mcgrof@do-not-panic.com>
-+Date: Wed, 23 Oct 2013 14:55:36 -0400
-+Subject: [RFC] cfg80211: make genregdb.awk skip antenna gain
-+
-+Now that wireless-regdb doesn't include
-+antenna gain lets skip parsing it completely
-+for when CONFIG_CFG80211_INTERNAL_REGDB is
-+enabled.
-+
-+Signed-off-by: Luis R. Rodriguez <mcgrof@do-not-panic.com>
-+---
-+ net/wireless/genregdb.awk | 11 ++++-------
-+ 1 file changed, 4 insertions(+), 7 deletions(-)
-+ mode change 100644 => 100755 net/wireless/genregdb.awk
-+
-+--- a/net/wireless/genregdb.awk
-++++ b/net/wireless/genregdb.awk
-+@@ -56,14 +56,11 @@ function parse_reg_rule()
-+ 	end = $3
-+ 	bw = $5
-+ 	sub(/\),/, "", bw)
-+-	gain = $6
-+-	sub(/\(/, "", gain)
-+-	sub(/,/, "", gain)
-+-	power = $7
-+-	sub(/\)/, "", power)
-++	power = $6
-++	sub(/\(/, "", power)
-+ 	sub(/,/, "", power)
-+ 	# power might be in mW...
-+-	units = $8
-++	units = $7
-+ 	sub(/\)/, "", units)
-+ 	sub(/,/, "", units)
-+ 	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++)
-+ 		flagstr = flagstr $i
-+ 	split(flagstr, flagarray, ",")
-+ 	flags = ""
-diff --git a/package/mac80211/patches/007-select_queue.patch b/package/mac80211/patches/007-select_queue.patch
-new file mode 100644
-index 0000000..0a1d292
---- /dev/null
-+++ b/package/mac80211/patches/007-select_queue.patch
-@@ -0,0 +1,11 @@
-+--- a/drivers/net/wireless/mwifiex/main.c
-++++ b/drivers/net/wireless/mwifiex/main.c
-+@@ -745,7 +745,7 @@ static struct net_device_stats *mwifiex_
-+ 	return &priv->stats;
-+ }
-+ 
-+-#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0)
-++#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0)
-+ static u16
-+ mwifiex_netdev_select_wmm_queue(struct net_device *dev, struct sk_buff *skb,
-+ 				void *accel_priv, select_queue_fallback_t fallback)
-diff --git a/package/mac80211/patches/020-disable_tty_set_termios.patch b/package/mac80211/patches/020-disable_tty_set_termios.patch
-deleted file mode 100644
-index e6d4ff6..0000000
---- a/package/mac80211/patches/020-disable_tty_set_termios.patch
-+++ /dev/null
-@@ -1,16 +0,0 @@
----- a/compat/compat-2.6.39.c
--+++ b/compat/compat-2.6.39.c
--@@ -13,6 +13,7 @@
-- #include <linux/sched.h>
-- #include <linux/module.h>
-- 
--+#ifdef CONFIG_COMPAT_BLUETOOTH
-- #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27))
-- #ifdef CONFIG_TTY
-- /*
--@@ -114,4 +115,4 @@ int tty_set_termios(struct tty_struct *t
-- EXPORT_SYMBOL_GPL(tty_set_termios);
-- #endif /* CONFIG_TTY */
-- #endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)) */
---
--+#endif
-diff --git a/package/mac80211/patches/050-lib80211_option.patch b/package/mac80211/patches/050-lib80211_option.patch
-index 5372114..168871a 100644
---- a/package/mac80211/patches/050-lib80211_option.patch
-+++ b/package/mac80211/patches/050-lib80211_option.patch
-@@ -1,6 +1,6 @@
- --- a/net/wireless/Kconfig
- +++ b/net/wireless/Kconfig
--@@ -123,7 +123,7 @@ config CFG80211_WEXT
-+@@ -160,7 +160,7 @@ config CFG80211_WEXT
-  	  extensions with cfg80211-based drivers.
-  
-  config LIB80211
-@@ -9,7 +9,7 @@
-  	depends on m
-  	default n
-  	help
--@@ -133,15 +133,15 @@ config LIB80211
-+@@ -170,15 +170,15 @@ config LIB80211
-  	  Drivers should select this themselves if needed.
-  
-  config LIB80211_CRYPT_WEP
-diff --git a/package/mac80211/patches/060-no_local_ssb_bcma.patch b/package/mac80211/patches/060-no_local_ssb_bcma.patch
-index f4b9470..93197ae 100644
---- a/package/mac80211/patches/060-no_local_ssb_bcma.patch
-+++ b/package/mac80211/patches/060-no_local_ssb_bcma.patch
-@@ -1,6 +1,6 @@
- --- a/.local-symbols
- +++ b/.local-symbols
--@@ -379,42 +379,6 @@ USB_CDC_PHONET=
-+@@ -403,42 +403,6 @@ USB_CDC_PHONET=
-  USB_IPHETH=
-  USB_SIERRA_NET=
-  USB_VL600=
-@@ -68,7 +68,7 @@
-  obj-$(CPTCFG_NFC) += net/nfc/
- --- a/drivers/net/wireless/b43/main.c
- +++ b/drivers/net/wireless/b43/main.c
--@@ -2734,7 +2734,7 @@ static struct ssb_device *b43_ssb_gpio_d
-+@@ -2733,7 +2733,7 @@ static struct ssb_device *b43_ssb_gpio_d
-  {
-  	struct ssb_bus *bus = dev->dev->sdev->bus;
-  
-@@ -77,12 +77,12 @@
-  	return (bus->chipco.dev ? bus->chipco.dev : bus->pcicore.dev);
-  #else
-  	return bus->chipco.dev;
--@@ -4751,7 +4751,7 @@ static int b43_wireless_core_init(struct
-+@@ -4698,7 +4698,7 @@ static int b43_wireless_core_init(struct
-  	}
-  	if (sprom->boardflags_lo & B43_BFL_XTAL_NOSLOW)
-  		hf |= B43_HF_DSCRQ; /* Disable slowclock requests from ucode. */
---#ifdef CPTCFG_SSB_DRIVER_PCICORE
--+#ifdef CONFIG_SSB_DRIVER_PCICORE
-+-#if defined(CPTCFG_B43_SSB) && defined(CPTCFG_SSB_DRIVER_PCICORE)
-++#if defined(CPTCFG_B43_SSB) && defined(CONFIG_SSB_DRIVER_PCICORE)
-  	if (dev->dev->bus_type == B43_BUS_SSB &&
-  	    dev->dev->sdev->bus->bustype == SSB_BUSTYPE_PCI &&
-  	    dev->dev->sdev->bus->pcicore.dev->id.revision <= 10)
-diff --git a/package/mac80211/patches/070-add-missing-header.patch b/package/mac80211/patches/070-add-missing-header.patch
-new file mode 100644
-index 0000000..e3ec780
---- /dev/null
-+++ b/package/mac80211/patches/070-add-missing-header.patch
-@@ -0,0 +1,10 @@
-+--- a/compat/backport-3.15.c
-++++ b/compat/backport-3.15.c
-+@@ -12,6 +12,7 @@
-+ #include <linux/kernel.h>
-+ #include <linux/device.h>
-+ #include <linux/of.h>
-++#include <linux/string.h>
-+ #include <net/net_namespace.h>
-+ 
-+ #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0))
-diff --git a/package/mac80211/patches/100-revert_aes_ccm_port.patch b/package/mac80211/patches/100-revert_aes_ccm_port.patch
-index 4654bc8..640d34e 100644
---- a/package/mac80211/patches/100-revert_aes_ccm_port.patch
-+++ b/package/mac80211/patches/100-revert_aes_ccm_port.patch
-@@ -4,7 +4,7 @@
-  	depends on CRYPTO
-  	depends on CRYPTO_ARC4
-  	depends on CRYPTO_AES
---	depends on CRYPTO_CCM
-+-	select BACKPORT_CRYPTO_CCM
-  	depends on CRC32
-  	select BACKPORT_AVERAGE
-  	---help---
-@@ -19,35 +19,17 @@
-   * This program is free software; you can redistribute it and/or modify
-   * it under the terms of the GNU General Public License version 2 as
-   * published by the Free Software Foundation.
--@@ -19,75 +17,134 @@
-+@@ -19,76 +17,134 @@
-  #include "key.h"
-  #include "aes_ccm.h"
-  
- -void ieee80211_aes_ccm_encrypt(struct crypto_aead *tfm, u8 *b_0, u8 *aad,
- -			       u8 *data, size_t data_len, u8 *mic)
- +static void aes_ccm_prepare(struct crypto_cipher *tfm, u8 *scratch, u8 *a)
-- {
---	struct scatterlist assoc, pt, ct[2];
---	struct {
---		struct aead_request	req;
---		u8			priv[crypto_aead_reqsize(tfm)];
---	} aead_req;
---
---	memset(&aead_req, 0, sizeof(aead_req));
---
---	sg_init_one(&pt, data, data_len);
---	sg_init_one(&assoc, &aad[2], be16_to_cpup((__be16 *)aad));
---	sg_init_table(ct, 2);
---	sg_set_buf(&ct[0], data, data_len);
---	sg_set_buf(&ct[1], mic, IEEE80211_CCMP_MIC_LEN);
---
---	aead_request_set_tfm(&aead_req.req, tfm);
---	aead_request_set_assoc(&aead_req.req, &assoc, assoc.length);
---	aead_request_set_crypt(&aead_req.req, &pt, ct, data_len, b_0);
-++{
- +	int i;
- +	u8 *b_0, *aad, *b, *s_0;
-- 
---	crypto_aead_encrypt(&aead_req.req);
-++
- +	b_0 = scratch + 3 * AES_BLOCK_SIZE;
- +	aad = scratch + 4 * AES_BLOCK_SIZE;
- +	b = scratch;
-@@ -73,22 +55,23 @@
- +	b_0[14] = 0;
- +	b_0[15] = 0;
- +	crypto_cipher_encrypt_one(tfm, s_0, b_0);
-- }
-- 
---int ieee80211_aes_ccm_decrypt(struct crypto_aead *tfm, u8 *b_0, u8 *aad,
---			      u8 *data, size_t data_len, u8 *mic)
-++}
-++
- +
- +void ieee80211_aes_ccm_encrypt(struct crypto_cipher *tfm, u8 *scratch,
- +			       u8 *data, size_t data_len,
- +			       u8 *cdata, u8 *mic)
-  {
- -	struct scatterlist assoc, pt, ct[2];
---	struct {
---		struct aead_request	req;
---		u8			priv[crypto_aead_reqsize(tfm)];
---	} aead_req;
-++	int i, j, last_len, num_blocks;
-++	u8 *pos, *cpos, *b, *s_0, *e, *b_0;
-+ 
-+-	char aead_req_data[sizeof(struct aead_request) +
-+-			   crypto_aead_reqsize(tfm)]
-+-		__aligned(__alignof__(struct aead_request));
-+-	struct aead_request *aead_req = (void *) aead_req_data;
- -
---	memset(&aead_req, 0, sizeof(aead_req));
-+-	memset(aead_req, 0, sizeof(aead_req_data));
- -
- -	sg_init_one(&pt, data, data_len);
- -	sg_init_one(&assoc, &aad[2], be16_to_cpup((__be16 *)aad));
-@@ -96,13 +79,9 @@
- -	sg_set_buf(&ct[0], data, data_len);
- -	sg_set_buf(&ct[1], mic, IEEE80211_CCMP_MIC_LEN);
- -
---	aead_request_set_tfm(&aead_req.req, tfm);
---	aead_request_set_assoc(&aead_req.req, &assoc, assoc.length);
---	aead_request_set_crypt(&aead_req.req, ct, &pt,
---			       data_len + IEEE80211_CCMP_MIC_LEN, b_0);
--+	int i, j, last_len, num_blocks;
--+	u8 *pos, *cpos, *b, *s_0, *e, *b_0;
--+
-+-	aead_request_set_tfm(aead_req, tfm);
-+-	aead_request_set_assoc(aead_req, &assoc, assoc.length);
-+-	aead_request_set_crypt(aead_req, &pt, ct, data_len, b_0);
- +	b = scratch;
- +	s_0 = scratch + AES_BLOCK_SIZE;
- +	e = scratch + 2 * AES_BLOCK_SIZE;
-@@ -131,30 +110,38 @@
- +			*cpos++ = *pos++ ^ e[i];
- +	}
-  
---	return crypto_aead_decrypt(&aead_req.req);
-+-	crypto_aead_encrypt(aead_req);
- +	for (i = 0; i < IEEE80211_CCMP_MIC_LEN; i++)
- +		mic[i] = b[i] ^ s_0[i];
-  }
-  
---struct crypto_aead *ieee80211_aes_key_setup_encrypt(const u8 key[])
-+-int ieee80211_aes_ccm_decrypt(struct crypto_aead *tfm, u8 *b_0, u8 *aad,
-+-			      u8 *data, size_t data_len, u8 *mic)
- +
- +int ieee80211_aes_ccm_decrypt(struct crypto_cipher *tfm, u8 *scratch,
- +			      u8 *cdata, size_t data_len, u8 *mic, u8 *data)
-  {
---	struct crypto_aead *tfm;
---	int err;
-+-	struct scatterlist assoc, pt, ct[2];
-+-	char aead_req_data[sizeof(struct aead_request) +
-+-			   crypto_aead_reqsize(tfm)]
-+-		__aligned(__alignof__(struct aead_request));
-+-	struct aead_request *aead_req = (void *) aead_req_data;
-+-
-+-	memset(aead_req, 0, sizeof(aead_req_data));
-+-
-+-	sg_init_one(&pt, data, data_len);
-+-	sg_init_one(&assoc, &aad[2], be16_to_cpup((__be16 *)aad));
-+-	sg_init_table(ct, 2);
-+-	sg_set_buf(&ct[0], data, data_len);
-+-	sg_set_buf(&ct[1], mic, IEEE80211_CCMP_MIC_LEN);
-+-
-+-	aead_request_set_tfm(aead_req, tfm);
-+-	aead_request_set_assoc(aead_req, &assoc, assoc.length);
-+-	aead_request_set_crypt(aead_req, ct, &pt,
-+-			       data_len + IEEE80211_CCMP_MIC_LEN, b_0);
- +	int i, j, last_len, num_blocks;
- +	u8 *pos, *cpos, *b, *s_0, *a, *b_0;
-- 
---	tfm = crypto_alloc_aead("ccm(aes)", 0, CRYPTO_ALG_ASYNC);
---	if (IS_ERR(tfm))
---		return tfm;
---
---	err = crypto_aead_setkey(tfm, key, WLAN_KEY_LEN_CCMP);
---	if (!err)
---		err = crypto_aead_setauthsize(tfm, IEEE80211_CCMP_MIC_LEN);
---	if (!err)
---		return tfm;
-++
- +	b = scratch;
- +	s_0 = scratch + AES_BLOCK_SIZE;
- +	a = scratch + 2 * AES_BLOCK_SIZE;
-@@ -187,24 +174,37 @@
- +			return -1;
- +	}
-  
---	crypto_free_aead(tfm);
---	return ERR_PTR(err);
-+-	return crypto_aead_decrypt(aead_req);
- +	return 0;
-  }
-  
---void ieee80211_aes_key_free(struct crypto_aead *tfm)
-+-struct crypto_aead *ieee80211_aes_key_setup_encrypt(const u8 key[])
- +
- +struct crypto_cipher *ieee80211_aes_key_setup_encrypt(const u8 key[])
--+{
-+ {
-+-	struct crypto_aead *tfm;
-+-	int err;
- +	struct crypto_cipher *tfm;
--+
-+ 
-+-	tfm = crypto_alloc_aead("ccm(aes)", 0, CRYPTO_ALG_ASYNC);
-+-	if (IS_ERR(tfm))
-+-		return tfm;
-+-
-+-	err = crypto_aead_setkey(tfm, key, WLAN_KEY_LEN_CCMP);
-+-	if (!err)
-+-		err = crypto_aead_setauthsize(tfm, IEEE80211_CCMP_MIC_LEN);
-+-	if (!err)
-+-		return tfm;
- +	tfm = crypto_alloc_cipher("aes", 0, CRYPTO_ALG_ASYNC);
- +	if (!IS_ERR(tfm))
- +		crypto_cipher_setkey(tfm, key, WLAN_KEY_LEN_CCMP);
--+
-+ 
-+-	crypto_free_aead(tfm);
-+-	return ERR_PTR(err);
- +	return tfm;
--+}
--+
-+ }
-+ 
-+-void ieee80211_aes_key_free(struct crypto_aead *tfm)
- +
- +void ieee80211_aes_key_free(struct crypto_cipher *tfm)
-  {
-@@ -246,13 +246,13 @@
-  		struct {
- --- a/net/mac80211/wpa.c
- +++ b/net/mac80211/wpa.c
--@@ -301,16 +301,22 @@ ieee80211_crypto_tkip_decrypt(struct iee
-+@@ -301,15 +301,22 @@ ieee80211_crypto_tkip_decrypt(struct iee
-  }
-  
-  
---static void ccmp_special_blocks(struct sk_buff *skb, u8 *pn, u8 *b_0, u8 *aad,
-+-static void ccmp_special_blocks(struct sk_buff *skb, u8 *pn, u8 *b_0, u8 *aad)
- +static void ccmp_special_blocks(struct sk_buff *skb, u8 *pn, u8 *scratch,
-- 				int encrypted)
-++				int encrypted)
-  {
-  	__le16 mask_fc;
-  	int a4_included, mgmt;
-@@ -271,7 +271,7 @@
-  	/*
-  	 * Mask FC: zero subtype b4 b5 b6 (if not mgmt)
-  	 * Retry, PwrMgt, MoreData; set Protected
--@@ -332,21 +338,20 @@ static void ccmp_special_blocks(struct s
-+@@ -331,21 +338,20 @@ static void ccmp_special_blocks(struct s
-  	else
-  		qos_tid = 0;
-  
-@@ -300,7 +300,7 @@
-  
-  	/* AAD (extra authenticate-only data) / masked 802.11 header
-  	 * FC | A1 | A2 | A3 | SC | [A4] | [QC] */
--@@ -402,8 +407,7 @@ static int ccmp_encrypt_skb(struct ieee8
-+@@ -401,8 +407,7 @@ static int ccmp_encrypt_skb(struct ieee8
-  	u8 *pos;
-  	u8 pn[6];
-  	u64 pn64;
-@@ -310,11 +310,11 @@
-  
-  	if (info->control.hw_key &&
-  	    !(info->control.hw_key->flags & IEEE80211_KEY_FLAG_GENERATE_IV) &&
--@@ -456,9 +460,9 @@ static int ccmp_encrypt_skb(struct ieee8
-+@@ -458,9 +463,9 @@ static int ccmp_encrypt_skb(struct ieee8
-  		return 0;
-  
-  	pos += IEEE80211_CCMP_HDR_LEN;
---	ccmp_special_blocks(skb, pn, b_0, aad, 0);
-+-	ccmp_special_blocks(skb, pn, b_0, aad);
- -	ieee80211_aes_ccm_encrypt(key->u.ccmp.tfm, b_0, aad, pos, len,
- -				  skb_put(skb, IEEE80211_CCMP_MIC_LEN));
- +	ccmp_special_blocks(skb, pn, scratch, 0);
-@@ -323,7 +323,7 @@
-  
-  	return 0;
-  }
--@@ -521,16 +525,16 @@ ieee80211_crypto_ccmp_decrypt(struct iee
-+@@ -523,16 +528,16 @@ ieee80211_crypto_ccmp_decrypt(struct iee
-  	}
-  
-  	if (!(status->flag & RX_FLAG_DECRYPTED)) {
-@@ -331,7 +331,7 @@
- -		u8 b_0[AES_BLOCK_SIZE];
- +		u8 scratch[6 * AES_BLOCK_SIZE];
-  		/* hardware didn't decrypt/verify MIC */
---		ccmp_special_blocks(skb, pn, b_0, aad, 1);
-+-		ccmp_special_blocks(skb, pn, b_0, aad);
- +		ccmp_special_blocks(skb, pn, scratch, 1);
-  
-  		if (ieee80211_aes_ccm_decrypt(
-diff --git a/package/mac80211/patches/150-disable_addr_notifier.patch b/package/mac80211/patches/150-disable_addr_notifier.patch
-index 7b50154..6a7f5c1 100644
---- a/package/mac80211/patches/150-disable_addr_notifier.patch
-+++ b/package/mac80211/patches/150-disable_addr_notifier.patch
-@@ -1,6 +1,6 @@
- --- a/net/mac80211/main.c
- +++ b/net/mac80211/main.c
--@@ -287,7 +287,7 @@ void ieee80211_restart_hw(struct ieee802
-+@@ -285,7 +285,7 @@ void ieee80211_restart_hw(struct ieee802
-  }
-  EXPORT_SYMBOL(ieee80211_restart_hw);
-  
-@@ -9,7 +9,7 @@
-  static int ieee80211_ifa_changed(struct notifier_block *nb,
-  				 unsigned long data, void *arg)
-  {
--@@ -346,7 +346,7 @@ static int ieee80211_ifa_changed(struct 
-+@@ -344,7 +344,7 @@ static int ieee80211_ifa_changed(struct 
-  }
-  #endif
-  
-@@ -18,7 +18,7 @@
-  static int ieee80211_ifa6_changed(struct notifier_block *nb,
-  				  unsigned long data, void *arg)
-  {
--@@ -1031,14 +1031,14 @@ int ieee80211_register_hw(struct ieee802
-+@@ -1036,14 +1036,14 @@ int ieee80211_register_hw(struct ieee802
-  		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/mac80211/patches/300-pending_work.patch b/package/mac80211/patches/300-pending_work.patch
-index a1af6c2..3305388 100644
---- a/package/mac80211/patches/300-pending_work.patch
-+++ b/package/mac80211/patches/300-pending_work.patch
-@@ -1,4153 +1,2752 @@
--commit 93f310a38a1d81a4bc8fcd9bf29628bd721cf2ef
--Author: Felix Fietkau <nbd@openwrt.org>
--Date:   Sun Apr 6 23:35:28 2014 +0200
--
--    ath9k_hw: reduce ANI firstep range for older chips
--    
--    Use 0-8 instead of 0-16, which is closer to the old implementation.
--    Also drop the overwrite of the firstep_low parameter to improve
--    stability.
--    
--    Signed-off-by: Felix Fietkau <nbd@openwrt.org>
--
--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
-+commit d3a58df87a2e4c2301ac843604202d290a48440b
-+Author: Avraham Stern <avraham.stern@intel.com>
-+Date:   Thu May 22 12:17:47 2014 +0300
- 
--    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.
-+    mac80211: set new interfaces as idle upon init
-     
--    On older chips, the differences are bigger and especially AR5008/AR9001
--    are configured to much more sensitive values than what is useful.
-+    Mark new interfaces as idle to allow operations that require that
-+    interfaces are idle to take place. Interface types that are always
-+    not idle (like AP interfaces) will be set as not idle when they are
-+    assigned a channel context.
-     
--    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>
-+    Signed-off-by: Avraham Stern <avraham.stern@intel.com>
-+    Signed-off-by: Emmanuel Grumbach<emmanuel.grumbach@intel.com>
-+    Signed-off-by: Johannes Berg <johannes.berg@intel.com>
- 
--commit c977493766310a825f406836636ffd66e1447783
--Author: Felix Fietkau <nbd@openwrt.org>
--Date:   Mon Mar 10 19:52:56 2014 +0100
-+commit 923eaf367206e01f22c97aee22300e332d071916
-+Author: Arik Nemtsov <arik@wizery.com>
-+Date:   Mon May 26 14:40:51 2014 +0300
- 
--    ath9k_hw: remove ANI function restrictions for AP mode
-+    mac80211: don't check netdev state for debugfs read/write
-     
--    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.
-+    Doing so will lead to an oops for a p2p-dev interface, since it has
-+    no netdev.
-     
--    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
-+    Cc: stable@vger.kernel.org
-+    Signed-off-by: Arik Nemtsov <arikx.nemtsov@intel.com>
-+    Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
-+    Signed-off-by: Johannes Berg <johannes.berg@intel.com>
- 
--    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 a9fb54169b197f31aff24c8d6270dd1e56cde395
-+Author: chaitanya.mgit@gmail.com <chaitanya.mgit@gmail.com>
-+Date:   Mon May 26 18:01:44 2014 +0530
-+
-+    regdb: Generalize the mW to dBm power conversion
-+    
-+    Generalize the power conversion from mW to dBm
-+    using log. This should fix the below compilation
-+    error for country NO which adds a new power value
-+    2000mW which is not handled earlier.
-+    
-+     CC [M]  net/wireless/wext-sme.o
-+     CC [M]  net/wireless/regdb.o
-+    net/wireless/regdb.c:1130:1: error: Unknown undeclared here (not in
-+    a function)
-+    net/wireless/regdb.c:1130:9: error: expected } before power
-+    make[2]: *** [net/wireless/regdb.o] Error 1
-+    make[1]: *** [net/wireless] Error 2
-+    make: *** [net] Error 2
-+    
-+    Reported-By:  John Walker <john@x109.net>
-+    Signed-off-by: Chaitanya T K <chaitanya.mgit@gmail.com>
-+    Acked-by: John W. Linville <linville@tuxdriver.com>
-+    [remove unneeded parentheses, fix rounding by using %.0f]
-+    Signed-off-by: Johannes Berg <johannes.berg@intel.com>
- 
--commit 22e298b5a3a8a49e33805d4e351965123dede35b
--Author: Felix Fietkau <nbd@openwrt.org>
--Date:   Sun Mar 9 10:58:47 2014 +0100
-+commit c7d37a66e345df2fdf1aa7b2c9a6d3d53846ca5b
-+Author: Krzysztof Hałasa <khalasa@piap.pl>
-+Date:   Mon May 26 14:14:46 2014 +0200
- 
--    ath9k: fix ready time of the multicast buffer queue
--    
--    qi->tqi_readyTime is written directly to registers that expect
--    microseconds as unit instead of TU.
--    When setting the CABQ ready time, cur_conf->beacon_interval is in TU, so
--    convert it to microseconds before passing it to ath9k_hw.
-+    mac80211: fix IBSS join by initializing last_scan_completed
-     
--    This should hopefully fix some Tx DMA issues with buffered multicast
--    frames in AP mode.
-+    Without this fix, freshly rebooted Linux creates a new IBSS
-+    instead of joining an existing one. Only when jiffies counter
-+    overflows after 5 minutes the IBSS can be successfully joined.
-     
-+    Signed-off-by: Krzysztof Hałasa <khalasa@piap.pl>
-+    [edit commit message slightly]
-     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
-+    Signed-off-by: Johannes Berg <johannes.berg@intel.com>
- 
--    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 34171dc0d623be2c1032416bf7d3819f388ed70d
-+Author: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
-+Date:   Sun May 25 15:35:41 2014 +0300
-+
-+    mac80211: fix virtual monitor interface addition
-+    
-+    Since the commit below, cfg80211_chandef_dfs_required()
-+    will warn if it gets a an NL80211_IFTYPE_UNSPECIFIED iftype
-+    as explicitely written in the commit log.
-+    When an virtual monitor interface is added, its type is set
-+    in ieee80211_sub_if_data.vif.type, but not in
-+    ieee80211_sub_if_data.wdev.iftype which is passed to
-+    cfg80211_chandef_dfs_required() hence resulting in the
-+    following warning:
-+    
-+    WARNING: CPU: 1 PID: 21265 at net/wireless/chan.c:376 cfg80211_chandef_dfs_required+0xbc/0x130 [cfg80211]()
-+    Modules linked in: [...]
-+    CPU: 1 PID: 21265 Comm: ifconfig Tainted: G        W  O 3.13.11+ #12
-+    Hardware name: Dell Inc. Latitude E6410/0667CC, BIOS A01 03/05/2010
-+     0000000000000009 ffff88008f5fdb08 ffffffff817d4219 ffff88008f5fdb50
-+     ffff88008f5fdb40 ffffffff8106f57d 0000000000000000 0000000000000000
-+     ffff880081062fb8 ffff8800810604e0 0000000000000001 ffff88008f5fdba0
-+    Call Trace:
-+     [<ffffffff817d4219>] dump_stack+0x4d/0x66
-+     [<ffffffff8106f57d>] warn_slowpath_common+0x7d/0xa0
-+     [<ffffffff8106f5ec>] warn_slowpath_fmt+0x4c/0x50
-+     [<ffffffffa04ea4ec>] cfg80211_chandef_dfs_required+0xbc/0x130 [cfg80211]
-+     [<ffffffffa06b1024>] ieee80211_vif_use_channel+0x94/0x500 [mac80211]
-+     [<ffffffffa0684e6b>] ieee80211_add_virtual_monitor+0x1ab/0x5c0 [mac80211]
-+     [<ffffffffa0686ae5>] ieee80211_do_open+0xe75/0x1580 [mac80211]
-+     [<ffffffffa0687259>] ieee80211_open+0x69/0x70 [mac80211]
-+    [snip]
-+    
-+    Fixes: 00ec75fc5a64 ("cfg80211: pass the actual iftype when calling cfg80211_chandef_dfs_required()")
-+    Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
-+    Acked-by: Luciano Coelho <luciano.coelho@intel.com>
-+    Signed-off-by: Johannes Berg <johannes.berg@intel.com>
- 
--commit 31959d8df39319e32c6d5ba9c135727be90cfad7
-+commit d93cc72b37b4e2c314e1c499e80e8801907c2fea
- Author: Michal Kazior <michal.kazior@tieto.com>
--Date:   Fri Mar 7 08:09:38 2014 +0100
-+Date:   Thu Jun 5 14:21:37 2014 +0200
- 
--    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:
-+    mac80211: use csa counter offsets instead of csa_active
-     
--    [ 4605.207223] BUG: unable to handle kernel NULL pointer dereference at 0000000000000018
--    [ 4605.210789] IP: [<ffffffffa07b5635>] ieee80211_parse_bitrates+0x65/0x110 [mac80211]
-+    vif->csa_active is protected by mutexes only. This
-+    means it is unreliable to depend on it on codeflow
-+    in non-sleepable beacon and CSA code. There was no
-+    guarantee to have vif->csa_active update be
-+    visible before beacons are updated on SMP systems.
-     
--    The splat was preceeded by WARN_ON(!chanctx_conf)
--    in ieee80211_get_sdata_band().
-+    Using csa counter offsets which are embedded in
-+    beacon struct (and thus are protected with single
-+    RCU assignment) is much safer.
-     
-     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
-+commit d2746694fcdef24e0a7a1947d8c70082cde81a26
-+Author: Michal Kazior <michal.kazior@tieto.com>
-+Date:   Thu Jun 5 14:21:36 2014 +0200
- 
--    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.
-+    mac80211: move csa counters from sdata to beacon/presp
-     
--    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
-+    Having csa counters part of beacon and probe_resp
-+    structures makes it easier to get rid of possible
-+    races between setting a beacon and updating
-+    counters on SMP systems by guaranteeing counters
-+    are always consistent against given beacon struct.
-     
--    Number of MAC hangs and stuck beacons were missing
-+    While at it relax WARN_ON into WARN_ON_ONCE to
-+    prevent spamming logs and racing.
-     
--    Signed-off-by: Felix Fietkau <nbd@openwrt.org>
-+    Signed-off-by: Michal Kazior <michal.kazior@tieto.com>
-+    Signed-off-by: Johannes Berg <johannes.berg@intel.com>
- 
--commit d84856012e0f10fe598a5ad3b7b869397a089e07
--Author: Johannes Berg <johannes.berg@intel.com>
--Date:   Thu Feb 20 11:19:58 2014 +0100
-+commit 5dcb54f3a1a8cd7e0331e773487574f9743615db
-+Author: Janusz Dziedzic <janusz.dziedzic@tieto.com>
-+Date:   Thu Jun 5 08:12:57 2014 +0200
- 
--    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
-+    mac80211: allow tx via monitor iface when DFS
-     
--    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
-+    Allow send frames using monitor interface
-+    when DFS chandef and we pass CAC (beaconing
-+    allowed).
-     
--    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.
-+    This fix problem when old kernel and new backports used,
-+    in such case hostapd create/use also monitor interface.
-+    Before this patch all frames hostapd send using monitor
-+    iface were dropped when AP was configured on DFS channel.
-     
-+    Signed-off-by: Janusz Dziedzic <janusz.dziedzic@tieto.com>
-     Signed-off-by: Johannes Berg <johannes.berg@intel.com>
- 
--commit 798f2786602cbe93e6b928299614aa36ebf50692
-+commit 6f09a1beb0d2007572248c986780562219bd206f
- Author: Johannes Berg <johannes.berg@intel.com>
--Date:   Mon Feb 17 20:49:03 2014 +0100
-+Date:   Wed Jun 4 17:31:56 2014 +0200
- 
--    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
-+    cfg80211: make ethtool the driver's responsibility
-     
--    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.
-+    Currently, cfg80211 tries to implement ethtool, but that doesn't
-+    really scale well, with all the different operations. Make the
-+    lower-level driver responsible for it, which currently only has
-+    an effect on mac80211. It will similarly not scale well at that
-+    level though, since mac80211 also has many drivers.
-     
--    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.
-+    To cleanly implement this in mac80211, introduce a new file and
-+    move some code to appropriate places.
-     
-     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
-+commit 6b0c6f133de8f90caeb1c4a902e6140567c5bf96
-+Author: Johannes Berg <johannes.berg@intel.com>
-+Date:   Wed Jun 4 17:06:23 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.
-+    mac80211: remove weak WEP IV accounting
-     
--    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.
-+    Since WEP is practically dead, there seems very little
-+    point in keeping WEP weak IV accounting.
-     
--    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
-+commit aecdc89fb4664c76baa4bbd46008f220532309ff
-+Author: Luciano Coelho <luciano.coelho@intel.com>
-+Date:   Fri May 23 11:04:50 2014 +0300
- 
--    cfg80211: bugfix in regulatory user hint process
-+    ath9k/ath10k: remove unnecessary channel_switch_beacon callbacks
-     
--    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".
-+    The channel_switch_beacon callback is optional, so it doesn't have to
-+    be defined if it's not going to do anything useful with it.  Both
-+    ath9k and ath10k define the callback and just returns.  This commit
-+    removes them.
-     
--    Signed-off-by: Inbal Hacohen <Inbal.Hacohen@intel.com>
--    Signed-off-by: Johannes Berg <johannes.berg@intel.com>
-+    Cc: Michal Kazior <michal.kazior@tieto.com>
-+    Signed-off-by: Luciano Coelho <luciano.coelho@intel.com>
-+    Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
- 
--commit 6514c93afede55284e2cb63359aadedb85884c80
--Author: Jouni Malinen <jouni@qca.qualcomm.com>
--Date:   Tue Feb 18 20:41:08 2014 +0200
-+commit 60ccc107c9b9fb732fdee1f76bb2dad44f0e1798
-+Author: Rajkumar Manoharan <rmanohar@qti.qualcomm.com>
-+Date:   Tue May 27 16:58:02 2014 +0530
- 
--    ath9k: Enable U-APSD AP mode support
-+    ath9k: Fix deadlock while updating p2p beacon timer
-     
--    mac80211 handles the actual operations, so ath9k can just indicate
--    support for this. Based on initial tests, this combination seems to
--    work fine.
-+    pm_lock is taken twice while syncing HW TSF of p2p vif.
-+    Fix this by taking the lock at caller side.
-     
--    Signed-off-by: Jouni Malinen <jouni@qca.qualcomm.com>
-+    Cc: Felix Fietkau <nbd@openwrt.org>
-+    Signed-off-by: Rajkumar Manoharan <rmanohar@qti.qualcomm.com>
-+    Signed-off-by: John W. Linville <linville@tuxdriver.com>
- 
--commit a63caf0a357ad5c1f08d6b7827dc76c451445017
-+commit f3831a4e3903dbc1a57d5df56deb6a143fd001bc
- Author: Stanislaw Gruszka <sgruszka@redhat.com>
--Date:   Wed Feb 19 13:15:17 2014 +0100
-+Date:   Thu Jun 5 13:52:27 2014 +0200
- 
--    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:
-+    rt2x00: do not initialize BCN_OFFSET registers
-     
--    [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]
-+    We setup BCN_OFFSET{0,1} registers dynamically, don't have to
-+    initialize them.
-     
--    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
-+commit e5c58ca7a48d4c82f282749a978052c47fd95998
-+Author: Stanislaw Gruszka <sgruszka@redhat.com>
-+Date:   Thu Jun 5 13:52:26 2014 +0200
- 
--    ath9k: Fix IQ cal post processing for SoC
-+    rt2x00: change order when stop beaconing
-     
--    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.
-+    When no beaconing is needed, first stop beacon queue (disable beaconing
-+    globally) to avoid possible sending of not prepared beacon on short
-+    period after clearing beacon and before stop of BCN queue.
-     
--    Signed-off-by: Sujith Manoharan <c_manoha@qca.qualcomm.com>
-+    Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
- 
--commit e138e0ef9560c46ce93dbb22a728a57888e94d1c
--Author: Sujith Manoharan <c_manoha@qca.qualcomm.com>
--Date:   Mon Feb 3 13:31:37 2014 +0530
-+commit 382c1b9e03f52d0cd741ef1d942cad0f649f0744
-+Author: Stanislaw Gruszka <sgruszka@redhat.com>
-+Date:   Thu Jun 5 13:52:25 2014 +0200
- 
--    ath9k: Fix TX power calculation
-+    rt2x00: change default MAC_BSSID_DW1_BSS_BCN_NUM
-     
--    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.
-+    We setup MAC_BSSID_DW1_BSS_BCN_NUM dynamically when numbers of active
-+    beacons increase. Change default to 0 to tell hardware that we want to
-+    send only one beacon as default.
-     
--    Cc: Rajkumar Manoharan <rmanohar@qti.qualcomm.com>
--    Signed-off-by: Sujith Manoharan <c_manoha@qca.qualcomm.com>
-+    Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
- 
--commit b9f268b5b01331c3c82179abca551429450e9417
--Author: Michal Kazior <michal.kazior@tieto.com>
--Date:   Wed Jan 29 14:22:27 2014 +0100
-+commit 3b400571dd033e46fa7e76c5bb92a3ce8198afa9
-+Author: Stanislaw Gruszka <sgruszka@redhat.com>
-+Date:   Thu Jun 5 13:52:24 2014 +0200
- 
--    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
-+    rt2x00: change beaconing setup on RT2800
-     
--    With the above interface combinations it was
--    possible to:
-+    As reported by Matthias, on 5572 chip, even if we clear up TXWI
-+    of corresponding beacon, hardware still try to send it or do other
-+    action that increase power consumption peak up to 1A.
-     
--     step 1. start AP on DFS channel by matching combo 2
--     step 2. start AP on non-DFS channel by matching combo 1
-+    To avoid the issue, setup beaconing dynamically by configuring offsets
-+    of currently active beacons and MAC_BSSID_DW1_BSS_BCN_NUM variable,
-+    which limit number of beacons that hardware will try to send.
-     
--    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>
-+    Reported-by: Matthias Fend <Matthias.Fend@wolfvision.net>
-+    Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
- 
--commit bc9c62f5f511cc395c62dbf4cdd437f23db53b28
--Author: Antonio Quartulli <antonio@open-mesh.com>
--Date:   Wed Jan 29 17:53:43 2014 +0100
-+commit 916e591b2cc41f7e572992175ca56d866d7bc958
-+Author: Stanislaw Gruszka <sgruszka@redhat.com>
-+Date:   Thu Jun 5 13:52:23 2014 +0200
- 
--    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.
-+    rt2x00: change beaconing locking
-     
--    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).
-+    This patch is needed for further changes to keep global variables
-+    consistent when changing beaconing on diffrent vif's.
-     
--    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>
-+    Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
- 
--commit 7e0c41cb41f215aba2c39b1c237bb4d42ec49a85
-+commit 930b0dffd1731f3f418f9132faea720a23b7af61
- 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.
-+Date:   Tue Jun 3 11:18:47 2014 +0200
-+
-+    mac80211: fix station/driver powersave race
-+    
-+    It is currently possible to have a race due to the station PS
-+    unblock work like this:
-+     * station goes to sleep with frames buffered in the driver
-+     * driver blocks wakeup
-+     * station wakes up again
-+     * driver flushes/returns frames, and unblocks, which schedules
-+       the unblock work
-+     * unblock work starts to run, and checks that the station is
-+       awake (i.e. that the WLAN_STA_PS_STA flag isn't set)
-+     * we process a received frame with PM=1, setting the flag again
-+     * ieee80211_sta_ps_deliver_wakeup() runs, delivering all frames
-+       to the driver, and then clearing the WLAN_STA_PS_DRIVER and
-+       WLAN_STA_PS_STA flags
-+    
-+    In this scenario, mac80211 will think that the station is awake,
-+    while it really is asleep, and any TX'ed frames should be filtered
-+    by the device (it will know that the station is sleeping) but then
-+    passed to mac80211 again, which will not buffer it either as it
-+    thinks the station is awake, and eventually the packets will be
-+    dropped.
-+    
-+    Fix this by moving the clearing of the flags to exactly where we
-+    learn about the situation. This creates a problem of reordering,
-+    so introduce another flag indicating that delivery is being done,
-+    this new flag also queues frames and is cleared only while the
-+    spinlock is held (which the queuing code also holds) so that any
-+    concurrent delivery/TX is handled correctly.
-     
--    Signed-off-by: Simon Wunderlich <simon@open-mesh.com>
--    [fix typo & 'wildcard SSID' in commit log]
-+    Reported-by: Andrei Otcheretianski <andrei.otcheretianski@intel.com>
-     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
-+commit 6df35206bc6c1c6aad1d8077df5786b4a7f77873
-+Author: Felix Fietkau <nbd@openwrt.org>
-+Date:   Fri May 23 19:58:14 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().
-+    mac80211: reduce packet loss notifications under load
-     
--    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
-+    During strong signal fluctuations under high throughput, few consecutive
-+    failed A-MPDU transmissions can easily trigger packet loss notification,
-+    and thus (in AP mode) client disconnection.
-     
--    The patch adds a missing sdata lock and adds a few
--    lockdeps for easier maintenance.
-+    Reduce the number of false positives by checking the A-MPDU status flag
-+    and treating a failed A-MPDU as a single packet.
-     
--    Signed-off-by: Michal Kazior <michal.kazior@tieto.com>
--    Signed-off-by: Johannes Berg <johannes.berg@intel.com>
-+    Signed-off-by: Felix Fietkau <nbd@openwrt.org>
- 
--commit ad17ba7d14d225b109b73c177cd446afb8050598
--Author: Michal Kazior <michal.kazior@tieto.com>
--Date:   Wed Jan 29 07:56:20 2014 +0100
-+commit 7b7843a36fbcc568834404c7430ff895d8502131
-+Author: Felix Fietkau <nbd@openwrt.org>
-+Date:   Fri May 23 19:26:32 2014 +0200
- 
--    mac80211: fix sdata->radar_required locking
-+    mac80211: fix a memory leak on sta rate selection table
-     
--    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>
-+    Cc: stable@vger.kernel.org
-+    Reported-by: Christophe Prévotaux <cprevotaux@nltinc.com>
-+    Signed-off-by: Felix Fietkau <nbd@openwrt.org>
- 
--commit 5fcd5f1808813a3d9e502fd756e01bee8a79c85d
--Author: Michal Kazior <michal.kazior@tieto.com>
--Date:   Wed Jan 29 07:56:19 2014 +0100
-+commit 96892d6aa0a153423070addf3070bc79578b3897
-+Author: Felix Fietkau <nbd@openwrt.org>
-+Date:   Mon May 19 21:20:49 2014 +0200
- 
--    mac80211: move csa_active setting in STA CSA
-+    ath9k: avoid passing buffers to the hardware during flush
-     
--    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.
-+    The commit "ath9k: fix possible hang on flush" changed the receive code
-+    to always link rx descriptors of processed frames, even when flushing.
-+    In some cases, this leads to flushed rx buffers being passed to the
-+    hardware while rx is already stopped.
-     
--    Signed-off-by: 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
-+    Signed-off-by: Felix Fietkau <nbd@openwrt.org>
- 
--    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);
-+--- a/drivers/net/wireless/ath/ath9k/recv.c
-++++ b/drivers/net/wireless/ath/ath9k/recv.c
-+@@ -34,7 +34,8 @@ static inline bool ath9k_check_auto_slee
-+  * buffer (or rx fifo). This can incorrectly acknowledge packets
-+  * to a sender if last desc is self-linked.
-+  */
-+-static void ath_rx_buf_link(struct ath_softc *sc, struct ath_rxbuf *bf)
-++static void ath_rx_buf_link(struct ath_softc *sc, struct ath_rxbuf *bf,
-++			    bool flush)
-+ {
-+ 	struct ath_hw *ah = sc->sc_ah;
-+ 	struct ath_common *common = ath9k_hw_common(ah);
-+@@ -59,18 +60,19 @@ static void ath_rx_buf_link(struct ath_s
-+ 			     common->rx_bufsize,
-+ 			     0);
-+ 
-+-	if (sc->rx.rxlink == NULL)
-+-		ath9k_hw_putrxbuf(ah, bf->bf_daddr);
-+-	else
-++	if (sc->rx.rxlink)
-+ 		*sc->rx.rxlink = bf->bf_daddr;
-++	else if (!flush)
-++		ath9k_hw_putrxbuf(ah, bf->bf_daddr);
-+ 
-+ 	sc->rx.rxlink = &ds->ds_link;
-+ }
-  
--@@ -1534,7 +1534,7 @@ EXPORT_SYMBOL(ath9k_hw_check_nav);
-- bool ath9k_hw_check_alive(struct ath_hw *ah)
-+-static void ath_rx_buf_relink(struct ath_softc *sc, struct ath_rxbuf *bf)
-++static void ath_rx_buf_relink(struct ath_softc *sc, struct ath_rxbuf *bf,
-++			      bool flush)
-  {
-- 	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);
-+ 	if (sc->rx.buf_hold)
-+-		ath_rx_buf_link(sc, sc->rx.buf_hold);
-++		ath_rx_buf_link(sc, sc->rx.buf_hold, flush);
-  
----- 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;
-+ 	sc->rx.buf_hold = bf;
-+ }
-+@@ -442,7 +444,7 @@ int ath_startrecv(struct ath_softc *sc)
-+ 	sc->rx.buf_hold = NULL;
-+ 	sc->rx.rxlink = NULL;
-+ 	list_for_each_entry_safe(bf, tbf, &sc->rx.rxbuf, list) {
-+-		ath_rx_buf_link(sc, bf);
-++		ath_rx_buf_link(sc, bf, false);
-  	}
-  
--@@ -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;
-+ 	/* We could have deleted elements so the list may be empty now */
-+@@ -1118,12 +1120,12 @@ requeue_drop_frag:
-+ requeue:
-+ 		list_add_tail(&bf->list, &sc->rx.rxbuf);
-+ 
-+-		if (edma) {
-+-			ath_rx_edma_buf_link(sc, qtype);
-+-		} else {
-+-			ath_rx_buf_relink(sc, bf);
-++		if (!edma) {
-++			ath_rx_buf_relink(sc, bf, flush);
-+ 			if (!flush)
-+ 				ath9k_hw_rxena(ah);
-++		} else if (!flush) {
-++			ath_rx_edma_buf_link(sc, qtype);
-  		}
--@@ -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
-- }
-+ 		if (!budget--)
-+--- a/net/mac80211/sta_info.c
-++++ b/net/mac80211/sta_info.c
-+@@ -100,7 +100,8 @@ static void __cleanup_single_sta(struct 
-+ 	struct ps_data *ps;
-  
-- /**
--+ * 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
-- }
-+ 	if (test_sta_flag(sta, WLAN_STA_PS_STA) ||
-+-	    test_sta_flag(sta, WLAN_STA_PS_DRIVER)) {
-++	    test_sta_flag(sta, WLAN_STA_PS_DRIVER) ||
-++	    test_sta_flag(sta, WLAN_STA_PS_DELIVER)) {
-+ 		if (sta->sdata->vif.type == NL80211_IFTYPE_AP ||
-+ 		    sta->sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
-+ 			ps = &sdata->bss->ps;
-+@@ -111,6 +112,7 @@ static void __cleanup_single_sta(struct 
-  
-- /**
--- * 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
-- }
-+ 		clear_sta_flag(sta, WLAN_STA_PS_STA);
-+ 		clear_sta_flag(sta, WLAN_STA_PS_DRIVER);
-++		clear_sta_flag(sta, WLAN_STA_PS_DELIVER);
-  
-- /**
--+ * 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;
-- };
-+ 		atomic_dec(&ps->num_sta_ps);
-+ 		sta_info_recalc_tim(sta);
-+@@ -125,7 +127,7 @@ static void __cleanup_single_sta(struct 
-+ 	if (ieee80211_vif_is_mesh(&sdata->vif))
-+ 		mesh_sta_cleanup(sta);
-  
-- /**
--@@ -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;
-+-	cancel_work_sync(&sta->drv_unblock_wk);
-++	cancel_work_sync(&sta->drv_deliver_wk);
-  
-- 	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.
-+ 	/*
-+ 	 * Destroy aggregation state here. It would be nice to wait for the
-+@@ -227,6 +229,7 @@ struct sta_info *sta_info_get_by_idx(str
-   */
---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;
-+ void sta_info_free(struct ieee80211_local *local, struct sta_info *sta)
-+ {
-++	struct ieee80211_sta_rates *rates;
-+ 	int i;
-  
-- 	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;
-+ 	if (sta->rate_ctrl)
-+@@ -238,6 +241,10 @@ void sta_info_free(struct ieee80211_loca
-+ 		kfree(sta->tx_lat);
-  	}
-  
--@@ -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);
-++	rates = rcu_dereference_protected(sta->sta.rates, true);
-++	if (rates)
-++		kfree(rates);
- +
-- 	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;
-+ 	sta_dbg(sta->sdata, "Destroyed STA %pM\n", sta->sta.addr);
-  
---	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;
-+ 	kfree(sta);
-+@@ -252,33 +259,23 @@ static void sta_info_hash_add(struct iee
-+ 	rcu_assign_pointer(local->sta_hash[STA_HASH(sta->sta.addr)], sta);
-  }
-  
--@@ -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);
-- }
-+-static void sta_unblock(struct work_struct *wk)
-++static void sta_deliver_ps_frames(struct work_struct *wk)
-+ {
-+ 	struct sta_info *sta;
-  
----- a/net/mac80211/iface.c
--+++ b/net/mac80211/iface.c
--@@ -770,12 +770,19 @@ static void ieee80211_do_stop(struct iee
-+-	sta = container_of(wk, struct sta_info, drv_unblock_wk);
-++	sta = container_of(wk, struct sta_info, drv_deliver_wk);
-  
-- 	ieee80211_roc_purge(local, sdata);
-+ 	if (sta->dead)
-+ 		return;
-  
---	if (sdata->vif.type == NL80211_IFTYPE_STATION)
--+	switch (sdata->vif.type) {
--+	case NL80211_IFTYPE_STATION:
-- 		ieee80211_mgd_stop(sdata);
-+-	if (!test_sta_flag(sta, WLAN_STA_PS_STA)) {
-+-		local_bh_disable();
-++	local_bh_disable();
-++	if (!test_sta_flag(sta, WLAN_STA_PS_STA))
-+ 		ieee80211_sta_ps_deliver_wakeup(sta);
-+-		local_bh_enable();
-+-	} else if (test_and_clear_sta_flag(sta, WLAN_STA_PSPOLL)) {
-+-		clear_sta_flag(sta, WLAN_STA_PS_DRIVER);
- -
---	if (sdata->vif.type == NL80211_IFTYPE_ADHOC)
--+		break;
--+	case NL80211_IFTYPE_ADHOC:
-- 		ieee80211_ibss_stop(sdata);
-+-		local_bh_disable();
-++	else if (test_and_clear_sta_flag(sta, WLAN_STA_PSPOLL))
-+ 		ieee80211_sta_ps_deliver_poll_response(sta);
-+-		local_bh_enable();
-+-	} else if (test_and_clear_sta_flag(sta, WLAN_STA_UAPSD)) {
-+-		clear_sta_flag(sta, WLAN_STA_PS_DRIVER);
- -
--+		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);
-+-		local_bh_disable();
-++	else if (test_and_clear_sta_flag(sta, WLAN_STA_UAPSD))
-+ 		ieee80211_sta_ps_deliver_uapsd(sta);
-+-		local_bh_enable();
-+-	} else
-+-		clear_sta_flag(sta, WLAN_STA_PS_DRIVER);
-++	local_bh_enable();
-  }
-  
-+ static int sta_prepare_rate_control(struct ieee80211_local *local,
-+@@ -340,7 +337,7 @@ struct sta_info *sta_info_alloc(struct i
-  
--@@ -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;
-+ 	spin_lock_init(&sta->lock);
-+ 	spin_lock_init(&sta->ps_lock);
-+-	INIT_WORK(&sta->drv_unblock_wk, sta_unblock);
-++	INIT_WORK(&sta->drv_deliver_wk, sta_deliver_ps_frames);
-+ 	INIT_WORK(&sta->ampdu_mlme.work, ieee80211_ba_session_work);
-+ 	mutex_init(&sta->ampdu_mlme.mtx);
-+ #ifdef CPTCFG_MAC80211_MESH
-+@@ -1140,8 +1137,15 @@ void ieee80211_sta_ps_deliver_wakeup(str
-  	}
-  
----- 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);
-+ 	ieee80211_add_pending_skbs(local, &pending);
-+-	clear_sta_flag(sta, WLAN_STA_PS_DRIVER);
-+-	clear_sta_flag(sta, WLAN_STA_PS_STA);
- +
--+		/* 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;
--+		}
-++	/* now we're no longer in the deliver code */
-++	clear_sta_flag(sta, WLAN_STA_PS_DELIVER);
- +
-- 		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);
-- 	}
-++	/* The station might have polled and then woken up before we responded,
-++	 * so clear these flags now to avoid them sticking around.
-++	 */
-++	clear_sta_flag(sta, WLAN_STA_PSPOLL);
-++	clear_sta_flag(sta, WLAN_STA_UAPSD);
-+ 	spin_unlock(&sta->ps_lock);
-  
-- 	return err;
----- a/net/wireless/core.c
--+++ b/net/wireless/core.c
--@@ -203,8 +203,11 @@ void cfg80211_stop_p2p_device(struct cfg
-+ 	atomic_dec(&ps->num_sta_ps);
-+@@ -1542,10 +1546,26 @@ void ieee80211_sta_block_awake(struct ie
-  
-- 	rdev->opencount--;
-+ 	trace_api_sta_block_awake(sta->local, pubsta, block);
-  
---	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 (block)
-++	if (block) {
-+ 		set_sta_flag(sta, WLAN_STA_PS_DRIVER);
-+-	else if (test_sta_flag(sta, WLAN_STA_PS_DRIVER))
-+-		ieee80211_queue_work(hw, &sta->drv_unblock_wk);
-++		return;
-++	}
-++
-++	if (!test_sta_flag(sta, WLAN_STA_PS_DRIVER))
-++		return;
-++
-++	if (!test_sta_flag(sta, WLAN_STA_PS_STA)) {
-++		set_sta_flag(sta, WLAN_STA_PS_DELIVER);
-++		clear_sta_flag(sta, WLAN_STA_PS_DRIVER);
-++		ieee80211_queue_work(hw, &sta->drv_deliver_wk);
-++	} else if (test_sta_flag(sta, WLAN_STA_PSPOLL) ||
-++		   test_sta_flag(sta, WLAN_STA_UAPSD)) {
-++		/* must be asleep in this case */
-++		clear_sta_flag(sta, WLAN_STA_PS_DRIVER);
-++		ieee80211_queue_work(hw, &sta->drv_deliver_wk);
-++	} else {
-++		clear_sta_flag(sta, WLAN_STA_PS_DRIVER);
- +	}
-  }
-+ EXPORT_SYMBOL(ieee80211_sta_block_awake);
-  
-- 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;
-+@@ -1703,3 +1723,137 @@ u8 sta_info_tx_streams(struct sta_info *
-+ 	return ((ht_cap->mcs.tx_params & IEEE80211_HT_MCS_TX_MAX_STREAMS_MASK)
-+ 			>> IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT) + 1;
-  }
-- 
-- 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);
-++void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo)
-++{
-++	struct ieee80211_sub_if_data *sdata = sta->sdata;
-++	struct ieee80211_local *local = sdata->local;
-++	struct rate_control_ref *ref = local->rate_ctrl;
-++	struct timespec uptime;
-++	u64 packets = 0;
-++	u32 thr = 0;
-++	int i, ac;
-++
-++	sinfo->generation = sdata->local->sta_generation;
-++
-++	sinfo->filled = STATION_INFO_INACTIVE_TIME |
-++			STATION_INFO_RX_BYTES64 |
-++			STATION_INFO_TX_BYTES64 |
-++			STATION_INFO_RX_PACKETS |
-++			STATION_INFO_TX_PACKETS |
-++			STATION_INFO_TX_RETRIES |
-++			STATION_INFO_TX_FAILED |
-++			STATION_INFO_TX_BITRATE |
-++			STATION_INFO_RX_BITRATE |
-++			STATION_INFO_RX_DROP_MISC |
-++			STATION_INFO_BSS_PARAM |
-++			STATION_INFO_CONNECTED_TIME |
-++			STATION_INFO_STA_FLAGS |
-++			STATION_INFO_BEACON_LOSS_COUNT;
-++
-++	do_posix_clock_monotonic_gettime(&uptime);
-++	sinfo->connected_time = uptime.tv_sec - sta->last_connected;
-++
-++	sinfo->inactive_time = jiffies_to_msecs(jiffies - sta->last_rx);
-++	sinfo->tx_bytes = 0;
-++	for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) {
-++		sinfo->tx_bytes += sta->tx_bytes[ac];
-++		packets += sta->tx_packets[ac];
-++	}
-++	sinfo->tx_packets = packets;
-++	sinfo->rx_bytes = sta->rx_bytes;
-++	sinfo->rx_packets = sta->rx_packets;
-++	sinfo->tx_retries = sta->tx_retry_count;
-++	sinfo->tx_failed = sta->tx_retry_failed;
-++	sinfo->rx_dropped_misc = sta->rx_dropped;
-++	sinfo->beacon_loss_count = sta->beacon_loss_count;
-++
-++	if ((sta->local->hw.flags & IEEE80211_HW_SIGNAL_DBM) ||
-++	    (sta->local->hw.flags & IEEE80211_HW_SIGNAL_UNSPEC)) {
-++		sinfo->filled |= STATION_INFO_SIGNAL | STATION_INFO_SIGNAL_AVG;
-++		if (!local->ops->get_rssi ||
-++		    drv_get_rssi(local, sdata, &sta->sta, &sinfo->signal))
-++			sinfo->signal = (s8)sta->last_signal;
-++		sinfo->signal_avg = (s8) -ewma_read(&sta->avg_signal);
-++	}
-++	if (sta->chains) {
-++		sinfo->filled |= STATION_INFO_CHAIN_SIGNAL |
-++				 STATION_INFO_CHAIN_SIGNAL_AVG;
-++
-++		sinfo->chains = sta->chains;
-++		for (i = 0; i < ARRAY_SIZE(sinfo->chain_signal); i++) {
-++			sinfo->chain_signal[i] = sta->chain_signal_last[i];
-++			sinfo->chain_signal_avg[i] =
-++				(s8) -ewma_read(&sta->chain_signal_avg[i]);
- +		}
- +	}
- +
--+	/* 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;
-++	sta_set_rate_info_tx(sta, &sta->last_tx_rate, &sinfo->txrate);
-++	sta_set_rate_info_rx(sta, &sinfo->rxrate);
-++
-++	if (ieee80211_vif_is_mesh(&sdata->vif)) {
-++#ifdef CPTCFG_MAC80211_MESH
-++		sinfo->filled |= STATION_INFO_LLID |
-++				 STATION_INFO_PLID |
-++				 STATION_INFO_PLINK_STATE |
-++				 STATION_INFO_LOCAL_PM |
-++				 STATION_INFO_PEER_PM |
-++				 STATION_INFO_NONPEER_PM;
-++
-++		sinfo->llid = sta->llid;
-++		sinfo->plid = sta->plid;
-++		sinfo->plink_state = sta->plink_state;
-++		if (test_sta_flag(sta, WLAN_STA_TOFFSET_KNOWN)) {
-++			sinfo->filled |= STATION_INFO_T_OFFSET;
-++			sinfo->t_offset = sta->t_offset;
-++		}
-++		sinfo->local_pm = sta->local_pm;
-++		sinfo->peer_pm = sta->peer_pm;
-++		sinfo->nonpeer_pm = sta->nonpeer_pm;
-++#endif
-++	}
- +
--+		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;
-++	sinfo->bss_param.flags = 0;
-++	if (sdata->vif.bss_conf.use_cts_prot)
-++		sinfo->bss_param.flags |= BSS_PARAM_FLAGS_CTS_PROT;
-++	if (sdata->vif.bss_conf.use_short_preamble)
-++		sinfo->bss_param.flags |= BSS_PARAM_FLAGS_SHORT_PREAMBLE;
-++	if (sdata->vif.bss_conf.use_short_slot)
-++		sinfo->bss_param.flags |= BSS_PARAM_FLAGS_SHORT_SLOT_TIME;
-++	sinfo->bss_param.dtim_period = sdata->local->hw.conf.ps_dtim_period;
-++	sinfo->bss_param.beacon_interval = sdata->vif.bss_conf.beacon_int;
-++
-++	sinfo->sta_flags.set = 0;
-++	sinfo->sta_flags.mask = BIT(NL80211_STA_FLAG_AUTHORIZED) |
-++				BIT(NL80211_STA_FLAG_SHORT_PREAMBLE) |
-++				BIT(NL80211_STA_FLAG_WME) |
-++				BIT(NL80211_STA_FLAG_MFP) |
-++				BIT(NL80211_STA_FLAG_AUTHENTICATED) |
-++				BIT(NL80211_STA_FLAG_ASSOCIATED) |
-++				BIT(NL80211_STA_FLAG_TDLS_PEER);
-++	if (test_sta_flag(sta, WLAN_STA_AUTHORIZED))
-++		sinfo->sta_flags.set |= BIT(NL80211_STA_FLAG_AUTHORIZED);
-++	if (test_sta_flag(sta, WLAN_STA_SHORT_PREAMBLE))
-++		sinfo->sta_flags.set |= BIT(NL80211_STA_FLAG_SHORT_PREAMBLE);
-++	if (test_sta_flag(sta, WLAN_STA_WME))
-++		sinfo->sta_flags.set |= BIT(NL80211_STA_FLAG_WME);
-++	if (test_sta_flag(sta, WLAN_STA_MFP))
-++		sinfo->sta_flags.set |= BIT(NL80211_STA_FLAG_MFP);
-++	if (test_sta_flag(sta, WLAN_STA_AUTH))
-++		sinfo->sta_flags.set |= BIT(NL80211_STA_FLAG_AUTHENTICATED);
-++	if (test_sta_flag(sta, WLAN_STA_ASSOC))
-++		sinfo->sta_flags.set |= BIT(NL80211_STA_FLAG_ASSOCIATED);
-++	if (test_sta_flag(sta, WLAN_STA_TDLS_PEER))
-++		sinfo->sta_flags.set |= BIT(NL80211_STA_FLAG_TDLS_PEER);
-++
-++	/* check if the driver has a SW RC implementation */
-++	if (ref && ref->ops->get_expected_throughput)
-++		thr = ref->ops->get_expected_throughput(sta->rate_ctrl_priv);
-++	else
-++		thr = drv_get_expected_throughput(local, &sta->sta);
- +
-- 		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);
-++	if (thr != 0) {
-++		sinfo->filled |= STATION_INFO_EXPECTED_THROUGHPUT;
-++		sinfo->expected_throughput = thr;
-++	}
-++}
-+--- a/net/mac80211/status.c
-++++ b/net/mac80211/status.c
-+@@ -541,6 +541,23 @@ static void ieee80211_tx_latency_end_msr
-+  */
-+ #define STA_LOST_PKT_THRESHOLD	50
-  
--+void nl80211_send_ap_stopped(struct wireless_dev *wdev)
-++static void ieee80211_lost_packet(struct sta_info *sta, struct sk_buff *skb)
- +{
--+	struct wiphy *wiphy = wdev->wiphy;
--+	struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
--+	struct sk_buff *msg;
--+	void *hdr;
-++	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
- +
--+	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
--+	if (!msg)
-++	/* This packet was aggregated but doesn't carry status info */
-++	if ((info->flags & IEEE80211_TX_CTL_AMPDU) &&
-++	    !(info->flags & IEEE80211_TX_STAT_AMPDU))
- +		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);
-++	if (++sta->lost_packets < STA_LOST_PKT_THRESHOLD)
-++		return;
- +
--+	genlmsg_multicast_netns(&nl80211_fam, wiphy_net(wiphy), msg, 0,
--+				NL80211_MCGRP_MLME, GFP_KERNEL);
--+	return;
--+ out:
--+	nlmsg_free(msg);
-++	cfg80211_cqm_pktloss_notify(sta->sdata->dev, sta->sta.addr,
-++				    sta->lost_packets, GFP_ATOMIC);
-++	sta->lost_packets = 0;
- +}
- +
-- /* 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)
-+ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
-  {
-- 	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;
--+	}
-+ 	struct sk_buff *skb2;
-+@@ -680,12 +697,8 @@ void ieee80211_tx_status(struct ieee8021
-+ 			if (info->flags & IEEE80211_TX_STAT_ACK) {
-+ 				if (sta->lost_packets)
-+ 					sta->lost_packets = 0;
-+-			} else if (++sta->lost_packets >= STA_LOST_PKT_THRESHOLD) {
-+-				cfg80211_cqm_pktloss_notify(sta->sdata->dev,
-+-							    sta->sta.addr,
-+-							    sta->lost_packets,
-+-							    GFP_ATOMIC);
-+-				sta->lost_packets = 0;
-++			} else {
-++				ieee80211_lost_packet(sta, skb);
-+ 			}
-+ 		}
-  
--+	request = rdev->scan_req;
-- 	if (!request)
-+--- a/net/mac80211/rx.c
-++++ b/net/mac80211/rx.c
-+@@ -1107,6 +1107,8 @@ static void sta_ps_end(struct sta_info *
-  		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);
-++	set_sta_flag(sta, WLAN_STA_PS_DELIVER);
-++	clear_sta_flag(sta, WLAN_STA_PS_STA);
-+ 	ieee80211_sta_ps_deliver_wakeup(sta);
-  }
-  
-- void __cfg80211_scan_done(struct work_struct *wk)
--@@ -221,7 +231,7 @@ void __cfg80211_scan_done(struct work_st
-- 			    scan_done_wk);
-+--- a/net/mac80211/sta_info.h
-++++ b/net/mac80211/sta_info.h
-+@@ -82,6 +82,7 @@ enum ieee80211_sta_info_flags {
-+ 	WLAN_STA_TOFFSET_KNOWN,
-+ 	WLAN_STA_MPSP_OWNER,
-+ 	WLAN_STA_MPSP_RECIPIENT,
-++	WLAN_STA_PS_DELIVER,
-+ };
-  
-- 	rtnl_lock();
---	___cfg80211_scan_done(rdev);
--+	___cfg80211_scan_done(rdev, true);
-- 	rtnl_unlock();
-- }
-+ #define ADDBA_RESP_INTERVAL HZ
-+@@ -265,7 +266,7 @@ struct ieee80211_tx_latency_stat {
-+  * @last_rx_rate_vht_nss: rx status nss of last data packet
-+  * @lock: used for locking all fields that require locking, see comments
-+  *	in the header file.
-+- * @drv_unblock_wk: used for driver PS unblocking
-++ * @drv_deliver_wk: used for delivering frames after 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
-+@@ -278,7 +279,6 @@ struct ieee80211_tx_latency_stat {
-+  * @driver_buffered_tids: bitmap of TIDs the driver has data buffered on
-+  * @rx_packets: Number of MSDUs received from this STA
-+  * @rx_bytes: Number of bytes received from this STA
-+- * @wep_weak_iv_count: number of weak WEP IVs received from this station
-+  * @last_rx: time (in jiffies) when last frame was received from this STA
-+  * @last_connected: time (in seconds) when a station got connected
-+  * @num_duplicates: number of duplicate frames received from this STA
-+@@ -345,7 +345,7 @@ struct sta_info {
-+ 	void *rate_ctrl_priv;
-+ 	spinlock_t lock;
-+ 
-+-	struct work_struct drv_unblock_wk;
-++	struct work_struct drv_deliver_wk;
-+ 
-+ 	u16 listen_interval;
-+ 
-+@@ -367,7 +367,6 @@ struct sta_info {
-+ 	/* Updated from RX path only, no locking requirements */
-+ 	unsigned long rx_packets;
-+ 	u64 rx_bytes;
-+-	unsigned long wep_weak_iv_count;
-+ 	unsigned long last_rx;
-+ 	long last_connected;
-+ 	unsigned long num_duplicates;
-+@@ -628,6 +627,8 @@ void sta_set_rate_info_tx(struct sta_inf
-+ 			  struct rate_info *rinfo);
-+ void sta_set_rate_info_rx(struct sta_info *sta,
-+ 			  struct rate_info *rinfo);
-++void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo);
-++
-+ void ieee80211_sta_expire(struct ieee80211_sub_if_data *sdata,
-+ 			  unsigned long exp_time);
-+ u8 sta_info_tx_streams(struct sta_info *sta);
-+--- a/net/mac80211/tx.c
-++++ b/net/mac80211/tx.c
-+@@ -469,7 +469,8 @@ ieee80211_tx_h_unicast_ps_buf(struct iee
-+ 		return TX_CONTINUE;
-  
--@@ -1079,7 +1089,7 @@ int cfg80211_wext_siwscan(struct net_dev
-- 	if (IS_ERR(rdev))
-- 		return PTR_ERR(rdev);
-+ 	if (unlikely((test_sta_flag(sta, WLAN_STA_PS_STA) ||
-+-		      test_sta_flag(sta, WLAN_STA_PS_DRIVER)) &&
-++		      test_sta_flag(sta, WLAN_STA_PS_DRIVER) ||
-++		      test_sta_flag(sta, WLAN_STA_PS_DELIVER)) &&
-+ 		     !(info->flags & IEEE80211_TX_CTL_NO_PS_BUFFER))) {
-+ 		int ac = skb_get_queue_mapping(tx->skb);
-  
---	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 
-- 	}
-+@@ -486,7 +487,8 @@ ieee80211_tx_h_unicast_ps_buf(struct iee
-+ 		 * ahead and Tx the packet.
-+ 		 */
-+ 		if (!test_sta_flag(sta, WLAN_STA_PS_STA) &&
-+-		    !test_sta_flag(sta, WLAN_STA_PS_DRIVER)) {
-++		    !test_sta_flag(sta, WLAN_STA_PS_DRIVER) &&
-++		    !test_sta_flag(sta, WLAN_STA_PS_DELIVER)) {
-+ 			spin_unlock(&sta->ps_lock);
-+ 			return TX_CONTINUE;
-+ 		}
-+@@ -1618,12 +1620,12 @@ netdev_tx_t ieee80211_monitor_start_xmit
-+ {
-+ 	struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
-+ 	struct ieee80211_chanctx_conf *chanctx_conf;
-+-	struct ieee80211_channel *chan;
-+ 	struct ieee80211_radiotap_header *prthdr =
-+ 		(struct ieee80211_radiotap_header *)skb->data;
-+ 	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
-+ 	struct ieee80211_hdr *hdr;
-+ 	struct ieee80211_sub_if_data *tmp_sdata, *sdata;
-++	struct cfg80211_chan_def *chandef;
-+ 	u16 len_rthdr;
-+ 	int hdrlen;
-  
-- 	ifmgd->flags |= IEEE80211_STA_CSA_RECEIVED;
---	sdata->vif.csa_active = true;
-+@@ -1721,9 +1723,9 @@ netdev_tx_t ieee80211_monitor_start_xmit
-+ 	}
-  
-- 	mutex_lock(&local->chanctx_mtx);
-- 	if (local->use_chanctx) {
--@@ -1039,6 +1038,7 @@ ieee80211_sta_process_chanswitch(struct 
-- 	mutex_unlock(&local->chanctx_mtx);
-+ 	if (chanctx_conf)
-+-		chan = chanctx_conf->def.chan;
-++		chandef = &chanctx_conf->def;
-+ 	else if (!local->use_chanctx)
-+-		chan = local->_oper_chandef.chan;
-++		chandef = &local->_oper_chandef;
-+ 	else
-+ 		goto fail_rcu;
-  
-- 	sdata->csa_chandef = csa_ie.chandef;
--+	sdata->vif.csa_active = true;
-+@@ -1743,10 +1745,11 @@ netdev_tx_t ieee80211_monitor_start_xmit
-+ 	 * radar detection by itself. We can do that later by adding a
-+ 	 * monitor flag interfaces used for AP support.
-+ 	 */
-+-	if ((chan->flags & (IEEE80211_CHAN_NO_IR | IEEE80211_CHAN_RADAR)))
-++	if (!cfg80211_reg_can_beacon(local->hw.wiphy, chandef,
-++				     sdata->vif.type))
-+ 		goto fail_rcu;
-  
-- 	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;
-+-	ieee80211_xmit(sdata, skb, chan->band);
-++	ieee80211_xmit(sdata, skb, chandef->chan->band);
-+ 	rcu_read_unlock();
-  
--+	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
-- 	}
-+ 	return NETDEV_TX_OK;
-+@@ -2425,7 +2428,7 @@ static void ieee80211_set_csa(struct iee
-+ 	u8 *beacon_data;
-+ 	size_t beacon_data_len;
-+ 	int i;
-+-	u8 count = sdata->csa_current_counter;
-++	u8 count = beacon->csa_current_counter;
-  
-- 	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);
-+ 	switch (sdata->vif.type) {
-+ 	case NL80211_IFTYPE_AP:
-+@@ -2444,46 +2447,54 @@ static void ieee80211_set_csa(struct iee
-  		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;
-++	rcu_read_lock();
-+ 	for (i = 0; i < IEEE80211_MAX_CSA_COUNTERS_NUM; ++i) {
-+-		u16 counter_offset_beacon =
-+-			sdata->csa_counter_offset_beacon[i];
-+-		u16 counter_offset_presp = sdata->csa_counter_offset_presp[i];
-+-
-+-		if (counter_offset_beacon) {
-+-			if (WARN_ON(counter_offset_beacon >= beacon_data_len))
-+-				return;
-+-
-+-			beacon_data[counter_offset_beacon] = count;
-+-		}
-+-
-+-		if (sdata->vif.type == NL80211_IFTYPE_AP &&
-+-		    counter_offset_presp) {
-+-			rcu_read_lock();
-+-			resp = rcu_dereference(sdata->u.ap.probe_resp);
-++		resp = rcu_dereference(sdata->u.ap.probe_resp);
-+ 
-+-			/* If nl80211 accepted the offset, this should
-+-			 * not happen.
-+-			 */
-+-			if (WARN_ON(!resp)) {
-++		if (beacon->csa_counter_offsets[i]) {
-++			if (WARN_ON_ONCE(beacon->csa_counter_offsets[i] >=
-++					 beacon_data_len)) {
-+ 				rcu_read_unlock();
-+ 				return;
-+ 			}
-+-			resp->data[counter_offset_presp] = count;
-+-			rcu_read_unlock();
- +
--+	/* avoid excessive retries for probe request to wildcard SSIDs */
--+	if (pos[1] == 0)
--+		IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_CTL_NO_ACK;
-++			beacon_data[beacon->csa_counter_offsets[i]] = count;
-+ 		}
- +
-- 	ieee80211_tx_skb(sdata, skb);
-++		if (sdata->vif.type == NL80211_IFTYPE_AP && resp &&
-++		    resp->csa_counter_offsets)
-++			resp->data[resp->csa_counter_offsets[i]] = count;
-+ 	}
-++	rcu_read_unlock();
-  }
-  
----- 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;
-+ u8 ieee80211_csa_update_counter(struct ieee80211_vif *vif)
-+ {
-+ 	struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
-++	struct beacon_data *beacon = NULL;
-++	u8 count = 0;
-++
-++	rcu_read_lock();
-++
-++	if (sdata->vif.type == NL80211_IFTYPE_AP)
-++		beacon = rcu_dereference(sdata->u.ap.beacon);
-++	else if (sdata->vif.type == NL80211_IFTYPE_ADHOC)
-++		beacon = rcu_dereference(sdata->u.ibss.presp);
-++	else if (ieee80211_vif_is_mesh(&sdata->vif))
-++		beacon = rcu_dereference(sdata->u.mesh.beacon);
-++
-++	if (!beacon)
-++		goto unlock;
-+ 
-+-	sdata->csa_current_counter--;
-++	beacon->csa_current_counter--;
-+ 
-+ 	/* the counter should never reach 0 */
-+-	WARN_ON(!sdata->csa_current_counter);
-++	WARN_ON_ONCE(!beacon->csa_current_counter);
-++	count = beacon->csa_current_counter;
-+ 
-+-	return sdata->csa_current_counter;
-++unlock:
-++	rcu_read_unlock();
-++	return count;
-+ }
-+ EXPORT_SYMBOL(ieee80211_csa_update_counter);
-  
--+	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"
-+@@ -2493,7 +2504,6 @@ bool ieee80211_csa_is_complete(struct ie
-+ 	struct beacon_data *beacon = NULL;
-+ 	u8 *beacon_data;
-+ 	size_t beacon_data_len;
-+-	int counter_beacon = sdata->csa_counter_offset_beacon[0];
-+ 	int ret = false;
-  
-+ 	if (!ieee80211_sdata_running(sdata))
-+@@ -2531,10 +2541,13 @@ bool ieee80211_csa_is_complete(struct ie
-+ 		goto out;
-+ 	}
-  
---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;
-+-	if (WARN_ON(counter_beacon > beacon_data_len))
-++	if (!beacon->csa_counter_offsets[0])
-++		goto out;
-++
-++	if (WARN_ON_ONCE(beacon->csa_counter_offsets[0] > beacon_data_len))
-+ 		goto out;
-  
---	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 (beacon_data[counter_beacon] == 1)
-++	if (beacon_data[beacon->csa_counter_offsets[0]] == 1)
-+ 		ret = true;
-+  out:
-+ 	rcu_read_unlock();
-+@@ -2550,6 +2563,7 @@ __ieee80211_beacon_get(struct ieee80211_
-+ 		       bool is_template)
-+ {
-+ 	struct ieee80211_local *local = hw_to_local(hw);
-++	struct beacon_data *beacon = NULL;
-+ 	struct sk_buff *skb = NULL;
-+ 	struct ieee80211_tx_info *info;
-+ 	struct ieee80211_sub_if_data *sdata = NULL;
-+@@ -2571,10 +2585,10 @@ __ieee80211_beacon_get(struct ieee80211_
-+ 
-+ 	if (sdata->vif.type == NL80211_IFTYPE_AP) {
-+ 		struct ieee80211_if_ap *ap = &sdata->u.ap;
-+-		struct beacon_data *beacon = rcu_dereference(ap->beacon);
-+ 
-++		beacon = rcu_dereference(ap->beacon);
-+ 		if (beacon) {
-+-			if (sdata->vif.csa_active) {
-++			if (beacon->csa_counter_offsets[0]) {
-+ 				if (!is_template)
-+ 					ieee80211_csa_update_counter(vif);
-+ 
-+@@ -2615,37 +2629,37 @@ __ieee80211_beacon_get(struct ieee80211_
-+ 	} else if (sdata->vif.type == NL80211_IFTYPE_ADHOC) {
-+ 		struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
-+ 		struct ieee80211_hdr *hdr;
-+-		struct beacon_data *presp = rcu_dereference(ifibss->presp);
-+ 
-+-		if (!presp)
-++		beacon = rcu_dereference(ifibss->presp);
-++		if (!beacon)
-+ 			goto out;
-  
-- 	if (WARN_ON(!bss))
--@@ -54,21 +54,26 @@ void __cfg80211_ibss_joined(struct net_d
-- #endif
-- }
-+-		if (sdata->vif.csa_active) {
-++		if (beacon->csa_counter_offsets[0]) {
-+ 			if (!is_template)
-+ 				ieee80211_csa_update_counter(vif);
-  
---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;
-+-			ieee80211_set_csa(sdata, presp);
-++			ieee80211_set_csa(sdata, beacon);
-+ 		}
-  
---	trace_cfg80211_ibss_joined(dev, bssid);
--+	trace_cfg80211_ibss_joined(dev, bssid, channel);
--+
--+	if (WARN_ON(!channel))
--+		return;
-+-		skb = dev_alloc_skb(local->tx_headroom + presp->head_len +
-++		skb = dev_alloc_skb(local->tx_headroom + beacon->head_len +
-+ 				    local->hw.extra_beacon_tailroom);
-+ 		if (!skb)
-+ 			goto out;
-+ 		skb_reserve(skb, local->tx_headroom);
-+-		memcpy(skb_put(skb, presp->head_len), presp->head,
-+-		       presp->head_len);
-++		memcpy(skb_put(skb, beacon->head_len), beacon->head,
-++		       beacon->head_len);
-+ 
-+ 		hdr = (struct ieee80211_hdr *) skb->data;
-+ 		hdr->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
-+ 						 IEEE80211_STYPE_BEACON);
-+ 	} else if (ieee80211_vif_is_mesh(&sdata->vif)) {
-+ 		struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
-+-		struct beacon_data *bcn = rcu_dereference(ifmsh->beacon);
-+ 
-+-		if (!bcn)
-++		beacon = rcu_dereference(ifmsh->beacon);
-++		if (!beacon)
-+ 			goto out;
-  
-- 	ev = kzalloc(sizeof(*ev), gfp);
-- 	if (!ev)
-- 		return;
-+-		if (sdata->vif.csa_active) {
-++		if (beacon->csa_counter_offsets[0]) {
-+ 			if (!is_template)
-+ 				/* TODO: For mesh csa_counter is in TU, so
-+ 				 * decrementing it by one isn't correct, but
-+@@ -2654,40 +2668,42 @@ __ieee80211_beacon_get(struct ieee80211_
-+ 				 */
-+ 				ieee80211_csa_update_counter(vif);
-  
-- 	ev->type = EVENT_IBSS_JOINED;
---	memcpy(ev->cr.bssid, bssid, ETH_ALEN);
--+	memcpy(ev->ij.bssid, bssid, ETH_ALEN);
--+	ev->ij.channel = channel;
-+-			ieee80211_set_csa(sdata, bcn);
-++			ieee80211_set_csa(sdata, beacon);
-+ 		}
-  
-- 	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
-+ 		if (ifmsh->sync_ops)
-+-			ifmsh->sync_ops->adjust_tbtt(sdata, bcn);
-++			ifmsh->sync_ops->adjust_tbtt(sdata, beacon);
-+ 
-+ 		skb = dev_alloc_skb(local->tx_headroom +
-+-				    bcn->head_len +
-++				    beacon->head_len +
-+ 				    256 + /* TIM IE */
-+-				    bcn->tail_len +
-++				    beacon->tail_len +
-+ 				    local->hw.extra_beacon_tailroom);
-+ 		if (!skb)
-+ 			goto out;
-+ 		skb_reserve(skb, local->tx_headroom);
-+-		memcpy(skb_put(skb, bcn->head_len), bcn->head, bcn->head_len);
-++		memcpy(skb_put(skb, beacon->head_len), beacon->head,
-++		       beacon->head_len);
-+ 		ieee80211_beacon_add_tim(sdata, &ifmsh->ps, skb, is_template);
-+ 
-+ 		if (offs) {
-+-			offs->tim_offset = bcn->head_len;
-+-			offs->tim_length = skb->len - bcn->head_len;
-++			offs->tim_offset = beacon->head_len;
-++			offs->tim_length = skb->len - beacon->head_len;
-+ 		}
-  
-- 	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))
-- );
-+-		memcpy(skb_put(skb, bcn->tail_len), bcn->tail, bcn->tail_len);
-++		memcpy(skb_put(skb, beacon->tail_len), beacon->tail,
-++		       beacon->tail_len);
-+ 	} else {
-+ 		WARN_ON(1);
-+ 		goto out;
-+ 	}
-  
---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)
-- );
-+ 	/* CSA offsets */
-+-	if (offs) {
-++	if (offs && beacon) {
-+ 		int i;
-+ 
-+ 		for (i = 0; i < IEEE80211_MAX_CSA_COUNTERS_NUM; i++) {
-+-			u16 csa_off = sdata->csa_counter_offset_beacon[i];
-++			u16 csa_off = beacon->csa_counter_offsets[i];
-+ 
-+ 			if (!csa_off)
-+ 				continue;
-+--- a/drivers/net/wireless/rt2x00/rt2800lib.c
-++++ b/drivers/net/wireless/rt2x00/rt2800lib.c
-+@@ -947,6 +947,40 @@ static inline u8 rt2800_get_beacon_offse
-+ 	return BEACON_BASE_TO_OFFSET(rt2800_hw_beacon_base(rt2x00dev, index));
-+ }
-  
--+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)
--+);
-++static void rt2800_update_beacons_setup(struct rt2x00_dev *rt2x00dev)
-++{
-++	struct data_queue *queue = rt2x00dev->bcn;
-++	struct queue_entry *entry;
-++	int i, bcn_num = 0;
-++	u64 off, reg = 0;
-++	u32 bssid_dw1;
- +
-- 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;
-++	/*
-++	 * Setup offsets of all active beacons in BCN_OFFSET{0,1} registers.
-++	 */
-++	for (i = 0; i < queue->limit; i++) {
-++		entry = &queue->entries[i];
-++		if (!test_bit(ENTRY_BCN_ENABLED, &entry->flags))
-++			continue;
-++		off = rt2800_get_beacon_offset(rt2x00dev, entry->entry_idx);
-++		reg |= off << (8 * bcn_num);
-++		bcn_num++;
-++	}
- +
--+			/* 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;
-++	WARN_ON_ONCE(bcn_num != rt2x00dev->intf_beaconing);
- +
--+			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;
-++	rt2800_register_write(rt2x00dev, BCN_OFFSET0, (u32) reg);
-++	rt2800_register_write(rt2x00dev, BCN_OFFSET1, (u32) (reg >> 32));
-++
-++	/*
-++	 * H/W sends up to MAC_BSSID_DW1_BSS_BCN_NUM + 1 consecutive beacons.
-++	 */
-++	rt2800_register_read(rt2x00dev, MAC_BSSID_DW1, &bssid_dw1);
-++	rt2x00_set_field32(&bssid_dw1, MAC_BSSID_DW1_BSS_BCN_NUM,
-++			   bcn_num > 0 ? bcn_num - 1 : 0);
-++	rt2800_register_write(rt2x00dev, MAC_BSSID_DW1, bssid_dw1);
-++}
-++
-+ void rt2800_write_beacon(struct queue_entry *entry, struct txentry_desc *txdesc)
-+ {
-+ 	struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
-+@@ -1003,6 +1037,12 @@ void rt2800_write_beacon(struct queue_en
-+ 
-+ 	rt2800_register_multiwrite(rt2x00dev, beacon_base, entry->skb->data,
-+ 				   entry->skb->len + padding_len);
-++	__set_bit(ENTRY_BCN_ENABLED, &entry->flags);
- +
--+			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;
-- 	}
-++	/*
-++	 * Change global beacons settings.
-++	 */
-++	rt2800_update_beacons_setup(rt2x00dev);
-  
-- 	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;
-+ 	/*
-+ 	 * Restore beaconing state.
-+@@ -1053,8 +1093,13 @@ void rt2800_clear_beacon(struct queue_en
-+ 	 * Clear beacon.
-+ 	 */
-+ 	rt2800_clear_beacon_register(rt2x00dev, entry->entry_idx);
-++	__clear_bit(ENTRY_BCN_ENABLED, &entry->flags);
-  
-- 		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);
-- 	}
-+ 	/*
-++	 * Change global beacons settings.
-++	 */
-++	rt2800_update_beacons_setup(rt2x00dev);
-++	/*
-+ 	 * Restore beaconing state.
-+ 	 */
-+ 	rt2800_register_write(rt2x00dev, BCN_TIME_CFG, orig_reg);
-+@@ -1556,7 +1601,7 @@ void rt2800_config_intf(struct rt2x00_de
-+ 		if (!is_zero_ether_addr((const u8 *)conf->bssid)) {
-+ 			reg = le32_to_cpu(conf->bssid[1]);
-+ 			rt2x00_set_field32(&reg, MAC_BSSID_DW1_BSS_ID_MASK, 3);
-+-			rt2x00_set_field32(&reg, MAC_BSSID_DW1_BSS_BCN_NUM, 7);
-++			rt2x00_set_field32(&reg, MAC_BSSID_DW1_BSS_BCN_NUM, 0);
-+ 			conf->bssid[1] = cpu_to_le32(reg);
-+ 		}
-  
----- 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;
-+@@ -4517,28 +4562,6 @@ static int rt2800_init_registers(struct 
-+ 	if (ret)
-+ 		return ret;
-+ 
-+-	rt2800_register_read(rt2x00dev, BCN_OFFSET0, &reg);
-+-	rt2x00_set_field32(&reg, BCN_OFFSET0_BCN0,
-+-			   rt2800_get_beacon_offset(rt2x00dev, 0));
-+-	rt2x00_set_field32(&reg, BCN_OFFSET0_BCN1,
-+-			   rt2800_get_beacon_offset(rt2x00dev, 1));
-+-	rt2x00_set_field32(&reg, BCN_OFFSET0_BCN2,
-+-			   rt2800_get_beacon_offset(rt2x00dev, 2));
-+-	rt2x00_set_field32(&reg, BCN_OFFSET0_BCN3,
-+-			   rt2800_get_beacon_offset(rt2x00dev, 3));
-+-	rt2800_register_write(rt2x00dev, BCN_OFFSET0, reg);
-+-
-+-	rt2800_register_read(rt2x00dev, BCN_OFFSET1, &reg);
-+-	rt2x00_set_field32(&reg, BCN_OFFSET1_BCN4,
-+-			   rt2800_get_beacon_offset(rt2x00dev, 4));
-+-	rt2x00_set_field32(&reg, BCN_OFFSET1_BCN5,
-+-			   rt2800_get_beacon_offset(rt2x00dev, 5));
-+-	rt2x00_set_field32(&reg, BCN_OFFSET1_BCN6,
-+-			   rt2800_get_beacon_offset(rt2x00dev, 6));
-+-	rt2x00_set_field32(&reg, BCN_OFFSET1_BCN7,
-+-			   rt2800_get_beacon_offset(rt2x00dev, 7));
-+-	rt2800_register_write(rt2x00dev, BCN_OFFSET1, reg);
-+-
-+ 	rt2800_register_write(rt2x00dev, LEGACY_BASIC_RATE, 0x0000013f);
-+ 	rt2800_register_write(rt2x00dev, HT_BASIC_RATE, 0x00008003);
-  
---	if (WARN_ON(!wdev->channel))
--+	if (WARN_ON(!wdev->chandef.chan))
-+--- a/drivers/net/wireless/rt2x00/rt2x00dev.c
-++++ b/drivers/net/wireless/rt2x00/rt2x00dev.c
-+@@ -141,8 +141,11 @@ static void rt2x00lib_intf_scheduled_ite
-+ 	if (!test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))
-  		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;
-+-	if (test_and_clear_bit(DELAYED_UPDATE_BEACON, &intf->delayed_flags))
-++	if (test_and_clear_bit(DELAYED_UPDATE_BEACON, &intf->delayed_flags)) {
-++		mutex_lock(&intf->beacon_skb_mutex);
-+ 		rt2x00queue_update_beacon(rt2x00dev, vif);
-++		mutex_unlock(&intf->beacon_skb_mutex);
-++	}
-  }
-  
----- 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];
-- };
-+ static void rt2x00lib_intf_scheduled(struct work_struct *work)
-+@@ -216,7 +219,7 @@ static void rt2x00lib_beaconupdate_iter(
-+ 	 * never be called for USB devices.
-+ 	 */
-+ 	WARN_ON(rt2x00_is_usb(rt2x00dev));
-+-	rt2x00queue_update_beacon_locked(rt2x00dev, vif);
-++	rt2x00queue_update_beacon(rt2x00dev, vif);
-+ }
-  
--@@ -800,7 +801,7 @@ static bool ar9003_hw_calc_iq_corr(struc
-- 	if (q_q_coff > 63)
-- 		q_q_coff = 63;
-+ void rt2x00lib_beacondone(struct rt2x00_dev *rt2x00dev)
-+--- a/drivers/net/wireless/rt2x00/rt2x00mac.c
-++++ b/drivers/net/wireless/rt2x00/rt2x00mac.c
-+@@ -624,25 +624,24 @@ void rt2x00mac_bss_info_changed(struct i
-+ 	 * Start/stop beaconing.
-+ 	 */
-+ 	if (changes & BSS_CHANGED_BEACON_ENABLED) {
-++		mutex_lock(&intf->beacon_skb_mutex);
-+ 		if (!bss_conf->enable_beacon && intf->enable_beacon) {
-+ 			rt2x00dev->intf_beaconing--;
-+ 			intf->enable_beacon = false;
-+-			/*
-+-			 * Clear beacon in the H/W for this vif. This is needed
-+-			 * to disable beaconing on this particular interface
-+-			 * and keep it running on other interfaces.
-+-			 */
-+-			rt2x00queue_clear_beacon(rt2x00dev, vif);
-  
---	iqc_coeff[0] = (q_q_coff * 128) + q_i_coff;
--+	iqc_coeff[0] = (q_q_coff * 128) + (0x7f & q_i_coff);
-+ 			if (rt2x00dev->intf_beaconing == 0) {
-+ 				/*
-+ 				 * Last beaconing interface disabled
-+ 				 * -> stop beacon queue.
-+ 				 */
-+-				mutex_lock(&intf->beacon_skb_mutex);
-+ 				rt2x00queue_stop_queue(rt2x00dev->bcn);
-+-				mutex_unlock(&intf->beacon_skb_mutex);
-+ 			}
-++			/*
-++			 * Clear beacon in the H/W for this vif. This is needed
-++			 * to disable beaconing on this particular interface
-++			 * and keep it running on other interfaces.
-++			 */
-++			rt2x00queue_clear_beacon(rt2x00dev, vif);
-+ 		} else if (bss_conf->enable_beacon && !intf->enable_beacon) {
-+ 			rt2x00dev->intf_beaconing++;
-+ 			intf->enable_beacon = true;
-+@@ -658,11 +657,10 @@ void rt2x00mac_bss_info_changed(struct i
-+ 				 * First beaconing interface enabled
-+ 				 * -> start beacon queue.
-+ 				 */
-+-				mutex_lock(&intf->beacon_skb_mutex);
-+ 				rt2x00queue_start_queue(rt2x00dev->bcn);
-+-				mutex_unlock(&intf->beacon_skb_mutex);
-+ 			}
-+ 		}
-++		mutex_unlock(&intf->beacon_skb_mutex);
-+ 	}
-  
-- 	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;
-+ 	/*
-+--- a/drivers/net/wireless/rt2x00/rt2x00queue.c
-++++ b/drivers/net/wireless/rt2x00/rt2x00queue.c
-+@@ -754,8 +754,6 @@ int rt2x00queue_clear_beacon(struct rt2x
-+ 	if (unlikely(!intf->beacon))
-+ 		return -ENOBUFS;
-  
---	iqc_coeff[1] = (q_q_coff * 128) + q_i_coff;
--+	iqc_coeff[1] = (q_q_coff * 128) + (0x7f & q_i_coff);
-+-	mutex_lock(&intf->beacon_skb_mutex);
-+-
-+ 	/*
-+ 	 * Clean up the beacon skb.
-+ 	 */
-+@@ -768,13 +766,11 @@ int rt2x00queue_clear_beacon(struct rt2x
-+ 	if (rt2x00dev->ops->lib->clear_beacon)
-+ 		rt2x00dev->ops->lib->clear_beacon(intf->beacon);
-  
-- 	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;
-+-	mutex_unlock(&intf->beacon_skb_mutex);
-+-
-+ 	return 0;
-  }
-  
---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 rt2x00queue_update_beacon_locked(struct rt2x00_dev *rt2x00dev,
-+-				     struct ieee80211_vif *vif)
-++int rt2x00queue_update_beacon(struct rt2x00_dev *rt2x00dev,
-++			      struct ieee80211_vif *vif)
-  {
-- 	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;
-- 		}
-- 	}
-+ 	struct rt2x00_intf *intf = vif_to_intf(vif);
-+ 	struct skb_frame_desc *skbdesc;
-+@@ -815,19 +811,6 @@ int rt2x00queue_update_beacon_locked(str
-  
-- 	/* 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);
-+-int rt2x00queue_update_beacon(struct rt2x00_dev *rt2x00dev,
-+-			      struct ieee80211_vif *vif)
-+-{
-+-	struct rt2x00_intf *intf = vif_to_intf(vif);
-+-	int ret;
- -
---			/* 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];
-+-	mutex_lock(&intf->beacon_skb_mutex);
-+-	ret = rt2x00queue_update_beacon_locked(rt2x00dev, vif);
-+-	mutex_unlock(&intf->beacon_skb_mutex);
-+-
-+-	return ret;
-+-}
-+-
-+ bool rt2x00queue_for_each_entry(struct data_queue *queue,
-+ 				enum queue_index start,
-+ 				enum queue_index end,
-+--- a/drivers/net/wireless/rt2x00/rt2x00queue.h
-++++ b/drivers/net/wireless/rt2x00/rt2x00queue.h
-+@@ -353,6 +353,7 @@ struct txentry_desc {
-+  */
-+ enum queue_entry_flags {
-+ 	ENTRY_BCN_ASSIGNED,
-++	ENTRY_BCN_ENABLED,
-+ 	ENTRY_OWNER_DEVICE_DATA,
-+ 	ENTRY_DATA_PENDING,
-+ 	ENTRY_DATA_IO_FAILED,
-+--- a/drivers/net/wireless/ath/ath9k/main.c
-++++ b/drivers/net/wireless/ath/ath9k/main.c
-+@@ -1757,7 +1757,6 @@ out:
-+ 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;
-  
---			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 (!sc->p2p_ps_timer)
-+@@ -1767,14 +1766,9 @@ void ath9k_update_p2p_ps(struct ath_soft
-+ 		return;
-  
-- 			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;
-+ 	sc->p2p_ps_vif = 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);
-++	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);
-  }
-  
---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)
-- {
-+ static void ath9k_bss_info_changed(struct ieee80211_hw *hw,
-+@@ -1791,6 +1785,7 @@ static void ath9k_bss_info_changed(struc
-+ 	struct ath_hw *ah = sc->sc_ah;
-  	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;
-- 		}
-+ 	struct ath_vif *avp = (void *)vif->drv_priv;
-++	unsigned long flags;
-+ 	int slottime;
-+ 
-+ 	ath9k_ps_wakeup(sc);
-+@@ -1853,7 +1848,10 @@ static void ath9k_bss_info_changed(struc
-+ 
-+ 	if (changed & BSS_CHANGED_P2P_PS) {
-+ 		spin_lock_bh(&sc->sc_pcu_lock);
-+-		ath9k_update_p2p_ps(sc, vif);
-++		spin_lock_irqsave(&sc->sc_pm_lock, flags);
-++		if (!(sc->ps_flags & PS_BEACON_SYNC))
-++			ath9k_update_p2p_ps(sc, vif);
-++		spin_unlock_irqrestore(&sc->sc_pm_lock, flags);
-+ 		spin_unlock_bh(&sc->sc_pcu_lock);
-  	}
---	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:
-- 	}
-+@@ -2232,14 +2230,6 @@ static void ath9k_sw_scan_complete(struc
-+ 	clear_bit(ATH_OP_SCANNING, &common->op_flags);
-+ }
-  
-- 	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);
-+-static void ath9k_channel_switch_beacon(struct ieee80211_hw *hw,
-+-					struct ieee80211_vif *vif,
-+-					struct cfg80211_chan_def *chandef)
-+-{
-+-	/* depend on vif->csa_active only */
-+-	return;
-+-}
-+-
-+ struct ieee80211_ops ath9k_ops = {
-+ 	.tx 		    = ath9k_tx,
-+ 	.start 		    = ath9k_start,
-+@@ -2287,5 +2277,4 @@ struct ieee80211_ops ath9k_ops = {
-+ #endif
-+ 	.sw_scan_start	    = ath9k_sw_scan_start,
-+ 	.sw_scan_complete   = ath9k_sw_scan_complete,
-+-	.channel_switch_beacon     = ath9k_channel_switch_beacon,
-+ };
-+--- a/drivers/net/wireless/ath/ath10k/mac.c
-++++ b/drivers/net/wireless/ath/ath10k/mac.c
-+@@ -4142,14 +4142,6 @@ static int ath10k_set_bitrate_mask(struc
-+ 					   fixed_nss, force_sgi);
-+ }
-  
--@@ -1455,14 +1530,38 @@ skip_tx_iqcal:
-- 	return true;
-+-static void ath10k_channel_switch_beacon(struct ieee80211_hw *hw,
-+-					 struct ieee80211_vif *vif,
-+-					 struct cfg80211_chan_def *chandef)
-+-{
-+-	/* there's no need to do anything here. vif->csa_active is enough */
-+-	return;
-+-}
-+-
-+ static void ath10k_sta_rc_update(struct ieee80211_hw *hw,
-+ 				 struct ieee80211_vif *vif,
-+ 				 struct ieee80211_sta *sta,
-+@@ -4256,7 +4248,6 @@ static const struct ieee80211_ops ath10k
-+ 	.restart_complete		= ath10k_restart_complete,
-+ 	.get_survey			= ath10k_get_survey,
-+ 	.set_bitrate_mask		= ath10k_set_bitrate_mask,
-+-	.channel_switch_beacon		= ath10k_channel_switch_beacon,
-+ 	.sta_rc_update			= ath10k_sta_rc_update,
-+ 	.get_tsf			= ath10k_get_tsf,
-+ #ifdef CONFIG_PM
-+--- a/net/mac80211/cfg.c
-++++ b/net/mac80211/cfg.c
-+@@ -468,327 +468,6 @@ void sta_set_rate_info_rx(struct sta_inf
-+ 		rinfo->flags |= RATE_INFO_FLAGS_160_MHZ_WIDTH;
-  }
-  
--+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);
-+-static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo)
-+-{
-+-	struct ieee80211_sub_if_data *sdata = sta->sdata;
-+-	struct ieee80211_local *local = sdata->local;
-+-	struct rate_control_ref *ref = local->rate_ctrl;
-+-	struct timespec uptime;
-+-	u64 packets = 0;
-+-	u32 thr = 0;
-+-	int i, ac;
-+-
-+-	sinfo->generation = sdata->local->sta_generation;
-+-
-+-	sinfo->filled = STATION_INFO_INACTIVE_TIME |
-+-			STATION_INFO_RX_BYTES64 |
-+-			STATION_INFO_TX_BYTES64 |
-+-			STATION_INFO_RX_PACKETS |
-+-			STATION_INFO_TX_PACKETS |
-+-			STATION_INFO_TX_RETRIES |
-+-			STATION_INFO_TX_FAILED |
-+-			STATION_INFO_TX_BITRATE |
-+-			STATION_INFO_RX_BITRATE |
-+-			STATION_INFO_RX_DROP_MISC |
-+-			STATION_INFO_BSS_PARAM |
-+-			STATION_INFO_CONNECTED_TIME |
-+-			STATION_INFO_STA_FLAGS |
-+-			STATION_INFO_BEACON_LOSS_COUNT;
- -
---		/* Poll for offset calibration complete */
---		status = ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL,
---				       AR_PHY_AGC_CONTROL_CAL,
---				       0, AH_WAIT_TIMEOUT);
-+-	do_posix_clock_monotonic_gettime(&uptime);
-+-	sinfo->connected_time = uptime.tv_sec - sta->last_connected;
-+-
-+-	sinfo->inactive_time = jiffies_to_msecs(jiffies - sta->last_rx);
-+-	sinfo->tx_bytes = 0;
-+-	for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) {
-+-		sinfo->tx_bytes += sta->tx_bytes[ac];
-+-		packets += sta->tx_packets[ac];
- -	}
--+		/*
--+		 * 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);
-+-	sinfo->tx_packets = packets;
-+-	sinfo->rx_bytes = sta->rx_bytes;
-+-	sinfo->rx_packets = sta->rx_packets;
-+-	sinfo->tx_retries = sta->tx_retry_count;
-+-	sinfo->tx_failed = sta->tx_retry_failed;
-+-	sinfo->rx_dropped_misc = sta->rx_dropped;
-+-	sinfo->beacon_loss_count = sta->beacon_loss_count;
-+-
-+-	if ((sta->local->hw.flags & IEEE80211_HW_SIGNAL_DBM) ||
-+-	    (sta->local->hw.flags & IEEE80211_HW_SIGNAL_UNSPEC)) {
-+-		sinfo->filled |= STATION_INFO_SIGNAL | STATION_INFO_SIGNAL_AVG;
-+-		if (!local->ops->get_rssi ||
-+-		    drv_get_rssi(local, sdata, &sta->sta, &sinfo->signal))
-+-			sinfo->signal = (s8)sta->last_signal;
-+-		sinfo->signal_avg = (s8) -ewma_read(&sta->avg_signal);
-+-	}
-+-	if (sta->chains) {
-+-		sinfo->filled |= STATION_INFO_CHAIN_SIGNAL |
-+-				 STATION_INFO_CHAIN_SIGNAL_AVG;
-+-
-+-		sinfo->chains = sta->chains;
-+-		for (i = 0; i < ARRAY_SIZE(sinfo->chain_signal); i++) {
-+-			sinfo->chain_signal[i] = sta->chain_signal_last[i];
-+-			sinfo->chain_signal_avg[i] =
-+-				(s8) -ewma_read(&sta->chain_signal_avg[i]);
-+-		}
-+-	}
-+-
-+-	sta_set_rate_info_tx(sta, &sta->last_tx_rate, &sinfo->txrate);
-+-	sta_set_rate_info_rx(sta, &sinfo->rxrate);
-+-
-+-	if (ieee80211_vif_is_mesh(&sdata->vif)) {
-+-#ifdef CPTCFG_MAC80211_MESH
-+-		sinfo->filled |= STATION_INFO_LLID |
-+-				 STATION_INFO_PLID |
-+-				 STATION_INFO_PLINK_STATE |
-+-				 STATION_INFO_LOCAL_PM |
-+-				 STATION_INFO_PEER_PM |
-+-				 STATION_INFO_NONPEER_PM;
-+-
-+-		sinfo->llid = sta->llid;
-+-		sinfo->plid = sta->plid;
-+-		sinfo->plink_state = sta->plink_state;
-+-		if (test_sta_flag(sta, WLAN_STA_TOFFSET_KNOWN)) {
-+-			sinfo->filled |= STATION_INFO_T_OFFSET;
-+-			sinfo->t_offset = sta->t_offset;
-+-		}
-+-		sinfo->local_pm = sta->local_pm;
-+-		sinfo->peer_pm = sta->peer_pm;
-+-		sinfo->nonpeer_pm = sta->nonpeer_pm;
-+-#endif
-+-	}
-+-
-+-	sinfo->bss_param.flags = 0;
-+-	if (sdata->vif.bss_conf.use_cts_prot)
-+-		sinfo->bss_param.flags |= BSS_PARAM_FLAGS_CTS_PROT;
-+-	if (sdata->vif.bss_conf.use_short_preamble)
-+-		sinfo->bss_param.flags |= BSS_PARAM_FLAGS_SHORT_PREAMBLE;
-+-	if (sdata->vif.bss_conf.use_short_slot)
-+-		sinfo->bss_param.flags |= BSS_PARAM_FLAGS_SHORT_SLOT_TIME;
-+-	sinfo->bss_param.dtim_period = sdata->local->hw.conf.ps_dtim_period;
-+-	sinfo->bss_param.beacon_interval = sdata->vif.bss_conf.beacon_int;
-+-
-+-	sinfo->sta_flags.set = 0;
-+-	sinfo->sta_flags.mask = BIT(NL80211_STA_FLAG_AUTHORIZED) |
-+-				BIT(NL80211_STA_FLAG_SHORT_PREAMBLE) |
-+-				BIT(NL80211_STA_FLAG_WME) |
-+-				BIT(NL80211_STA_FLAG_MFP) |
-+-				BIT(NL80211_STA_FLAG_AUTHENTICATED) |
-+-				BIT(NL80211_STA_FLAG_ASSOCIATED) |
-+-				BIT(NL80211_STA_FLAG_TDLS_PEER);
-+-	if (test_sta_flag(sta, WLAN_STA_AUTHORIZED))
-+-		sinfo->sta_flags.set |= BIT(NL80211_STA_FLAG_AUTHORIZED);
-+-	if (test_sta_flag(sta, WLAN_STA_SHORT_PREAMBLE))
-+-		sinfo->sta_flags.set |= BIT(NL80211_STA_FLAG_SHORT_PREAMBLE);
-+-	if (test_sta_flag(sta, WLAN_STA_WME))
-+-		sinfo->sta_flags.set |= BIT(NL80211_STA_FLAG_WME);
-+-	if (test_sta_flag(sta, WLAN_STA_MFP))
-+-		sinfo->sta_flags.set |= BIT(NL80211_STA_FLAG_MFP);
-+-	if (test_sta_flag(sta, WLAN_STA_AUTH))
-+-		sinfo->sta_flags.set |= BIT(NL80211_STA_FLAG_AUTHENTICATED);
-+-	if (test_sta_flag(sta, WLAN_STA_ASSOC))
-+-		sinfo->sta_flags.set |= BIT(NL80211_STA_FLAG_ASSOCIATED);
-+-	if (test_sta_flag(sta, WLAN_STA_TDLS_PEER))
-+-		sinfo->sta_flags.set |= BIT(NL80211_STA_FLAG_TDLS_PEER);
-+-
-+-	/* check if the driver has a SW RC implementation */
-+-	if (ref && ref->ops->get_expected_throughput)
-+-		thr = ref->ops->get_expected_throughput(sta->rate_ctrl_priv);
-+-	else
-+-		thr = drv_get_expected_throughput(local, &sta->sta);
-+-
-+-	if (thr != 0) {
-+-		sinfo->filled |= STATION_INFO_EXPECTED_THROUGHPUT;
-+-		sinfo->expected_throughput = thr;
-+-	}
-+-}
-+-
-+-static const char ieee80211_gstrings_sta_stats[][ETH_GSTRING_LEN] = {
-+-	"rx_packets", "rx_bytes", "wep_weak_iv_count",
-+-	"rx_duplicates", "rx_fragments", "rx_dropped",
-+-	"tx_packets", "tx_bytes", "tx_fragments",
-+-	"tx_filtered", "tx_retry_failed", "tx_retries",
-+-	"beacon_loss", "sta_state", "txrate", "rxrate", "signal",
-+-	"channel", "noise", "ch_time", "ch_time_busy",
-+-	"ch_time_ext_busy", "ch_time_rx", "ch_time_tx"
-+-};
-+-#define STA_STATS_LEN	ARRAY_SIZE(ieee80211_gstrings_sta_stats)
-+-
-+-static int ieee80211_get_et_sset_count(struct wiphy *wiphy,
-+-				       struct net_device *dev,
-+-				       int sset)
-+-{
-+-	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
-+-	int rv = 0;
-+-
-+-	if (sset == ETH_SS_STATS)
-+-		rv += STA_STATS_LEN;
-+-
-+-	rv += drv_get_et_sset_count(sdata, sset);
-+-
-+-	if (rv == 0)
-+-		return -EOPNOTSUPP;
-+-	return rv;
-+-}
-+-
-+-static void ieee80211_get_et_stats(struct wiphy *wiphy,
-+-				   struct net_device *dev,
-+-				   struct ethtool_stats *stats,
-+-				   u64 *data)
-+-{
-+-	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
-+-	struct ieee80211_chanctx_conf *chanctx_conf;
-+-	struct ieee80211_channel *channel;
-+-	struct sta_info *sta;
-+-	struct ieee80211_local *local = sdata->local;
-+-	struct station_info sinfo;
-+-	struct survey_info survey;
-+-	int i, q;
-+-#define STA_STATS_SURVEY_LEN 7
-+-
-+-	memset(data, 0, sizeof(u64) * STA_STATS_LEN);
-+-
-+-#define ADD_STA_STATS(sta)				\
-+-	do {						\
-+-		data[i++] += sta->rx_packets;		\
-+-		data[i++] += sta->rx_bytes;		\
-+-		data[i++] += sta->wep_weak_iv_count;	\
-+-		data[i++] += sta->num_duplicates;	\
-+-		data[i++] += sta->rx_fragments;		\
-+-		data[i++] += sta->rx_dropped;		\
-+-							\
-+-		data[i++] += sinfo.tx_packets;		\
-+-		data[i++] += sinfo.tx_bytes;		\
-+-		data[i++] += sta->tx_fragments;		\
-+-		data[i++] += sta->tx_filtered_count;	\
-+-		data[i++] += sta->tx_retry_failed;	\
-+-		data[i++] += sta->tx_retry_count;	\
-+-		data[i++] += sta->beacon_loss_count;	\
-+-	} while (0)
-+-
-+-	/* For Managed stations, find the single station based on BSSID
-+-	 * and use that.  For interface types, iterate through all available
-+-	 * stations and add stats for any station that is assigned to this
-+-	 * network device.
-+-	 */
-+-
-+-	mutex_lock(&local->sta_mtx);
-+-
-+-	if (sdata->vif.type == NL80211_IFTYPE_STATION) {
-+-		sta = sta_info_get_bss(sdata, sdata->u.mgd.bssid);
-+-
-+-		if (!(sta && !WARN_ON(sta->sdata->dev != dev)))
-+-			goto do_survey;
-+-
-+-		sinfo.filled = 0;
-+-		sta_set_sinfo(sta, &sinfo);
-+-
-+-		i = 0;
-+-		ADD_STA_STATS(sta);
-+-
-+-		data[i++] = sta->sta_state;
-+-
-+-
-+-		if (sinfo.filled & STATION_INFO_TX_BITRATE)
-+-			data[i] = 100000 *
-+-				cfg80211_calculate_bitrate(&sinfo.txrate);
-+-		i++;
-+-		if (sinfo.filled & STATION_INFO_RX_BITRATE)
-+-			data[i] = 100000 *
-+-				cfg80211_calculate_bitrate(&sinfo.rxrate);
-+-		i++;
-+-
-+-		if (sinfo.filled & STATION_INFO_SIGNAL_AVG)
-+-			data[i] = (u8)sinfo.signal_avg;
-+-		i++;
-+-	} else {
-+-		list_for_each_entry(sta, &local->sta_list, list) {
-+-			/* Make sure this station belongs to the proper dev */
-+-			if (sta->sdata->dev != dev)
-+-				continue;
-+-
-+-			sinfo.filled = 0;
-+-			sta_set_sinfo(sta, &sinfo);
-+-			i = 0;
-+-			ADD_STA_STATS(sta);
-+-		}
-+-	}
-+-
-+-do_survey:
-+-	i = STA_STATS_LEN - STA_STATS_SURVEY_LEN;
-+-	/* Get survey stats for current channel */
-+-	survey.filled = 0;
-+-
-+-	rcu_read_lock();
-+-	chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf);
-+-	if (chanctx_conf)
-+-		channel = chanctx_conf->def.chan;
-+-	else
-+-		channel = NULL;
-+-	rcu_read_unlock();
- -
-- 	/* Revert chainmask to runtime parameters */
-- 	ar9003_hw_set_chain_masks(ah, ah->rxchainmask, ah->txchainmask);
-+-	if (channel) {
-+-		q = 0;
-+-		do {
-+-			survey.filled = 0;
-+-			if (drv_get_survey(local, q, &survey) != 0) {
-+-				survey.filled = 0;
-+-				break;
-+-			}
-+-			q++;
-+-		} while (channel != survey.channel);
-+-	}
-+-
-+-	if (survey.filled)
-+-		data[i++] = survey.channel->center_freq;
-+-	else
-+-		data[i++] = 0;
-+-	if (survey.filled & SURVEY_INFO_NOISE_DBM)
-+-		data[i++] = (u8)survey.noise;
-+-	else
-+-		data[i++] = -1LL;
-+-	if (survey.filled & SURVEY_INFO_CHANNEL_TIME)
-+-		data[i++] = survey.channel_time;
-+-	else
-+-		data[i++] = -1LL;
-+-	if (survey.filled & SURVEY_INFO_CHANNEL_TIME_BUSY)
-+-		data[i++] = survey.channel_time_busy;
-+-	else
-+-		data[i++] = -1LL;
-+-	if (survey.filled & SURVEY_INFO_CHANNEL_TIME_EXT_BUSY)
-+-		data[i++] = survey.channel_time_ext_busy;
-+-	else
-+-		data[i++] = -1LL;
-+-	if (survey.filled & SURVEY_INFO_CHANNEL_TIME_RX)
-+-		data[i++] = survey.channel_time_rx;
-+-	else
-+-		data[i++] = -1LL;
-+-	if (survey.filled & SURVEY_INFO_CHANNEL_TIME_TX)
-+-		data[i++] = survey.channel_time_tx;
-+-	else
-+-		data[i++] = -1LL;
-+-
-+-	mutex_unlock(&local->sta_mtx);
-+-
-+-	if (WARN_ON(i != STA_STATS_LEN))
-+-		return;
-+-
-+-	drv_get_et_stats(sdata, stats, &(data[STA_STATS_LEN]));
-+-}
-+-
-+-static void ieee80211_get_et_strings(struct wiphy *wiphy,
-+-				     struct net_device *dev,
-+-				     u32 sset, u8 *data)
-+-{
-+-	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
-+-	int sz_sta_stats = 0;
-+-
-+-	if (sset == ETH_SS_STATS) {
-+-		sz_sta_stats = sizeof(ieee80211_gstrings_sta_stats);
-+-		memcpy(data, ieee80211_gstrings_sta_stats, sz_sta_stats);
-+-	}
-+-	drv_get_et_strings(sdata, sset, &(data[sz_sta_stats]));
-+-}
-+-
-+ static int ieee80211_dump_station(struct wiphy *wiphy, struct net_device *dev,
-+ 				  int idx, u8 *mac, struct station_info *sinfo)
-+ {
-+@@ -875,7 +554,8 @@ static int ieee80211_set_monitor_channel
-+ }
-+ 
-+ static int ieee80211_set_probe_resp(struct ieee80211_sub_if_data *sdata,
-+-				    const u8 *resp, size_t resp_len)
-++				    const u8 *resp, size_t resp_len,
-++				    const struct ieee80211_csa_settings *csa)
-+ {
-+ 	struct probe_resp *new, *old;
-  
----- 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
-+@@ -891,6 +571,11 @@ static int ieee80211_set_probe_resp(stru
-+ 	new->len = resp_len;
-+ 	memcpy(new->data, resp, resp_len);
-  
--+#include <linux/cache.h>
-++	if (csa)
-++		memcpy(new->csa_counter_offsets, csa->counter_offsets_presp,
-++		       csa->n_counter_offsets_presp *
-++		       sizeof(new->csa_counter_offsets[0]));
- +
-- #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;
-- 	}
-+ 	rcu_assign_pointer(sdata->u.ap.probe_resp, new);
-+ 	if (old)
-+ 		kfree_rcu(old, rcu_head);
-+@@ -899,7 +584,8 @@ static int ieee80211_set_probe_resp(stru
-+ }
-  
--+	if (skb->protocol == sdata->control_port_protocol) {
--+		skb->priority = 7;
--+		return ieee80211_downgrade_queue(sdata, skb);
-+ static int ieee80211_assign_beacon(struct ieee80211_sub_if_data *sdata,
-+-				   struct cfg80211_beacon_data *params)
-++				   struct cfg80211_beacon_data *params,
-++				   const struct ieee80211_csa_settings *csa)
-+ {
-+ 	struct beacon_data *new, *old;
-+ 	int new_head_len, new_tail_len;
-+@@ -943,6 +629,13 @@ static int ieee80211_assign_beacon(struc
-+ 	new->head_len = new_head_len;
-+ 	new->tail_len = new_tail_len;
-+ 
-++	if (csa) {
-++		new->csa_current_counter = csa->count;
-++		memcpy(new->csa_counter_offsets, csa->counter_offsets_beacon,
-++		       csa->n_counter_offsets_beacon *
-++		       sizeof(new->csa_counter_offsets[0]));
- +	}
- +
-- 	/* 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;
-+ 	/* copy in head */
-+ 	if (params->head)
-+ 		memcpy(new->head, params->head, new_head_len);
-+@@ -957,7 +650,7 @@ static int ieee80211_assign_beacon(struc
-+ 			memcpy(new->tail, old->tail, new_tail_len);
-  
-- 		ath_txq_lock(sc, txq);
-+ 	err = ieee80211_set_probe_resp(sdata, params->probe_resp,
-+-				       params->probe_resp_len);
-++				       params->probe_resp_len, csa);
-+ 	if (err < 0)
-+ 		return err;
-+ 	if (err == 0)
-+@@ -1042,7 +735,7 @@ static int ieee80211_start_ap(struct wip
-+ 		sdata->vif.bss_conf.p2p_noa_attr.oppps_ctwindow |=
-+ 					IEEE80211_P2P_OPPPS_ENABLE_BIT;
-  
--+		if (!tid->sched) {
--+			ath_txq_unlock(sc, txq);
--+			continue;
--+		}
--+
-- 		buffered = ath_tid_has_buffered(tid);
-+-	err = ieee80211_assign_beacon(sdata, &params->beacon);
-++	err = ieee80211_assign_beacon(sdata, &params->beacon, NULL);
-+ 	if (err < 0) {
-+ 		ieee80211_vif_release_channel(sdata);
-+ 		return err;
-+@@ -1090,7 +783,7 @@ static int ieee80211_change_beacon(struc
-+ 	if (!old)
-+ 		return -ENOENT;
-  
-- 		tid->sched = false;
--@@ -1696,7 +1698,7 @@ int ath_cabq_update(struct ath_softc *sc
-+-	err = ieee80211_assign_beacon(sdata, params);
-++	err = ieee80211_assign_beacon(sdata, params, NULL);
-+ 	if (err < 0)
-+ 		return err;
-+ 	ieee80211_bss_info_change_notify(sdata, err);
-+@@ -3073,7 +2766,8 @@ static int ieee80211_set_after_csa_beaco
-  
-- 	ath9k_hw_get_txq_props(sc->sc_ah, qnum, &qi);
-+ 	switch (sdata->vif.type) {
-+ 	case NL80211_IFTYPE_AP:
-+-		err = ieee80211_assign_beacon(sdata, sdata->u.ap.next_beacon);
-++		err = ieee80211_assign_beacon(sdata, sdata->u.ap.next_beacon,
-++					      NULL);
-+ 		kfree(sdata->u.ap.next_beacon);
-+ 		sdata->u.ap.next_beacon = NULL;
-+ 
-+@@ -3176,6 +2870,7 @@ static int ieee80211_set_csa_beacon(stru
-+ 				    struct cfg80211_csa_settings *params,
-+ 				    u32 *changed)
-+ {
-++	struct ieee80211_csa_settings csa = {};
-+ 	int err;
-  
---	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);
-+ 	switch (sdata->vif.type) {
-+@@ -3210,20 +2905,13 @@ static int ieee80211_set_csa_beacon(stru
-+ 		     IEEE80211_MAX_CSA_COUNTERS_NUM))
-+ 			return -EINVAL;
-  
--@@ -2061,7 +2063,7 @@ static struct ath_buf *ath_tx_setup_buff
-+-		/* make sure we don't have garbage in other counters */
-+-		memset(sdata->csa_counter_offset_beacon, 0,
-+-		       sizeof(sdata->csa_counter_offset_beacon));
-+-		memset(sdata->csa_counter_offset_presp, 0,
-+-		       sizeof(sdata->csa_counter_offset_presp));
-+-
-+-		memcpy(sdata->csa_counter_offset_beacon,
-+-		       params->counter_offsets_beacon,
-+-		       params->n_counter_offsets_beacon * sizeof(u16));
-+-		memcpy(sdata->csa_counter_offset_presp,
-+-		       params->counter_offsets_presp,
-+-		       params->n_counter_offsets_presp * sizeof(u16));
-++		csa.counter_offsets_beacon = params->counter_offsets_beacon;
-++		csa.counter_offsets_presp = params->counter_offsets_presp;
-++		csa.n_counter_offsets_beacon = params->n_counter_offsets_beacon;
-++		csa.n_counter_offsets_presp = params->n_counter_offsets_presp;
-++		csa.count = params->count;
-+ 
-+-		err = ieee80211_assign_beacon(sdata, &params->beacon_csa);
-++		err = ieee80211_assign_beacon(sdata, &params->beacon_csa, &csa);
-+ 		if (err < 0) {
-+ 			kfree(sdata->u.ap.next_beacon);
-+ 			return err;
-+@@ -3367,7 +3055,6 @@ __ieee80211_channel_switch(struct wiphy 
-+ 	sdata->csa_radar_required = params->radar_required;
-+ 	sdata->csa_chandef = params->chandef;
-+ 	sdata->csa_block_tx = params->block_tx;
-+-	sdata->csa_current_counter = params->count;
-+ 	sdata->vif.csa_active = true;
-+ 
-+ 	if (sdata->csa_block_tx)
-+@@ -3515,10 +3202,23 @@ static int ieee80211_mgmt_tx(struct wiph
-+ 	     sdata->vif.type == NL80211_IFTYPE_ADHOC) &&
-+ 	    params->n_csa_offsets) {
-+ 		int i;
-+-		u8 c = sdata->csa_current_counter;
-++		struct beacon_data *beacon = NULL;
-++
-++		rcu_read_lock();
-+ 
-+-		for (i = 0; i < params->n_csa_offsets; i++)
-+-			data[params->csa_offsets[i]] = c;
-++		if (sdata->vif.type == NL80211_IFTYPE_AP)
-++			beacon = rcu_dereference(sdata->u.ap.beacon);
-++		else if (sdata->vif.type == NL80211_IFTYPE_ADHOC)
-++			beacon = rcu_dereference(sdata->u.ibss.presp);
-++		else if (ieee80211_vif_is_mesh(&sdata->vif))
-++			beacon = rcu_dereference(sdata->u.mesh.beacon);
-++
-++		if (beacon)
-++			for (i = 0; i < params->n_csa_offsets; i++)
-++				data[params->csa_offsets[i]] =
-++					beacon->csa_current_counter;
-++
-++		rcu_read_unlock();
-+ 	}
-  
-- 	ATH_TXBUF_RESET(bf);
-+ 	IEEE80211_SKB_CB(skb)->flags = flags;
-+@@ -3598,21 +3298,6 @@ static int ieee80211_get_antenna(struct 
-+ 	return drv_get_antenna(local, tx_ant, rx_ant);
-+ }
-  
---	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;
-- 	}
-+-static int ieee80211_set_ringparam(struct wiphy *wiphy, u32 tx, u32 rx)
-+-{
-+-	struct ieee80211_local *local = wiphy_priv(wiphy);
-+-
-+-	return drv_set_ringparam(local, tx, rx);
-+-}
-+-
-+-static void ieee80211_get_ringparam(struct wiphy *wiphy,
-+-				    u32 *tx, u32 *tx_max, u32 *rx, u32 *rx_max)
-+-{
-+-	struct ieee80211_local *local = wiphy_priv(wiphy);
-+-
-+-	drv_get_ringparam(local, tx, tx_max, rx, rx_max);
-+-}
-+-
-+ static int ieee80211_set_rekey_data(struct wiphy *wiphy,
-+ 				    struct net_device *dev,
-+ 				    struct cfg80211_gtk_rekey_data *data)
-+@@ -3844,8 +3529,6 @@ const struct cfg80211_ops mac80211_confi
-+ 	.mgmt_frame_register = ieee80211_mgmt_frame_register,
-+ 	.set_antenna = ieee80211_set_antenna,
-+ 	.get_antenna = ieee80211_get_antenna,
-+-	.set_ringparam = ieee80211_set_ringparam,
-+-	.get_ringparam = ieee80211_get_ringparam,
-+ 	.set_rekey_data = ieee80211_set_rekey_data,
-+ 	.tdls_oper = ieee80211_tdls_oper,
-+ 	.tdls_mgmt = ieee80211_tdls_mgmt,
-+@@ -3854,9 +3537,6 @@ const struct cfg80211_ops mac80211_confi
-+ #ifdef CONFIG_PM
-+ 	.set_wakeup = ieee80211_set_wakeup,
-+ #endif
-+-	.get_et_sset_count = ieee80211_get_et_sset_count,
-+-	.get_et_stats = ieee80211_get_et_stats,
-+-	.get_et_strings = ieee80211_get_et_strings,
-+ 	.get_channel = ieee80211_cfg_get_channel,
-+ 	.start_radar_detection = ieee80211_start_radar_detection,
-+ 	.channel_switch = ieee80211_channel_switch,
-+--- a/net/mac80211/debugfs_sta.c
-++++ b/net/mac80211/debugfs_sta.c
-+@@ -587,7 +587,6 @@ void ieee80211_sta_debugfs_add(struct st
-+ 	DEBUGFS_ADD_COUNTER(tx_filtered, tx_filtered_count);
-+ 	DEBUGFS_ADD_COUNTER(tx_retry_failed, tx_retry_failed);
-+ 	DEBUGFS_ADD_COUNTER(tx_retry_count, tx_retry_count);
-+-	DEBUGFS_ADD_COUNTER(wep_weak_iv_count, wep_weak_iv_count);
-+ 
-+ 	if (sizeof(sta->driver_buffered_tids) == sizeof(u32))
-+ 		debugfs_create_x32("driver_buffered_tids", 0400,
-+--- a/net/mac80211/wep.c
-++++ b/net/mac80211/wep.c
-+@@ -271,22 +271,6 @@ static int ieee80211_wep_decrypt(struct 
-+ 	return ret;
-+ }
-  
--+	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)
-+-static bool ieee80211_wep_is_weak_iv(struct sk_buff *skb,
-+-				     struct ieee80211_key *key)
- -{
---	ieee80211_add_pending_skbs_fn(local, skbs, NULL, NULL);
-+-	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
-+-	unsigned int hdrlen;
-+-	u8 *ivpos;
-+-	u32 iv;
-+-
-+-	hdrlen = ieee80211_hdrlen(hdr->frame_control);
-+-	ivpos = skb->data + hdrlen;
-+-	iv = (ivpos[0] << 16) | (ivpos[1] << 8) | ivpos[2];
-+-
-+-	return ieee80211_wep_weak_iv(iv, key->conf.keylen);
- -}
--+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);
-+-
-+ ieee80211_rx_result
-+ ieee80211_crypto_wep_decrypt(struct ieee80211_rx_data *rx)
-+ {
-+@@ -301,16 +285,12 @@ ieee80211_crypto_wep_decrypt(struct ieee
-+ 	if (!(status->flag & RX_FLAG_DECRYPTED)) {
-+ 		if (skb_linearize(rx->skb))
-+ 			return RX_DROP_UNUSABLE;
-+-		if (rx->sta && ieee80211_wep_is_weak_iv(rx->skb, rx->key))
-+-			rx->sta->wep_weak_iv_count++;
-+ 		if (ieee80211_wep_decrypt(rx->local, rx->skb, rx->key))
-+ 			return RX_DROP_UNUSABLE;
-+ 	} else if (!(status->flag & RX_FLAG_IV_STRIPPED)) {
-+ 		if (!pskb_may_pull(rx->skb, ieee80211_hdrlen(fc) +
-+ 					    IEEE80211_WEP_IV_LEN))
-+ 			return RX_DROP_UNUSABLE;
-+-		if (rx->sta && ieee80211_wep_is_weak_iv(rx->skb, rx->key))
-+-			rx->sta->wep_weak_iv_count++;
-+ 		ieee80211_wep_remove_iv(rx->local, rx->skb, rx->key);
-+ 		/* remove ICV */
-+ 		if (pskb_trim(rx->skb, rx->skb->len - IEEE80211_WEP_ICV_LEN))
-+--- a/include/net/cfg80211.h
-++++ b/include/net/cfg80211.h
-+@@ -2278,16 +2278,6 @@ struct cfg80211_qos_map {
-+  *
-+  * @set_noack_map: Set the NoAck Map for the TIDs.
-+  *
-+- * @get_et_sset_count:  Ethtool API to get string-set count.
-+- *	See @ethtool_ops.get_sset_count
-+- *
-+- * @get_et_stats:  Ethtool API to get a set of u64 stats.
-+- *	See @ethtool_ops.get_ethtool_stats
-+- *
-+- * @get_et_strings:  Ethtool API to get a set of strings to describe stats
-+- *	and perhaps other supported types of ethtool data-sets.
-+- *	See @ethtool_ops.get_strings
-+- *
-+  * @get_channel: Get the current operating channel for the virtual interface.
-+  *	For monitor interfaces, it should return %NULL unless there's a single
-+  *	current monitoring channel.
-+@@ -2529,13 +2519,6 @@ struct cfg80211_ops {
-+ 				  struct net_device *dev,
-+ 				  u16 noack_map);
-+ 
-+-	int	(*get_et_sset_count)(struct wiphy *wiphy,
-+-				     struct net_device *dev, int sset);
-+-	void	(*get_et_stats)(struct wiphy *wiphy, struct net_device *dev,
-+-				struct ethtool_stats *stats, u64 *data);
-+-	void	(*get_et_strings)(struct wiphy *wiphy, struct net_device *dev,
-+-				  u32 sset, u8 *data);
-+-
-+ 	int	(*get_channel)(struct wiphy *wiphy,
-+ 			       struct wireless_dev *wdev,
-+ 			       struct cfg80211_chan_def *chandef);
-+@@ -4846,6 +4829,10 @@ void cfg80211_stop_iface(struct wiphy *w
-+  */
-+ void cfg80211_shutdown_all_interfaces(struct wiphy *wiphy);
-  
----- 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;
-- }
-++
-++/* ethtool helper */
-++void cfg80211_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info);
-++
-+ /* Logging, debugging and troubleshooting/diagnostic helpers. */
-+ 
-+ /* wiphy_printk helpers, similar to dev_printk */
-+--- a/net/mac80211/Makefile
-++++ b/net/mac80211/Makefile
-+@@ -17,6 +17,7 @@ mac80211-y := \
-+ 	aes_ccm.o \
-+ 	aes_cmac.o \
-+ 	cfg.o \
-++	ethtool.o \
-+ 	rx.o \
-+ 	spectmgmt.o \
-+ 	tx.o \
-+--- a/net/mac80211/ieee80211_i.h
-++++ b/net/mac80211/ieee80211_i.h
-+@@ -229,16 +229,29 @@ struct ieee80211_rx_data {
-+ 	u16 tkip_iv16;
-+ };
-+ 
-++struct ieee80211_csa_settings {
-++	const u16 *counter_offsets_beacon;
-++	const u16 *counter_offsets_presp;
-++
-++	int n_counter_offsets_beacon;
-++	int n_counter_offsets_presp;
-++
-++	u8 count;
-++};
-++
-+ struct beacon_data {
-+ 	u8 *head, *tail;
-+ 	int head_len, tail_len;
-+ 	struct ieee80211_meshconf_ie *meshconf;
-++	u16 csa_counter_offsets[IEEE80211_MAX_CSA_COUNTERS_NUM];
-++	u8 csa_current_counter;
-+ 	struct rcu_head rcu_head;
-+ };
-+ 
-+ struct probe_resp {
-+ 	struct rcu_head rcu_head;
-+ 	int len;
-++	u16 csa_counter_offsets[IEEE80211_MAX_CSA_COUNTERS_NUM];
-+ 	u8 data[0];
-+ };
-  
---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;
-+@@ -754,8 +767,6 @@ struct ieee80211_sub_if_data {
-+ 	struct mac80211_qos_map __rcu *qos_map;
-  
---	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;
-+ 	struct work_struct csa_finalize_work;
-+-	u16 csa_counter_offset_beacon[IEEE80211_MAX_CSA_COUNTERS_NUM];
-+-	u16 csa_counter_offset_presp[IEEE80211_MAX_CSA_COUNTERS_NUM];
-+ 	bool csa_radar_required;
-+ 	bool csa_block_tx; /* write-protected by sdata_lock and local->mtx */
-+ 	struct cfg80211_chan_def csa_chandef;
-+@@ -767,7 +778,6 @@ struct ieee80211_sub_if_data {
-+ 	struct ieee80211_chanctx *reserved_chanctx;
-+ 	struct cfg80211_chan_def reserved_chandef;
-+ 	bool reserved_radar_required;
-+-	u8 csa_current_counter;
-  
-- 		clear_sta_flag(sta, WLAN_STA_PS_STA);
--+		clear_sta_flag(sta, WLAN_STA_PS_DRIVER);
-+ 	/* used to reconfigure hardware SM PS */
-+ 	struct work_struct recalc_smps;
-+@@ -1850,6 +1860,8 @@ int ieee80211_tdls_oper(struct wiphy *wi
-+ 			const u8 *peer, enum nl80211_tdls_operation oper);
-  
-- 		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;
-++extern const struct ethtool_ops ieee80211_ethtool_ops;
- +
--+	__cleanup_single_sta(sta);
-- 	sta_info_free(local, sta);
-- }
-+ #ifdef CPTCFG_MAC80211_NOINLINE
-+ #define debug_noinline noinline
-+ #else
-+--- a/net/mac80211/iface.c
-++++ b/net/mac80211/iface.c
-+@@ -399,6 +399,7 @@ int ieee80211_add_virtual_monitor(struct
-+ 	sdata->vif.type = NL80211_IFTYPE_MONITOR;
-+ 	snprintf(sdata->name, IFNAMSIZ, "%s-monitor",
-+ 		 wiphy_name(local->hw.wiphy));
-++	sdata->wdev.iftype = NL80211_IFTYPE_MONITOR;
-  
--@@ -330,6 +339,7 @@ struct sta_info *sta_info_alloc(struct i
-- 	rcu_read_unlock();
-+ 	sdata->encrypt_headroom = IEEE80211_ENCRYPT_HEADROOM;
-  
-- 	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;
-- 	}
-+@@ -1303,6 +1304,7 @@ static void ieee80211_setup_sdata(struct
-+ 	sdata->control_port_protocol = cpu_to_be16(ETH_P_PAE);
-+ 	sdata->control_port_no_encrypt = false;
-+ 	sdata->encrypt_headroom = IEEE80211_ENCRYPT_HEADROOM;
-++	sdata->vif.bss_conf.idle = true;
-  
---	/* notify driver */
---	err = sta_info_insert_drv_state(local, sdata, sta);
---	if (err)
---		goto out_err;
---
-- 	local->num_sta++;
-- 	local->sta_generation++;
-- 	smp_mb();
-+ 	sdata->noack_map = 0;
-  
--+	/* 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);
-+@@ -1721,6 +1723,8 @@ int ieee80211_if_add(struct ieee80211_lo
-  
-- 	list_add_rcu(&sta->list, &local->sta_list);
-+ 		ndev->features |= local->hw.netdev_features;
-  
--+	/* notify driver */
--+	err = sta_info_insert_drv_state(local, sdata, sta);
--+	if (err)
--+		goto out_remove;
-++		netdev_set_default_ethtool_ops(ndev, &ieee80211_ethtool_ops);
- +
-- 	set_sta_flag(sta, WLAN_STA_INSERTED);
--+	/* accept BA sessions now */
--+	clear_sta_flag(sta, WLAN_STA_BLOCK_BA);
-+ 		ret = register_netdevice(ndev);
-+ 		if (ret) {
-+ 			free_netdev(ndev);
-+--- a/net/wireless/core.c
-++++ b/net/wireless/core.c
-+@@ -25,7 +25,6 @@
-+ #include "sysfs.h"
-+ #include "debugfs.h"
-+ #include "wext-compat.h"
-+-#include "ethtool.h"
-+ #include "rdev-ops.h"
-  
-- 	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);
-+ /* name for sysfs, %d is appended */
-+@@ -940,8 +939,6 @@ static int cfg80211_netdev_notifier_call
-+ 		/* allow mac80211 to determine the timeout */
-+ 		wdev->ps_timeout = -1;
-  
-- 	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);
-+-		netdev_set_default_ethtool_ops(dev, &cfg80211_ethtool_ops);
-+-
-+ 		if ((wdev->iftype == NL80211_IFTYPE_STATION ||
-+ 		     wdev->iftype == NL80211_IFTYPE_P2P_CLIENT ||
-+ 		     wdev->iftype == NL80211_IFTYPE_ADHOC) && !wdev->use_4addr)
-+--- a/net/wireless/ethtool.c
-++++ b/net/wireless/ethtool.c
-+@@ -1,11 +1,9 @@
-+ #include <linux/utsname.h>
-+ #include <net/cfg80211.h>
-+ #include "core.h"
-+-#include "ethtool.h"
-+ #include "rdev-ops.h"
-  
---static void clear_sta_ps_flags(void *_sta)
--+/* powersave support code */
--+void ieee80211_sta_ps_deliver_wakeup(struct sta_info *sta)
-+-static void cfg80211_get_drvinfo(struct net_device *dev,
-+-					struct ethtool_drvinfo *info)
-++void cfg80211_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
-  {
---	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;
-+ 	struct wireless_dev *wdev = dev->ieee80211_ptr;
-  
---	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);
-+@@ -23,84 +21,4 @@ static void cfg80211_get_drvinfo(struct 
-+ 	strlcpy(info->bus_info, dev_name(wiphy_dev(wdev->wiphy)),
-+ 		sizeof(info->bus_info));
-+ }
-+-
-+-static int cfg80211_get_regs_len(struct net_device *dev)
-+-{
-+-	/* For now, return 0... */
-+-	return 0;
- -}
- -
---/* powersave support code */
---void ieee80211_sta_ps_deliver_wakeup(struct sta_info *sta)
-+-static void cfg80211_get_regs(struct net_device *dev, struct ethtool_regs *regs,
-+-			void *data)
- -{
---	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 wireless_dev *wdev = dev->ieee80211_ptr;
- -
-- 	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
-+-	regs->version = wdev->wiphy->hw_version;
-+-	regs->len = 0;
-+-}
-+-
-+-static void cfg80211_get_ringparam(struct net_device *dev,
-+-				   struct ethtool_ringparam *rp)
-+-{
-+-	struct wireless_dev *wdev = dev->ieee80211_ptr;
-+-	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
-+-
-+-	memset(rp, 0, sizeof(*rp));
-+-
-+-	if (rdev->ops->get_ringparam)
-+-		rdev_get_ringparam(rdev, &rp->tx_pending, &rp->tx_max_pending,
-+-				   &rp->rx_pending, &rp->rx_max_pending);
-+-}
-+-
-+-static int cfg80211_set_ringparam(struct net_device *dev,
-+-				  struct ethtool_ringparam *rp)
-+-{
-+-	struct wireless_dev *wdev = dev->ieee80211_ptr;
-+-	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
-+-
-+-	if (rp->rx_mini_pending != 0 || rp->rx_jumbo_pending != 0)
-+-		return -EINVAL;
-+-
-+-	if (rdev->ops->set_ringparam)
-+-		return rdev_set_ringparam(rdev, rp->tx_pending, rp->rx_pending);
-+-
-+-	return -ENOTSUPP;
-+-}
-+-
-+-static int cfg80211_get_sset_count(struct net_device *dev, int sset)
-+-{
-+-	struct wireless_dev *wdev = dev->ieee80211_ptr;
-+-	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
-+-	if (rdev->ops->get_et_sset_count)
-+-		return rdev_get_et_sset_count(rdev, dev, sset);
-+-	return -EOPNOTSUPP;
-+-}
-+-
-+-static void cfg80211_get_stats(struct net_device *dev,
-+-			       struct ethtool_stats *stats, u64 *data)
-+-{
-+-	struct wireless_dev *wdev = dev->ieee80211_ptr;
-+-	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
-+-	if (rdev->ops->get_et_stats)
-+-		rdev_get_et_stats(rdev, dev, stats, data);
-+-}
-+-
-+-static void cfg80211_get_strings(struct net_device *dev, u32 sset, u8 *data)
-+-{
-+-	struct wireless_dev *wdev = dev->ieee80211_ptr;
-+-	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
-+-	if (rdev->ops->get_et_strings)
-+-		rdev_get_et_strings(rdev, dev, sset, data);
-+-}
-+-
-+-const struct ethtool_ops cfg80211_ethtool_ops = {
-+-	.get_drvinfo = cfg80211_get_drvinfo,
-+-	.get_regs_len = cfg80211_get_regs_len,
-+-	.get_regs = cfg80211_get_regs,
-+-	.get_link = ethtool_op_get_link,
-+-	.get_ringparam = cfg80211_get_ringparam,
-+-	.set_ringparam = cfg80211_set_ringparam,
-+-	.get_strings = cfg80211_get_strings,
-+-	.get_ethtool_stats = cfg80211_get_stats,
-+-	.get_sset_count = cfg80211_get_sset_count,
-+-};
-++EXPORT_SYMBOL(cfg80211_get_drvinfo);
-+--- a/net/wireless/ethtool.h
-++++ /dev/null
-+@@ -1,6 +0,0 @@
-+-#ifndef __CFG80211_ETHTOOL__
-+-#define __CFG80211_ETHTOOL__
-+-
-+-extern const struct ethtool_ops cfg80211_ethtool_ops;
-+-
-+-#endif /* __CFG80211_ETHTOOL__ */
-+--- a/net/wireless/rdev-ops.h
-++++ b/net/wireless/rdev-ops.h
-+@@ -714,25 +714,6 @@ static inline int rdev_get_antenna(struc
-+ 	return ret;
-+ }
-  
-- 	skb_queue_head_init(&pending);
-+-static inline int rdev_set_ringparam(struct cfg80211_registered_device *rdev,
-+-				     u32 tx, u32 rx)
-+-{
-+-	int ret;
-+-	trace_rdev_set_ringparam(&rdev->wiphy, tx, rx);
-+-	ret = rdev->ops->set_ringparam(&rdev->wiphy, tx, rx);
-+-	trace_rdev_return_int(&rdev->wiphy, ret);
-+-	return ret;
-+-}
-+-
-+-static inline void rdev_get_ringparam(struct cfg80211_registered_device *rdev,
-+-				      u32 *tx, u32 *tx_max, u32 *rx,
-+-				      u32 *rx_max)
-+-{
-+-	trace_rdev_get_ringparam(&rdev->wiphy);
-+-	rdev->ops->get_ringparam(&rdev->wiphy, tx, tx_max, rx, rx_max);
-+-	trace_rdev_return_void_tx_rx(&rdev->wiphy, *tx, *tx_max, *rx, *rx_max);
-+-}
-+-
-+ static inline int
-+ rdev_sched_scan_start(struct cfg80211_registered_device *rdev,
-+ 		      struct net_device *dev,
-+@@ -816,35 +797,6 @@ static inline int rdev_set_noack_map(str
-+ }
-  
--+	/* 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;
-- 	}
-+ static inline int
-+-rdev_get_et_sset_count(struct cfg80211_registered_device *rdev,
-+-		       struct net_device *dev, int sset)
-+-{
-+-	int ret;
-+-	trace_rdev_get_et_sset_count(&rdev->wiphy, dev, sset);
-+-	ret = rdev->ops->get_et_sset_count(&rdev->wiphy, dev, sset);
-+-	trace_rdev_return_int(&rdev->wiphy, ret);
-+-	return ret;
-+-}
-+-
-+-static inline void rdev_get_et_stats(struct cfg80211_registered_device *rdev,
-+-				     struct net_device *dev,
-+-				     struct ethtool_stats *stats, u64 *data)
-+-{
-+-	trace_rdev_get_et_stats(&rdev->wiphy, dev);
-+-	rdev->ops->get_et_stats(&rdev->wiphy, dev, stats, data);
-+-	trace_rdev_return_void(&rdev->wiphy);
-+-}
-+-
-+-static inline void rdev_get_et_strings(struct cfg80211_registered_device *rdev,
-+-				       struct net_device *dev, u32 sset,
-+-				       u8 *data)
-+-{
-+-	trace_rdev_get_et_strings(&rdev->wiphy, dev, sset);
-+-	rdev->ops->get_et_strings(&rdev->wiphy, dev, sset, data);
-+-	trace_rdev_return_void(&rdev->wiphy);
-+-}
-+-
-+-static inline int
-+ rdev_get_channel(struct cfg80211_registered_device *rdev,
-+ 		 struct wireless_dev *wdev,
-+ 		 struct cfg80211_chan_def *chandef)
-+--- a/net/wireless/trace.h
-++++ b/net/wireless/trace.h
-+@@ -298,11 +298,6 @@ DEFINE_EVENT(wiphy_only_evt, rdev_return
-+ 	TP_ARGS(wiphy)
-+ );
-  
---	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);
-+-DEFINE_EVENT(wiphy_only_evt, rdev_get_ringparam,
-+-	TP_PROTO(struct wiphy *wiphy),
-+-	TP_ARGS(wiphy)
-+-);
-+-
-+ DEFINE_EVENT(wiphy_only_evt, rdev_get_antenna,
-+ 	TP_PROTO(struct wiphy *wiphy),
-+ 	TP_ARGS(wiphy)
-+@@ -580,11 +575,6 @@ DEFINE_EVENT(wiphy_netdev_evt, rdev_stop
-+ 	TP_ARGS(wiphy, netdev)
-+ );
-  
-- 	/* 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);
-- }
-+-DEFINE_EVENT(wiphy_netdev_evt, rdev_get_et_stats,
-+-	TP_PROTO(struct wiphy *wiphy, struct net_device *netdev),
-+-	TP_ARGS(wiphy, netdev)
-+-);
-+-
-+ DEFINE_EVENT(wiphy_netdev_evt, rdev_sched_scan_stop,
-+ 	TP_PROTO(struct wiphy *wiphy, struct net_device *netdev),
-+ 	TP_ARGS(wiphy, netdev)
-+@@ -1439,11 +1429,6 @@ DECLARE_EVENT_CLASS(tx_rx_evt,
-+ 		  WIPHY_PR_ARG, __entry->tx, __entry->rx)
-+ );
-  
---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);
-- 	}
-+-DEFINE_EVENT(tx_rx_evt, rdev_set_ringparam,
-+-	TP_PROTO(struct wiphy *wiphy, u32 tx, u32 rx),
-+-	TP_ARGS(wiphy, rx, tx)
-+-);
-+-
-+ DEFINE_EVENT(tx_rx_evt, rdev_set_antenna,
-+ 	TP_PROTO(struct wiphy *wiphy, u32 tx, u32 rx),
-+ 	TP_ARGS(wiphy, rx, tx)
-+@@ -1725,40 +1710,6 @@ TRACE_EVENT(rdev_set_noack_map,
-+ 		  WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->noack_map)
-+ );
-  
---	if (fn)
---		fn(data);
-+-TRACE_EVENT(rdev_get_et_sset_count,
-+-	TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, int sset),
-+-	TP_ARGS(wiphy, netdev, sset),
-+-	TP_STRUCT__entry(
-+-		WIPHY_ENTRY
-+-		NETDEV_ENTRY
-+-		__field(int, sset)
-+-	),
-+-	TP_fast_assign(
-+-		WIPHY_ASSIGN;
-+-		NETDEV_ASSIGN;
-+-		__entry->sset = sset;
-+-	),
-+-	TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", sset: %d",
-+-		  WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->sset)
-+-);
- -
-- 	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");
-+-TRACE_EVENT(rdev_get_et_strings,
-+-	TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, u32 sset),
-+-	TP_ARGS(wiphy, netdev, sset),
-+-	TP_STRUCT__entry(
-+-		WIPHY_ENTRY
-+-		NETDEV_ENTRY
-+-		__field(u32, sset)
-+-	),
-+-	TP_fast_assign(
-+-		WIPHY_ASSIGN;
-+-		NETDEV_ASSIGN;
-+-		__entry->sset = sset;
-+-	),
-+-	TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", sset: %u",
-+-		  WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->sset)
-+-);
-+-
-+ DEFINE_EVENT(wiphy_wdev_evt, rdev_get_channel,
-+ 	TP_PROTO(struct wiphy *wiphy, struct wireless_dev *wdev),
-+ 	TP_ARGS(wiphy, wdev)
-+--- /dev/null
-++++ b/net/mac80211/ethtool.c
-+@@ -0,0 +1,244 @@
-++/*
-++ * mac80211 ethtool hooks for cfg80211
-++ *
-++ * Copied from cfg.c - originally
-++ * Copyright 2006-2010	Johannes Berg <johannes@sipsolutions.net>
-++ * Copyright 2014	Intel Corporation (Author: Johannes Berg)
-++ *
-++ * This file is GPLv2 as found in COPYING.
-++ */
-++#include <linux/types.h>
-++#include <net/cfg80211.h>
-++#include "ieee80211_i.h"
-++#include "sta_info.h"
-++#include "driver-ops.h"
-++
-++static int ieee80211_set_ringparam(struct net_device *dev,
-++				   struct ethtool_ringparam *rp)
-++{
-++	struct ieee80211_local *local = wiphy_priv(dev->ieee80211_ptr->wiphy);
- +
--+	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);
-++	if (rp->rx_mini_pending != 0 || rp->rx_jumbo_pending != 0)
-++		return -EINVAL;
- +
-- 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;
-++	return drv_set_ringparam(local, rp->tx_pending, rp->rx_pending);
-++}
- +
--+	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.
-++static void ieee80211_get_ringparam(struct net_device *dev,
-++				    struct ethtool_ringparam *rp)
-++{
-++	struct ieee80211_local *local = wiphy_priv(dev->ieee80211_ptr->wiphy);
-++
-++	memset(rp, 0, sizeof(*rp));
-++
-++	drv_get_ringparam(local, &rp->tx_pending, &rp->tx_max_pending,
-++			  &rp->rx_pending, &rp->rx_max_pending);
-++}
-++
-++static const char ieee80211_gstrings_sta_stats[][ETH_GSTRING_LEN] = {
-++	"rx_packets", "rx_bytes",
-++	"rx_duplicates", "rx_fragments", "rx_dropped",
-++	"tx_packets", "tx_bytes", "tx_fragments",
-++	"tx_filtered", "tx_retry_failed", "tx_retries",
-++	"beacon_loss", "sta_state", "txrate", "rxrate", "signal",
-++	"channel", "noise", "ch_time", "ch_time_busy",
-++	"ch_time_ext_busy", "ch_time_rx", "ch_time_tx"
-++};
-++#define STA_STATS_LEN	ARRAY_SIZE(ieee80211_gstrings_sta_stats)
-++
-++static int ieee80211_get_sset_count(struct net_device *dev, int sset)
-++{
-++	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
-++	int rv = 0;
-++
-++	if (sset == ETH_SS_STATS)
-++		rv += STA_STATS_LEN;
-++
-++	rv += drv_get_et_sset_count(sdata, sset);
-++
-++	if (rv == 0)
-++		return -EOPNOTSUPP;
-++	return rv;
-++}
-++
-++static void ieee80211_get_stats(struct net_device *dev,
-++				struct ethtool_stats *stats,
-++				u64 *data)
-++{
-++	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
-++	struct ieee80211_chanctx_conf *chanctx_conf;
-++	struct ieee80211_channel *channel;
-++	struct sta_info *sta;
-++	struct ieee80211_local *local = sdata->local;
-++	struct station_info sinfo;
-++	struct survey_info survey;
-++	int i, q;
-++#define STA_STATS_SURVEY_LEN 7
-++
-++	memset(data, 0, sizeof(u64) * STA_STATS_LEN);
-++
-++#define ADD_STA_STATS(sta)				\
-++	do {						\
-++		data[i++] += sta->rx_packets;		\
-++		data[i++] += sta->rx_bytes;		\
-++		data[i++] += sta->num_duplicates;	\
-++		data[i++] += sta->rx_fragments;		\
-++		data[i++] += sta->rx_dropped;		\
-++							\
-++		data[i++] += sinfo.tx_packets;		\
-++		data[i++] += sinfo.tx_bytes;		\
-++		data[i++] += sta->tx_fragments;		\
-++		data[i++] += sta->tx_filtered_count;	\
-++		data[i++] += sta->tx_retry_failed;	\
-++		data[i++] += sta->tx_retry_count;	\
-++		data[i++] += sta->beacon_loss_count;	\
-++	} while (0)
-++
-++	/* For Managed stations, find the single station based on BSSID
-++	 * and use that.  For interface types, iterate through all available
-++	 * stations and add stats for any station that is assigned to this
-++	 * network device.
- +	 */
-- 	if (rx_stats->rs_datalen > (common->rx_bufsize - ah->caps.rx_status_len)) {
-- 		RX_STAT_INC(rx_len_err);
---		return -EINVAL;
--+		goto corrupt;
-++
-++	mutex_lock(&local->sta_mtx);
-++
-++	if (sdata->vif.type == NL80211_IFTYPE_STATION) {
-++		sta = sta_info_get_bss(sdata, sdata->u.mgd.bssid);
-++
-++		if (!(sta && !WARN_ON(sta->sdata->dev != dev)))
-++			goto do_survey;
-++
-++		sinfo.filled = 0;
-++		sta_set_sinfo(sta, &sinfo);
-++
-++		i = 0;
-++		ADD_STA_STATS(sta);
-++
-++		data[i++] = sta->sta_state;
-++
-++
-++		if (sinfo.filled & STATION_INFO_TX_BITRATE)
-++			data[i] = 100000 *
-++				cfg80211_calculate_bitrate(&sinfo.txrate);
-++		i++;
-++		if (sinfo.filled & STATION_INFO_RX_BITRATE)
-++			data[i] = 100000 *
-++				cfg80211_calculate_bitrate(&sinfo.rxrate);
-++		i++;
-++
-++		if (sinfo.filled & STATION_INFO_SIGNAL_AVG)
-++			data[i] = (u8)sinfo.signal_avg;
-++		i++;
-++	} else {
-++		list_for_each_entry(sta, &local->sta_list, list) {
-++			/* Make sure this station belongs to the proper dev */
-++			if (sta->sdata->dev != dev)
-++				continue;
-++
-++			sinfo.filled = 0;
-++			sta_set_sinfo(sta, &sinfo);
-++			i = 0;
-++			ADD_STA_STATS(sta);
-++		}
-++	}
-++
-++do_survey:
-++	i = STA_STATS_LEN - STA_STATS_SURVEY_LEN;
-++	/* Get survey stats for current channel */
-++	survey.filled = 0;
-++
-++	rcu_read_lock();
-++	chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf);
-++	if (chanctx_conf)
-++		channel = chanctx_conf->def.chan;
-++	else
-++		channel = NULL;
-++	rcu_read_unlock();
-++
-++	if (channel) {
-++		q = 0;
-++		do {
-++			survey.filled = 0;
-++			if (drv_get_survey(local, q, &survey) != 0) {
-++				survey.filled = 0;
-++				break;
-++			}
-++			q++;
-++		} while (channel != survey.channel);
-++	}
-++
-++	if (survey.filled)
-++		data[i++] = survey.channel->center_freq;
-++	else
-++		data[i++] = 0;
-++	if (survey.filled & SURVEY_INFO_NOISE_DBM)
-++		data[i++] = (u8)survey.noise;
-++	else
-++		data[i++] = -1LL;
-++	if (survey.filled & SURVEY_INFO_CHANNEL_TIME)
-++		data[i++] = survey.channel_time;
-++	else
-++		data[i++] = -1LL;
-++	if (survey.filled & SURVEY_INFO_CHANNEL_TIME_BUSY)
-++		data[i++] = survey.channel_time_busy;
-++	else
-++		data[i++] = -1LL;
-++	if (survey.filled & SURVEY_INFO_CHANNEL_TIME_EXT_BUSY)
-++		data[i++] = survey.channel_time_ext_busy;
-++	else
-++		data[i++] = -1LL;
-++	if (survey.filled & SURVEY_INFO_CHANNEL_TIME_RX)
-++		data[i++] = survey.channel_time_rx;
-++	else
-++		data[i++] = -1LL;
-++	if (survey.filled & SURVEY_INFO_CHANNEL_TIME_TX)
-++		data[i++] = survey.channel_time_tx;
-++	else
-++		data[i++] = -1LL;
-++
-++	mutex_unlock(&local->sta_mtx);
-++
-++	if (WARN_ON(i != STA_STATS_LEN))
-++		return;
-++
-++	drv_get_et_stats(sdata, stats, &(data[STA_STATS_LEN]));
-++}
-++
-++static void ieee80211_get_strings(struct net_device *dev, u32 sset, u8 *data)
-++{
-++	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
-++	int sz_sta_stats = 0;
-++
-++	if (sset == ETH_SS_STATS) {
-++		sz_sta_stats = sizeof(ieee80211_gstrings_sta_stats);
-++		memcpy(data, ieee80211_gstrings_sta_stats, sz_sta_stats);
-++	}
-++	drv_get_et_strings(sdata, sset, &(data[sz_sta_stats]));
-++}
-++
-++static int ieee80211_get_regs_len(struct net_device *dev)
-++{
-++	return 0;
-++}
-++
-++static void ieee80211_get_regs(struct net_device *dev,
-++			       struct ethtool_regs *regs,
-++			       void *data)
-++{
-++	struct wireless_dev *wdev = dev->ieee80211_ptr;
-++
-++	regs->version = wdev->wiphy->hw_version;
-++	regs->len = 0;
-++}
-++
-++const struct ethtool_ops ieee80211_ethtool_ops = {
-++	.get_drvinfo = cfg80211_get_drvinfo,
-++	.get_regs_len = ieee80211_get_regs_len,
-++	.get_regs = ieee80211_get_regs,
-++	.get_link = ethtool_op_get_link,
-++	.get_ringparam = ieee80211_get_ringparam,
-++	.set_ringparam = ieee80211_set_ringparam,
-++	.get_strings = ieee80211_get_strings,
-++	.get_ethtool_stats = ieee80211_get_stats,
-++	.get_sset_count = ieee80211_get_sset_count,
-++};
-+--- a/net/mac80211/ibss.c
-++++ b/net/mac80211/ibss.c
-+@@ -143,7 +143,7 @@ ieee80211_ibss_build_presp(struct ieee80
-+ 		*pos++ = csa_settings->block_tx ? 1 : 0;
-+ 		*pos++ = ieee80211_frequency_to_channel(
-+ 				csa_settings->chandef.chan->center_freq);
-+-		sdata->csa_counter_offset_beacon[0] = (pos - presp->head);
-++		presp->csa_counter_offsets[0] = (pos - presp->head);
-+ 		*pos++ = csa_settings->count;
-  	}
-  
-- 	/* 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);
-+@@ -1677,6 +1677,7 @@ int ieee80211_ibss_join(struct ieee80211
-+ 	sdata->u.ibss.control_port = params->control_port;
-+ 	sdata->u.ibss.userspace_handles_dfs = params->userspace_handles_dfs;
-+ 	sdata->u.ibss.basic_rates = params->basic_rates;
-++	sdata->u.ibss.last_scan_completed = jiffies;
-  
---		ret = -EINVAL;
---		goto exit;
--+		return -EINVAL;
-+ 	/* fix basic_rates if channel does not support these rates */
-+ 	rate_flags = ieee80211_chandef_rate_flags(&params->chandef);
-+--- a/net/mac80211/mesh.c
-++++ b/net/mac80211/mesh.c
-+@@ -679,7 +679,7 @@ ieee80211_mesh_build_beacon(struct ieee8
-+ 		*pos++ = 0x0;
-+ 		*pos++ = ieee80211_frequency_to_channel(
-+ 				csa->settings.chandef.chan->center_freq);
-+-		sdata->csa_counter_offset_beacon[0] = hdr_len + 6;
-++		bcn->csa_counter_offsets[0] = hdr_len + 6;
-+ 		*pos++ = csa->settings.count;
-+ 		*pos++ = WLAN_EID_CHAN_SWITCH_PARAM;
-+ 		*pos++ = 6;
-+--- a/net/wireless/genregdb.awk
-++++ b/net/wireless/genregdb.awk
-+@@ -65,17 +65,7 @@ function parse_reg_rule()
-+ 	sub(/,/, "", units)
-+ 	dfs_cac = $9
-+ 	if (units == "mW") {
-+-		if (power == 100) {
-+-			power = 20
-+-		} else if (power == 200) {
-+-			power = 23
-+-		} else if (power == 500) {
-+-			power = 27
-+-		} else if (power == 1000) {
-+-			power = 30
-+-		} else {
-+-			print "Unknown power value in database!"
-+-		}
-++		power = 10 * log(power)/log(10)
-+ 	} else {
-+ 		dfs_cac = $8
-  	}
-+@@ -114,7 +104,7 @@ function parse_reg_rule()
-  
-- 	/*
-- 	 * 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);
-+ 	}
-+ 	flags = flags "0"
-+-	printf "\t\tREG_RULE_EXT(%d, %d, %d, %d, %d, %d, %s),\n", start, end, bw, gain, power, dfs_cac, flags
-++	printf "\t\tREG_RULE_EXT(%d, %d, %d, %d, %.0f, %d, %s),\n", start, end, bw, gain, power, dfs_cac, flags
-+ 	rules++
-+ }
-  
--@@ -1087,9 +1085,11 @@ static int ath9k_rx_skb_preprocess(struc
-- 		sc->rx.num_pkts++;
-- #endif
-+--- a/net/mac80211/debugfs_netdev.c
-++++ b/net/mac80211/debugfs_netdev.c
-+@@ -34,8 +34,7 @@ static ssize_t ieee80211_if_read(
-+ 	ssize_t ret = -EINVAL;
-  
---exit:
---	sc->rx.discard_next = false;
---	return ret;
--+	return 0;
--+
--+corrupt:
--+	sc->rx.discard_next = rx_stats->rs_more;
--+	return -EINVAL;
-- }
-+ 	read_lock(&dev_base_lock);
-+-	if (sdata->dev->reg_state == NETREG_REGISTERED)
-+-		ret = (*format)(sdata, buf, sizeof(buf));
-++	ret = (*format)(sdata, buf, sizeof(buf));
-+ 	read_unlock(&dev_base_lock);
-  
-- 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 (ret >= 0)
-+@@ -62,8 +61,7 @@ static ssize_t ieee80211_if_write(
-  
-- 	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;
--+	}
-+ 	ret = -ENODEV;
-+ 	rtnl_lock();
-+-	if (sdata->dev->reg_state == NETREG_REGISTERED)
-+-		ret = (*write)(sdata, buf, count);
-++	ret = (*write)(sdata, buf, count);
-+ 	rtnl_unlock();
-  
-- 	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,9 @@ 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;
-- 		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;
---
---		REG_RMW_FIELD(ah, AR_PHY_FIND_SIG_LOW,
---			      AR_PHY_FIND_SIG_FIRSTEP_LOW, value2);
--+			      AR_PHY_FIND_SIG_FIRSTEP, value);
-- 
-- 		if (level != aniState->firstepLevel) {
-- 			ath_dbg(common, ANI,
--@@ -1060,7 +1023,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 +1036,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 +1059,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++;
-+ 	return ret;
-diff --git a/package/mac80211/patches/310-ap_scan.patch b/package/mac80211/patches/310-ap_scan.patch
-index 389a003..23ecd37 100644
---- a/package/mac80211/patches/310-ap_scan.patch
-+++ b/package/mac80211/patches/310-ap_scan.patch
-@@ -1,6 +1,6 @@
- --- a/net/mac80211/cfg.c
- +++ b/net/mac80211/cfg.c
--@@ -2148,7 +2148,7 @@ static int ieee80211_scan(struct wiphy *
-+@@ -1903,7 +1903,7 @@ static int ieee80211_scan(struct wiphy *
-  		 * the  frames sent while scanning on other channel will be
-  		 * lost)
-  		 */
-diff --git a/package/mac80211/patches/400-ath_move_debug_code.patch b/package/mac80211/patches/400-ath_move_debug_code.patch
-index 0dba7ac..4cc77af 100644
---- a/package/mac80211/patches/400-ath_move_debug_code.patch
-+++ b/package/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/mac80211/patches/403-ath_regd_optional.patch b/package/mac80211/patches/403-ath_regd_optional.patch
-index 07c54cc..808e729 100644
---- a/package/mac80211/patches/403-ath_regd_optional.patch
-+++ b/package/mac80211/patches/403-ath_regd_optional.patch
-@@ -58,7 +58,7 @@
-  	---help---
- --- a/.local-symbols
- +++ b/.local-symbols
--@@ -119,6 +119,7 @@ RTL8187_LEDS=
-+@@ -116,6 +116,7 @@ RTL8187_LEDS=
-  ATH_COMMON=
-  ATH_CARDS=
-  ATH_DEBUG=
-diff --git a/package/mac80211/patches/405-regd_no_assoc_hints.patch b/package/mac80211/patches/405-regd_no_assoc_hints.patch
-index 6ad4fda..2152433 100644
---- a/package/mac80211/patches/405-regd_no_assoc_hints.patch
-+++ b/package/mac80211/patches/405-regd_no_assoc_hints.patch
-@@ -1,6 +1,6 @@
- --- a/net/wireless/reg.c
- +++ b/net/wireless/reg.c
--@@ -1878,6 +1878,8 @@ void regulatory_hint_country_ie(struct w
-+@@ -2080,6 +2080,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(
-+@@ -2276,6 +2278,7 @@ static void restore_regulatory_settings(
-  
-  void regulatory_hint_disconnect(void)
-  {
-diff --git a/package/mac80211/patches/410-ath9k_allow_adhoc_and_ap.patch b/package/mac80211/patches/410-ath9k_allow_adhoc_and_ap.patch
-index 1f71e0b..ce752f1 100644
---- a/package/mac80211/patches/410-ath9k_allow_adhoc_and_ap.patch
-+++ b/package/mac80211/patches/410-ath9k_allow_adhoc_and_ap.patch
-@@ -1,8 +1,8 @@
- --- a/drivers/net/wireless/ath/ath9k/init.c
- +++ b/drivers/net/wireless/ath/ath9k/init.c
--@@ -866,6 +866,7 @@ static const struct ieee80211_iface_limi
-- #endif
-- 				 BIT(NL80211_IFTYPE_AP) |
-+@@ -655,6 +655,7 @@ static const struct ieee80211_iface_limi
-+ 				 BIT(NL80211_IFTYPE_AP) },
-+ 	{ .max = 1,	.types = BIT(NL80211_IFTYPE_P2P_CLIENT) |
-  				 BIT(NL80211_IFTYPE_P2P_GO) },
- +	{ .max = 1,	.types = BIT(NL80211_IFTYPE_ADHOC) },
-  };
-diff --git a/package/mac80211/patches/411-ath5k_allow_adhoc_and_ap.patch b/package/mac80211/patches/411-ath5k_allow_adhoc_and_ap.patch
-index 3487ab2..1f06994 100644
---- a/package/mac80211/patches/411-ath5k_allow_adhoc_and_ap.patch
-+++ b/package/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/mac80211/patches/431-add_platform_eeprom_support_to_ath5k.patch b/package/mac80211/patches/431-add_platform_eeprom_support_to_ath5k.patch
-index a223b38..5cb4b51 100644
---- a/package/mac80211/patches/431-add_platform_eeprom_support_to_ath5k.patch
-+++ b/package/mac80211/patches/431-add_platform_eeprom_support_to_ath5k.patch
-@@ -22,14 +22,14 @@
-  	u32 status, timeout;
-  
- +	struct ath5k_platform_data *pdata = NULL;
--+	
-++
- +	if (ah->pdev)
- +		pdata = ah->pdev->dev.platform_data;
- +
- +	if (pdata && pdata->eeprom_data && pdata->eeprom_data[61] == AR5K_EEPROM_MAGIC_VALUE) {
--+		if (offset >= ATH5K_PLAT_EEP_MAX_WORDS) 
-++		if (offset >= ATH5K_PLAT_EEP_MAX_WORDS)
- +			return false;
--+		
-++
- +		*data = pdata->eeprom_data[offset];
- +		return true;
- +	}
-diff --git a/package/mac80211/patches/500-ath9k_eeprom_debugfs.patch b/package/mac80211/patches/500-ath9k_eeprom_debugfs.patch
-index 664cf45..65821fe 100644
---- a/package/mac80211/patches/500-ath9k_eeprom_debugfs.patch
-+++ b/package/mac80211/patches/500-ath9k_eeprom_debugfs.patch
-@@ -1,6 +1,6 @@
- --- a/drivers/net/wireless/ath/ath9k/debug.c
- +++ b/drivers/net/wireless/ath/ath9k/debug.c
--@@ -1481,6 +1481,53 @@ void ath9k_deinit_debug(struct ath_softc
-+@@ -1289,6 +1289,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)
-+@@ -1308,6 +1355,8 @@ int ath9k_init_debug(struct ath_hw *ah)
-  	ath9k_tx99_init_debug(sc);
-  	ath9k_spectral_init_debug(sc);
-  
-diff --git a/package/mac80211/patches/501-ath9k-eeprom_endianess.patch b/package/mac80211/patches/501-ath9k-eeprom_endianess.patch
-index 96e7c6d..169eb9a 100644
---- a/package/mac80211/patches/501-ath9k-eeprom_endianess.patch
-+++ b/package/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/mac80211/patches/502-ath9k_ahb_init.patch b/package/mac80211/patches/502-ath9k_ahb_init.patch
-index 4edc63b..0c8e813 100644
---- a/package/mac80211/patches/502-ath9k_ahb_init.patch
-+++ b/package/mac80211/patches/502-ath9k_ahb_init.patch
-@@ -1,15 +1,15 @@
- --- 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;
-- 	}
-+@@ -904,23 +904,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/mac80211/patches/511-ath9k_reduce_rxbuf.patch b/package/mac80211/patches/511-ath9k_reduce_rxbuf.patch
-index ef0b9a1..e457267 100644
---- a/package/mac80211/patches/511-ath9k_reduce_rxbuf.patch
-+++ b/package/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/mac80211/patches/512-ath9k_channelbw_debugfs.patch b/package/mac80211/patches/512-ath9k_channelbw_debugfs.patch
-index 8f3cc03..c0e173f 100644
---- a/package/mac80211/patches/512-ath9k_channelbw_debugfs.patch
-+++ b/package/mac80211/patches/512-ath9k_channelbw_debugfs.patch
-@@ -1,6 +1,6 @@
- --- a/drivers/net/wireless/ath/ath9k/debug.c
- +++ b/drivers/net/wireless/ath/ath9k/debug.c
--@@ -1528,6 +1528,52 @@ static const struct file_operations fops
-+@@ -1336,6 +1336,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)
-+@@ -1357,6 +1403,8 @@ int ath9k_init_debug(struct ath_hw *ah)
-  
-  	debugfs_create_file("eeprom", S_IRUSR, sc->debug.debugfs_phy, sc,
-  			    &fops_eeprom);
-@@ -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/mac80211/patches/520-mac80211_cur_txpower.patch b/package/mac80211/patches/520-mac80211_cur_txpower.patch
-index 6df95bc..ef7906e 100644
---- a/package/mac80211/patches/520-mac80211_cur_txpower.patch
-+++ b/package/mac80211/patches/520-mac80211_cur_txpower.patch
-@@ -1,6 +1,6 @@
- --- a/include/net/mac80211.h
- +++ b/include/net/mac80211.h
--@@ -1711,6 +1711,7 @@ struct ieee80211_hw {
-+@@ -1718,6 +1718,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
-+@@ -2084,7 +2084,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);
-  
-@@ -23,7 +23,7 @@
-  		*dbm = sdata->vif.bss_conf.txpower;
- --- a/net/mac80211/main.c
- +++ b/net/mac80211/main.c
--@@ -158,6 +158,7 @@ static u32 ieee80211_hw_conf_chan(struct
-+@@ -156,6 +156,7 @@ static u32 ieee80211_hw_conf_chan(struct
-  
-  	if (local->hw.conf.power_level != power) {
-  		changed |= IEEE80211_CONF_CHANGE_POWER;
-diff --git a/package/mac80211/patches/521-ath9k_cur_txpower.patch b/package/mac80211/patches/521-ath9k_cur_txpower.patch
-index 0d6c360..83ff465 100644
---- a/package/mac80211/patches/521-ath9k_cur_txpower.patch
-+++ b/package/mac80211/patches/521-ath9k_cur_txpower.patch
-@@ -1,6 +1,6 @@
- --- a/drivers/net/wireless/ath/ath9k/main.c
- +++ b/drivers/net/wireless/ath/ath9k/main.c
--@@ -308,8 +308,12 @@ static int ath_reset_internal(struct ath
-+@@ -310,8 +310,12 @@ static int ath_reset_internal(struct ath
-  	    (sc->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL))
-  		ath9k_mci_set_txpower(sc, true, false);
-  
-@@ -14,7 +14,7 @@
-  
-  out:
-  	spin_unlock_bh(&sc->sc_pcu_lock);
--@@ -1371,6 +1375,7 @@ static int ath9k_config(struct ieee80211
-+@@ -1405,6 +1409,7 @@ static int ath9k_config(struct ieee80211
-  		sc->config.txpowlimit = 2 * conf->power_level;
-  		ath9k_cmn_update_txpow(ah, sc->curtxpow,
-  				       sc->config.txpowlimit, &sc->curtxpow);
-diff --git a/package/mac80211/patches/522-mac80211_configure_antenna_gain.patch b/package/mac80211/patches/522-mac80211_configure_antenna_gain.patch
-index 308ee6e..2109d2e 100644
---- a/package/mac80211/patches/522-mac80211_configure_antenna_gain.patch
-+++ b/package/mac80211/patches/522-mac80211_configure_antenna_gain.patch
-@@ -1,6 +1,6 @@
- --- a/include/net/cfg80211.h
- +++ b/include/net/cfg80211.h
--@@ -2156,6 +2156,7 @@ struct cfg80211_qos_map {
-+@@ -2207,6 +2207,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 {
-+@@ -2431,6 +2432,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.
-+@@ -1591,6 +1591,9 @@ enum nl80211_commands {
-+  *	creation then the new interface will be owned by the netlink socket
-+  *	that created it and will be destroyed when the socket is closed
-   *
- + * @NL80211_ATTR_WIPHY_ANTENNA_GAIN: Configured antenna gain. Used to reduce
- + *	transmit power to stay within regulatory limits. u32, dBi.
-@@ -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 {
-- 
-- 	NL80211_ATTR_QOS_MAP,
-+@@ -1931,6 +1934,8 @@ enum nl80211_attrs {
-+ 	NL80211_ATTR_CSA_C_OFFSETS_TX,
-+ 	NL80211_ATTR_MAX_CSA_COUNTERS,
-  
- +	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
-+@@ -2094,6 +2094,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 
-+@@ -3517,6 +3530,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 {
-+@@ -1243,6 +1243,7 @@ struct ieee80211_local {
-  	int dynamic_ps_forced_timeout;
-  
-  	int user_power_level; /* in dBm, for all interfaces */
-@@ -97,39 +97,29 @@
-  
- --- a/net/mac80211/main.c
- +++ b/net/mac80211/main.c
--@@ -101,7 +101,7 @@ static u32 ieee80211_hw_conf_chan(struct
-+@@ -97,7 +97,7 @@ static u32 ieee80211_hw_conf_chan(struct
-  	struct ieee80211_sub_if_data *sdata;
-  	struct cfg80211_chan_def chandef = {};
-  	u32 changed = 0;
- -	int power;
--+	int power, ant_gain, max_power;
-++	int power, max_power;
-  	u32 offchannel_flag;
-  
-  	offchannel_flag = local->hw.conf.flags & IEEE80211_CONF_OFFCHANNEL;
--@@ -156,8 +156,21 @@ static u32 ieee80211_hw_conf_chan(struct
-+@@ -154,6 +154,12 @@ static u32 ieee80211_hw_conf_chan(struct
-  	}
-  	rcu_read_unlock();
-  
---	if (local->hw.conf.power_level != power) {
- +	max_power = chandef.chan->max_reg_power;
--+	ant_gain = chandef.chan->max_antenna_gain;
- +	if (local->user_antenna_gain > 0) {
--+		if (local->user_antenna_gain > ant_gain) {
--+			max_power -= local->user_antenna_gain - ant_gain;
--+			ant_gain = 0;
--+		} else
--+			ant_gain -= local->user_antenna_gain;
-++		max_power -= local->user_antenna_gain;
- +		power = min(power, max_power);
- +	}
- +
--+	if (local->hw.conf.power_level != power ||
--+	    local->hw.conf.max_antenna_gain != ant_gain) {
-+ 	if (local->hw.conf.power_level != power) {
-  		changed |= IEEE80211_CONF_CHANGE_POWER;
--+		local->hw.conf.max_antenna_gain = ant_gain;
-  		local->hw.cur_power_level = power;
-- 		local->hw.conf.power_level = power;
-- 	}
--@@ -584,6 +597,7 @@ struct ieee80211_hw *ieee80211_alloc_hw(
-+@@ -584,6 +590,7 @@ struct ieee80211_hw *ieee80211_alloc_hw(
-  					 IEEE80211_RADIOTAP_MCS_HAVE_BW;
-  	local->hw.radiotap_vht_details = IEEE80211_RADIOTAP_VHT_KNOWN_GI |
-  					 IEEE80211_RADIOTAP_VHT_KNOWN_BANDWIDTH;
-@@ -139,32 +129,30 @@
-  	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 },
-+@@ -387,6 +387,7 @@ static const struct nla_policy nl80211_p
-+ 	[NL80211_ATTR_TDLS_PEER_CAPABILITY] = { .type = NLA_U32 },
-+ 	[NL80211_ATTR_IFACE_SOCKET_OWNER] = { .type = NLA_FLAG },
-+ 	[NL80211_ATTR_CSA_C_OFFSETS_TX] = { .type = NLA_BINARY },
- +	[NL80211_ATTR_WIPHY_ANTENNA_GAIN] = { .type = NLA_U32 },
-  };
-  
-  /* policy for the key attributes */
--@@ -2105,6 +2106,22 @@ static int nl80211_set_wiphy(struct sk_b
-- 			goto bad_res;
-+@@ -2162,6 +2163,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] &&
-diff --git a/package/mac80211/patches/523-ath9k_use_configured_antenna_gain.patch b/package/mac80211/patches/523-ath9k_use_configured_antenna_gain.patch
-index 30aa9ee..0b28ab8 100644
---- a/package/mac80211/patches/523-ath9k_use_configured_antenna_gain.patch
-+++ b/package/mac80211/patches/523-ath9k_use_configured_antenna_gain.patch
-@@ -1,6 +1,6 @@
- --- 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;
-@@ -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
-+@@ -1405,7 +1405,10 @@ static int ath9k_config(struct ieee80211
-  	}
-  
-  	if (changed & IEEE80211_CONF_CHANGE_POWER) {
-diff --git a/package/mac80211/patches/530-ath9k_extra_leds.patch b/package/mac80211/patches/530-ath9k_extra_leds.patch
-index 59f78d9..b5f2f8b 100644
---- a/package/mac80211/patches/530-ath9k_extra_leds.patch
-+++ b/package/mac80211/patches/530-ath9k_extra_leds.patch
-@@ -1,6 +1,6 @@
- --- a/drivers/net/wireless/ath/ath9k/ath9k.h
- +++ b/drivers/net/wireless/ath/ath9k/ath9k.h
--@@ -563,6 +563,9 @@ static inline int ath9k_dump_btcoex(stru
-+@@ -564,6 +564,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 {
-+@@ -702,6 +705,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];
-+@@ -744,9 +754,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 
-+@@ -815,7 +815,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
-+@@ -1381,6 +1381,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)
-+@@ -1405,6 +1460,10 @@ int ath9k_init_debug(struct ath_hw *ah)
-  			    &fops_eeprom);
-  	debugfs_create_file("chanbw", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy,
-  			    sc, &fops_chanbw);
-diff --git a/package/mac80211/patches/531-ath9k_extra_platform_leds.patch b/package/mac80211/patches/531-ath9k_extra_platform_leds.patch
-index 6c9832c..718a3d0 100644
---- a/package/mac80211/patches/531-ath9k_extra_platform_leds.patch
-+++ b/package/mac80211/patches/531-ath9k_extra_platform_leds.patch
-@@ -1,9 +1,9 @@
- --- a/include/linux/ath9k_platform.h
- +++ b/include/linux/ath9k_platform.h
--@@ -37,6 +37,9 @@ struct ath9k_platform_data {
-- 
-- 	int (*get_mac_revision)(void);
-+@@ -39,6 +39,9 @@ struct ath9k_platform_data {
-  	int (*external_reset)(void);
-+ 
-+ 	bool use_eeprom;
- +
- +	int num_leds;
- +	const struct gpio_led *leds;
-diff --git a/package/mac80211/patches/542-ath9k_debugfs_diag.patch b/package/mac80211/patches/542-ath9k_debugfs_diag.patch
-index e1b6ff1..2a56352 100644
---- a/package/mac80211/patches/542-ath9k_debugfs_diag.patch
-+++ b/package/mac80211/patches/542-ath9k_debugfs_diag.patch
-@@ -1,6 +1,6 @@
- --- a/drivers/net/wireless/ath/ath9k/debug.c
- +++ b/drivers/net/wireless/ath/ath9k/debug.c
--@@ -1629,6 +1629,50 @@ static const struct file_operations fops
-+@@ -1437,6 +1437,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)
-+@@ -1464,6 +1508,8 @@ int ath9k_init_debug(struct ath_hw *ah)
-  	debugfs_create_file("gpio_led", S_IWUSR,
-  			   sc->debug.debugfs_phy, sc, &fops_gpio_led);
-  #endif
-@@ -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)
-+@@ -606,6 +606,11 @@ irqreturn_t ath_isr(int irq, void *dev)
-  	ath9k_debug_sync_cause(sc, sync_cause);
-  	status &= ah->imask;	/* discard unasked-for bits */
-  
-diff --git a/package/mac80211/patches/543-ath9k-allow-to-disable-bands-via-platform-data.patch b/package/mac80211/patches/543-ath9k-allow-to-disable-bands-via-platform-data.patch
-index d26a5af..0501582 100644
---- a/package/mac80211/patches/543-ath9k-allow-to-disable-bands-via-platform-data.patch
-+++ b/package/mac80211/patches/543-ath9k-allow-to-disable-bands-via-platform-data.patch
-@@ -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/mac80211/patches/550-ath9k_entropy_from_adc.patch b/package/mac80211/patches/550-ath9k_entropy_from_adc.patch
-index b59c362..7210a02 100644
---- a/package/mac80211/patches/550-ath9k_entropy_from_adc.patch
-+++ b/package/mac80211/patches/550-ath9k_entropy_from_adc.patch
-@@ -55,7 +55,7 @@
-  	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
-+@@ -646,7 +646,8 @@ static void ath9k_init_txpower_limits(st
-  	if (ah->caps.hw_caps & ATH9K_HW_CAP_5GHZ)
-  		ath9k_init_band_txpower(sc, IEEE80211_BAND_5GHZ);
-  
-@@ -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[] = {
-+@@ -774,6 +775,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 
-+@@ -822,6 +835,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/mac80211/patches/551-ath9k-ar933x-usb-hang-workaround.patch b/package/mac80211/patches/551-ath9k-ar933x-usb-hang-workaround.patch
-new file mode 100644
-index 0000000..10280d9
---- /dev/null
-+++ b/package/mac80211/patches/551-ath9k-ar933x-usb-hang-workaround.patch
-@@ -0,0 +1,79 @@
-+--- a/drivers/net/wireless/ath/ath9k/hw.c
-++++ b/drivers/net/wireless/ath/ath9k/hw.c
-+@@ -215,6 +215,19 @@ void ath9k_hw_get_channel_centers(struct
-+ 		centers->synth_center + (extoff * HT40_CHANNEL_CENTER_SHIFT);
-+ }
-+ 
-++static inline void ath9k_hw_disable_pll_lock_detect(struct ath_hw *ah)
-++{
-++	/* On AR9330 and AR9340 devices, some PHY registers must be
-++	 * tuned to gain better stability/performance. These registers
-++	 * might be changed while doing wlan reset so the registers must
-++	 * be reprogrammed after each reset.
-++	 */
-++	REG_CLR_BIT(ah, AR_PHY_USB_CTRL1, BIT(20));
-++	REG_RMW(ah, AR_PHY_USB_CTRL2,
-++		(1 << 21) | (0xf << 22),
-++		(1 << 21) | (0x3 << 22));
-++}
-++
-+ /******************/
-+ /* Chip Revisions */
-+ /******************/
-+@@ -1337,6 +1350,9 @@ static bool ath9k_hw_set_reset(struct at
-+ 	if (AR_SREV_9100(ah))
-+ 		udelay(50);
-+ 
-++	if (AR_SREV_9330(ah) || AR_SREV_9340(ah))
-++		ath9k_hw_disable_pll_lock_detect(ah);
-++
-+ 	return true;
-+ }
-+ 
-+@@ -1436,6 +1452,9 @@ static bool ath9k_hw_chip_reset(struct a
-+ 		ar9003_hw_internal_regulator_apply(ah);
-+ 	ath9k_hw_init_pll(ah, chan);
-+ 
-++	if (AR_SREV_9330(ah) || AR_SREV_9340(ah))
-++		ath9k_hw_disable_pll_lock_detect(ah);
-++
-+ 	return true;
-+ }
-+ 
-+@@ -1730,8 +1749,14 @@ static int ath9k_hw_do_fastcc(struct ath
-+ 	if (AR_SREV_9271(ah))
-+ 		ar9002_hw_load_ani_reg(ah, chan);
-+ 
-++	if (AR_SREV_9330(ah) || AR_SREV_9340(ah))
-++		ath9k_hw_disable_pll_lock_detect(ah);
-++
-+ 	return 0;
-+ fail:
-++	if (AR_SREV_9330(ah) || AR_SREV_9340(ah))
-++		ath9k_hw_disable_pll_lock_detect(ah);
-++
-+ 	return -EINVAL;
-+ }
-+ 
-+@@ -1959,6 +1984,9 @@ int ath9k_hw_reset(struct ath_hw *ah, st
-+ 	if (AR_SREV_9565(ah) && common->bt_ant_diversity)
-+ 		REG_SET_BIT(ah, AR_BTCOEX_WL_LNADIV, AR_BTCOEX_WL_LNADIV_FORCE_ON);
-+ 
-++	if (AR_SREV_9330(ah) || AR_SREV_9340(ah))
-++		ath9k_hw_disable_pll_lock_detect(ah);
-++
-+ 	return 0;
-+ }
-+ EXPORT_SYMBOL(ath9k_hw_reset);
-+--- a/drivers/net/wireless/ath/ath9k/phy.h
-++++ b/drivers/net/wireless/ath/ath9k/phy.h
-+@@ -48,6 +48,9 @@
-+ #define AR_PHY_PLL_CONTROL 0x16180
-+ #define AR_PHY_PLL_MODE 0x16184
-+ 
-++#define AR_PHY_USB_CTRL1	0x16c84
-++#define AR_PHY_USB_CTRL2	0x16c88
-++
-+ enum ath9k_ant_div_comb_lna_conf {
-+ 	ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2,
-+ 	ATH_ANT_DIV_COMB_LNA2,
-diff --git a/package/mac80211/patches/551-ath9k_p2p_ifcomb.patch b/package/mac80211/patches/551-ath9k_p2p_ifcomb.patch
-deleted file mode 100644
-index ffffe0c..0000000
---- a/package/mac80211/patches/551-ath9k_p2p_ifcomb.patch
-+++ /dev/null
-@@ -1,33 +0,0 @@
--From c997a1da25fe7c717ed099888b8eb35d4e139e70 Mon Sep 17 00:00:00 2001
--From: Felix Fietkau <nbd@openwrt.org>
--Date: Sun, 8 Dec 2013 08:52:52 +0100
--Subject: [PATCH] ath9k: support only one P2P interface
--
--Preparation for adding P2P powersave and multi-channel support.
--
--Signed-off-by: Felix Fietkau <nbd@openwrt.org>
-----
-- drivers/net/wireless/ath/ath9k/init.c | 4 ++--
--  1 file changed, 2 insertions(+), 2 deletions(-)
--
----- a/drivers/net/wireless/ath/ath9k/init.c
--+++ b/drivers/net/wireless/ath/ath9k/init.c
--@@ -863,15 +863,15 @@ void ath9k_reload_chainmask_settings(str
-- 
-- static const struct ieee80211_iface_limit if_limits[] = {
-- 	{ .max = 2048,	.types = BIT(NL80211_IFTYPE_STATION) |
---				 BIT(NL80211_IFTYPE_P2P_CLIENT) |
-- 				 BIT(NL80211_IFTYPE_WDS) },
-- 	{ .max = 8,	.types =
-- #ifdef CPTCFG_MAC80211_MESH
-- 				 BIT(NL80211_IFTYPE_MESH_POINT) |
-- #endif
---				 BIT(NL80211_IFTYPE_AP) |
---				 BIT(NL80211_IFTYPE_P2P_GO) },
--+				 BIT(NL80211_IFTYPE_AP) },
-- 	{ .max = 1,	.types = BIT(NL80211_IFTYPE_ADHOC) },
--+	{ .max = 1,	.types = BIT(NL80211_IFTYPE_P2P_CLIENT) |
--+				 BIT(NL80211_IFTYPE_P2P_GO) },
-- };
-- 
-- static const struct ieee80211_iface_limit if_dfs_limits[] = {
-diff --git a/package/mac80211/patches/552-ath9k_p2p_ps_support.patch b/package/mac80211/patches/552-ath9k_p2p_ps_support.patch
-deleted file mode 100644
-index 4a61db3..0000000
---- a/package/mac80211/patches/552-ath9k_p2p_ps_support.patch
-+++ /dev/null
-@@ -1,247 +0,0 @@
--From 6744d0a7ea037c7d65e13ca906da93009b241d00 Mon Sep 17 00:00:00 2001
--From: Felix Fietkau <nbd@openwrt.org>
--Date: Tue, 11 Feb 2014 11:16:24 +0100
--Subject: [PATCH] ath9k: implement p2p client powersave support
--
--Use generic TSF timers to trigger powersave state changes based
--information from the P2P NoA attribute.
--Opportunistic Powersave is not handled, because the driver does not
--support powersave at the moment.
--
--Signed-off-by: Felix Fietkau <nbd@openwrt.org>
-----
-- drivers/net/wireless/ath/ath9k/ath9k.h |  12 ++++
-- drivers/net/wireless/ath/ath9k/init.c  |   6 ++
-- drivers/net/wireless/ath/ath9k/main.c  | 104 +++++++++++++++++++++++++++++++++
-- drivers/net/wireless/ath/ath9k/recv.c  |   3 +
-- 4 files changed, 125 insertions(+)
--
----- a/drivers/net/wireless/ath/ath9k/main.c
--+++ b/drivers/net/wireless/ath/ath9k/main.c
--@@ -261,6 +261,8 @@ static bool ath_complete_reset(struct at
-- 	sc->gtt_cnt = 0;
-- 	ieee80211_wake_queues(sc->hw);
-- 
--+	ath9k_p2p_ps_timer(sc);
--+
-- 	return true;
-- }
-- 
--@@ -1126,6 +1128,8 @@ static int ath9k_add_interface(struct ie
-- 	if (ath9k_uses_beacons(vif->type))
-- 		ath9k_beacon_assign_slot(sc, vif);
-- 
--+	avp->vif = vif;
--+
-- 	an->sc = sc;
-- 	an->sta = NULL;
-- 	an->vif = vif;
--@@ -1170,6 +1174,29 @@ static int ath9k_change_interface(struct
-- 	return 0;
-- }
-- 
--+static void
--+ath9k_update_p2p_ps_timer(struct ath_softc *sc, struct ath_vif *avp)
--+{
--+	struct ath_hw *ah = sc->sc_ah;
--+	s32 tsf, target_tsf;
--+
--+	if (!avp || !avp->noa.has_next_tsf)
--+		return;
--+
--+	ath9k_hw_gen_timer_stop(ah, sc->p2p_ps_timer);
--+
--+	tsf = ath9k_hw_gettsf32(sc->sc_ah);
--+
--+	target_tsf = avp->noa.next_tsf;
--+	if (!avp->noa.absent)
--+		target_tsf -= ATH_P2P_PS_STOP_TIME;
--+
--+	if (target_tsf - tsf < ATH_P2P_PS_STOP_TIME)
--+		target_tsf = tsf + ATH_P2P_PS_STOP_TIME;
--+
--+	ath9k_hw_gen_timer_start(ah, sc->p2p_ps_timer, (u32) target_tsf, 1000000);
--+}
--+
-- static void ath9k_remove_interface(struct ieee80211_hw *hw,
-- 				   struct ieee80211_vif *vif)
-- {
--@@ -1181,6 +1208,13 @@ static void ath9k_remove_interface(struc
-- 
-- 	mutex_lock(&sc->mutex);
-- 
--+	spin_lock_bh(&sc->sc_pcu_lock);
--+	if (avp == sc->p2p_ps_vif) {
--+		sc->p2p_ps_vif = NULL;
--+		ath9k_update_p2p_ps_timer(sc, NULL);
--+	}
--+	spin_unlock_bh(&sc->sc_pcu_lock);
--+
-- 	sc->nvifs--;
-- 	sc->tx99_vif = NULL;
-- 
--@@ -1649,6 +1683,70 @@ static void ath9k_bss_assoc_iter(void *d
-- 		ath9k_set_assoc_state(sc, vif);
-- }
-- 
--+void ath9k_p2p_ps_timer(void *priv)
--+{
--+	struct ath_softc *sc = priv;
--+	struct ath_vif *avp = sc->p2p_ps_vif;
--+	struct ieee80211_vif *vif;
--+	struct ieee80211_sta *sta;
--+	struct ath_node *an;
--+	u32 tsf;
--+
--+	if (!avp)
--+		return;
--+
--+	tsf = ath9k_hw_gettsf32(sc->sc_ah);
--+	if (!avp->noa.absent)
--+		tsf += ATH_P2P_PS_STOP_TIME;
--+
--+	if (!avp->noa.has_next_tsf ||
--+	    avp->noa.next_tsf - tsf > BIT(31))
--+		ieee80211_update_p2p_noa(&avp->noa, tsf);
--+
--+	ath9k_update_p2p_ps_timer(sc, avp);
--+
--+	rcu_read_lock();
--+
--+	vif = avp->vif;
--+	sta = ieee80211_find_sta(vif, vif->bss_conf.bssid);
--+	if (!sta)
--+		goto out;
--+
--+	an = (void *) sta->drv_priv;
--+	if (an->sleeping == !!avp->noa.absent)
--+		goto out;
--+
--+	an->sleeping = avp->noa.absent;
--+	if (an->sleeping)
--+		ath_tx_aggr_sleep(sta, sc, an);
--+	else
--+		ath_tx_aggr_wakeup(sc, an);
--+
--+out:
--+	rcu_read_unlock();
--+}
--+
--+void ath9k_update_p2p_ps(struct ath_softc *sc, struct ieee80211_vif *vif)
--+{
--+	struct ath_vif *avp = (void *)vif->drv_priv;
--+	u32 tsf;
--+
--+	if (!sc->p2p_ps_timer)
--+		return;
--+
--+	if (vif->type != NL80211_IFTYPE_STATION || !vif->p2p)
--+		return;
--+
--+	sc->p2p_ps_vif = avp;
--+
--+	if (sc->ps_flags & PS_BEACON_SYNC)
--+		return;
--+
--+	tsf = ath9k_hw_gettsf32(sc->sc_ah);
--+	ieee80211_parse_p2p_noa(&vif->bss_conf.p2p_noa_attr, &avp->noa, tsf);
--+	ath9k_update_p2p_ps_timer(sc, avp);
--+}
--+
-- 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
-- 		}
-- 	}
-- 
--+	if (changed & BSS_CHANGED_P2P_PS) {
--+		spin_lock_bh(&sc->sc_pcu_lock);
--+		ath9k_update_p2p_ps(sc, vif);
--+		spin_unlock_bh(&sc->sc_pcu_lock);
--+	}
--+
-- 	if (changed & CHECK_ANI)
-- 		ath_check_ani(sc);
-- 
----- a/drivers/net/wireless/ath/ath9k/ath9k.h
--+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
--@@ -115,6 +115,9 @@ int ath_descdma_setup(struct ath_softc *
-- #define ATH_TXFIFO_DEPTH           8
-- #define ATH_TX_ERROR               0x01
-- 
--+/* Stop tx traffic 1ms before the GO goes away */
--+#define ATH_P2P_PS_STOP_TIME       1000
--+
-- #define IEEE80211_SEQ_SEQ_SHIFT    4
-- #define IEEE80211_SEQ_MAX          4096
-- #define IEEE80211_WEP_IVLEN        3
--@@ -363,11 +366,15 @@ void ath9k_release_buffered_frames(struc
-- /********/
-- 
-- struct ath_vif {
--+	struct ieee80211_vif *vif;
-- 	struct ath_node mcast_node;
-- 	int av_bslot;
-- 	bool primary_sta_vif;
-- 	__le64 tsf_adjust; /* TSF adjustment for staggered beacons */
-- 	struct ath_buf *av_bcbuf;
--+
--+	/* P2P Client */
--+	struct ieee80211_noa_data noa;
-- };
-- 
-- struct ath9k_vif_iter_data {
--@@ -472,6 +479,8 @@ int ath_update_survey_stats(struct ath_s
-- void ath_update_survey_nf(struct ath_softc *sc, int channel);
-- void ath9k_queue_reset(struct ath_softc *sc, enum ath_reset_type type);
-- void ath_ps_full_sleep(unsigned long data);
--+void ath9k_p2p_ps_timer(void *priv);
--+void ath9k_update_p2p_ps(struct ath_softc *sc, struct ieee80211_vif *vif);
-- 
-- /**********/
-- /* BTCOEX */
--@@ -741,6 +750,9 @@ struct ath_softc {
-- 	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;
-- 
----- 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
-- 	if (ret)
-- 		goto err_btcoex;
-- 
--+	sc->p2p_ps_timer = ath_gen_timer_alloc(sc->sc_ah, ath9k_p2p_ps_timer,
--+		NULL, sc, AR_FIRST_NDP_TIMER);
--+
-- 	ath9k_cmn_init_crypto(sc->sc_ah);
-- 	ath9k_init_misc(sc);
-- 	ath_fill_led_pin(sc);
--@@ -1082,6 +1085,9 @@ static void ath9k_deinit_softc(struct at
-- {
-- 	int i = 0;
-- 
--+	if (sc->p2p_ps_timer)
--+		ath_gen_timer_free(sc->sc_ah, sc->p2p_ps_timer);
--+
-- 	ath9k_deinit_btcoex(sc);
-- 
-- 	for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++)
----- a/drivers/net/wireless/ath/ath9k/recv.c
--+++ b/drivers/net/wireless/ath/ath9k/recv.c
--@@ -539,6 +539,9 @@ static void ath_rx_ps_beacon(struct ath_
-- 		ath_dbg(common, PS,
-- 			"Reconfigure beacon timers based on synchronized timestamp\n");
-- 		ath9k_set_beacon(sc);
--+
--+		if (sc->p2p_ps_vif)
--+			ath9k_update_p2p_ps(sc, sc->p2p_ps_vif->vif);
-- 	}
-- 
-- 	if (ath_beacon_dtim_pending_cab(skb)) {
-diff --git a/package/mac80211/patches/560-ath9k_pcoem_optional.patch b/package/mac80211/patches/560-ath9k_pcoem_optional.patch
-new file mode 100644
-index 0000000..4d4ea3b
---- /dev/null
-+++ b/package/mac80211/patches/560-ath9k_pcoem_optional.patch
-@@ -0,0 +1,249 @@
-+--- a/drivers/net/wireless/ath/ath9k/Kconfig
-++++ b/drivers/net/wireless/ath/ath9k/Kconfig
-+@@ -133,6 +133,11 @@ config ATH9K_RFKILL
-+ 	  seconds. Turn off to save power, but enable it if you have
-+ 	  a platform that can toggle the RF-Kill GPIO.
-+ 
-++config ATH9K_PCOEM
-++	bool "Atheros ath9k support for PC OEM cards" if EXPERT
-++	depends on ATH9K
-++	default y
-++
-+ config ATH9K_HTC
-+        tristate "Atheros HTC based wireless cards support"
-+        depends on m
-+--- a/drivers/net/wireless/ath/ath9k/Makefile
-++++ b/drivers/net/wireless/ath/ath9k/Makefile
-+@@ -31,7 +31,6 @@ ath9k_hw-y:=	\
-+ 		ar5008_phy.o \
-+ 		ar9002_calib.o \
-+ 		ar9003_calib.o \
-+-		ar9003_rtt.o \
-+ 		calib.o \
-+ 		eeprom.o \
-+ 		eeprom_def.o \
-+@@ -48,6 +47,8 @@ ath9k_hw-$(CPTCFG_ATH9K_WOW) += ar9003_w
-+ 
-+ ath9k_hw-$(CPTCFG_ATH9K_BTCOEX_SUPPORT) += btcoex.o \
-+ 					   ar9003_mci.o
-++ath9k_hw-$(CPTCFG_ATH9K_PCOEM) += ar9003_rtt.o
-++
-+ obj-$(CPTCFG_ATH9K_HW) += ath9k_hw.o
-+ 
-+ obj-$(CPTCFG_ATH9K_COMMON) += ath9k_common.o
-+--- a/drivers/net/wireless/ath/ath9k/ar9003_rtt.h
-++++ b/drivers/net/wireless/ath/ath9k/ar9003_rtt.h
-+@@ -17,6 +17,7 @@
-+ #ifndef AR9003_RTT_H
-+ #define AR9003_RTT_H
-+ 
-++#ifdef CPTCFG_ATH9K_PCOEM
-+ void ar9003_hw_rtt_enable(struct ath_hw *ah);
-+ void ar9003_hw_rtt_disable(struct ath_hw *ah);
-+ void ar9003_hw_rtt_set_mask(struct ath_hw *ah, u32 rtt_mask);
-+@@ -25,5 +26,40 @@ void ar9003_hw_rtt_load_hist(struct ath_
-+ void ar9003_hw_rtt_fill_hist(struct ath_hw *ah);
-+ void ar9003_hw_rtt_clear_hist(struct ath_hw *ah);
-+ bool ar9003_hw_rtt_restore(struct ath_hw *ah, struct ath9k_channel *chan);
-++#else
-++static inline void ar9003_hw_rtt_enable(struct ath_hw *ah)
-++{
-++}
-++
-++static inline void ar9003_hw_rtt_disable(struct ath_hw *ah)
-++{
-++}
-++
-++static inline void ar9003_hw_rtt_set_mask(struct ath_hw *ah, u32 rtt_mask)
-++{
-++}
-++
-++static inline bool ar9003_hw_rtt_force_restore(struct ath_hw *ah)
-++{
-++	return false;
-++}
-++
-++static inline void ar9003_hw_rtt_load_hist(struct ath_hw *ah)
-++{
-++}
-++
-++static inline void ar9003_hw_rtt_fill_hist(struct ath_hw *ah)
-++{
-++}
-++
-++static inline void ar9003_hw_rtt_clear_hist(struct ath_hw *ah)
-++{
-++}
-++
-++static inline bool ar9003_hw_rtt_restore(struct ath_hw *ah, struct ath9k_channel *chan)
-++{
-++	return false;
-++}
-++#endif
-+ 
-+ #endif
-+--- a/drivers/net/wireless/ath/ath9k/hw.h
-++++ b/drivers/net/wireless/ath/ath9k/hw.h
-+@@ -244,13 +244,20 @@ enum ath9k_hw_caps {
-+ 	ATH9K_HW_CAP_2GHZ			= BIT(11),
-+ 	ATH9K_HW_CAP_5GHZ			= BIT(12),
-+ 	ATH9K_HW_CAP_APM			= BIT(13),
-++#ifdef CPTCFG_ATH9K_PCOEM
-+ 	ATH9K_HW_CAP_RTT			= BIT(14),
-+ 	ATH9K_HW_CAP_MCI			= BIT(15),
-+-	ATH9K_HW_CAP_DFS			= BIT(16),
-+-	ATH9K_HW_WOW_DEVICE_CAPABLE		= BIT(17),
-+-	ATH9K_HW_CAP_PAPRD			= BIT(18),
-+-	ATH9K_HW_CAP_FCC_BAND_SWITCH		= BIT(19),
-+-	ATH9K_HW_CAP_BT_ANT_DIV			= BIT(20),
-++	ATH9K_HW_WOW_DEVICE_CAPABLE		= BIT(16),
-++	ATH9K_HW_CAP_BT_ANT_DIV			= BIT(17),
-++#else
-++	ATH9K_HW_CAP_RTT			= 0,
-++	ATH9K_HW_CAP_MCI			= 0,
-++	ATH9K_HW_WOW_DEVICE_CAPABLE		= 0,
-++	ATH9K_HW_CAP_BT_ANT_DIV			= 0,
-++#endif
-++	ATH9K_HW_CAP_DFS			= BIT(18),
-++	ATH9K_HW_CAP_PAPRD			= BIT(19),
-++	ATH9K_HW_CAP_FCC_BAND_SWITCH		= BIT(20),
-+ };
-+ 
-+ /*
-+--- a/drivers/net/wireless/ath/ath9k/init.c
-++++ b/drivers/net/wireless/ath/ath9k/init.c
-+@@ -355,6 +355,9 @@ static void ath9k_init_pcoem_platform(st
-+ 	struct ath9k_hw_capabilities *pCap = &ah->caps;
-+ 	struct ath_common *common = ath9k_hw_common(ah);
-+ 
-++	if (!IS_ENABLED(CPTCFG_ATH9K_PCOEM))
-++		return;
-++
-+ 	if (common->bus_ops->ath_bus_type != ATH_PCI)
-+ 		return;
-+ 
-+--- a/drivers/net/wireless/ath/ath9k/pci.c
-++++ b/drivers/net/wireless/ath/ath9k/pci.c
-+@@ -30,6 +30,7 @@ static DEFINE_PCI_DEVICE_TABLE(ath_pci_i
-+ 	{ PCI_VDEVICE(ATHEROS, 0x0029) }, /* PCI   */
-+ 	{ PCI_VDEVICE(ATHEROS, 0x002A) }, /* PCI-E */
-+ 
-++#ifdef CPTCFG_ATH9K_PCOEM
-+ 	{ PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
-+ 			 0x002A,
-+ 			 PCI_VENDOR_ID_AZWAVE,
-+@@ -82,6 +83,7 @@ static DEFINE_PCI_DEVICE_TABLE(ath_pci_i
-+ 			 PCI_VENDOR_ID_AZWAVE,
-+ 			 0x2C37),
-+ 	  .driver_data = ATH9K_PCI_BT_ANT_DIV },
-++#endif
-+ 
-+ 	{ PCI_VDEVICE(ATHEROS, 0x002B) }, /* PCI-E */
-+ 	{ PCI_VDEVICE(ATHEROS, 0x002C) }, /* PCI-E 802.11n bonded out */
-+@@ -102,6 +104,7 @@ static DEFINE_PCI_DEVICE_TABLE(ath_pci_i
-+ 
-+ 	{ PCI_VDEVICE(ATHEROS, 0x0030) }, /* PCI-E  AR9300 */
-+ 
-++#ifdef CPTCFG_ATH9K_PCOEM
-+ 	/* PCI-E CUS198 */
-+ 	{ PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
-+ 			 0x0032,
-+@@ -294,10 +297,12 @@ static DEFINE_PCI_DEVICE_TABLE(ath_pci_i
-+ 			 PCI_VENDOR_ID_ASUSTEK,
-+ 			 0x850D),
-+ 	  .driver_data = ATH9K_PCI_NO_PLL_PWRSAVE },
-++#endif
-+ 
-+ 	{ PCI_VDEVICE(ATHEROS, 0x0032) }, /* PCI-E  AR9485 */
-+ 	{ PCI_VDEVICE(ATHEROS, 0x0033) }, /* PCI-E  AR9580 */
-+ 
-++#ifdef CPTCFG_ATH9K_PCOEM
-+ 	/* PCI-E CUS217 */
-+ 	{ PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
-+ 			 0x0034,
-+@@ -657,6 +662,7 @@ static DEFINE_PCI_DEVICE_TABLE(ath_pci_i
-+ 	/* PCI-E AR9565 (WB335) */
-+ 	{ PCI_VDEVICE(ATHEROS, 0x0036),
-+ 	  .driver_data = ATH9K_PCI_BT_ANT_DIV },
-++#endif
-+ 
-+ 	{ PCI_VDEVICE(ATHEROS, 0xabcd) }, /* PCI-E  internal chip default ID */
-+ 	{ 0 }
-+--- a/drivers/net/wireless/ath/ath9k/reg.h
-++++ b/drivers/net/wireless/ath/ath9k/reg.h
-+@@ -891,10 +891,21 @@
-+ 	(AR_SREV_9330((_ah)) && \
-+ 	 ((_ah)->hw_version.macRev == AR_SREV_REVISION_9330_12))
-+ 
-++#ifdef CPTCFG_ATH9K_PCOEM
-++#define AR_SREV_9462(_ah) \
-++	(((_ah)->hw_version.macVersion == AR_SREV_VERSION_9462))
-+ #define AR_SREV_9485(_ah) \
-+ 	(((_ah)->hw_version.macVersion == AR_SREV_VERSION_9485))
-++#define AR_SREV_9565(_ah) \
-++	(((_ah)->hw_version.macVersion == AR_SREV_VERSION_9565))
-++#else
-++#define AR_SREV_9462(_ah) 0
-++#define AR_SREV_9485(_ah) 0
-++#define AR_SREV_9565(_ah) 0
-++#endif
-++
-+ #define AR_SREV_9485_11_OR_LATER(_ah) \
-+-	(((_ah)->hw_version.macVersion == AR_SREV_VERSION_9485) && \
-++	(AR_SREV_9485(_ah) && \
-+ 	 ((_ah)->hw_version.macRev >= AR_SREV_REVISION_9485_11))
-+ #define AR_SREV_9485_OR_LATER(_ah) \
-+ 	(((_ah)->hw_version.macVersion >= AR_SREV_VERSION_9485))
-+@@ -910,34 +921,30 @@
-+     (AR_SREV_9285_12_OR_LATER(_ah) && \
-+      ((REG_READ(_ah, AR_AN_SYNTH9) & 0x7) == 0x1))
-+ 
-+-#define AR_SREV_9462(_ah) \
-+-	(((_ah)->hw_version.macVersion == AR_SREV_VERSION_9462))
-+ #define AR_SREV_9462_20(_ah) \
-+-	(((_ah)->hw_version.macVersion == AR_SREV_VERSION_9462) && \
-++	(AR_SREV_9462(_ah) && \
-+ 	 ((_ah)->hw_version.macRev == AR_SREV_REVISION_9462_20))
-+ #define AR_SREV_9462_21(_ah) \
-+-	(((_ah)->hw_version.macVersion == AR_SREV_VERSION_9462) && \
-++	(AR_SREV_9462(_ah) && \
-+ 	 ((_ah)->hw_version.macRev == AR_SREV_REVISION_9462_21))
-+ #define AR_SREV_9462_20_OR_LATER(_ah) \
-+-	(((_ah)->hw_version.macVersion == AR_SREV_VERSION_9462) && \
-++	(AR_SREV_9462(_ah) && \
-+ 	 ((_ah)->hw_version.macRev >= AR_SREV_REVISION_9462_20))
-+ #define AR_SREV_9462_21_OR_LATER(_ah) \
-+-	(((_ah)->hw_version.macVersion == AR_SREV_VERSION_9462) && \
-++	(AR_SREV_9462(_ah) && \
-+ 	 ((_ah)->hw_version.macRev >= AR_SREV_REVISION_9462_21))
-+ 
-+-#define AR_SREV_9565(_ah) \
-+-	(((_ah)->hw_version.macVersion == AR_SREV_VERSION_9565))
-+ #define AR_SREV_9565_10(_ah) \
-+-	(((_ah)->hw_version.macVersion == AR_SREV_VERSION_9565) && \
-++	(AR_SREV_9565(_ah) && \
-+ 	 ((_ah)->hw_version.macRev == AR_SREV_REVISION_9565_10))
-+ #define AR_SREV_9565_101(_ah) \
-+-	(((_ah)->hw_version.macVersion == AR_SREV_VERSION_9565) && \
-++	(AR_SREV_9565(_ah) && \
-+ 	 ((_ah)->hw_version.macRev == AR_SREV_REVISION_9565_101))
-+ #define AR_SREV_9565_11(_ah) \
-+-	(((_ah)->hw_version.macVersion == AR_SREV_VERSION_9565) && \
-++	(AR_SREV_9565(_ah) && \
-+ 	 ((_ah)->hw_version.macRev == AR_SREV_REVISION_9565_11))
-+ #define AR_SREV_9565_11_OR_LATER(_ah) \
-+-	(((_ah)->hw_version.macVersion == AR_SREV_VERSION_9565) && \
-++	(AR_SREV_9565(_ah) && \
-+ 	 ((_ah)->hw_version.macRev >= AR_SREV_REVISION_9565_11))
-+ 
-+ #define AR_SREV_9550(_ah) \
-+--- a/.local-symbols
-++++ b/.local-symbols
-+@@ -129,6 +129,7 @@ ATH9K_HW=
-+ ATH9K_COMMON=
-+ ATH9K_DFS_DEBUGFS=
-+ ATH9K_BTCOEX_SUPPORT=
-++ATH9K_PCOEM=
-+ ATH9K=
-+ ATH9K_PCI=
-+ ATH9K_AHB=
-diff --git a/package/mac80211/patches/561-ath9k_remove_gain_tables.patch b/package/mac80211/patches/561-ath9k_remove_gain_tables.patch
-new file mode 100644
-index 0000000..852eae3
---- /dev/null
-+++ b/package/mac80211/patches/561-ath9k_remove_gain_tables.patch
-@@ -0,0 +1,12 @@
-+--- a/drivers/net/wireless/ath/ath9k/ar9003_hw.c
-++++ b/drivers/net/wireless/ath/ath9k/ar9003_hw.c
-+@@ -663,9 +663,6 @@ static void ar9003_tx_gain_table_mode5(s
-+ 	if (AR_SREV_9485_11_OR_LATER(ah))
-+ 		INIT_INI_ARRAY(&ah->iniModesTxGain,
-+ 			ar9485Modes_green_ob_db_tx_gain_1_1);
-+-	else if (AR_SREV_9340(ah))
-+-		INIT_INI_ARRAY(&ah->iniModesTxGain,
-+-			ar9340Modes_ub124_tx_gain_table_1p0);
-+ 	else if (AR_SREV_9580(ah))
-+ 		INIT_INI_ARRAY(&ah->iniModesTxGain,
-+ 			ar9580_1p0_type5_tx_gain_table);
-diff --git a/package/mac80211/patches/562-ath9k_ani_ws_detect.patch b/package/mac80211/patches/562-ath9k_ani_ws_detect.patch
-new file mode 100644
-index 0000000..1e4f451
---- /dev/null
-+++ b/package/mac80211/patches/562-ath9k_ani_ws_detect.patch
-@@ -0,0 +1,155 @@
-+--- a/drivers/net/wireless/ath/ath9k/ar5008_phy.c
-++++ b/drivers/net/wireless/ath/ath9k/ar5008_phy.c
-+@@ -929,55 +929,6 @@ static bool ar5008_hw_ani_control_new(st
-+ 		 * on == 0 means more noise imm
-+ 		 */
-+ 		u32 on = param ? 1 : 0;
-+-		/*
-+-		 * make register setting for default
-+-		 * (weak sig detect ON) come from INI file
-+-		 */
-+-		int m1ThreshLow = on ?
-+-			aniState->iniDef.m1ThreshLow : m1ThreshLow_off;
-+-		int m2ThreshLow = on ?
-+-			aniState->iniDef.m2ThreshLow : m2ThreshLow_off;
-+-		int m1Thresh = on ?
-+-			aniState->iniDef.m1Thresh : m1Thresh_off;
-+-		int m2Thresh = on ?
-+-			aniState->iniDef.m2Thresh : m2Thresh_off;
-+-		int m2CountThr = on ?
-+-			aniState->iniDef.m2CountThr : m2CountThr_off;
-+-		int m2CountThrLow = on ?
-+-			aniState->iniDef.m2CountThrLow : m2CountThrLow_off;
-+-		int m1ThreshLowExt = on ?
-+-			aniState->iniDef.m1ThreshLowExt : m1ThreshLowExt_off;
-+-		int m2ThreshLowExt = on ?
-+-			aniState->iniDef.m2ThreshLowExt : m2ThreshLowExt_off;
-+-		int m1ThreshExt = on ?
-+-			aniState->iniDef.m1ThreshExt : m1ThreshExt_off;
-+-		int m2ThreshExt = on ?
-+-			aniState->iniDef.m2ThreshExt : m2ThreshExt_off;
-+-
-+-		REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW,
-+-			      AR_PHY_SFCORR_LOW_M1_THRESH_LOW,
-+-			      m1ThreshLow);
-+-		REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW,
-+-			      AR_PHY_SFCORR_LOW_M2_THRESH_LOW,
-+-			      m2ThreshLow);
-+-		REG_RMW_FIELD(ah, AR_PHY_SFCORR,
-+-			      AR_PHY_SFCORR_M1_THRESH, m1Thresh);
-+-		REG_RMW_FIELD(ah, AR_PHY_SFCORR,
-+-			      AR_PHY_SFCORR_M2_THRESH, m2Thresh);
-+-		REG_RMW_FIELD(ah, AR_PHY_SFCORR,
-+-			      AR_PHY_SFCORR_M2COUNT_THR, m2CountThr);
-+-		REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW,
-+-			      AR_PHY_SFCORR_LOW_M2COUNT_THR_LOW,
-+-			      m2CountThrLow);
-+-
-+-		REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
-+-			      AR_PHY_SFCORR_EXT_M1_THRESH_LOW, m1ThreshLowExt);
-+-		REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
-+-			      AR_PHY_SFCORR_EXT_M2_THRESH_LOW, m2ThreshLowExt);
-+-		REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
-+-			      AR_PHY_SFCORR_EXT_M1_THRESH, m1ThreshExt);
-+-		REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
-+-			      AR_PHY_SFCORR_EXT_M2_THRESH, m2ThreshExt);
-+ 
-+ 		if (on)
-+ 			REG_SET_BIT(ah, AR_PHY_SFCORR_LOW,
-+--- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c
-++++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
-+@@ -26,20 +26,6 @@ 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
-+- */
-+-static const int m1ThreshLow_off = 127;
-+-static const int m2ThreshLow_off = 127;
-+-static const int m1Thresh_off = 127;
-+-static const int m2Thresh_off = 127;
-+-static const int m2CountThr_off =  31;
-+-static const int m2CountThrLow_off =  63;
-+-static const int m1ThreshLowExt_off = 127;
-+-static const int m2ThreshLowExt_off = 127;
-+-static const int m1ThreshExt_off = 127;
-+-static const int m2ThreshExt_off = 127;
-+-
-+ /**
-+  * ar9003_hw_set_channel - set channel on single-chip device
-+  * @ah: atheros hardware structure
-+@@ -954,11 +940,6 @@ static bool ar9003_hw_ani_control(struct
-+ 	struct ath_common *common = ath9k_hw_common(ah);
-+ 	struct ath9k_channel *chan = ah->curchan;
-+ 	struct ar5416AniState *aniState = &ah->ani;
-+-	int m1ThreshLow, m2ThreshLow;
-+-	int m1Thresh, m2Thresh;
-+-	int m2CountThr, m2CountThrLow;
-+-	int m1ThreshLowExt, m2ThreshLowExt;
-+-	int m1ThreshExt, m2ThreshExt;
-+ 	s32 value, value2;
-+ 
-+ 	switch (cmd & ah->ani_function) {
-+@@ -972,61 +953,6 @@ static bool ar9003_hw_ani_control(struct
-+ 		 */
-+ 		u32 on = param ? 1 : 0;
-+ 
-+-		if (AR_SREV_9462(ah) || AR_SREV_9565(ah))
-+-			goto skip_ws_det;
-+-
-+-		m1ThreshLow = on ?
-+-			aniState->iniDef.m1ThreshLow : m1ThreshLow_off;
-+-		m2ThreshLow = on ?
-+-			aniState->iniDef.m2ThreshLow : m2ThreshLow_off;
-+-		m1Thresh = on ?
-+-			aniState->iniDef.m1Thresh : m1Thresh_off;
-+-		m2Thresh = on ?
-+-			aniState->iniDef.m2Thresh : m2Thresh_off;
-+-		m2CountThr = on ?
-+-			aniState->iniDef.m2CountThr : m2CountThr_off;
-+-		m2CountThrLow = on ?
-+-			aniState->iniDef.m2CountThrLow : m2CountThrLow_off;
-+-		m1ThreshLowExt = on ?
-+-			aniState->iniDef.m1ThreshLowExt : m1ThreshLowExt_off;
-+-		m2ThreshLowExt = on ?
-+-			aniState->iniDef.m2ThreshLowExt : m2ThreshLowExt_off;
-+-		m1ThreshExt = on ?
-+-			aniState->iniDef.m1ThreshExt : m1ThreshExt_off;
-+-		m2ThreshExt = on ?
-+-			aniState->iniDef.m2ThreshExt : m2ThreshExt_off;
-+-
-+-		REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW,
-+-			      AR_PHY_SFCORR_LOW_M1_THRESH_LOW,
-+-			      m1ThreshLow);
-+-		REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW,
-+-			      AR_PHY_SFCORR_LOW_M2_THRESH_LOW,
-+-			      m2ThreshLow);
-+-		REG_RMW_FIELD(ah, AR_PHY_SFCORR,
-+-			      AR_PHY_SFCORR_M1_THRESH,
-+-			      m1Thresh);
-+-		REG_RMW_FIELD(ah, AR_PHY_SFCORR,
-+-			      AR_PHY_SFCORR_M2_THRESH,
-+-			      m2Thresh);
-+-		REG_RMW_FIELD(ah, AR_PHY_SFCORR,
-+-			      AR_PHY_SFCORR_M2COUNT_THR,
-+-			      m2CountThr);
-+-		REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW,
-+-			      AR_PHY_SFCORR_LOW_M2COUNT_THR_LOW,
-+-			      m2CountThrLow);
-+-		REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
-+-			      AR_PHY_SFCORR_EXT_M1_THRESH_LOW,
-+-			      m1ThreshLowExt);
-+-		REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
-+-			      AR_PHY_SFCORR_EXT_M2_THRESH_LOW,
-+-			      m2ThreshLowExt);
-+-		REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
-+-			      AR_PHY_SFCORR_EXT_M1_THRESH,
-+-			      m1ThreshExt);
-+-		REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
-+-			      AR_PHY_SFCORR_EXT_M2_THRESH,
-+-			      m2ThreshExt);
-+-skip_ws_det:
-+ 		if (on)
-+ 			REG_SET_BIT(ah, AR_PHY_SFCORR_LOW,
-+ 				    AR_PHY_SFCORR_LOW_USE_SELF_CORR_LOW);
-diff --git a/package/mac80211/patches/563-ath9k_rxorn_intr_fix.patch b/package/mac80211/patches/563-ath9k_rxorn_intr_fix.patch
-new file mode 100644
-index 0000000..47a7d82
---- /dev/null
-+++ b/package/mac80211/patches/563-ath9k_rxorn_intr_fix.patch
-@@ -0,0 +1,12 @@
-+--- a/drivers/net/wireless/ath/ath9k/main.c
-++++ b/drivers/net/wireless/ath/ath9k/main.c
-+@@ -628,8 +628,7 @@ irqreturn_t ath_isr(int irq, void *dev)
-+ 	 * If a FATAL or RXORN interrupt is received, we have to reset the
-+ 	 * chip immediately.
-+ 	 */
-+-	if ((status & ATH9K_INT_FATAL) || ((status & ATH9K_INT_RXORN) &&
-+-	    !(ah->caps.hw_caps & ATH9K_HW_CAP_EDMA)))
-++	if (status & ATH9K_INT_FATAL)
-+ 		goto chip_reset;
-+ 
-+ 	if ((ah->config.hw_hang_checks & HW_BB_WATCHDOG) &&
-diff --git a/package/mac80211/patches/564-ath9k_cleanup_reset_debug.patch b/package/mac80211/patches/564-ath9k_cleanup_reset_debug.patch
-new file mode 100644
-index 0000000..c636c5a
---- /dev/null
-+++ b/package/mac80211/patches/564-ath9k_cleanup_reset_debug.patch
-@@ -0,0 +1,60 @@
-+--- a/drivers/net/wireless/ath/ath9k/debug.c
-++++ b/drivers/net/wireless/ath/ath9k/debug.c
-+@@ -846,36 +846,30 @@ static ssize_t read_file_reset(struct fi
-+ 			       size_t count, loff_t *ppos)
-+ {
-+ 	struct ath_softc *sc = file->private_data;
-++	static const char * const reset_cause[__RESET_TYPE_MAX] = {
-++		[RESET_TYPE_BB_HANG] = "Baseband Hang",
-++		[RESET_TYPE_BB_WATCHDOG] = "Baseband Watchdog",
-++		[RESET_TYPE_FATAL_INT] = "Fatal HW Error",
-++		[RESET_TYPE_TX_ERROR] = "TX HW error",
-++		[RESET_TYPE_TX_GTT] = "Transmit timeout",
-++		[RESET_TYPE_TX_HANG] = "TX Path Hang",
-++		[RESET_TYPE_PLL_HANG] = "PLL RX Hang",
-++		[RESET_TYPE_MAC_HANG] = "MAC Hang",
-++		[RESET_TYPE_BEACON_STUCK] = "Stuck Beacon",
-++		[RESET_TYPE_MCI] = "MCI Reset",
-++	};
-+ 	char buf[512];
-+ 	unsigned int len = 0;
-++	int i;
-+ 
-+-	len += scnprintf(buf + len, sizeof(buf) - len,
-+-			 "%17s: %2d\n", "Baseband Hang",
-+-			 sc->debug.stats.reset[RESET_TYPE_BB_HANG]);
-+-	len += scnprintf(buf + len, sizeof(buf) - len,
-+-			 "%17s: %2d\n", "Baseband Watchdog",
-+-			 sc->debug.stats.reset[RESET_TYPE_BB_WATCHDOG]);
-+-	len += scnprintf(buf + len, sizeof(buf) - len,
-+-			 "%17s: %2d\n", "Fatal HW Error",
-+-			 sc->debug.stats.reset[RESET_TYPE_FATAL_INT]);
-+-	len += scnprintf(buf + len, sizeof(buf) - len,
-+-			 "%17s: %2d\n", "TX HW error",
-+-			 sc->debug.stats.reset[RESET_TYPE_TX_ERROR]);
-+-	len += scnprintf(buf + len, sizeof(buf) - len,
-+-			 "%17s: %2d\n", "TX Path Hang",
-+-			 sc->debug.stats.reset[RESET_TYPE_TX_HANG]);
-+-	len += scnprintf(buf + len, sizeof(buf) - len,
-+-			 "%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]);
-++	for (i = 0; i < ARRAY_SIZE(reset_cause); i++) {
-++		if (!reset_cause[i])
-++		    continue;
-++
-++		len += scnprintf(buf + len, sizeof(buf) - len,
-++				 "%17s: %2d\n", reset_cause[i],
-++				 sc->debug.stats.reset[i]);
-++	}
-+ 
-+ 	if (len > sizeof(buf))
-+ 		len = sizeof(buf);
-diff --git a/package/mac80211/patches/565-ath9k_restart_after_nfcal_failure.patch b/package/mac80211/patches/565-ath9k_restart_after_nfcal_failure.patch
-new file mode 100644
-index 0000000..366cc3c
---- /dev/null
-+++ b/package/mac80211/patches/565-ath9k_restart_after_nfcal_failure.patch
-@@ -0,0 +1,172 @@
-+--- a/drivers/net/wireless/ath/ath9k/calib.c
-++++ b/drivers/net/wireless/ath/ath9k/calib.c
-+@@ -234,7 +234,7 @@ void ath9k_hw_start_nfcal(struct ath_hw 
-+ 	REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NF);
-+ }
-+ 
-+-void ath9k_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan)
-++int ath9k_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan)
-+ {
-+ 	struct ath9k_nfcal_hist *h = NULL;
-+ 	unsigned i, j;
-+@@ -301,7 +301,7 @@ void ath9k_hw_loadnf(struct ath_hw *ah, 
-+ 		ath_dbg(common, ANY,
-+ 			"Timeout while waiting for nf to load: AR_PHY_AGC_CONTROL=0x%x\n",
-+ 			REG_READ(ah, AR_PHY_AGC_CONTROL));
-+-		return;
-++		return -ETIMEDOUT;
-+ 	}
-+ 
-+ 	/*
-+@@ -322,6 +322,8 @@ void ath9k_hw_loadnf(struct ath_hw *ah, 
-+ 		}
-+ 	}
-+ 	REGWRITE_BUFFER_FLUSH(ah);
-++
-++	return 0;
-+ }
-+ 
-+ 
-+--- a/drivers/net/wireless/ath/ath9k/calib.h
-++++ b/drivers/net/wireless/ath/ath9k/calib.h
-+@@ -109,7 +109,7 @@ struct ath9k_pacal_info{
-+ 
-+ bool ath9k_hw_reset_calvalid(struct ath_hw *ah);
-+ void ath9k_hw_start_nfcal(struct ath_hw *ah, bool update);
-+-void ath9k_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan);
-++int ath9k_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan);
-+ bool ath9k_hw_getnf(struct ath_hw *ah, struct ath9k_channel *chan);
-+ void ath9k_init_nfcal_hist_buffer(struct ath_hw *ah,
-+ 				  struct ath9k_channel *chan);
-+--- a/drivers/net/wireless/ath/ath9k/ar9002_calib.c
-++++ b/drivers/net/wireless/ath/ath9k/ar9002_calib.c
-+@@ -657,14 +657,13 @@ static void ar9002_hw_olc_temp_compensat
-+ 		ar9280_hw_olc_temp_compensation(ah);
-+ }
-+ 
-+-static bool ar9002_hw_calibrate(struct ath_hw *ah,
-+-				struct ath9k_channel *chan,
-+-				u8 rxchainmask,
-+-				bool longcal)
-++static int ar9002_hw_calibrate(struct ath_hw *ah, struct ath9k_channel *chan,
-++			       u8 rxchainmask, bool longcal)
-+ {
-+ 	bool iscaldone = true;
-+ 	struct ath9k_cal_list *currCal = ah->cal_list_curr;
-+ 	bool nfcal, nfcal_pending = false;
-++	int ret;
-+ 
-+ 	nfcal = !!(REG_READ(ah, AR_PHY_AGC_CONTROL) & AR_PHY_AGC_CONTROL_NF);
-+ 	if (ah->caldata)
-+@@ -698,7 +697,9 @@ static bool ar9002_hw_calibrate(struct a
-+ 			 * NF is slow time-variant, so it is OK to use a
-+ 			 * historical value.
-+ 			 */
-+-			ath9k_hw_loadnf(ah, ah->curchan);
-++			ret = ath9k_hw_loadnf(ah, ah->curchan);
-++			if (ret < 0)
-++				return ret;
-+ 		}
-+ 
-+ 		if (longcal) {
-+--- a/drivers/net/wireless/ath/ath9k/hw-ops.h
-++++ b/drivers/net/wireless/ath/ath9k/hw-ops.h
-+@@ -41,10 +41,9 @@ static inline void ath9k_hw_set_desc_lin
-+ 	ath9k_hw_ops(ah)->set_desc_link(ds, link);
-+ }
-+ 
-+-static inline bool ath9k_hw_calibrate(struct ath_hw *ah,
-+-				      struct ath9k_channel *chan,
-+-				      u8 rxchainmask,
-+-				      bool longcal)
-++static inline int ath9k_hw_calibrate(struct ath_hw *ah,
-++				     struct ath9k_channel *chan,
-++				     u8 rxchainmask, bool longcal)
-+ {
-+ 	return ath9k_hw_ops(ah)->calibrate(ah, chan, rxchainmask, longcal);
-+ }
-+--- a/drivers/net/wireless/ath/ath9k/ar9003_calib.c
-++++ b/drivers/net/wireless/ath/ath9k/ar9003_calib.c
-+@@ -121,13 +121,12 @@ static bool ar9003_hw_per_calibration(st
-+ 	return iscaldone;
-+ }
-+ 
-+-static bool ar9003_hw_calibrate(struct ath_hw *ah,
-+-				struct ath9k_channel *chan,
-+-				u8 rxchainmask,
-+-				bool longcal)
-++static int ar9003_hw_calibrate(struct ath_hw *ah, struct ath9k_channel *chan,
-++			       u8 rxchainmask, bool longcal)
-+ {
-+ 	bool iscaldone = true;
-+ 	struct ath9k_cal_list *currCal = ah->cal_list_curr;
-++	int ret;
-+ 
-+ 	/*
-+ 	 * For given calibration:
-+@@ -163,7 +162,9 @@ static bool ar9003_hw_calibrate(struct a
-+ 		 * NF is slow time-variant, so it is OK to use a historical
-+ 		 * value.
-+ 		 */
-+-		ath9k_hw_loadnf(ah, ah->curchan);
-++		ret = ath9k_hw_loadnf(ah, ah->curchan);
-++		if (ret < 0)
-++			return ret;
-+ 
-+ 		/* start NF calibration, without updating BB NF register */
-+ 		ath9k_hw_start_nfcal(ah, false);
-+--- a/drivers/net/wireless/ath/ath9k/hw.h
-++++ b/drivers/net/wireless/ath/ath9k/hw.h
-+@@ -695,10 +695,8 @@ struct ath_hw_ops {
-+ 				     bool power_off);
-+ 	void (*rx_enable)(struct ath_hw *ah);
-+ 	void (*set_desc_link)(void *ds, u32 link);
-+-	bool (*calibrate)(struct ath_hw *ah,
-+-			  struct ath9k_channel *chan,
-+-			  u8 rxchainmask,
-+-			  bool longcal);
-++	int (*calibrate)(struct ath_hw *ah, struct ath9k_channel *chan,
-++			 u8 rxchainmask, bool longcal);
-+ 	bool (*get_isr)(struct ath_hw *ah, enum ath9k_int *masked,
-+ 			u32 *sync_cause_p);
-+ 	void (*set_txdesc)(struct ath_hw *ah, void *ds,
-+--- a/drivers/net/wireless/ath/ath9k/debug.h
-++++ b/drivers/net/wireless/ath/ath9k/debug.h
-+@@ -49,6 +49,7 @@ enum ath_reset_type {
-+ 	RESET_TYPE_MAC_HANG,
-+ 	RESET_TYPE_BEACON_STUCK,
-+ 	RESET_TYPE_MCI,
-++	RESET_TYPE_CALIBRATION,
-+ 	__RESET_TYPE_MAX
-+ };
-+ 
-+--- a/drivers/net/wireless/ath/ath9k/debug.c
-++++ b/drivers/net/wireless/ath/ath9k/debug.c
-+@@ -857,6 +857,7 @@ static ssize_t read_file_reset(struct fi
-+ 		[RESET_TYPE_MAC_HANG] = "MAC Hang",
-+ 		[RESET_TYPE_BEACON_STUCK] = "Stuck Beacon",
-+ 		[RESET_TYPE_MCI] = "MCI Reset",
-++		[RESET_TYPE_CALIBRATION] = "Calibration error",
-+ 	};
-+ 	char buf[512];
-+ 	unsigned int len = 0;
-+--- a/drivers/net/wireless/ath/ath9k/link.c
-++++ b/drivers/net/wireless/ath/ath9k/link.c
-+@@ -376,9 +376,14 @@ void ath_ani_calibrate(unsigned long dat
-+ 
-+ 	/* Perform calibration if necessary */
-+ 	if (longcal || shortcal) {
-+-		common->ani.caldone =
-+-			ath9k_hw_calibrate(ah, ah->curchan,
-+-					   ah->rxchainmask, longcal);
-++		int ret = ath9k_hw_calibrate(ah, ah->curchan, ah->rxchainmask,
-++					     longcal);
-++		if (ret < 0) {
-++			ath9k_queue_reset(sc, RESET_TYPE_CALIBRATION);
-++			return;
-++		}
-++
-++		common->ani.caldone = ret;
-+ 	}
-+ 
-+ 	ath_dbg(common, ANI,
-diff --git a/package/mac80211/patches/566-ath9k-ar933x-usb-hang-workaround.patch b/package/mac80211/patches/566-ath9k-ar933x-usb-hang-workaround.patch
-deleted file mode 100644
-index af94c9e..0000000
---- a/package/mac80211/patches/566-ath9k-ar933x-usb-hang-workaround.patch
-+++ /dev/null
-@@ -1,79 +0,0 @@
----- a/drivers/net/wireless/ath/ath9k/hw.c
--+++ b/drivers/net/wireless/ath/ath9k/hw.c
--@@ -217,6 +217,19 @@ void ath9k_hw_get_channel_centers(struct
-- 		centers->synth_center + (extoff * HT40_CHANNEL_CENTER_SHIFT);
-- }
-- 
--+static inline void ath9k_hw_disable_pll_lock_detect(struct ath_hw *ah)
--+{
--+	/* On AR9330 and AR9340 devices, some PHY registers must be
--+	 * tuned to gain better stability/performance. These registers
--+	 * might be changed while doing wlan reset so the registers must
--+	 * be reprogrammed after each reset.
--+	 */
--+	REG_CLR_BIT(ah, AR_PHY_USB_CTRL1, BIT(20));
--+	REG_RMW(ah, AR_PHY_USB_CTRL2,
--+		(1 << 21) | (0xf << 22),
--+		(1 << 21) | (0x3 << 22));
--+}
--+
-- /******************/
-- /* Chip Revisions */
-- /******************/
--@@ -1337,6 +1350,9 @@ static bool ath9k_hw_set_reset(struct at
-- 	if (AR_SREV_9100(ah))
-- 		udelay(50);
-- 
--+	if (AR_SREV_9330(ah) || AR_SREV_9340(ah))
--+		ath9k_hw_disable_pll_lock_detect(ah);
--+
-- 	return true;
-- }
-- 
--@@ -1436,6 +1452,9 @@ static bool ath9k_hw_chip_reset(struct a
-- 		ar9003_hw_internal_regulator_apply(ah);
-- 	ath9k_hw_init_pll(ah, chan);
-- 
--+	if (AR_SREV_9330(ah) || AR_SREV_9340(ah))
--+		ath9k_hw_disable_pll_lock_detect(ah);
--+
-- 	return true;
-- }
-- 
--@@ -1730,8 +1749,14 @@ static int ath9k_hw_do_fastcc(struct ath
-- 	if (AR_SREV_9271(ah))
-- 		ar9002_hw_load_ani_reg(ah, chan);
-- 
--+	if (AR_SREV_9330(ah) || AR_SREV_9340(ah))
--+		ath9k_hw_disable_pll_lock_detect(ah);
--+
-- 	return 0;
-- fail:
--+	if (AR_SREV_9330(ah) || AR_SREV_9340(ah))
--+		ath9k_hw_disable_pll_lock_detect(ah);
--+
-- 	return -EINVAL;
-- }
-- 
--@@ -1959,6 +1984,9 @@ int ath9k_hw_reset(struct ath_hw *ah, st
-- 	if (AR_SREV_9565(ah) && common->bt_ant_diversity)
-- 		REG_SET_BIT(ah, AR_BTCOEX_WL_LNADIV, AR_BTCOEX_WL_LNADIV_FORCE_ON);
-- 
--+	if (AR_SREV_9330(ah) || AR_SREV_9340(ah))
--+		ath9k_hw_disable_pll_lock_detect(ah);
--+
-- 	return 0;
-- }
-- EXPORT_SYMBOL(ath9k_hw_reset);
----- a/drivers/net/wireless/ath/ath9k/phy.h
--+++ b/drivers/net/wireless/ath/ath9k/phy.h
--@@ -48,6 +48,9 @@
-- #define AR_PHY_PLL_CONTROL 0x16180
-- #define AR_PHY_PLL_MODE 0x16184
-- 
--+#define AR_PHY_USB_CTRL1	0x16c84
--+#define AR_PHY_USB_CTRL2	0x16c88
--+
-- enum ath9k_ant_div_comb_lna_conf {
-- 	ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2,
-- 	ATH_ANT_DIV_COMB_LNA2,
-diff --git a/package/mac80211/patches/600-0001-rt2x00-rt2800lib-move-rt2800_drv_data-declaration-in.patch b/package/mac80211/patches/600-0001-rt2x00-rt2800lib-move-rt2800_drv_data-declaration-in.patch
-new file mode 100644
-index 0000000..d344957
---- /dev/null
-+++ b/package/mac80211/patches/600-0001-rt2x00-rt2800lib-move-rt2800_drv_data-declaration-in.patch
-@@ -0,0 +1,62 @@
-+From 7a69da907de668fb22a30ae218062d6f081864ea Mon Sep 17 00:00:00 2001
-+From: Gabor Juhos <juhosg@openwrt.org>
-+Date: Sat, 17 Aug 2013 19:31:41 +0200
-+Subject: [PATCH] rt2x00: rt2800lib: move rt2800_drv_data declaration into
-+ rt2800lib.h
-+
-+The rt2800_drv_data structure contains driver specific
-+information. Move the declaration into the rt2800lib.h
-+header which is a more logical place for it. Also fix
-+the comment style to avoid checkpatch warning.
-+
-+The patch contains no functional changes, it is in
-+preparation for the next patch.
-+
-+Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
-+---
-+Changes since v1: ---
-+---
-+ drivers/net/wireless/rt2x00/rt2800.h    |   13 -------------
-+ drivers/net/wireless/rt2x00/rt2800lib.h |   11 +++++++++++
-+ 2 files changed, 11 insertions(+), 13 deletions(-)
-+
-+--- a/drivers/net/wireless/rt2x00/rt2800.h
-++++ b/drivers/net/wireless/rt2x00/rt2800.h
-+@@ -2958,17 +2958,4 @@ enum rt2800_eeprom_word {
-+  */
-+ #define BCN_TBTT_OFFSET 64
-+ 
-+-/*
-+- * RT2800 driver data structure
-+- */
-+-struct rt2800_drv_data {
-+-	u8 calibration_bw20;
-+-	u8 calibration_bw40;
-+-	u8 bbp25;
-+-	u8 bbp26;
-+-	u8 txmixer_gain_24g;
-+-	u8 txmixer_gain_5g;
-+-	unsigned int tbtt_tick;
-+-};
-+-
-+ #endif /* RT2800_H */
-+--- a/drivers/net/wireless/rt2x00/rt2800lib.h
-++++ b/drivers/net/wireless/rt2x00/rt2800lib.h
-+@@ -20,6 +20,17 @@
-+ #ifndef RT2800LIB_H
-+ #define RT2800LIB_H
-+ 
-++/* RT2800 driver data structure */
-++struct rt2800_drv_data {
-++	u8 calibration_bw20;
-++	u8 calibration_bw40;
-++	u8 bbp25;
-++	u8 bbp26;
-++	u8 txmixer_gain_24g;
-++	u8 txmixer_gain_5g;
-++	unsigned int tbtt_tick;
-++};
-++
-+ struct rt2800_ops {
-+ 	void (*register_read)(struct rt2x00_dev *rt2x00dev,
-+ 			      const unsigned int offset, u32 *value);
-diff --git a/package/mac80211/patches/600-0002-rt2x00-rt2800lib-introduce-RT2800_HAS_HIGH_SHARED_ME.patch b/package/mac80211/patches/600-0002-rt2x00-rt2800lib-introduce-RT2800_HAS_HIGH_SHARED_ME.patch
-new file mode 100644
-index 0000000..60d4c55
---- /dev/null
-+++ b/package/mac80211/patches/600-0002-rt2x00-rt2800lib-introduce-RT2800_HAS_HIGH_SHARED_ME.patch
-@@ -0,0 +1,80 @@
-+From a7f268af31dddf763fe3dbe9cbf96ea77e0540e0 Mon Sep 17 00:00:00 2001
-+From: Gabor Juhos <juhosg@openwrt.org>
-+Date: Sat, 17 Aug 2013 19:31:41 +0200
-+Subject: [PATCH] rt2x00: rt2800lib: introduce RT2800_HAS_HIGH_SHARED_MEM flag
-+
-+Some chipsets have more than 16KB of shared memory.
-+Introduce a new rt2800 specific flag to indicate that
-+and add a helper function which helps to check the
-+presence of the new flag.
-+
-+Also enable the new flag for the RT3593 chipset which
-+has 24KB of shared memory. The flag can also be used
-+for other chipsets, but none of those has been tested
-+yet.
-+
-+Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
-+---
-+Changes since v1:
-+  - don't enable the new flag for RT3071 and RT5592
-+---
-+ drivers/net/wireless/rt2x00/rt2800lib.c |    4 ++++
-+ drivers/net/wireless/rt2x00/rt2800lib.h |   13 +++++++++++++
-+ 2 files changed, 17 insertions(+)
-+
-+--- a/drivers/net/wireless/rt2x00/rt2800lib.c
-++++ b/drivers/net/wireless/rt2x00/rt2800lib.c
-+@@ -7734,6 +7734,7 @@ static int rt2800_probe_rt(struct rt2x00
-+ 
-+ int rt2800_probe_hw(struct rt2x00_dev *rt2x00dev)
-+ {
-++	struct rt2800_drv_data *drv_data = rt2x00dev->drv_data;
-+ 	int retval;
-+ 	u32 reg;
-+ 
-+@@ -7741,6 +7742,9 @@ int rt2800_probe_hw(struct rt2x00_dev *r
-+ 	if (retval)
-+ 		return retval;
-+ 
-++	if (rt2x00_rt(rt2x00dev, RT3593))
-++		__set_bit(RT2800_HAS_HIGH_SHARED_MEM, &drv_data->rt2800_flags);
-++
-+ 	/*
-+ 	 * Allocate eeprom data.
-+ 	 */
-+--- a/drivers/net/wireless/rt2x00/rt2800lib.h
-++++ b/drivers/net/wireless/rt2x00/rt2800lib.h
-+@@ -20,6 +20,10 @@
-+ #ifndef RT2800LIB_H
-+ #define RT2800LIB_H
-+ 
-++enum rt2800_flag {
-++	RT2800_HAS_HIGH_SHARED_MEM,
-++};
-++
-+ /* RT2800 driver data structure */
-+ struct rt2800_drv_data {
-+ 	u8 calibration_bw20;
-+@@ -29,6 +33,8 @@ struct rt2800_drv_data {
-+ 	u8 txmixer_gain_24g;
-+ 	u8 txmixer_gain_5g;
-+ 	unsigned int tbtt_tick;
-++
-++	unsigned long rt2800_flags;
-+ };
-+ 
-+ struct rt2800_ops {
-+@@ -61,6 +67,13 @@ struct rt2800_ops {
-+ 	__le32 *(*drv_get_txwi)(struct queue_entry *entry);
-+ };
-+ 
-++static inline bool rt2800_has_high_shared_mem(struct rt2x00_dev *rt2x00dev)
-++{
-++	struct rt2800_drv_data *drv_data = rt2x00dev->drv_data;
-++
-++	return test_bit(RT2800_HAS_HIGH_SHARED_MEM, &drv_data->rt2800_flags);
-++}
-++
-+ static inline void rt2800_register_read(struct rt2x00_dev *rt2x00dev,
-+ 					const unsigned int offset,
-+ 					u32 *value)
-diff --git a/package/mac80211/patches/600-0003-rt2x00-rt2800-serialize-shared-memory-access.patch b/package/mac80211/patches/600-0003-rt2x00-rt2800-serialize-shared-memory-access.patch
-new file mode 100644
-index 0000000..2accf73
---- /dev/null
-+++ b/package/mac80211/patches/600-0003-rt2x00-rt2800-serialize-shared-memory-access.patch
-@@ -0,0 +1,531 @@
-+From 250a1b520cd7fdc0df4fc3fedea9066913f49ecf Mon Sep 17 00:00:00 2001
-+From: Gabor Juhos <juhosg@openwrt.org>
-+Date: Sat, 17 Aug 2013 19:31:42 +0200
-+Subject: [PATCH] rt2x00: rt2800: serialize shared memory access
-+
-+The shared memory of the rt2800 devices is accessible
-+through the register offset range between 0x4000 and
-+0x8000. The size of this range is 16KB only and on
-+devices which have more than 16KB of shared memory either
-+the low or the high part of the memory is accessible at a
-+time.
-+
-+Serialize all accesses to the shared memory by a mutex,
-+in order to avoid concurrent use of that.
-+
-+Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
-+---
-+Changes since v1: ---
-+---
-+ drivers/net/wireless/rt2x00/rt2800lib.c  |   55 +++++++++++++++++++++++++++++-
-+ drivers/net/wireless/rt2x00/rt2800lib.h  |   32 +++++++++++++++++
-+ drivers/net/wireless/rt2x00/rt2800mmio.c |   26 ++++++++++++++
-+ drivers/net/wireless/rt2x00/rt2800mmio.h |    4 +++
-+ drivers/net/wireless/rt2x00/rt2800pci.c  |   14 ++++++++
-+ drivers/net/wireless/rt2x00/rt2800soc.c  |    3 ++
-+ drivers/net/wireless/rt2x00/rt2800usb.c  |   31 +++++++++++++++++
-+ 7 files changed, 164 insertions(+), 1 deletion(-)
-+
-+--- a/drivers/net/wireless/rt2x00/rt2800lib.c
-++++ b/drivers/net/wireless/rt2x00/rt2800lib.c
-+@@ -451,11 +451,13 @@ void rt2800_mcu_request(struct rt2x00_de
-+ 		rt2x00_set_field32(&reg, H2M_MAILBOX_CSR_CMD_TOKEN, token);
-+ 		rt2x00_set_field32(&reg, H2M_MAILBOX_CSR_ARG0, arg0);
-+ 		rt2x00_set_field32(&reg, H2M_MAILBOX_CSR_ARG1, arg1);
-++		rt2800_shared_mem_lock(rt2x00dev);
-+ 		rt2800_register_write_lock(rt2x00dev, H2M_MAILBOX_CSR, reg);
-+ 
-+ 		reg = 0;
-+ 		rt2x00_set_field32(&reg, HOST_CMD_CSR_HOST_COMMAND, command);
-+ 		rt2800_register_write_lock(rt2x00dev, HOST_CMD_CSR, reg);
-++		rt2800_shared_mem_unlock(rt2x00dev);
-+ 	}
-+ 
-+ 	mutex_unlock(&rt2x00dev->csr_mutex);
-+@@ -674,7 +676,9 @@ int rt2800_load_firmware(struct rt2x00_d
-+ 	 * Wait for device to stabilize.
-+ 	 */
-+ 	for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
-++		rt2800_shared_mem_lock(rt2x00dev);
-+ 		rt2800_register_read(rt2x00dev, PBF_SYS_CTRL, &reg);
-++		rt2800_shared_mem_unlock(rt2x00dev);
-+ 		if (rt2x00_get_field32(reg, PBF_SYS_CTRL_READY))
-+ 			break;
-+ 		msleep(1);
-+@@ -694,10 +698,16 @@ int rt2800_load_firmware(struct rt2x00_d
-+ 	/*
-+ 	 * Initialize firmware.
-+ 	 */
-++	rt2800_shared_mem_lock(rt2x00dev);
-+ 	rt2800_register_write(rt2x00dev, H2M_BBP_AGENT, 0);
-+ 	rt2800_register_write(rt2x00dev, H2M_MAILBOX_CSR, 0);
-++	rt2800_shared_mem_unlock(rt2x00dev);
-++
-+ 	if (rt2x00_is_usb(rt2x00dev)) {
-++		rt2800_shared_mem_lock(rt2x00dev);
-+ 		rt2800_register_write(rt2x00dev, H2M_INT_SRC, 0);
-++		rt2800_shared_mem_unlock(rt2x00dev);
-++
-+ 		rt2800_mcu_request(rt2x00dev, MCU_BOOT_SIGNAL, 0, 0, 0);
-+ 	}
-+ 	msleep(1);
-+@@ -1035,8 +1045,10 @@ void rt2800_write_beacon(struct queue_en
-+ 
-+ 	beacon_base = rt2800_hw_beacon_base(rt2x00dev, entry->entry_idx);
-+ 
-++	rt2800_shared_mem_lock(rt2x00dev);
-+ 	rt2800_register_multiwrite(rt2x00dev, beacon_base, entry->skb->data,
-+ 				   entry->skb->len + padding_len);
-++	rt2800_shared_mem_unlock(rt2x00dev);
-+ 	__set_bit(ENTRY_BCN_ENABLED, &entry->flags);
-+ 
-+ 	/*
-+@@ -1066,6 +1078,8 @@ static inline void rt2800_clear_beacon_r
-+ 
-+ 	beacon_base = rt2800_hw_beacon_base(rt2x00dev, index);
-+ 
-++	rt2800_shared_mem_lock(rt2x00dev);
-++
-+ 	/*
-+ 	 * For the Beacon base registers we only need to clear
-+ 	 * the whole TXWI which (when set to 0) will invalidate
-+@@ -1073,6 +1087,8 @@ static inline void rt2800_clear_beacon_r
-+ 	 */
-+ 	for (i = 0; i < txwi_desc_size; i += sizeof(__le32))
-+ 		rt2800_register_write(rt2x00dev, beacon_base + i, 0);
-++
-++	rt2800_shared_mem_unlock(rt2x00dev);
-+ }
-+ 
-+ void rt2800_clear_beacon(struct queue_entry *entry)
-+@@ -1261,7 +1277,9 @@ static void rt2800_delete_wcid_attr(stru
-+ {
-+ 	u32 offset;
-+ 	offset = MAC_WCID_ATTR_ENTRY(wcid);
-++	rt2800_shared_mem_lock(rt2x00dev);
-+ 	rt2800_register_write(rt2x00dev, offset, 0);
-++	rt2800_shared_mem_unlock(rt2x00dev);
-+ }
-+ 
-+ static void rt2800_config_wcid_attr_bssidx(struct rt2x00_dev *rt2x00dev,
-+@@ -1274,11 +1292,13 @@ static void rt2800_config_wcid_attr_bssi
-+ 	 * The BSS Idx numbers is split in a main value of 3 bits,
-+ 	 * and a extended field for adding one additional bit to the value.
-+ 	 */
-++	rt2800_shared_mem_lock(rt2x00dev);
-+ 	rt2800_register_read(rt2x00dev, offset, &reg);
-+ 	rt2x00_set_field32(&reg, MAC_WCID_ATTRIBUTE_BSS_IDX, (bssidx & 0x7));
-+ 	rt2x00_set_field32(&reg, MAC_WCID_ATTRIBUTE_BSS_IDX_EXT,
-+ 			   (bssidx & 0x8) >> 3);
-+ 	rt2800_register_write(rt2x00dev, offset, reg);
-++	rt2800_shared_mem_unlock(rt2x00dev);
-+ }
-+ 
-+ static void rt2800_config_wcid_attr_cipher(struct rt2x00_dev *rt2x00dev,
-+@@ -1291,6 +1311,7 @@ static void rt2800_config_wcid_attr_ciph
-+ 
-+ 	offset = MAC_WCID_ATTR_ENTRY(key->hw_key_idx);
-+ 
-++	rt2800_shared_mem_lock(rt2x00dev);
-+ 	if (crypto->cmd == SET_KEY) {
-+ 		rt2800_register_read(rt2x00dev, offset, &reg);
-+ 		rt2x00_set_field32(&reg, MAC_WCID_ATTRIBUTE_KEYTAB,
-+@@ -1315,6 +1336,7 @@ static void rt2800_config_wcid_attr_ciph
-+ 		rt2x00_set_field32(&reg, MAC_WCID_ATTRIBUTE_RX_WIUDF, 0);
-+ 		rt2800_register_write(rt2x00dev, offset, reg);
-+ 	}
-++	rt2800_shared_mem_unlock(rt2x00dev);
-+ 
-+ 	offset = MAC_IVEIV_ENTRY(key->hw_key_idx);
-+ 
-+@@ -1324,8 +1346,11 @@ static void rt2800_config_wcid_attr_ciph
-+ 	    (crypto->cipher == CIPHER_AES))
-+ 		iveiv_entry.iv[3] |= 0x20;
-+ 	iveiv_entry.iv[3] |= key->keyidx << 6;
-++
-++	rt2800_shared_mem_lock(rt2x00dev);
-+ 	rt2800_register_multiwrite(rt2x00dev, offset,
-+ 				      &iveiv_entry, sizeof(iveiv_entry));
-++	rt2800_shared_mem_unlock(rt2x00dev);
-+ }
-+ 
-+ int rt2800_config_shared_key(struct rt2x00_dev *rt2x00dev,
-+@@ -1348,8 +1373,11 @@ int rt2800_config_shared_key(struct rt2x
-+ 		       sizeof(key_entry.rx_mic));
-+ 
-+ 		offset = SHARED_KEY_ENTRY(key->hw_key_idx);
-++
-++		rt2800_shared_mem_lock(rt2x00dev);
-+ 		rt2800_register_multiwrite(rt2x00dev, offset,
-+ 					      &key_entry, sizeof(key_entry));
-++		rt2800_shared_mem_unlock(rt2x00dev);
-+ 	}
-+ 
-+ 	/*
-+@@ -1364,10 +1392,12 @@ int rt2800_config_shared_key(struct rt2x
-+ 
-+ 	offset = SHARED_KEY_MODE_ENTRY(key->hw_key_idx / 8);
-+ 
-++	rt2800_shared_mem_lock(rt2x00dev);
-+ 	rt2800_register_read(rt2x00dev, offset, &reg);
-+ 	rt2x00_set_field32(&reg, field,
-+ 			   (crypto->cmd == SET_KEY) * crypto->cipher);
-+ 	rt2800_register_write(rt2x00dev, offset, reg);
-++	rt2800_shared_mem_unlock(rt2x00dev);
-+ 
-+ 	/*
-+ 	 * Update WCID information
-+@@ -1437,8 +1467,11 @@ int rt2800_config_pairwise_key(struct rt
-+ 		       sizeof(key_entry.rx_mic));
-+ 
-+ 		offset = PAIRWISE_KEY_ENTRY(key->hw_key_idx);
-++
-++		rt2800_shared_mem_lock(rt2x00dev);
-+ 		rt2800_register_multiwrite(rt2x00dev, offset,
-+ 					      &key_entry, sizeof(key_entry));
-++		rt2800_shared_mem_unlock(rt2x00dev);
-+ 	}
-+ 
-+ 	/*
-+@@ -4898,14 +4931,19 @@ static int rt2800_init_registers(struct 
-+ 	/*
-+ 	 * ASIC will keep garbage value after boot, clear encryption keys.
-+ 	 */
-++	rt2800_shared_mem_lock(rt2x00dev);
-+ 	for (i = 0; i < 4; i++)
-+ 		rt2800_register_write(rt2x00dev,
-+ 					 SHARED_KEY_MODE_ENTRY(i), 0);
-++	rt2800_shared_mem_unlock(rt2x00dev);
-+ 
-+ 	for (i = 0; i < 256; i++) {
-+ 		rt2800_config_wcid(rt2x00dev, NULL, i);
-+ 		rt2800_delete_wcid_attr(rt2x00dev, i);
-++
-++		rt2800_shared_mem_lock(rt2x00dev);
-+ 		rt2800_register_write(rt2x00dev, MAC_IVEIV_ENTRY(i), 0);
-++		rt2800_shared_mem_unlock(rt2x00dev);
-+ 	}
-+ 
-+ 	/*
-+@@ -5031,8 +5069,10 @@ static int rt2800_wait_bbp_ready(struct 
-+ 	 * BBP was enabled after firmware was loaded,
-+ 	 * but we need to reactivate it now.
-+ 	 */
-++	rt2800_shared_mem_lock(rt2x00dev);
-+ 	rt2800_register_write(rt2x00dev, H2M_BBP_AGENT, 0);
-+ 	rt2800_register_write(rt2x00dev, H2M_MAILBOX_CSR, 0);
-++	rt2800_shared_mem_unlock(rt2x00dev);
-+ 	msleep(1);
-+ 
-+ 	for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
-+@@ -6728,11 +6768,19 @@ int rt2800_enable_radio(struct rt2x00_de
-+ 	/*
-+ 	 * Send signal during boot time to initialize firmware.
-+ 	 */
-++	rt2800_shared_mem_lock(rt2x00dev);
-+ 	rt2800_register_write(rt2x00dev, H2M_BBP_AGENT, 0);
-+ 	rt2800_register_write(rt2x00dev, H2M_MAILBOX_CSR, 0);
-+-	if (rt2x00_is_usb(rt2x00dev))
-++	rt2800_shared_mem_unlock(rt2x00dev);
-++
-++	if (rt2x00_is_usb(rt2x00dev)) {
-++		rt2800_shared_mem_lock(rt2x00dev);
-+ 		rt2800_register_write(rt2x00dev, H2M_INT_SRC, 0);
-++		rt2800_shared_mem_unlock(rt2x00dev);
-++	}
-++
-+ 	rt2800_mcu_request(rt2x00dev, MCU_BOOT_SIGNAL, 0, 0, 0);
-++
-+ 	msleep(1);
-+ 
-+ 	/*
-+@@ -7738,6 +7786,8 @@ int rt2800_probe_hw(struct rt2x00_dev *r
-+ 	int retval;
-+ 	u32 reg;
-+ 
-++	rt2800_shared_mem_init_lock(rt2x00dev);
-++
-+ 	retval = rt2800_probe_rt(rt2x00dev);
-+ 	if (retval)
-+ 		return retval;
-+@@ -7817,8 +7867,11 @@ void rt2800_get_tkip_seq(struct ieee8021
-+ 	u32 offset;
-+ 
-+ 	offset = MAC_IVEIV_ENTRY(hw_key_idx);
-++
-++	rt2800_shared_mem_lock(rt2x00dev);
-+ 	rt2800_register_multiread(rt2x00dev, offset,
-+ 				      &iveiv_entry, sizeof(iveiv_entry));
-++	rt2800_shared_mem_unlock(rt2x00dev);
-+ 
-+ 	memcpy(iv16, &iveiv_entry.iv[0], sizeof(*iv16));
-+ 	memcpy(iv32, &iveiv_entry.iv[4], sizeof(*iv32));
-+--- a/drivers/net/wireless/rt2x00/rt2800lib.h
-++++ b/drivers/net/wireless/rt2x00/rt2800lib.h
-+@@ -35,6 +35,11 @@ struct rt2800_drv_data {
-+ 	unsigned int tbtt_tick;
-+ 
-+ 	unsigned long rt2800_flags;
-++
-++	union {
-++		spinlock_t spin;
-++		struct mutex mutex;
-++	} shmem_lock;
-+ };
-+ 
-+ struct rt2800_ops {
-+@@ -65,6 +70,10 @@ struct rt2800_ops {
-+ 				  const u8 *data, const size_t len);
-+ 	int (*drv_init_registers)(struct rt2x00_dev *rt2x00dev);
-+ 	__le32 *(*drv_get_txwi)(struct queue_entry *entry);
-++
-++	void (*shmem_init_lock)(struct rt2x00_dev *rt2x00dev);
-++	void (*shmem_lock)(struct rt2x00_dev *rt2x00dev);
-++	void (*shmem_unlock)(struct rt2x00_dev *rt2x00dev);
-+ };
-+ 
-+ static inline bool rt2800_has_high_shared_mem(struct rt2x00_dev *rt2x00dev)
-+@@ -74,6 +83,29 @@ static inline bool rt2800_has_high_share
-+ 	return test_bit(RT2800_HAS_HIGH_SHARED_MEM, &drv_data->rt2800_flags);
-+ }
-+ 
-++static inline void rt2800_shared_mem_init_lock(struct rt2x00_dev *rt2x00dev)
-++{
-++	const struct rt2800_ops *rt2800ops = rt2x00dev->ops->drv;
-++
-++	rt2800ops->shmem_init_lock(rt2x00dev);
-++}
-++
-++static inline void rt2800_shared_mem_lock(struct rt2x00_dev *rt2x00dev)
-++{
-++	const struct rt2800_ops *rt2800ops = rt2x00dev->ops->drv;
-++
-++	if (rt2800_has_high_shared_mem(rt2x00dev))
-++		rt2800ops->shmem_lock(rt2x00dev);
-++}
-++
-++static inline void rt2800_shared_mem_unlock(struct rt2x00_dev *rt2x00dev)
-++{
-++	const struct rt2800_ops *rt2800ops = rt2x00dev->ops->drv;
-++
-++	if (rt2800_has_high_shared_mem(rt2x00dev))
-++		rt2800ops->shmem_unlock(rt2x00dev);
-++}
-++
-+ static inline void rt2800_register_read(struct rt2x00_dev *rt2x00dev,
-+ 					const unsigned int offset,
-+ 					u32 *value)
-+--- a/drivers/net/wireless/rt2x00/rt2800mmio.c
-++++ b/drivers/net/wireless/rt2x00/rt2800mmio.c
-+@@ -820,8 +820,10 @@ int rt2800mmio_init_registers(struct rt2
-+ 	rt2x00_set_field32(&reg, WPDMA_RST_IDX_DRX_IDX0, 1);
-+ 	rt2x00mmio_register_write(rt2x00dev, WPDMA_RST_IDX, reg);
-+ 
-++	rt2800_shared_mem_lock(rt2x00dev);
-+ 	rt2x00mmio_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00000e1f);
-+ 	rt2x00mmio_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00000e00);
-++	rt2800_shared_mem_unlock(rt2x00dev);
-+ 
-+ 	if (rt2x00_is_pcie(rt2x00dev) &&
-+ 	    (rt2x00_rt(rt2x00dev, RT3090) ||
-+@@ -865,6 +867,30 @@ int rt2800mmio_enable_radio(struct rt2x0
-+ }
-+ EXPORT_SYMBOL_GPL(rt2800mmio_enable_radio);
-+ 
-++void rt2800mmio_shmem_init_lock(struct rt2x00_dev *rt2x00dev)
-++{
-++	struct rt2800_drv_data *drv_data = rt2x00dev->drv_data;
-++
-++	spin_lock_init(&drv_data->shmem_lock.spin);
-++}
-++EXPORT_SYMBOL_GPL(rt2800mmio_shmem_init_lock);
-++
-++void rt2800mmio_shmem_lock(struct rt2x00_dev *rt2x00dev)
-++{
-++	struct rt2800_drv_data *drv_data = rt2x00dev->drv_data;
-++
-++	spin_lock_bh(&drv_data->shmem_lock.spin);
-++}
-++EXPORT_SYMBOL_GPL(rt2800mmio_shmem_lock);
-++
-++void rt2800mmio_shmem_unlock(struct rt2x00_dev *rt2x00dev)
-++{
-++	struct rt2800_drv_data *drv_data = rt2x00dev->drv_data;
-++
-++	spin_unlock_bh(&drv_data->shmem_lock.spin);
-++}
-++EXPORT_SYMBOL_GPL(rt2800mmio_shmem_unlock);
-++
-+ MODULE_AUTHOR(DRV_PROJECT);
-+ MODULE_VERSION(DRV_VERSION);
-+ MODULE_DESCRIPTION("rt2800 MMIO library");
-+--- a/drivers/net/wireless/rt2x00/rt2800mmio.h
-++++ b/drivers/net/wireless/rt2x00/rt2800mmio.h
-+@@ -160,4 +160,8 @@ int rt2800mmio_init_registers(struct rt2
-+ /* Device state switch handlers. */
-+ int rt2800mmio_enable_radio(struct rt2x00_dev *rt2x00dev);
-+ 
-++void rt2800mmio_shmem_init_lock(struct rt2x00_dev *rt2x00dev);
-++void rt2800mmio_shmem_lock(struct rt2x00_dev *rt2x00dev);
-++void rt2800mmio_shmem_unlock(struct rt2x00_dev *rt2x00dev);
-++
-+ #endif /* RT2800MMIO_H */
-+--- a/drivers/net/wireless/rt2x00/rt2800pci.c
-++++ b/drivers/net/wireless/rt2x00/rt2800pci.c
-+@@ -69,7 +69,9 @@ static void rt2800pci_mcu_status(struct 
-+ 		return;
-+ 
-+ 	for (i = 0; i < 200; i++) {
-++		rt2800_shared_mem_lock(rt2x00dev);
-+ 		rt2x00mmio_register_read(rt2x00dev, H2M_MAILBOX_CID, &reg);
-++		rt2800_shared_mem_unlock(rt2x00dev);
-+ 
-+ 		if ((rt2x00_get_field32(reg, H2M_MAILBOX_CID_CMD0) == token) ||
-+ 		    (rt2x00_get_field32(reg, H2M_MAILBOX_CID_CMD1) == token) ||
-+@@ -83,8 +85,10 @@ static void rt2800pci_mcu_status(struct 
-+ 	if (i == 200)
-+ 		rt2x00_err(rt2x00dev, "MCU request failed, no response from hardware\n");
-+ 
-++	rt2800_shared_mem_lock(rt2x00dev);
-+ 	rt2x00mmio_register_write(rt2x00dev, H2M_MAILBOX_STATUS, ~0);
-+ 	rt2x00mmio_register_write(rt2x00dev, H2M_MAILBOX_CID, ~0);
-++	rt2800_shared_mem_unlock(rt2x00dev);
-+ }
-+ 
-+ static void rt2800pci_eepromregister_read(struct eeprom_93cx6 *eeprom)
-+@@ -184,6 +188,8 @@ static int rt2800pci_write_firmware(stru
-+ 	 */
-+ 	reg = 0;
-+ 	rt2x00_set_field32(&reg, PBF_SYS_CTRL_HOST_RAM_WRITE, 1);
-++
-++	rt2800_shared_mem_lock(rt2x00dev);
-+ 	rt2x00mmio_register_write(rt2x00dev, PBF_SYS_CTRL, reg);
-+ 
-+ 	/*
-+@@ -197,6 +203,7 @@ static int rt2800pci_write_firmware(stru
-+ 
-+ 	rt2x00mmio_register_write(rt2x00dev, H2M_BBP_AGENT, 0);
-+ 	rt2x00mmio_register_write(rt2x00dev, H2M_MAILBOX_CSR, 0);
-++	rt2800_shared_mem_unlock(rt2x00dev);
-+ 
-+ 	return 0;
-+ }
-+@@ -213,8 +220,10 @@ static int rt2800pci_enable_radio(struct
-+ 		return retval;
-+ 
-+ 	/* After resume MCU_BOOT_SIGNAL will trash these. */
-++	rt2800_shared_mem_lock(rt2x00dev);
-+ 	rt2x00mmio_register_write(rt2x00dev, H2M_MAILBOX_STATUS, ~0);
-+ 	rt2x00mmio_register_write(rt2x00dev, H2M_MAILBOX_CID, ~0);
-++	rt2800_shared_mem_unlock(rt2x00dev);
-+ 
-+ 	rt2800_mcu_request(rt2x00dev, MCU_SLEEP, TOKEN_RADIO_OFF, 0xff, 0x02);
-+ 	rt2800pci_mcu_status(rt2x00dev, TOKEN_RADIO_OFF);
-+@@ -233,10 +242,12 @@ static int rt2800pci_set_state(struct rt
-+ 				   0, 0x02);
-+ 		rt2800pci_mcu_status(rt2x00dev, TOKEN_WAKEUP);
-+ 	} else if (state == STATE_SLEEP) {
-++		rt2800_shared_mem_lock(rt2x00dev);
-+ 		rt2x00mmio_register_write(rt2x00dev, H2M_MAILBOX_STATUS,
-+ 					  0xffffffff);
-+ 		rt2x00mmio_register_write(rt2x00dev, H2M_MAILBOX_CID,
-+ 					  0xffffffff);
-++		rt2800_shared_mem_unlock(rt2x00dev);
-+ 		rt2800_mcu_request(rt2x00dev, MCU_SLEEP, TOKEN_SLEEP,
-+ 				   0xff, 0x01);
-+ 	}
-+@@ -337,6 +348,9 @@ static const struct rt2800_ops rt2800pci
-+ 	.drv_write_firmware	= rt2800pci_write_firmware,
-+ 	.drv_init_registers	= rt2800mmio_init_registers,
-+ 	.drv_get_txwi		= rt2800mmio_get_txwi,
-++	.shmem_init_lock	= rt2800mmio_shmem_init_lock,
-++	.shmem_lock		= rt2800mmio_shmem_lock,
-++	.shmem_unlock		= rt2800mmio_shmem_unlock,
-+ };
-+ 
-+ static const struct rt2x00lib_ops rt2800pci_rt2x00_ops = {
-+--- a/drivers/net/wireless/rt2x00/rt2800soc.c
-++++ b/drivers/net/wireless/rt2x00/rt2800soc.c
-+@@ -176,6 +176,9 @@ static const struct rt2800_ops rt2800soc
-+ 	.drv_write_firmware	= rt2800soc_write_firmware,
-+ 	.drv_init_registers	= rt2800mmio_init_registers,
-+ 	.drv_get_txwi		= rt2800mmio_get_txwi,
-++	.shmem_init_lock	= rt2800mmio_shmem_init_lock,
-++	.shmem_lock		= rt2800mmio_shmem_lock,
-++	.shmem_unlock		= rt2800mmio_shmem_unlock,
-+ };
-+ 
-+ static const struct rt2x00lib_ops rt2800soc_rt2x00_ops = {
-+--- a/drivers/net/wireless/rt2x00/rt2800usb.c
-++++ b/drivers/net/wireless/rt2x00/rt2800usb.c
-+@@ -51,6 +51,27 @@ static bool rt2800usb_hwcrypt_disabled(s
-+ 	return modparam_nohwcrypt;
-+ }
-+ 
-++static void rt2800usb_shmem_init_lock(struct rt2x00_dev *rt2x00dev)
-++{
-++	struct rt2800_drv_data *drv_data = rt2x00dev->drv_data;
-++
-++	mutex_init(&drv_data->shmem_lock.mutex);
-++}
-++
-++static void rt2800usb_shmem_lock(struct rt2x00_dev *rt2x00dev)
-++{
-++	struct rt2800_drv_data *drv_data = rt2x00dev->drv_data;
-++
-++	mutex_lock(&drv_data->shmem_lock.mutex);
-++}
-++
-++static void rt2800usb_shmem_unlock(struct rt2x00_dev *rt2x00dev)
-++{
-++	struct rt2800_drv_data *drv_data = rt2x00dev->drv_data;
-++
-++	mutex_unlock(&drv_data->shmem_lock.mutex);
-++}
-++
-+ /*
-+  * Queue handlers.
-+  */
-+@@ -260,8 +281,10 @@ static int rt2800usb_write_firmware(stru
-+ 	rt2x00usb_register_multiwrite(rt2x00dev, FIRMWARE_IMAGE_BASE,
-+ 				      data + offset, length);
-+ 
-++	rt2800_shared_mem_lock(rt2x00dev);
-+ 	rt2x00usb_register_write(rt2x00dev, H2M_MAILBOX_CID, ~0);
-+ 	rt2x00usb_register_write(rt2x00dev, H2M_MAILBOX_STATUS, ~0);
-++	rt2800_shared_mem_unlock(rt2x00dev);
-+ 
-+ 	/*
-+ 	 * Send firmware request to device to load firmware,
-+@@ -276,7 +299,10 @@ static int rt2800usb_write_firmware(stru
-+ 	}
-+ 
-+ 	msleep(10);
-++
-++	rt2800_shared_mem_lock(rt2x00dev);
-+ 	rt2x00usb_register_write(rt2x00dev, H2M_MAILBOX_CSR, 0);
-++	rt2800_shared_mem_unlock(rt2x00dev);
-+ 
-+ 	return 0;
-+ }
-+@@ -294,8 +320,10 @@ static int rt2800usb_init_registers(stru
-+ 	if (rt2800_wait_csr_ready(rt2x00dev))
-+ 		return -EBUSY;
-+ 
-++	rt2800_shared_mem_lock(rt2x00dev);
-+ 	rt2x00usb_register_read(rt2x00dev, PBF_SYS_CTRL, &reg);
-+ 	rt2x00usb_register_write(rt2x00dev, PBF_SYS_CTRL, reg & ~0x00002000);
-++	rt2800_shared_mem_unlock(rt2x00dev);
-+ 
-+ 	reg = 0;
-+ 	rt2x00_set_field32(&reg, MAC_SYS_CTRL_RESET_CSR, 1);
-+@@ -810,6 +838,9 @@ static const struct rt2800_ops rt2800usb
-+ 	.drv_write_firmware	= rt2800usb_write_firmware,
-+ 	.drv_init_registers	= rt2800usb_init_registers,
-+ 	.drv_get_txwi		= rt2800usb_get_txwi,
-++	.shmem_init_lock	= rt2800usb_shmem_init_lock,
-++	.shmem_lock		= rt2800usb_shmem_lock,
-++	.shmem_unlock		= rt2800usb_shmem_unlock,
-+ };
-+ 
-+ static const struct rt2x00lib_ops rt2800usb_rt2x00_ops = {
-diff --git a/package/mac80211/patches/600-0004-rt2x00-rt2800lib-fix-beacon-generation-on-RT3593.patch b/package/mac80211/patches/600-0004-rt2x00-rt2800lib-fix-beacon-generation-on-RT3593.patch
-new file mode 100644
-index 0000000..7167f28
---- /dev/null
-+++ b/package/mac80211/patches/600-0004-rt2x00-rt2800lib-fix-beacon-generation-on-RT3593.patch
-@@ -0,0 +1,131 @@
-+From dcfe3dd46242050f100162dce2bcad24d2c942c6 Mon Sep 17 00:00:00 2001
-+From: Gabor Juhos <juhosg@openwrt.org>
-+Date: Sat, 17 Aug 2013 19:31:42 +0200
-+Subject: [PATCH] rt2x00: rt2800lib: fix beacon generation on RT3593
-+
-+On the RT3593 chipset, the beacon registers are located
-+in the high 8KB part of the shared memory.
-+
-+The high part of the shared memory is only accessible
-+if it is explicitly selected. Add a helper function
-+in order to be able to control the SHR_MSEL bit in
-+the PBF_SYS_CTRL register. Also add a few more helper
-+functions and use those to select the correct part of
-+the shared memory before and after accessing the beacon
-+registers.
-+
-+The base addresses of the beacon registers are also
-+different from the actually used values, so fix the
-+'rt2800_hw_beacon_base' function to return the correct
-+values.
-+
-+Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
-+---
-+Changes since v1: ---
-+---
-+ drivers/net/wireless/rt2x00/rt2800.h    |    3 +++
-+ drivers/net/wireless/rt2x00/rt2800lib.c |   44 +++++++++++++++++++++++++++++++
-+ 2 files changed, 47 insertions(+)
-+
-+--- a/drivers/net/wireless/rt2x00/rt2800.h
-++++ b/drivers/net/wireless/rt2x00/rt2800.h
-+@@ -572,6 +572,7 @@
-+ #define PBF_SYS_CTRL			0x0400
-+ #define PBF_SYS_CTRL_READY		FIELD32(0x00000080)
-+ #define PBF_SYS_CTRL_HOST_RAM_WRITE	FIELD32(0x00010000)
-++#define PBF_SYS_CTRL_SHR_MSEL		FIELD32(0x00080000)
-+ 
-+ /*
-+  * HOST-MCU shared memory
-+@@ -2024,6 +2025,8 @@ struct mac_iveiv_entry {
-+ 	  (((__index) < 6) ? (HW_BEACON_BASE4 + ((__index - 4) * 0x0200)) : \
-+ 	  (HW_BEACON_BASE6 - ((__index - 6) * 0x0200))))
-+ 
-++#define HW_BEACON_BASE_HIGH(__index)	(0x4000 + (__index) * 512)
-++
-+ #define BEACON_BASE_TO_OFFSET(_base)	(((_base) - 0x4000) / 64)
-+ 
-+ /*
-+--- a/drivers/net/wireless/rt2x00/rt2800lib.c
-++++ b/drivers/net/wireless/rt2x00/rt2800lib.c
-+@@ -82,6 +82,39 @@ static inline bool rt2800_is_305x_soc(st
-+ 	return false;
-+ }
-+ 
-++static inline void rt2800_shared_mem_select(struct rt2x00_dev *rt2x00dev,
-++					    bool high)
-++{
-++	u32 reg;
-++
-++	if (WARN_ON_ONCE(!rt2800_has_high_shared_mem(rt2x00dev)))
-++		return;
-++
-++	rt2800_register_read(rt2x00dev, PBF_SYS_CTRL, &reg);
-++	rt2x00_set_field32(&reg, PBF_SYS_CTRL_SHR_MSEL, high);
-++	rt2800_register_write(rt2x00dev, PBF_SYS_CTRL, reg);
-++}
-++
-++static inline bool rt2800_beacon_uses_high_mem(struct rt2x00_dev *rt2x00dev)
-++{
-++	if (rt2x00_rt(rt2x00dev, RT3593))
-++		return true;
-++
-++	return false;
-++}
-++
-++static inline void rt2800_select_beacon_mem(struct rt2x00_dev *rt2x00dev)
-++{
-++	if (rt2800_beacon_uses_high_mem(rt2x00dev))
-++		rt2800_shared_mem_select(rt2x00dev, true);
-++}
-++
-++static inline void rt2800_deselect_beacon_mem(struct rt2x00_dev *rt2x00dev)
-++{
-++	if (rt2800_beacon_uses_high_mem(rt2x00dev))
-++		rt2800_shared_mem_select(rt2x00dev, false);
-++}
-++
-+ static void rt2800_bbp_write(struct rt2x00_dev *rt2x00dev,
-+ 			     const unsigned int word, const u8 value)
-+ {
-+@@ -948,6 +981,9 @@ EXPORT_SYMBOL_GPL(rt2800_txdone_entry);
-+ static unsigned int rt2800_hw_beacon_base(struct rt2x00_dev *rt2x00dev,
-+ 					  unsigned int index)
-+ {
-++	if (rt2x00_rt(rt2x00dev, RT3593))
-++		return HW_BEACON_BASE_HIGH(index);
-++
-+ 	return HW_BEACON_BASE(index);
-+ }
-+ 
-+@@ -1046,8 +1082,12 @@ void rt2800_write_beacon(struct queue_en
-+ 	beacon_base = rt2800_hw_beacon_base(rt2x00dev, entry->entry_idx);
-+ 
-+ 	rt2800_shared_mem_lock(rt2x00dev);
-++
-++	rt2800_select_beacon_mem(rt2x00dev);
-+ 	rt2800_register_multiwrite(rt2x00dev, beacon_base, entry->skb->data,
-+ 				   entry->skb->len + padding_len);
-++	rt2800_deselect_beacon_mem(rt2x00dev);
-++
-+ 	rt2800_shared_mem_unlock(rt2x00dev);
-+ 	__set_bit(ENTRY_BCN_ENABLED, &entry->flags);
-+ 
-+@@ -1080,6 +1120,8 @@ static inline void rt2800_clear_beacon_r
-+ 
-+ 	rt2800_shared_mem_lock(rt2x00dev);
-+ 
-++	rt2800_select_beacon_mem(rt2x00dev);
-++
-+ 	/*
-+ 	 * For the Beacon base registers we only need to clear
-+ 	 * the whole TXWI which (when set to 0) will invalidate
-+@@ -1088,6 +1130,8 @@ static inline void rt2800_clear_beacon_r
-+ 	for (i = 0; i < txwi_desc_size; i += sizeof(__le32))
-+ 		rt2800_register_write(rt2x00dev, beacon_base + i, 0);
-+ 
-++	rt2800_deselect_beacon_mem(rt2x00dev);
-++
-+ 	rt2800_shared_mem_unlock(rt2x00dev);
-+ }
-+ 
-diff --git a/package/mac80211/patches/600-0005-rt2x00-rt2800lib-add-hw_beacon_count-field-to-struct.patch b/package/mac80211/patches/600-0005-rt2x00-rt2800lib-add-hw_beacon_count-field-to-struct.patch
-new file mode 100644
-index 0000000..0b509df
---- /dev/null
-+++ b/package/mac80211/patches/600-0005-rt2x00-rt2800lib-add-hw_beacon_count-field-to-struct.patch
-@@ -0,0 +1,62 @@
-+From a058825fa7b53fab3b003d8928b60e5b686b3421 Mon Sep 17 00:00:00 2001
-+From: Gabor Juhos <juhosg@openwrt.org>
-+Date: Sun, 4 Aug 2013 14:36:11 +0200
-+Subject: [PATCH] rt2x00: rt2800lib: add hw_beacon_count field to struct
-+ rt2800_drv_data
-+
-+Some chipsets can handle more than 8 beacons at once.
-+Add a new field to the rt2800_drv_data structure which
-+will hold the number of supported beacons of the given
-+chipset.
-+
-+Update the rt2x00_init_registers function to get the
-+beacon count from the new field instead of using a
-+hardcoded value.
-+
-+In order to keep the current behaviour, initialize the
-+new field with the actually used value.
-+
-+Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
-+---
-+ drivers/net/wireless/rt2x00/rt2800lib.c |    5 ++++-
-+ drivers/net/wireless/rt2x00/rt2800lib.h |    1 +
-+ 2 files changed, 5 insertions(+), 1 deletion(-)
-+
-+--- a/drivers/net/wireless/rt2x00/rt2800lib.c
-++++ b/drivers/net/wireless/rt2x00/rt2800lib.c
-+@@ -4628,6 +4628,7 @@ EXPORT_SYMBOL_GPL(rt2800_link_tuner);
-+  */
-+ static int rt2800_init_registers(struct rt2x00_dev *rt2x00dev)
-+ {
-++	struct rt2800_drv_data *drv_data = rt2x00dev->drv_data;
-+ 	u32 reg;
-+ 	u16 eeprom;
-+ 	unsigned int i;
-+@@ -4993,7 +4994,7 @@ static int rt2800_init_registers(struct 
-+ 	/*
-+ 	 * Clear all beacons
-+ 	 */
-+-	for (i = 0; i < 8; i++)
-++	for (i = 0; i < drv_data->hw_beacon_count; i++)
-+ 		rt2800_clear_beacon_register(rt2x00dev, i);
-+ 
-+ 	if (rt2x00_is_usb(rt2x00dev)) {
-+@@ -7839,6 +7840,8 @@ int rt2800_probe_hw(struct rt2x00_dev *r
-+ 	if (rt2x00_rt(rt2x00dev, RT3593))
-+ 		__set_bit(RT2800_HAS_HIGH_SHARED_MEM, &drv_data->rt2800_flags);
-+ 
-++	drv_data->hw_beacon_count = 8;
-++
-+ 	/*
-+ 	 * Allocate eeprom data.
-+ 	 */
-+--- a/drivers/net/wireless/rt2x00/rt2800lib.h
-++++ b/drivers/net/wireless/rt2x00/rt2800lib.h
-+@@ -33,6 +33,7 @@ struct rt2800_drv_data {
-+ 	u8 txmixer_gain_24g;
-+ 	u8 txmixer_gain_5g;
-+ 	unsigned int tbtt_tick;
-++	unsigned int hw_beacon_count;
-+ 
-+ 	unsigned long rt2800_flags;
-+ 
-diff --git a/package/mac80211/patches/600-0006-rt2x00-rt2800lib-init-additional-beacon-offset-regis.patch b/package/mac80211/patches/600-0006-rt2x00-rt2800lib-init-additional-beacon-offset-regis.patch
-new file mode 100644
-index 0000000..95f44b5
---- /dev/null
-+++ b/package/mac80211/patches/600-0006-rt2x00-rt2800lib-init-additional-beacon-offset-regis.patch
-@@ -0,0 +1,67 @@
-+From 1bfa43ca8f30be53ce4fa79cfc3e219642a812b6 Mon Sep 17 00:00:00 2001
-+From: Gabor Juhos <juhosg@openwrt.org>
-+Date: Mon, 2 Sep 2013 10:58:32 +0200
-+Subject: [PATCH] rt2x00: rt2800lib: init additional beacon offset registers
-+
-+Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
-+---
-+ drivers/net/wireless/rt2x00/rt2800.h    |   14 ++++++++++++++
-+ drivers/net/wireless/rt2x00/rt2800lib.c |   24 ++++++++++++++++++++++++
-+ 2 files changed, 38 insertions(+)
-+
-+--- a/drivers/net/wireless/rt2x00/rt2800.h
-++++ b/drivers/net/wireless/rt2x00/rt2800.h
-+@@ -627,6 +627,20 @@
-+  */
-+ #define PBF_DBG				0x043c
-+ 
-++/* BCN_OFFSET2 */
-++#define BCN_OFFSET2			0x0444
-++#define BCN_OFFSET2_BCN8		FIELD32(0x000000ff)
-++#define BCN_OFFSET2_BCN9		FIELD32(0x0000ff00)
-++#define BCN_OFFSET2_BCN10		FIELD32(0x00ff0000)
-++#define BCN_OFFSET2_BCN11		FIELD32(0xff000000)
-++
-++/* BCN_OFFSET3 */
-++#define BCN_OFFSET3			0x0448
-++#define BCN_OFFSET3_BCN12		FIELD32(0x000000ff)
-++#define BCN_OFFSET3_BCN13		FIELD32(0x0000ff00)
-++#define BCN_OFFSET3_BCN14		FIELD32(0x00ff0000)
-++#define BCN_OFFSET3_BCN15		FIELD32(0xff000000)
-++
-+ /*
-+  * RF registers
-+  */
-+--- a/drivers/net/wireless/rt2x00/rt2800lib.c
-++++ b/drivers/net/wireless/rt2x00/rt2800lib.c
-+@@ -4640,6 +4640,30 @@ static int rt2800_init_registers(struct 
-+ 	if (ret)
-+ 		return ret;
-+ 
-++	if (drv_data->hw_beacon_count == 16) {
-++		rt2800_register_read(rt2x00dev, BCN_OFFSET2, &reg);
-++		rt2x00_set_field32(&reg, BCN_OFFSET2_BCN8,
-++				   rt2800_get_beacon_offset(rt2x00dev, 8));
-++		rt2x00_set_field32(&reg, BCN_OFFSET2_BCN9,
-++				   rt2800_get_beacon_offset(rt2x00dev, 9));
-++		rt2x00_set_field32(&reg, BCN_OFFSET2_BCN10,
-++				   rt2800_get_beacon_offset(rt2x00dev, 10));
-++		rt2x00_set_field32(&reg, BCN_OFFSET2_BCN11,
-++				   rt2800_get_beacon_offset(rt2x00dev, 11));
-++		rt2800_register_write(rt2x00dev, BCN_OFFSET2, reg);
-++
-++		rt2800_register_read(rt2x00dev, BCN_OFFSET3, &reg);
-++		rt2x00_set_field32(&reg, BCN_OFFSET3_BCN12,
-++				   rt2800_get_beacon_offset(rt2x00dev, 12));
-++		rt2x00_set_field32(&reg, BCN_OFFSET3_BCN13,
-++				   rt2800_get_beacon_offset(rt2x00dev, 13));
-++		rt2x00_set_field32(&reg, BCN_OFFSET3_BCN14,
-++				   rt2800_get_beacon_offset(rt2x00dev, 14));
-++		rt2x00_set_field32(&reg, BCN_OFFSET3_BCN15,
-++				   rt2800_get_beacon_offset(rt2x00dev, 15));
-++		rt2800_register_write(rt2x00dev, BCN_OFFSET3, reg);
-++	}
-++
-+ 	rt2800_register_write(rt2x00dev, LEGACY_BASIC_RATE, 0x0000013f);
-+ 	rt2800_register_write(rt2x00dev, HT_BASIC_RATE, 0x00008003);
-+ 
-diff --git a/package/mac80211/patches/600-0007-rt2x00-rt2800lib-fix-max-supported-beacon-count-for-.patch b/package/mac80211/patches/600-0007-rt2x00-rt2800lib-fix-max-supported-beacon-count-for-.patch
-new file mode 100644
-index 0000000..303d2be
---- /dev/null
-+++ b/package/mac80211/patches/600-0007-rt2x00-rt2800lib-fix-max-supported-beacon-count-for-.patch
-@@ -0,0 +1,24 @@
-+From 9bea8b61f6025cd633bd5ac71be258620b49bcb3 Mon Sep 17 00:00:00 2001
-+From: Gabor Juhos <juhosg@openwrt.org>
-+Date: Mon, 2 Sep 2013 11:00:06 +0200
-+Subject: [PATCH] rt2x00: rt2800lib: fix max supported beacon count for RT3593
-+
-+Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
-+---
-+ drivers/net/wireless/rt2x00/rt2800lib.c |    5 ++++-
-+ 1 file changed, 4 insertions(+), 1 deletion(-)
-+
-+--- a/drivers/net/wireless/rt2x00/rt2800lib.c
-++++ b/drivers/net/wireless/rt2x00/rt2800lib.c
-+@@ -7864,7 +7864,10 @@ int rt2800_probe_hw(struct rt2x00_dev *r
-+ 	if (rt2x00_rt(rt2x00dev, RT3593))
-+ 		__set_bit(RT2800_HAS_HIGH_SHARED_MEM, &drv_data->rt2800_flags);
-+ 
-+-	drv_data->hw_beacon_count = 8;
-++	if (rt2x00_rt(rt2x00dev, RT3593))
-++		drv_data->hw_beacon_count = 16;
-++	else
-++		drv_data->hw_beacon_count = 8;
-+ 
-+ 	/*
-+ 	 * Allocate eeprom data.
-diff --git a/package/mac80211/patches/600-0008-rt2x00-allow-to-build-rt2800soc-module-for-RT3883.patch b/package/mac80211/patches/600-0008-rt2x00-allow-to-build-rt2800soc-module-for-RT3883.patch
-new file mode 100644
-index 0000000..8a10c6e
---- /dev/null
-+++ b/package/mac80211/patches/600-0008-rt2x00-allow-to-build-rt2800soc-module-for-RT3883.patch
-@@ -0,0 +1,30 @@
-+From 91094ed065f7794886b4a5490fd6de942f036bb4 Mon Sep 17 00:00:00 2001
-+From: Gabor Juhos <juhosg@openwrt.org>
-+Date: Sun, 24 Mar 2013 19:26:26 +0100
-+Subject: [PATCH] rt2x00: allow to build rt2800soc module for RT3883
-+
-+Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
-+---
-+ drivers/net/wireless/rt2x00/Kconfig |    2 +-
-+ 1 file changed, 1 insertion(+), 1 deletion(-)
-+
-+--- a/drivers/net/wireless/rt2x00/Kconfig
-++++ b/drivers/net/wireless/rt2x00/Kconfig
-+@@ -210,7 +210,7 @@ endif
-+ config RT2800SOC
-+ 	tristate "Ralink WiSoC support"
-+ 	depends on m
-+-	depends on SOC_RT288X || SOC_RT305X
-++	depends on SOC_RT288X || SOC_RT305X || SOC_RT3883
-+ 	select RT2X00_LIB_SOC
-+ 	select RT2X00_LIB_MMIO
-+ 	select RT2X00_LIB_CRYPTO
-+@@ -245,7 +245,7 @@ config RT2X00_LIB_PCI
-+ 
-+ config RT2X00_LIB_SOC
-+ 	tristate "RT2x00 SoC support"
-+-	depends on SOC_RT288X || SOC_RT305X
-++	depends on SOC_RT288X || SOC_RT305X || SOC_RT3883
-+ 	depends on m
-+ 	select RT2X00_LIB
-+ 
-diff --git a/package/mac80211/patches/600-0009-rt2x00-rt2800lib-enable-support-for-RT3883.patch b/package/mac80211/patches/600-0009-rt2x00-rt2800lib-enable-support-for-RT3883.patch
-new file mode 100644
-index 0000000..848d95f
---- /dev/null
-+++ b/package/mac80211/patches/600-0009-rt2x00-rt2800lib-enable-support-for-RT3883.patch
-@@ -0,0 +1,20 @@
-+From 4f16582c93a71eba9d389e0f0a8aa9099a9587cd Mon Sep 17 00:00:00 2001
-+From: Gabor Juhos <juhosg@openwrt.org>
-+Date: Sun, 24 Mar 2013 19:26:26 +0100
-+Subject: [PATCH] rt2x00: rt2800lib: enable support for RT3883
-+
-+Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
-+---
-+ drivers/net/wireless/rt2x00/rt2800lib.c |    1 +
-+ 1 file changed, 1 insertion(+)
-+
-+--- a/drivers/net/wireless/rt2x00/rt2800lib.c
-++++ b/drivers/net/wireless/rt2x00/rt2800lib.c
-+@@ -7834,6 +7834,7 @@ static int rt2800_probe_rt(struct rt2x00
-+ 	case RT3390:
-+ 	case RT3572:
-+ 	case RT3593:
-++	case RT3883:
-+ 	case RT5390:
-+ 	case RT5392:
-+ 	case RT5592:
-diff --git a/package/mac80211/patches/600-0010-rt2x00-rt2800lib-add-rf_vals-for-RF3853.patch b/package/mac80211/patches/600-0010-rt2x00-rt2800lib-add-rf_vals-for-RF3853.patch
-new file mode 100644
-index 0000000..4ccd47f
---- /dev/null
-+++ b/package/mac80211/patches/600-0010-rt2x00-rt2800lib-add-rf_vals-for-RF3853.patch
-@@ -0,0 +1,112 @@
-+From ecb394ccf248d8652c463133c4f404458a57a9c1 Mon Sep 17 00:00:00 2001
-+From: Gabor Juhos <juhosg@openwrt.org>
-+Date: Sun, 24 Mar 2013 19:26:26 +0100
-+Subject: [PATCH] rt2x00: rt2800lib: add rf_vals for RF3853
-+
-+Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
-+---
-+ drivers/net/wireless/rt2x00/rt2800.h    |    4 +-
-+ drivers/net/wireless/rt2x00/rt2800lib.c |   65 +++++++++++++++++++++++++++++++
-+ 2 files changed, 68 insertions(+), 1 deletion(-)
-+
-+--- a/drivers/net/wireless/rt2x00/rt2800.h
-++++ b/drivers/net/wireless/rt2x00/rt2800.h
-+@@ -48,7 +48,8 @@
-+  * RF2853 2.4G/5G 3T3R
-+  * RF3320 2.4G 1T1R(RT3350/RT3370/RT3390)
-+  * RF3322 2.4G 2T2R(RT3352/RT3371/RT3372/RT3391/RT3392)
-+- * RF3053 2.4G/5G 3T3R(RT3883/RT3563/RT3573/RT3593/RT3662)
-++ * RF3053 2.4G/5G 3T3R(RT3563/RT3573/RT3593)
-++ * RF3853 2.4G/5G 3T3R(RT3883/RT3662)
-+  * RF5592 2.4G/5G 2T2R
-+  * RF3070 2.4G 1T1R
-+  * RF5360 2.4G 1T1R
-+@@ -71,6 +72,7 @@
-+ #define RF5592				0x000f
-+ #define RF3070				0x3070
-+ #define RF3290				0x3290
-++#define RF3853				0x3853
-+ #define RF5360				0x5360
-+ #define RF5370				0x5370
-+ #define RF5372				0x5372
-+--- a/drivers/net/wireless/rt2x00/rt2800lib.c
-++++ b/drivers/net/wireless/rt2x00/rt2800lib.c
-+@@ -7454,6 +7454,66 @@ static const struct rf_channel rf_vals_3
-+ 	{173, 0x61, 0, 9},
-+ };
-+ 
-++static const struct rf_channel rf_vals_3853[] = {
-++	{1,  241, 6, 2},
-++	{2,  241, 6, 7},
-++	{3,  242, 6, 2},
-++	{4,  242, 6, 7},
-++	{5,  243, 6, 2},
-++	{6,  243, 6, 7},
-++	{7,  244, 6, 2},
-++	{8,  244, 6, 7},
-++	{9,  245, 6, 2},
-++	{10, 245, 6, 7},
-++	{11, 246, 6, 2},
-++	{12, 246, 6, 7},
-++	{13, 247, 6, 2},
-++	{14, 248, 6, 4},
-++
-++	{36, 0x56, 8, 4},
-++	{38, 0x56, 8, 6},
-++	{40, 0x56, 8, 8},
-++	{44, 0x57, 8, 0},
-++	{46, 0x57, 8, 2},
-++	{48, 0x57, 8, 4},
-++	{52, 0x57, 8, 8},
-++	{54, 0x57, 8, 10},
-++	{56, 0x58, 8, 0},
-++	{60, 0x58, 8, 4},
-++	{62, 0x58, 8, 6},
-++	{64, 0x58, 8, 8},
-++
-++	{100, 0x5b, 8, 8},
-++	{102, 0x5b, 8, 10},
-++	{104, 0x5c, 8, 0},
-++	{108, 0x5c, 8, 4},
-++	{110, 0x5c, 8, 6},
-++	{112, 0x5c, 8, 8},
-++	{114, 0x5c, 8, 10},
-++	{116, 0x5d, 8, 0},
-++	{118, 0x5d, 8, 2},
-++	{120, 0x5d, 8, 4},
-++	{124, 0x5d, 8, 8},
-++	{126, 0x5d, 8, 10},
-++	{128, 0x5e, 8, 0},
-++	{132, 0x5e, 8, 4},
-++	{134, 0x5e, 8, 6},
-++	{136, 0x5e, 8, 8},
-++	{140, 0x5f, 8, 0},
-++
-++	{149, 0x5f, 8, 9},
-++	{151, 0x5f, 8, 11},
-++	{153, 0x60, 8, 1},
-++	{157, 0x60, 8, 5},
-++	{159, 0x60, 8, 7},
-++	{161, 0x60, 8, 9},
-++	{165, 0x61, 8, 1},
-++	{167, 0x61, 8, 3},
-++	{169, 0x61, 8, 5},
-++	{171, 0x61, 8, 7},
-++	{173, 0x61, 8, 9},
-++};
-++
-+ static const struct rf_channel rf_vals_5592_xtal20[] = {
-+ 	/* Channel, N, K, mod, R */
-+ 	{1, 482, 4, 10, 3},
-+@@ -7682,6 +7742,11 @@ static int rt2800_probe_hw_mode(struct r
-+ 		spec->channels = rf_vals_3x;
-+ 		break;
-+ 
-++	case RF3853:
-++		spec->num_channels = ARRAY_SIZE(rf_vals_3853);
-++		spec->channels = rf_vals_3853;
-++		break;
-++
-+ 	case RF5592:
-+ 		rt2800_register_read(rt2x00dev, MAC_DEBUG_INDEX, &reg);
-+ 		if (rt2x00_get_field32(reg, MAC_DEBUG_INDEX_XTAL)) {
-diff --git a/package/mac80211/patches/600-0011-rt2x00-rt2800lib-enable-VCO-calibration-for-RF3853.patch b/package/mac80211/patches/600-0011-rt2x00-rt2800lib-enable-VCO-calibration-for-RF3853.patch
-new file mode 100644
-index 0000000..7dbfd7f
---- /dev/null
-+++ b/package/mac80211/patches/600-0011-rt2x00-rt2800lib-enable-VCO-calibration-for-RF3853.patch
-@@ -0,0 +1,28 @@
-+From f8e3fcf18e1f2d7f9e6a9680c5452da090f33d88 Mon Sep 17 00:00:00 2001
-+From: Gabor Juhos <juhosg@openwrt.org>
-+Date: Thu, 1 Aug 2013 14:40:44 +0200
-+Subject: [PATCH] rt2x00: rt2800lib: enable VCO calibration for RF3853
-+
-+Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
-+---
-+ drivers/net/wireless/rt2x00/rt2800lib.c |    2 ++
-+ 1 file changed, 2 insertions(+)
-+
-+--- a/drivers/net/wireless/rt2x00/rt2800lib.c
-++++ b/drivers/net/wireless/rt2x00/rt2800lib.c
-+@@ -4393,6 +4393,7 @@ void rt2800_vco_calibration(struct rt2x0
-+ 	case RF3053:
-+ 	case RF3070:
-+ 	case RF3290:
-++	case RF3853:
-+ 	case RF5360:
-+ 	case RF5370:
-+ 	case RF5372:
-+@@ -7861,6 +7862,7 @@ static int rt2800_probe_hw_mode(struct r
-+ 	case RF3053:
-+ 	case RF3070:
-+ 	case RF3290:
-++	case RF3853:
-+ 	case RF5360:
-+ 	case RF5370:
-+ 	case RF5372:
-diff --git a/package/mac80211/patches/600-0012-rt2x00-rt2800lib-add-channel-configuration-function-.patch b/package/mac80211/patches/600-0012-rt2x00-rt2800lib-add-channel-configuration-function-.patch
-new file mode 100644
-index 0000000..4c28f9b
---- /dev/null
-+++ b/package/mac80211/patches/600-0012-rt2x00-rt2800lib-add-channel-configuration-function-.patch
-@@ -0,0 +1,235 @@
-+From 6e3a17190815c6aa4dc53c2cfe9125fb1154f187 Mon Sep 17 00:00:00 2001
-+From: Gabor Juhos <juhosg@openwrt.org>
-+Date: Sun, 24 Mar 2013 19:26:27 +0100
-+Subject: [PATCH] rt2x00: rt2800lib: add channel configuration function for
-+ RF3853
-+
-+Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
-+---
-+ drivers/net/wireless/rt2x00/rt2800lib.c |  208 +++++++++++++++++++++++++++++++
-+ 1 file changed, 208 insertions(+)
-+
-+--- a/drivers/net/wireless/rt2x00/rt2800lib.c
-++++ b/drivers/net/wireless/rt2x00/rt2800lib.c
-+@@ -2649,6 +2649,211 @@ static void rt2800_config_channel_rf3053
-+ 	}
-+ }
-+ 
-++static void rt2800_config_channel_rf3853(struct rt2x00_dev *rt2x00dev,
-++					 struct ieee80211_conf *conf,
-++					 struct rf_channel *rf,
-++					 struct channel_info *info)
-++{
-++	u8 rfcsr;
-++	u8 bbp;
-++	u8 pwr1, pwr2, pwr3;
-++
-++	const bool txbf_enabled = false; /* TODO */
-++
-++	/* TODO: add band selection */
-++
-++	if (rf->channel <= 14)
-++		rt2800_rfcsr_write(rt2x00dev, 6, 0x40);
-++	else if (rf->channel < 132)
-++		rt2800_rfcsr_write(rt2x00dev, 6, 0x80);
-++	else
-++		rt2800_rfcsr_write(rt2x00dev, 6, 0x40);
-++
-++	rt2800_rfcsr_write(rt2x00dev, 8, rf->rf1);
-++	rt2800_rfcsr_write(rt2x00dev, 9, rf->rf3);
-++
-++	if (rf->channel <= 14)
-++		rt2800_rfcsr_write(rt2x00dev, 11, 0x46);
-++	else
-++		rt2800_rfcsr_write(rt2x00dev, 11, 0x48);
-++
-++	if (rf->channel <= 14)
-++		rt2800_rfcsr_write(rt2x00dev, 12, 0x1a);
-++	else
-++		rt2800_rfcsr_write(rt2x00dev, 12, 0x52);
-++
-++	rt2800_rfcsr_write(rt2x00dev, 13, 0x12);
-++
-++	rt2800_rfcsr_read(rt2x00dev, 1, &rfcsr);
-++	rt2x00_set_field8(&rfcsr, RFCSR1_RX0_PD, 0);
-++	rt2x00_set_field8(&rfcsr, RFCSR1_TX0_PD, 0);
-++	rt2x00_set_field8(&rfcsr, RFCSR1_RX1_PD, 0);
-++	rt2x00_set_field8(&rfcsr, RFCSR1_TX1_PD, 0);
-++	rt2x00_set_field8(&rfcsr, RFCSR1_RX2_PD, 0);
-++	rt2x00_set_field8(&rfcsr, RFCSR1_TX2_PD, 0);
-++	rt2x00_set_field8(&rfcsr, RFCSR1_RF_BLOCK_EN, 1);
-++	rt2x00_set_field8(&rfcsr, RFCSR1_PLL_PD, 1);
-++
-++	switch (rt2x00dev->default_ant.tx_chain_num) {
-++	case 3:
-++		rt2x00_set_field8(&rfcsr, RFCSR1_TX2_PD, 1);
-++		/* fallthrough */
-++	case 2:
-++		rt2x00_set_field8(&rfcsr, RFCSR1_TX1_PD, 1);
-++		/* fallthrough */
-++	case 1:
-++		rt2x00_set_field8(&rfcsr, RFCSR1_TX0_PD, 1);
-++		break;
-++	}
-++
-++	switch (rt2x00dev->default_ant.rx_chain_num) {
-++	case 3:
-++		rt2x00_set_field8(&rfcsr, RFCSR1_RX2_PD, 1);
-++		/* fallthrough */
-++	case 2:
-++		rt2x00_set_field8(&rfcsr, RFCSR1_RX1_PD, 1);
-++		/* fallthrough */
-++	case 1:
-++		rt2x00_set_field8(&rfcsr, RFCSR1_RX0_PD, 1);
-++		break;
-++	}
-++	rt2800_rfcsr_write(rt2x00dev, 1, rfcsr);
-++
-++	rt2800_adjust_freq_offset(rt2x00dev);
-++
-++	rt2800_rfcsr_read(rt2x00dev, 30, &rfcsr);
-++	if (!conf_is_ht40(conf))
-++		rfcsr &= ~(0x06);
-++	else
-++		rfcsr |= 0x06;
-++	rt2800_rfcsr_write(rt2x00dev, 30, rfcsr);
-++
-++	if (rf->channel <= 14)
-++		rt2800_rfcsr_write(rt2x00dev, 31, 0xa0);
-++	else
-++		rt2800_rfcsr_write(rt2x00dev, 31, 0x80);
-++
-++	if (conf_is_ht40(conf))
-++		rt2800_rfcsr_write(rt2x00dev, 32, 0x80);
-++	else
-++		rt2800_rfcsr_write(rt2x00dev, 32, 0xd8);
-++
-++	if (rf->channel <= 14)
-++		rt2800_rfcsr_write(rt2x00dev, 34, 0x3c);
-++	else
-++		rt2800_rfcsr_write(rt2x00dev, 34, 0x20);
-++
-++	/* loopback RF_BS */
-++	rt2800_rfcsr_read(rt2x00dev, 36, &rfcsr);
-++	if (rf->channel <= 14)
-++		rt2x00_set_field8(&rfcsr, RFCSR36_RF_BS, 1);
-++	else
-++		rt2x00_set_field8(&rfcsr, RFCSR36_RF_BS, 0);
-++	rt2800_rfcsr_write(rt2x00dev, 36, rfcsr);
-++
-++	if (rf->channel <= 14)
-++		rfcsr = 0x23;
-++	else if (rf->channel < 100)
-++		rfcsr = 0x36;
-++	else if (rf->channel < 132)
-++		rfcsr = 0x32;
-++	else
-++		rfcsr = 0x30;
-++
-++	if (txbf_enabled)
-++		rfcsr |= 0x40;
-++
-++	rt2800_rfcsr_write(rt2x00dev, 39, rfcsr);
-++
-++	if (rf->channel <= 14)
-++		rt2800_rfcsr_write(rt2x00dev, 44, 0x93);
-++	else
-++		rt2800_rfcsr_write(rt2x00dev, 44, 0x9b);
-++
-++	if (rf->channel <= 14)
-++		rfcsr = 0xbb;
-++	else if (rf->channel < 100)
-++		rfcsr = 0xeb;
-++	else if (rf->channel < 132)
-++		rfcsr = 0xb3;
-++	else
-++		rfcsr = 0x9b;
-++	rt2800_rfcsr_write(rt2x00dev, 45, rfcsr);
-++
-++	if (rf->channel <= 14)
-++		rfcsr = 0x8e;
-++	else
-++		rfcsr = 0x8a;
-++
-++	if (txbf_enabled)
-++		rfcsr |= 0x20;
-++
-++	rt2800_rfcsr_write(rt2x00dev, 49, rfcsr);
-++
-++	rt2800_rfcsr_write(rt2x00dev, 50, 0x86);
-++
-++	rt2800_rfcsr_read(rt2x00dev, 51, &rfcsr);
-++	if (rf->channel <= 14)
-++		rt2800_rfcsr_write(rt2x00dev, 51, 0x75);
-++	else
-++		rt2800_rfcsr_write(rt2x00dev, 51, 0x51);
-++
-++	rt2800_rfcsr_read(rt2x00dev, 52, &rfcsr);
-++	if (rf->channel <= 14)
-++		rt2800_rfcsr_write(rt2x00dev, 52, 0x45);
-++	else
-++		rt2800_rfcsr_write(rt2x00dev, 52, 0x05);
-++
-++	if (rf->channel <= 14) {
-++		pwr1 = info->default_power1 & 0x1f;
-++		pwr2 = info->default_power2 & 0x1f;
-++		pwr3 = info->default_power3 & 0x1f;
-++	} else {
-++		pwr1 = 0x48 | ((info->default_power1 & 0x18) << 1) |
-++			(info->default_power1 & 0x7);
-++		pwr2 = 0x48 | ((info->default_power2 & 0x18) << 1) |
-++			(info->default_power2 & 0x7);
-++		pwr3 = 0x48 | ((info->default_power3 & 0x18) << 1) |
-++			(info->default_power3 & 0x7);
-++	}
-++
-++	rt2800_rfcsr_write(rt2x00dev, 53, pwr1);
-++	rt2800_rfcsr_write(rt2x00dev, 54, pwr2);
-++	rt2800_rfcsr_write(rt2x00dev, 55, pwr3);
-++
-++	rt2x00_dbg(rt2x00dev, "Channel:%d, pwr1:%02x, pwr2:%02x, pwr3:%02x\n",
-++		   rf->channel, pwr1, pwr2, pwr3);
-++
-++	bbp = (info->default_power1 >> 5) |
-++	      ((info->default_power2 & 0xe0) >> 1);
-++	rt2800_bbp_write(rt2x00dev, 109, bbp);
-++
-++	rt2800_bbp_read(rt2x00dev, 110, &bbp);
-++	bbp &= 0x0f;
-++	bbp |= (info->default_power3 & 0xe0) >> 1;
-++	rt2800_bbp_write(rt2x00dev, 110, bbp);
-++
-++	rt2800_rfcsr_read(rt2x00dev, 57, &rfcsr);
-++	if (rf->channel <= 14)
-++		rt2800_rfcsr_write(rt2x00dev, 57, 0x6e);
-++	else
-++		rt2800_rfcsr_write(rt2x00dev, 57, 0x3e);
-++
-++	/* Enable RF tuning */
-++	rt2800_rfcsr_read(rt2x00dev, 3, &rfcsr);
-++	rt2x00_set_field8(&rfcsr, RFCSR3_VCOCAL_EN, 1);
-++	rt2800_rfcsr_write(rt2x00dev, 3, rfcsr);
-++
-++	udelay(2000);
-++
-++	rt2800_bbp_read(rt2x00dev, 49, &bbp);
-++	/* clear update flag */
-++	rt2800_bbp_write(rt2x00dev, 49, bbp & 0xfe);
-++	rt2800_bbp_write(rt2x00dev, 49, bbp);
-++
-++	/* TODO: add calibration for TxBF */
-++}
-++
-+ #define POWER_BOUND		0x27
-+ #define POWER_BOUND_5G		0x2b
-+ 
-+@@ -3261,6 +3466,9 @@ static void rt2800_config_channel(struct
-+ 	case RF3322:
-+ 		rt2800_config_channel_rf3322(rt2x00dev, conf, rf, info);
-+ 		break;
-++	case RF3853:
-++		rt2800_config_channel_rf3853(rt2x00dev, conf, rf, info);
-++		break;
-+ 	case RF3070:
-+ 	case RF5360:
-+ 	case RF5370:
-diff --git a/package/mac80211/patches/600-0013-rt2x00-rt2800lib-enable-RF3853-support.patch b/package/mac80211/patches/600-0013-rt2x00-rt2800lib-enable-RF3853-support.patch
-new file mode 100644
-index 0000000..9419e62
---- /dev/null
-+++ b/package/mac80211/patches/600-0013-rt2x00-rt2800lib-enable-RF3853-support.patch
-@@ -0,0 +1,20 @@
-+From afd38ae82226551bf879b6c7c4b620c271fee9d2 Mon Sep 17 00:00:00 2001
-+From: Gabor Juhos <juhosg@openwrt.org>
-+Date: Thu, 1 Aug 2013 14:42:05 +0200
-+Subject: [PATCH] rt2x00: rt2800lib: enable RF3853 support
-+
-+Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
-+---
-+ drivers/net/wireless/rt2x00/rt2800lib.c |    1 +
-+ 1 file changed, 1 insertion(+)
-+
-+--- a/drivers/net/wireless/rt2x00/rt2800lib.c
-++++ b/drivers/net/wireless/rt2x00/rt2800lib.c
-+@@ -7420,6 +7420,7 @@ static int rt2800_init_eeprom(struct rt2
-+ 	case RF3290:
-+ 	case RF3320:
-+ 	case RF3322:
-++	case RF3853:
-+ 	case RF5360:
-+ 	case RF5370:
-+ 	case RF5372:
-diff --git a/package/mac80211/patches/600-0014-rt2x00-rt2800lib-add-MAC-register-initialization-for.patch b/package/mac80211/patches/600-0014-rt2x00-rt2800lib-add-MAC-register-initialization-for.patch
-new file mode 100644
-index 0000000..65c6720
---- /dev/null
-+++ b/package/mac80211/patches/600-0014-rt2x00-rt2800lib-add-MAC-register-initialization-for.patch
-@@ -0,0 +1,77 @@
-+From 0094872a5e8e4664c6ea1b2dfa487063d39ae363 Mon Sep 17 00:00:00 2001
-+From: Gabor Juhos <juhosg@openwrt.org>
-+Date: Sun, 24 Mar 2013 19:26:26 +0100
-+Subject: [PATCH] rt2x00: rt2800lib: add MAC register initialization for
-+ RT3883
-+
-+Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
-+---
-+ drivers/net/wireless/rt2x00/rt2800.h    |   14 ++++++++++++++
-+ drivers/net/wireless/rt2x00/rt2800lib.c |   19 ++++++++++++++++---
-+ 2 files changed, 30 insertions(+), 3 deletions(-)
-+
-+--- a/drivers/net/wireless/rt2x00/rt2800.h
-++++ b/drivers/net/wireless/rt2x00/rt2800.h
-+@@ -1586,6 +1586,20 @@
-+ #define TX_PWR_CFG_9_STBC7_CH2		FIELD32(0x00000f00)
-+ 
-+ /*
-++ * TX_TXBF_CFG:
-++ */
-++#define TX_TXBF_CFG_0			0x138c
-++#define TX_TXBF_CFG_1			0x13a4
-++#define TX_TXBF_CFG_2			0x13a8
-++#define TX_TXBF_CFG_3			0x13ac
-++
-++/*
-++ * TX_FBK_CFG_3S:
-++ */
-++#define TX_FBK_CFG_3S_0			0x13c4
-++#define TX_FBK_CFG_3S_1			0x13c8
-++
-++/*
-+  * RX_FILTER_CFG: RX configuration register.
-+  */
-+ #define RX_FILTER_CFG			0x1400
-+--- a/drivers/net/wireless/rt2x00/rt2800lib.c
-++++ b/drivers/net/wireless/rt2x00/rt2800lib.c
-+@@ -4995,6 +4995,12 @@ static int rt2800_init_registers(struct 
-+ 			rt2800_register_write(rt2x00dev, TX_SW_CFG2,
-+ 					      0x00000000);
-+ 		}
-++	} else if (rt2x00_rt(rt2x00dev, RT3883)) {
-++		rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000402);
-++		rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00000000);
-++		rt2800_register_write(rt2x00dev, TX_SW_CFG2, 0x00040000);
-++		rt2800_register_write(rt2x00dev, TX_TXBF_CFG_0, 0x8000fc21);
-++		rt2800_register_write(rt2x00dev, TX_TXBF_CFG_3, 0x00009c40);
-+ 	} else if (rt2x00_rt(rt2x00dev, RT5390) ||
-+ 		   rt2x00_rt(rt2x00dev, RT5392) ||
-+ 		   rt2x00_rt(rt2x00dev, RT5592)) {
-+@@ -5025,9 +5031,11 @@ static int rt2800_init_registers(struct 
-+ 
-+ 	rt2800_register_read(rt2x00dev, MAX_LEN_CFG, &reg);
-+ 	rt2x00_set_field32(&reg, MAX_LEN_CFG_MAX_MPDU, AGGREGATION_SIZE);
-+-	if (rt2x00_rt_rev_gte(rt2x00dev, RT2872, REV_RT2872E) ||
-+-	    rt2x00_rt(rt2x00dev, RT2883) ||
-+-	    rt2x00_rt_rev_lt(rt2x00dev, RT3070, REV_RT3070E))
-++	if (rt2x00_rt(rt2x00dev, RT3883))
-++		rt2x00_set_field32(&reg, MAX_LEN_CFG_MAX_PSDU, 3);
-++	else if (rt2x00_rt_rev_gte(rt2x00dev, RT2872, REV_RT2872E) ||
-++		 rt2x00_rt(rt2x00dev, RT2883) ||
-++		 rt2x00_rt_rev_lt(rt2x00dev, RT3070, REV_RT3070E))
-+ 		rt2x00_set_field32(&reg, MAX_LEN_CFG_MAX_PSDU, 2);
-+ 	else
-+ 		rt2x00_set_field32(&reg, MAX_LEN_CFG_MAX_PSDU, 1);
-+@@ -5180,6 +5188,11 @@ static int rt2800_init_registers(struct 
-+ 	reg = rt2x00_rt(rt2x00dev, RT5592) ? 0x00000082 : 0x00000002;
-+ 	rt2800_register_write(rt2x00dev, TXOP_HLDR_ET, reg);
-+ 
-++	if (rt2x00_rt(rt2x00dev, RT3883)) {
-++		rt2800_register_write(rt2x00dev, TX_FBK_CFG_3S_0, 0x12111008);
-++		rt2800_register_write(rt2x00dev, TX_FBK_CFG_3S_1, 0x16151413);
-++	}
-++
-+ 	rt2800_register_read(rt2x00dev, TX_RTS_CFG, &reg);
-+ 	rt2x00_set_field32(&reg, TX_RTS_CFG_AUTO_RTS_RETRY_LIMIT, 32);
-+ 	rt2x00_set_field32(&reg, TX_RTS_CFG_RTS_THRES,
-diff --git a/package/mac80211/patches/600-0015-rt2x00-rt2800soc-fix-rt2800soc_disable_radio-for-RT3.patch b/package/mac80211/patches/600-0015-rt2x00-rt2800soc-fix-rt2800soc_disable_radio-for-RT3.patch
-new file mode 100644
-index 0000000..837c025
---- /dev/null
-+++ b/package/mac80211/patches/600-0015-rt2x00-rt2800soc-fix-rt2800soc_disable_radio-for-RT3.patch
-@@ -0,0 +1,30 @@
-+From 6c2d32478159fffff0b85abb6817a21bb2338231 Mon Sep 17 00:00:00 2001
-+From: Gabor Juhos <juhosg@openwrt.org>
-+Date: Sun, 24 Mar 2013 19:26:27 +0100
-+Subject: [PATCH] rt2x00: rt2800soc: fix rt2800soc_disable_radio for RT3883
-+
-+Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
-+---
-+ drivers/net/wireless/rt2x00/rt2800soc.c |    9 ++++++++-
-+ 1 file changed, 8 insertions(+), 1 deletion(-)
-+
-+--- a/drivers/net/wireless/rt2x00/rt2800soc.c
-++++ b/drivers/net/wireless/rt2x00/rt2800soc.c
-+@@ -51,9 +51,16 @@ static bool rt2800soc_hwcrypt_disabled(s
-+ 
-+ static void rt2800soc_disable_radio(struct rt2x00_dev *rt2x00dev)
-+ {
-++	u32 reg;
-++
-+ 	rt2800_disable_radio(rt2x00dev);
-+ 	rt2x00mmio_register_write(rt2x00dev, PWR_PIN_CFG, 0);
-+-	rt2x00mmio_register_write(rt2x00dev, TX_PIN_CFG, 0);
-++
-++	reg = 0;
-++	if (rt2x00_rt(rt2x00dev, RT3883))
-++		rt2x00_set_field32(&reg, TX_PIN_CFG_RFTR_EN, 1);
-++
-++	rt2x00mmio_register_write(rt2x00dev, TX_PIN_CFG, reg);
-+ }
-+ 
-+ static int rt2800soc_set_device_state(struct rt2x00_dev *rt2x00dev,
-diff --git a/package/mac80211/patches/600-0016-rt2x00-rt2800lib-add-BBP-register-initialization-for.patch b/package/mac80211/patches/600-0016-rt2x00-rt2800lib-add-BBP-register-initialization-for.patch
-new file mode 100644
-index 0000000..bba96db
---- /dev/null
-+++ b/package/mac80211/patches/600-0016-rt2x00-rt2800lib-add-BBP-register-initialization-for.patch
-@@ -0,0 +1,71 @@
-+From 84833056aa7dd25f5b097e31c78f2a0914c5160c Mon Sep 17 00:00:00 2001
-+From: Gabor Juhos <juhosg@openwrt.org>
-+Date: Sun, 24 Mar 2013 19:26:26 +0100
-+Subject: [PATCH] rt2x00: rt2800lib: add BBP register initialization for
-+ RT3883
-+
-+Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
-+---
-+ drivers/net/wireless/rt2x00/rt2800lib.c |   44 +++++++++++++++++++++++++++++++
-+ 1 file changed, 44 insertions(+)
-+
-+--- a/drivers/net/wireless/rt2x00/rt2800lib.c
-++++ b/drivers/net/wireless/rt2x00/rt2800lib.c
-+@@ -5798,6 +5798,47 @@ static void rt2800_init_bbp_3593(struct 
-+ 		rt2800_bbp_write(rt2x00dev, 103, 0xc0);
-+ }
-+ 
-++static void rt2800_init_bbp_3883(struct rt2x00_dev *rt2x00dev)
-++{
-++	rt2800_init_bbp_early(rt2x00dev);
-++
-++	rt2800_bbp_write(rt2x00dev, 4, 0x50);
-++	rt2800_bbp_write(rt2x00dev, 47, 0x48);
-++
-++	rt2800_bbp_write(rt2x00dev, 86, 0x46);
-++	rt2800_bbp_write(rt2x00dev, 88, 0x90);
-++
-++	rt2800_bbp_write(rt2x00dev, 92, 0x02);
-++
-++	rt2800_bbp_write(rt2x00dev, 103, 0xc0);
-++	rt2800_bbp_write(rt2x00dev, 104, 0x92);
-++	rt2800_bbp_write(rt2x00dev, 105, 0x34);
-++	rt2800_bbp_write(rt2x00dev, 106, 0x12);
-++	rt2800_bbp_write(rt2x00dev, 120, 0x50);
-++	rt2800_bbp_write(rt2x00dev, 137, 0x0f);
-++	rt2800_bbp_write(rt2x00dev, 163, 0x9d);
-++
-++	/* Set ITxBF timeout to 0x9C40=1000msec */
-++	rt2800_bbp_write(rt2x00dev, 179, 0x02);
-++	rt2800_bbp_write(rt2x00dev, 180, 0x00);
-++	rt2800_bbp_write(rt2x00dev, 182, 0x40);
-++	rt2800_bbp_write(rt2x00dev, 180, 0x01);
-++	rt2800_bbp_write(rt2x00dev, 182, 0x9c);
-++
-++	rt2800_bbp_write(rt2x00dev, 179, 0x00);
-++
-++	/* Reprogram the inband interface to put right values in RXWI */
-++	rt2800_bbp_write(rt2x00dev, 142, 0x04);
-++	rt2800_bbp_write(rt2x00dev, 143, 0x3b);
-++	rt2800_bbp_write(rt2x00dev, 142, 0x06);
-++	rt2800_bbp_write(rt2x00dev, 143, 0xa0);
-++	rt2800_bbp_write(rt2x00dev, 142, 0x07);
-++	rt2800_bbp_write(rt2x00dev, 143, 0xa1);
-++	rt2800_bbp_write(rt2x00dev, 142, 0x08);
-++	rt2800_bbp_write(rt2x00dev, 143, 0xa2);
-++	rt2800_bbp_write(rt2x00dev, 148, 0xc8);
-++}
-++
-+ static void rt2800_init_bbp_53xx(struct rt2x00_dev *rt2x00dev)
-+ {
-+ 	int ant, div_mode;
-+@@ -6016,6 +6057,9 @@ static void rt2800_init_bbp(struct rt2x0
-+ 	case RT3593:
-+ 		rt2800_init_bbp_3593(rt2x00dev);
-+ 		return;
-++	case RT3883:
-++		rt2800_init_bbp_3883(rt2x00dev);
-++		return;
-+ 	case RT5390:
-+ 	case RT5392:
-+ 		rt2800_init_bbp_53xx(rt2x00dev);
-diff --git a/package/mac80211/patches/600-0017-rt2x00-rt2800lib-add-RFCSR-initialization-for-RT3883.patch b/package/mac80211/patches/600-0017-rt2x00-rt2800lib-add-RFCSR-initialization-for-RT3883.patch
-new file mode 100644
-index 0000000..568e60e
---- /dev/null
-+++ b/package/mac80211/patches/600-0017-rt2x00-rt2800lib-add-RFCSR-initialization-for-RT3883.patch
-@@ -0,0 +1,178 @@
-+From 99c659cf345640fd0f733cbcaf4583cc2c868ec0 Mon Sep 17 00:00:00 2001
-+From: Gabor Juhos <juhosg@openwrt.org>
-+Date: Mon, 29 Apr 2013 13:21:48 +0200
-+Subject: [PATCH] rt2x00: rt2800lib: add RFCSR initialization for RT3883
-+
-+Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
-+---
-+ drivers/net/wireless/rt2x00/rt2800.h    |    1 +
-+ drivers/net/wireless/rt2x00/rt2800lib.c |  141 +++++++++++++++++++++++++++++++
-+ 2 files changed, 142 insertions(+)
-+
-+--- a/drivers/net/wireless/rt2x00/rt2800.h
-++++ b/drivers/net/wireless/rt2x00/rt2800.h
-+@@ -2169,6 +2169,7 @@ struct mac_iveiv_entry {
-+ /*
-+  * RFCSR 2:
-+  */
-++#define RFCSR2_RESCAL_BP		FIELD8(0x40)
-+ #define RFCSR2_RESCAL_EN		FIELD8(0x80)
-+ 
-+ /*
-+--- a/drivers/net/wireless/rt2x00/rt2800lib.c
-++++ b/drivers/net/wireless/rt2x00/rt2800lib.c
-+@@ -6833,6 +6833,144 @@ static void rt2800_init_rfcsr_3593(struc
-+ 	/* TODO: enable stream mode support */
-+ }
-+ 
-++static void rt2800_init_rfcsr_3883(struct rt2x00_dev *rt2x00dev)
-++{
-++	u8 rfcsr;
-++
-++	/* TODO: get the actual ECO value from the SoC */
-++	const unsigned int eco = 5;
-++
-++	rt2800_rf_init_calibration(rt2x00dev, 2);
-++
-++	rt2800_rfcsr_write(rt2x00dev, 0, 0xe0);
-++	rt2800_rfcsr_write(rt2x00dev, 1, 0x03);
-++	rt2800_rfcsr_write(rt2x00dev, 2, 0x50);
-++	rt2800_rfcsr_write(rt2x00dev, 3, 0x20);
-++	rt2800_rfcsr_write(rt2x00dev, 4, 0x00);
-++	rt2800_rfcsr_write(rt2x00dev, 5, 0x00);
-++	rt2800_rfcsr_write(rt2x00dev, 6, 0x40);
-++	rt2800_rfcsr_write(rt2x00dev, 7, 0x00);
-++	rt2800_rfcsr_write(rt2x00dev, 8, 0x5b);
-++	rt2800_rfcsr_write(rt2x00dev, 9, 0x08);
-++	rt2800_rfcsr_write(rt2x00dev, 10, 0xd3);
-++	rt2800_rfcsr_write(rt2x00dev, 11, 0x48);
-++	rt2800_rfcsr_write(rt2x00dev, 12, 0x1a);
-++	rt2800_rfcsr_write(rt2x00dev, 13, 0x12);
-++	rt2800_rfcsr_write(rt2x00dev, 14, 0x00);
-++	rt2800_rfcsr_write(rt2x00dev, 15, 0x00);
-++	rt2800_rfcsr_write(rt2x00dev, 16, 0x00);
-++
-++	/* RFCSR 17 will be initialized later based on the
-++	 * frequency offset stored in the EEPROM
-++	 */
-++
-++	rt2800_rfcsr_write(rt2x00dev, 18, 0x40);
-++	rt2800_rfcsr_write(rt2x00dev, 19, 0x00);
-++	rt2800_rfcsr_write(rt2x00dev, 20, 0x00);
-++	rt2800_rfcsr_write(rt2x00dev, 21, 0x00);
-++	rt2800_rfcsr_write(rt2x00dev, 22, 0x20);
-++	rt2800_rfcsr_write(rt2x00dev, 23, 0xc0);
-++	rt2800_rfcsr_write(rt2x00dev, 24, 0x00);
-++	rt2800_rfcsr_write(rt2x00dev, 25, 0x00);
-++	rt2800_rfcsr_write(rt2x00dev, 26, 0x00);
-++	rt2800_rfcsr_write(rt2x00dev, 27, 0x00);
-++	rt2800_rfcsr_write(rt2x00dev, 28, 0x00);
-++	rt2800_rfcsr_write(rt2x00dev, 29, 0x00);
-++	rt2800_rfcsr_write(rt2x00dev, 30, 0x10);
-++	rt2800_rfcsr_write(rt2x00dev, 31, 0x80);
-++	rt2800_rfcsr_write(rt2x00dev, 32, 0x80);
-++	rt2800_rfcsr_write(rt2x00dev, 33, 0x00);
-++	rt2800_rfcsr_write(rt2x00dev, 34, 0x20);
-++	rt2800_rfcsr_write(rt2x00dev, 35, 0x00);
-++	rt2800_rfcsr_write(rt2x00dev, 36, 0x00);
-++	rt2800_rfcsr_write(rt2x00dev, 37, 0x00);
-++	rt2800_rfcsr_write(rt2x00dev, 38, 0x86);
-++	rt2800_rfcsr_write(rt2x00dev, 39, 0x23);
-++	rt2800_rfcsr_write(rt2x00dev, 40, 0x00);
-++	rt2800_rfcsr_write(rt2x00dev, 41, 0x00);
-++	rt2800_rfcsr_write(rt2x00dev, 42, 0x00);
-++	rt2800_rfcsr_write(rt2x00dev, 43, 0x00);
-++	rt2800_rfcsr_write(rt2x00dev, 44, 0x93);
-++	rt2800_rfcsr_write(rt2x00dev, 45, 0xbb);
-++	rt2800_rfcsr_write(rt2x00dev, 46, 0x60);
-++	rt2800_rfcsr_write(rt2x00dev, 47, 0x00);
-++	rt2800_rfcsr_write(rt2x00dev, 48, 0x00);
-++	rt2800_rfcsr_write(rt2x00dev, 49, 0x8e);
-++	rt2800_rfcsr_write(rt2x00dev, 50, 0x86);
-++	rt2800_rfcsr_write(rt2x00dev, 51, 0x51);
-++	rt2800_rfcsr_write(rt2x00dev, 52, 0x05);
-++	rt2800_rfcsr_write(rt2x00dev, 53, 0x76);
-++	rt2800_rfcsr_write(rt2x00dev, 54, 0x76);
-++	rt2800_rfcsr_write(rt2x00dev, 55, 0x76);
-++	rt2800_rfcsr_write(rt2x00dev, 56, 0xdb);
-++	rt2800_rfcsr_write(rt2x00dev, 57, 0x3e);
-++	rt2800_rfcsr_write(rt2x00dev, 58, 0x00);
-++	rt2800_rfcsr_write(rt2x00dev, 59, 0x00);
-++	rt2800_rfcsr_write(rt2x00dev, 60, 0x00);
-++	rt2800_rfcsr_write(rt2x00dev, 61, 0x00);
-++	rt2800_rfcsr_write(rt2x00dev, 62, 0x00);
-++	rt2800_rfcsr_write(rt2x00dev, 63, 0x00);
-++
-++	/* TODO: rx filter calibration? */
-++
-++	rt2800_bbp_write(rt2x00dev, 137, 0x0f);
-++
-++	rt2800_bbp_write(rt2x00dev, 163, 0x9d);
-++
-++	rt2800_bbp_write(rt2x00dev, 105, 0x05);
-++
-++	rt2800_bbp_write(rt2x00dev, 179, 0x02);
-++	rt2800_bbp_write(rt2x00dev, 180, 0x00);
-++	rt2800_bbp_write(rt2x00dev, 182, 0x40);
-++	rt2800_bbp_write(rt2x00dev, 180, 0x01);
-++	rt2800_bbp_write(rt2x00dev, 182, 0x9c);
-++
-++	rt2800_bbp_write(rt2x00dev, 179, 0x00);
-++
-++	rt2800_bbp_write(rt2x00dev, 142, 0x04);
-++	rt2800_bbp_write(rt2x00dev, 143, 0x3b);
-++	rt2800_bbp_write(rt2x00dev, 142, 0x06);
-++	rt2800_bbp_write(rt2x00dev, 143, 0xa0);
-++	rt2800_bbp_write(rt2x00dev, 142, 0x07);
-++	rt2800_bbp_write(rt2x00dev, 143, 0xa1);
-++	rt2800_bbp_write(rt2x00dev, 142, 0x08);
-++	rt2800_bbp_write(rt2x00dev, 143, 0xa2);
-++	rt2800_bbp_write(rt2x00dev, 148, 0xc8);
-++
-++	if (eco == 5) {
-++		rt2800_rfcsr_write(rt2x00dev, 32, 0xd8);
-++		rt2800_rfcsr_write(rt2x00dev, 33, 0x32);
-++	}
-++
-++	rt2800_rfcsr_read(rt2x00dev, 2, &rfcsr);
-++	rt2x00_set_field8(&rfcsr, RFCSR2_RESCAL_BP, 0);
-++	rt2x00_set_field8(&rfcsr, RFCSR2_RESCAL_EN, 1);
-++	rt2800_rfcsr_write(rt2x00dev, 2, rfcsr);
-++	msleep(1);
-++	rt2x00_set_field8(&rfcsr, RFCSR2_RESCAL_EN, 0);
-++	rt2800_rfcsr_write(rt2x00dev, 2, rfcsr);
-++
-++	rt2800_rfcsr_read(rt2x00dev, 1, &rfcsr);
-++	rt2x00_set_field8(&rfcsr, RFCSR1_RF_BLOCK_EN, 1);
-++	rt2800_rfcsr_write(rt2x00dev, 1, rfcsr);
-++
-++	rt2800_rfcsr_read(rt2x00dev, 6, &rfcsr);
-++	rfcsr |= 0xc0;
-++	rt2800_rfcsr_write(rt2x00dev, 6, rfcsr);
-++
-++	rt2800_rfcsr_read(rt2x00dev, 22, &rfcsr);
-++	rfcsr |= 0x20;
-++	rt2800_rfcsr_write(rt2x00dev, 22, rfcsr);
-++
-++	rt2800_rfcsr_read(rt2x00dev, 46, &rfcsr);
-++	rfcsr |= 0x20;
-++	rt2800_rfcsr_write(rt2x00dev, 46, rfcsr);
-++
-++	rt2800_rfcsr_read(rt2x00dev, 20, &rfcsr);
-++	rfcsr &= ~0xee;
-++	rt2800_rfcsr_write(rt2x00dev, 20, rfcsr);
-++}
-++
-+ static void rt2800_init_rfcsr_5390(struct rt2x00_dev *rt2x00dev)
-+ {
-+ 	rt2800_rf_init_calibration(rt2x00dev, 2);
-+@@ -7064,6 +7202,9 @@ static void rt2800_init_rfcsr(struct rt2
-+ 	case RT3390:
-+ 		rt2800_init_rfcsr_3390(rt2x00dev);
-+ 		break;
-++	case RT3883:
-++		rt2800_init_rfcsr_3883(rt2x00dev);
-++		break;
-+ 	case RT3572:
-+ 		rt2800_init_rfcsr_3572(rt2x00dev);
-+ 		break;
-diff --git a/package/mac80211/patches/600-0018-rt2x00-rt2800lib-use-the-extended-EEPROM-map-for-RT3.patch b/package/mac80211/patches/600-0018-rt2x00-rt2800lib-use-the-extended-EEPROM-map-for-RT3.patch
-new file mode 100644
-index 0000000..57af961
---- /dev/null
-+++ b/package/mac80211/patches/600-0018-rt2x00-rt2800lib-use-the-extended-EEPROM-map-for-RT3.patch
-@@ -0,0 +1,22 @@
-+From 86022438ffeb1b87dfcd018bf477fdbb43076691 Mon Sep 17 00:00:00 2001
-+From: Gabor Juhos <juhosg@openwrt.org>
-+Date: Wed, 8 May 2013 19:35:33 +0200
-+Subject: [PATCH] rt2x00: rt2800lib: use the extended EEPROM map for RT3883
-+
-+Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
-+---
-+ drivers/net/wireless/rt2x00/rt2800lib.c |    3 ++-
-+ 1 file changed, 2 insertions(+), 1 deletion(-)
-+
-+--- a/drivers/net/wireless/rt2x00/rt2800lib.c
-++++ b/drivers/net/wireless/rt2x00/rt2800lib.c
-+@@ -342,7 +342,8 @@ static unsigned int rt2800_eeprom_word_i
-+ 		      wiphy_name(rt2x00dev->hw->wiphy), word))
-+ 		return 0;
-+ 
-+-	if (rt2x00_rt(rt2x00dev, RT3593))
-++	if (rt2x00_rt(rt2x00dev, RT3593) ||
-++	    rt2x00_rt(rt2x00dev, RT3883))
-+ 		map = rt2800_eeprom_map_ext;
-+ 	else
-+ 		map = rt2800_eeprom_map;
-diff --git a/package/mac80211/patches/600-0019-rt2x00-rt2800lib-force-rf-type-to-RF3853-on-RT3883.patch b/package/mac80211/patches/600-0019-rt2x00-rt2800lib-force-rf-type-to-RF3853-on-RT3883.patch
-new file mode 100644
-index 0000000..50fa94f
---- /dev/null
-+++ b/package/mac80211/patches/600-0019-rt2x00-rt2800lib-force-rf-type-to-RF3853-on-RT3883.patch
-@@ -0,0 +1,21 @@
-+From 4cf5403f02fa65dc2207f61d223cffa9ae50e907 Mon Sep 17 00:00:00 2001
-+From: Gabor Juhos <juhosg@openwrt.org>
-+Date: Thu, 1 Aug 2013 14:48:21 +0200
-+Subject: [PATCH] rt2x00: rt2800lib: force rf type to RF3853 on RT3883
-+
-+Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
-+---
-+ drivers/net/wireless/rt2x00/rt2800lib.c |    2 ++
-+ 1 file changed, 2 insertions(+)
-+
-+--- a/drivers/net/wireless/rt2x00/rt2800lib.c
-++++ b/drivers/net/wireless/rt2x00/rt2800lib.c
-+@@ -7601,6 +7601,8 @@ static int rt2800_init_eeprom(struct rt2
-+ 	    rt2x00_rt(rt2x00dev, RT5390) ||
-+ 	    rt2x00_rt(rt2x00dev, RT5392))
-+ 		rt2800_eeprom_read(rt2x00dev, EEPROM_CHIP_ID, &rf);
-++	else if (rt2x00_rt(rt2x00dev, RT3883))
-++		rf = RF3853;
-+ 	else
-+ 		rf = rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_RF_TYPE);
-+ 
-diff --git a/package/mac80211/patches/600-0020-rt2x00-rt2800lib-add-channel-configuration-code-for-.patch b/package/mac80211/patches/600-0020-rt2x00-rt2800lib-add-channel-configuration-code-for-.patch
-new file mode 100644
-index 0000000..e717baa
---- /dev/null
-+++ b/package/mac80211/patches/600-0020-rt2x00-rt2800lib-add-channel-configuration-code-for-.patch
-@@ -0,0 +1,136 @@
-+From 269f19c848a2380db03a3f207cafb88e28d71c53 Mon Sep 17 00:00:00 2001
-+From: Gabor Juhos <juhosg@openwrt.org>
-+Date: Sun, 24 Mar 2013 19:26:28 +0100
-+Subject: [PATCH] rt2x00: rt2800lib: add channel configuration code for RT3883
-+
-+Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
-+---
-+ drivers/net/wireless/rt2x00/rt2800lib.c |   72 +++++++++++++++++++++++++++++--
-+ 1 file changed, 69 insertions(+), 3 deletions(-)
-+
-+--- a/drivers/net/wireless/rt2x00/rt2800lib.c
-++++ b/drivers/net/wireless/rt2x00/rt2800lib.c
-+@@ -3429,6 +3429,36 @@ static char rt2800_txpower_to_dev(struct
-+ 		return clamp_t(char, txpower, MIN_A_TXPOWER, MAX_A_TXPOWER);
-+ }
-+ 
-++static void rt3883_bbp_adjust(struct rt2x00_dev *rt2x00dev,
-++			      struct rf_channel *rf)
-++{
-++	u8 bbp;
-++
-++	bbp = (rf->channel > 14) ? 0x48 : 0x38;
-++	rt2800_bbp_write_with_rx_chain(rt2x00dev, 66, bbp);
-++
-++	rt2800_bbp_write(rt2x00dev, 69, 0x12);
-++
-++	if (rf->channel <= 14) {
-++		rt2800_bbp_write(rt2x00dev, 70, 0x0a);
-++	} else {
-++		/* Disable CCK packet detection */
-++		rt2800_bbp_write(rt2x00dev, 70, 0x00);
-++	}
-++
-++	rt2800_bbp_write(rt2x00dev, 73, 0x10);
-++
-++	if (rf->channel > 14) {
-++		rt2800_bbp_write(rt2x00dev, 62, 0x1d);
-++		rt2800_bbp_write(rt2x00dev, 63, 0x1d);
-++		rt2800_bbp_write(rt2x00dev, 64, 0x1d);
-++	} else {
-++		rt2800_bbp_write(rt2x00dev, 62, 0x2d);
-++		rt2800_bbp_write(rt2x00dev, 63, 0x2d);
-++		rt2800_bbp_write(rt2x00dev, 64, 0x2d);
-++	}
-++}
-++
-+ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev,
-+ 				  struct ieee80211_conf *conf,
-+ 				  struct rf_channel *rf,
-+@@ -3447,6 +3477,12 @@ static void rt2800_config_channel(struct
-+ 			rt2800_txpower_to_dev(rt2x00dev, rf->channel,
-+ 					      info->default_power3);
-+ 
-++	switch (rt2x00dev->chip.rt) {
-++	case RT3883:
-++		rt3883_bbp_adjust(rt2x00dev, rf);
-++		break;
-++	}
-++
-+ 	switch (rt2x00dev->chip.rf) {
-+ 	case RF2020:
-+ 	case RF3020:
-+@@ -3528,6 +3564,15 @@ static void rt2800_config_channel(struct
-+ 		rt2800_bbp_write(rt2x00dev, 63, 0x37 - rt2x00dev->lna_gain);
-+ 		rt2800_bbp_write(rt2x00dev, 64, 0x37 - rt2x00dev->lna_gain);
-+ 		rt2800_bbp_write(rt2x00dev, 77, 0x98);
-++	} else if (rt2x00_rt(rt2x00dev, RT3883)) {
-++		rt2800_bbp_write(rt2x00dev, 62, 0x37 - rt2x00dev->lna_gain);
-++		rt2800_bbp_write(rt2x00dev, 63, 0x37 - rt2x00dev->lna_gain);
-++		rt2800_bbp_write(rt2x00dev, 64, 0x37 - rt2x00dev->lna_gain);
-++
-++		if (rt2x00dev->default_ant.rx_chain_num > 1)
-++			rt2800_bbp_write(rt2x00dev, 86, 0x46);
-++		else
-++			rt2800_bbp_write(rt2x00dev, 86, 0);
-+ 	} else {
-+ 		rt2800_bbp_write(rt2x00dev, 62, 0x37 - rt2x00dev->lna_gain);
-+ 		rt2800_bbp_write(rt2x00dev, 63, 0x37 - rt2x00dev->lna_gain);
-+@@ -3540,6 +3585,7 @@ static void rt2800_config_channel(struct
-+ 		    !rt2x00_rt(rt2x00dev, RT5392)) {
-+ 			if (rt2x00_has_cap_external_lna_bg(rt2x00dev)) {
-+ 				rt2800_bbp_write(rt2x00dev, 82, 0x62);
-++				rt2800_bbp_write(rt2x00dev, 82, 0x62);
-+ 				rt2800_bbp_write(rt2x00dev, 75, 0x46);
-+ 			} else {
-+ 				if (rt2x00_rt(rt2x00dev, RT3593))
-+@@ -3548,19 +3594,22 @@ static void rt2800_config_channel(struct
-+ 					rt2800_bbp_write(rt2x00dev, 82, 0x84);
-+ 				rt2800_bbp_write(rt2x00dev, 75, 0x50);
-+ 			}
-+-			if (rt2x00_rt(rt2x00dev, RT3593))
-++			if (rt2x00_rt(rt2x00dev, RT3593) ||
-++			    rt2x00_rt(rt2x00dev, RT3883))
-+ 				rt2800_bbp_write(rt2x00dev, 83, 0x8a);
-+ 		}
-+ 
-+ 	} else {
-+ 		if (rt2x00_rt(rt2x00dev, RT3572))
-+ 			rt2800_bbp_write(rt2x00dev, 82, 0x94);
-+-		else if (rt2x00_rt(rt2x00dev, RT3593))
-++		else if (rt2x00_rt(rt2x00dev, RT3593) ||
-++			 rt2x00_rt(rt2x00dev, RT3883))
-+ 			rt2800_bbp_write(rt2x00dev, 82, 0x82);
-+ 		else
-+ 			rt2800_bbp_write(rt2x00dev, 82, 0xf2);
-+ 
-+-		if (rt2x00_rt(rt2x00dev, RT3593))
-++		if (rt2x00_rt(rt2x00dev, RT3593) ||
-++		    rt2x00_rt(rt2x00dev, RT3883))
-+ 			rt2800_bbp_write(rt2x00dev, 83, 0x9a);
-+ 
-+ 		if (rt2x00_has_cap_external_lna_a(rt2x00dev))
-+@@ -3685,6 +3734,23 @@ static void rt2800_config_channel(struct
-+ 		usleep_range(1000, 1500);
-+ 	}
-+ 
-++	if (rt2x00_rt(rt2x00dev, RT3883)) {
-++		if (!conf_is_ht40(conf))
-++			rt2800_bbp_write(rt2x00dev, 105, 0x34);
-++		else
-++			rt2800_bbp_write(rt2x00dev, 105, 0x04);
-++
-++		/* AGC init */
-++		if (rf->channel <= 14)
-++			reg = 0x2e + rt2x00dev->lna_gain;
-++		else
-++			reg = 0x20 + ((rt2x00dev->lna_gain * 5) / 3);
-++
-++		rt2800_bbp_write_with_rx_chain(rt2x00dev, 66, reg);
-++
-++		usleep_range(1000, 1500);
-++	}
-++
-+ 	if (rt2x00_rt(rt2x00dev, RT5592)) {
-+ 		rt2800_bbp_write(rt2x00dev, 195, 141);
-+ 		rt2800_bbp_write(rt2x00dev, 196, conf_is_ht40(conf) ? 0x10 : 0x1a);
-diff --git a/package/mac80211/patches/600-0021-rt2x00-rt2800lib-fix-txpower_to_dev-function-for-RT3.patch b/package/mac80211/patches/600-0021-rt2x00-rt2800lib-fix-txpower_to_dev-function-for-RT3.patch
-new file mode 100644
-index 0000000..1773128
---- /dev/null
-+++ b/package/mac80211/patches/600-0021-rt2x00-rt2800lib-fix-txpower_to_dev-function-for-RT3.patch
-@@ -0,0 +1,30 @@
-+From e37d93abaabe3ab72b0332a18092acc162307274 Mon Sep 17 00:00:00 2001
-+From: Gabor Juhos <juhosg@openwrt.org>
-+Date: Mon, 30 Sep 2013 13:57:26 +0200
-+Subject: [PATCH] rt2x00: rt2800lib: fix txpower_to_dev function for RT3883
-+
-+Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
-+---
-+ drivers/net/wireless/rt2x00/rt2800lib.c |    6 ++++--
-+ 1 file changed, 4 insertions(+), 2 deletions(-)
-+
-+--- a/drivers/net/wireless/rt2x00/rt2800lib.c
-++++ b/drivers/net/wireless/rt2x00/rt2800lib.c
-+@@ -3416,13 +3416,15 @@ static char rt2800_txpower_to_dev(struct
-+ 				  unsigned int channel,
-+ 				  char txpower)
-+ {
-+-	if (rt2x00_rt(rt2x00dev, RT3593))
-++	if (rt2x00_rt(rt2x00dev, RT3593) ||
-++	    rt2x00_rt(rt2x00dev, RT3883))
-+ 		txpower = rt2x00_get_field8(txpower, EEPROM_TXPOWER_ALC);
-+ 
-+ 	if (channel <= 14)
-+ 		return clamp_t(char, txpower, MIN_G_TXPOWER, MAX_G_TXPOWER);
-+ 
-+-	if (rt2x00_rt(rt2x00dev, RT3593))
-++	if (rt2x00_rt(rt2x00dev, RT3593) ||
-++	    rt2x00_rt(rt2x00dev, RT3883))
-+ 		return clamp_t(char, txpower, MIN_A_TXPOWER_3593,
-+ 			       MAX_A_TXPOWER_3593);
-+ 	else
-diff --git a/package/mac80211/patches/600-0022-rt2x00-rt2800lib-use-correct-txpower-calculation-fun.patch b/package/mac80211/patches/600-0022-rt2x00-rt2800lib-use-correct-txpower-calculation-fun.patch
-new file mode 100644
-index 0000000..4956373
---- /dev/null
-+++ b/package/mac80211/patches/600-0022-rt2x00-rt2800lib-use-correct-txpower-calculation-fun.patch
-@@ -0,0 +1,23 @@
-+From c4d79e344bd580d85821390d49f92dced7d8e125 Mon Sep 17 00:00:00 2001
-+From: Gabor Juhos <juhosg@openwrt.org>
-+Date: Sun, 24 Mar 2013 19:26:29 +0100
-+Subject: [PATCH] rt2x00: rt2800lib: use correct txpower calculation function
-+ for RT3883
-+
-+Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
-+---
-+ drivers/net/wireless/rt2x00/rt2800lib.c |    3 ++-
-+ 1 file changed, 2 insertions(+), 1 deletion(-)
-+
-+--- a/drivers/net/wireless/rt2x00/rt2800lib.c
-++++ b/drivers/net/wireless/rt2x00/rt2800lib.c
-+@@ -4626,7 +4626,8 @@ static void rt2800_config_txpower(struct
-+ 				  struct ieee80211_channel *chan,
-+ 				  int power_level)
-+ {
-+-	if (rt2x00_rt(rt2x00dev, RT3593))
-++	if (rt2x00_rt(rt2x00dev, RT3593) ||
-++	    rt2x00_rt(rt2x00dev, RT3883))
-+ 		rt2800_config_txpower_rt3593(rt2x00dev, chan, power_level);
-+ 	else
-+ 		rt2800_config_txpower_rt28xx(rt2x00dev, chan, power_level);
-diff --git a/package/mac80211/patches/600-0023-rt2x00-rt2800lib-hardcode-txmixer-gain-values-to-zer.patch b/package/mac80211/patches/600-0023-rt2x00-rt2800lib-hardcode-txmixer-gain-values-to-zer.patch
-new file mode 100644
-index 0000000..a692fd8
---- /dev/null
-+++ b/package/mac80211/patches/600-0023-rt2x00-rt2800lib-hardcode-txmixer-gain-values-to-zer.patch
-@@ -0,0 +1,33 @@
-+From caea0671cd8fd9ade4f5969cbe0ee545e94ae105 Mon Sep 17 00:00:00 2001
-+From: Gabor Juhos <juhosg@openwrt.org>
-+Date: Sat, 24 Aug 2013 11:49:55 +0200
-+Subject: [PATCH] rt2x00: rt2800lib: hardcode txmixer gain values to zero for
-+ RT3883
-+
-+Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
-+---
-+ drivers/net/wireless/rt2x00/rt2800lib.c |    6 ++++--
-+ 1 file changed, 4 insertions(+), 2 deletions(-)
-+
-+--- a/drivers/net/wireless/rt2x00/rt2800lib.c
-++++ b/drivers/net/wireless/rt2x00/rt2800lib.c
-+@@ -7483,7 +7483,8 @@ static u8 rt2800_get_txmixer_gain_24g(st
-+ {
-+ 	u16 word;
-+ 
-+-	if (rt2x00_rt(rt2x00dev, RT3593))
-++	if (rt2x00_rt(rt2x00dev, RT3593) ||
-++	    rt2x00_rt(rt2x00dev, RT3883))
-+ 		return 0;
-+ 
-+ 	rt2800_eeprom_read(rt2x00dev, EEPROM_TXMIXER_GAIN_BG, &word);
-+@@ -7497,7 +7498,8 @@ static u8 rt2800_get_txmixer_gain_5g(str
-+ {
-+ 	u16 word;
-+ 
-+-	if (rt2x00_rt(rt2x00dev, RT3593))
-++	if (rt2x00_rt(rt2x00dev, RT3593) ||
-++	    rt2x00_rt(rt2x00dev, RT3883))
-+ 		return 0;
-+ 
-+ 	rt2800_eeprom_read(rt2x00dev, EEPROM_TXMIXER_GAIN_A, &word);
-diff --git a/package/mac80211/patches/600-0024-rt2x00-rt2800lib-use-correct-RT-XWI-size-for-RT3883.patch b/package/mac80211/patches/600-0024-rt2x00-rt2800lib-use-correct-RT-XWI-size-for-RT3883.patch
-new file mode 100644
-index 0000000..53435aa
---- /dev/null
-+++ b/package/mac80211/patches/600-0024-rt2x00-rt2800lib-use-correct-RT-XWI-size-for-RT3883.patch
-@@ -0,0 +1,20 @@
-+From 11c40fb47c4a4dd6ad060c2ae127ced89ffb9fe1 Mon Sep 17 00:00:00 2001
-+From: Gabor Juhos <juhosg@openwrt.org>
-+Date: Thu, 18 Apr 2013 14:33:33 +0200
-+Subject: [PATCH] rt2x00: rt2800lib: use correct [RT]XWI size for RT3883
-+
-+Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
-+---
-+ drivers/net/wireless/rt2x00/rt2800lib.c |    1 +
-+ 1 file changed, 1 insertion(+)
-+
-+--- a/drivers/net/wireless/rt2x00/rt2800lib.c
-++++ b/drivers/net/wireless/rt2x00/rt2800lib.c
-+@@ -558,6 +558,7 @@ void rt2800_get_txwi_rxwi_size(struct rt
-+ {
-+ 	switch (rt2x00dev->chip.rt) {
-+ 	case RT3593:
-++	case RT3883:
-+ 		*txwi_size = TXWI_DESC_SIZE_4WORDS;
-+ 		*rxwi_size = RXWI_DESC_SIZE_5WORDS;
-+ 		break;
-diff --git a/package/mac80211/patches/600-0025-rt2x00-rt2800lib-use-correct-beacon-base-for-RT3883.patch b/package/mac80211/patches/600-0025-rt2x00-rt2800lib-use-correct-beacon-base-for-RT3883.patch
-new file mode 100644
-index 0000000..08f3f88
---- /dev/null
-+++ b/package/mac80211/patches/600-0025-rt2x00-rt2800lib-use-correct-beacon-base-for-RT3883.patch
-@@ -0,0 +1,22 @@
-+From b403bdfa00665ce6b53583bdb837ffad0b91c09f Mon Sep 17 00:00:00 2001
-+From: Gabor Juhos <juhosg@openwrt.org>
-+Date: Sun, 24 Mar 2013 19:26:29 +0100
-+Subject: [PATCH] rt2x00: rt2800lib: use correct beacon base for RT3883
-+
-+Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
-+---
-+ drivers/net/wireless/rt2x00/rt2800lib.c |    3 ++-
-+ 1 file changed, 2 insertions(+), 1 deletion(-)
-+
-+--- a/drivers/net/wireless/rt2x00/rt2800lib.c
-++++ b/drivers/net/wireless/rt2x00/rt2800lib.c
-+@@ -983,7 +983,8 @@ EXPORT_SYMBOL_GPL(rt2800_txdone_entry);
-+ static unsigned int rt2800_hw_beacon_base(struct rt2x00_dev *rt2x00dev,
-+ 					  unsigned int index)
-+ {
-+-	if (rt2x00_rt(rt2x00dev, RT3593))
-++	if (rt2x00_rt(rt2x00dev, RT3593) ||
-++	    rt2x00_rt(rt2x00dev, RT3883))
-+ 		return HW_BEACON_BASE_HIGH(index);
-+ 
-+ 	return HW_BEACON_BASE(index);
-diff --git a/package/mac80211/patches/600-0026-rt2x00-rt2800lib-use-correct-beacon-count-for-RT3883.patch b/package/mac80211/patches/600-0026-rt2x00-rt2800lib-use-correct-beacon-count-for-RT3883.patch
-new file mode 100644
-index 0000000..f8fe496
---- /dev/null
-+++ b/package/mac80211/patches/600-0026-rt2x00-rt2800lib-use-correct-beacon-count-for-RT3883.patch
-@@ -0,0 +1,22 @@
-+From 74b7eaf75fc6eb86292056ef705e543f9cd6086b Mon Sep 17 00:00:00 2001
-+From: Gabor Juhos <juhosg@openwrt.org>
-+Date: Sun, 18 Aug 2013 09:57:58 +0200
-+Subject: [PATCH] rt2x00: rt2800lib: use correct beacon count for RT3883
-+
-+Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
-+---
-+ drivers/net/wireless/rt2x00/rt2800lib.c |    3 ++-
-+ 1 file changed, 2 insertions(+), 1 deletion(-)
-+
-+--- a/drivers/net/wireless/rt2x00/rt2800lib.c
-++++ b/drivers/net/wireless/rt2x00/rt2800lib.c
-+@@ -8415,7 +8415,8 @@ int rt2800_probe_hw(struct rt2x00_dev *r
-+ 	if (rt2x00_rt(rt2x00dev, RT3593))
-+ 		__set_bit(RT2800_HAS_HIGH_SHARED_MEM, &drv_data->rt2800_flags);
-+ 
-+-	if (rt2x00_rt(rt2x00dev, RT3593))
-++	if (rt2x00_rt(rt2x00dev, RT3593) ||
-++	    rt2x00_rt(rt2x00dev, RT3883))
-+ 		drv_data->hw_beacon_count = 16;
-+ 	else
-+ 		drv_data->hw_beacon_count = 8;
-diff --git a/package/mac80211/patches/600-0027-rt2x00-rt2800lib-fix-antenna-configuration-for-RT388.patch b/package/mac80211/patches/600-0027-rt2x00-rt2800lib-fix-antenna-configuration-for-RT388.patch
-new file mode 100644
-index 0000000..22f7110
---- /dev/null
-+++ b/package/mac80211/patches/600-0027-rt2x00-rt2800lib-fix-antenna-configuration-for-RT388.patch
-@@ -0,0 +1,22 @@
-+From fa5ad9c025610c22048add2f0ad03f62b6ca1e74 Mon Sep 17 00:00:00 2001
-+From: Gabor Juhos <juhosg@openwrt.org>
-+Date: Mon, 30 Sep 2013 16:53:33 +0200
-+Subject: [PATCH] rt2x00: rt2800lib: fix antenna configuration for RT3883
-+
-+Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
-+---
-+ drivers/net/wireless/rt2x00/rt2800lib.c |    3 ++-
-+ 1 file changed, 2 insertions(+), 1 deletion(-)
-+
-+--- a/drivers/net/wireless/rt2x00/rt2800lib.c
-++++ b/drivers/net/wireless/rt2x00/rt2800lib.c
-+@@ -1961,7 +1961,8 @@ void rt2800_config_ant(struct rt2x00_dev
-+ 	rt2800_bbp_write(rt2x00dev, 3, r3);
-+ 	rt2800_bbp_write(rt2x00dev, 1, r1);
-+ 
-+-	if (rt2x00_rt(rt2x00dev, RT3593)) {
-++	if (rt2x00_rt(rt2x00dev, RT3593) ||
-++	    rt2x00_rt(rt2x00dev, RT3883)) {
-+ 		if (ant->rx_chain_num == 1)
-+ 			rt2800_bbp_write(rt2x00dev, 86, 0x00);
-+ 		else
-diff --git a/package/mac80211/patches/600-0028-rt2x00-rt2800lib-fix-LNA-gain-configuration-for-RT38.patch b/package/mac80211/patches/600-0028-rt2x00-rt2800lib-fix-LNA-gain-configuration-for-RT38.patch
-new file mode 100644
-index 0000000..9945f38
---- /dev/null
-+++ b/package/mac80211/patches/600-0028-rt2x00-rt2800lib-fix-LNA-gain-configuration-for-RT38.patch
-@@ -0,0 +1,32 @@
-+From 6d668fef3a1baa60bdd715ee062ddb6333d2647c Mon Sep 17 00:00:00 2001
-+From: Gabor Juhos <juhosg@openwrt.org>
-+Date: Mon, 30 Sep 2013 16:58:23 +0200
-+Subject: [PATCH] rt2x00: rt2800lib: fix LNA gain configuration for RT3883
-+
-+Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
-+---
-+ drivers/net/wireless/rt2x00/rt2800lib.c |    6 ++++--
-+ 1 file changed, 4 insertions(+), 2 deletions(-)
-+
-+--- a/drivers/net/wireless/rt2x00/rt2800lib.c
-++++ b/drivers/net/wireless/rt2x00/rt2800lib.c
-+@@ -1984,7 +1984,8 @@ static void rt2800_config_lna_gain(struc
-+ 		rt2800_eeprom_read(rt2x00dev, EEPROM_LNA, &eeprom);
-+ 		lna_gain = rt2x00_get_field16(eeprom, EEPROM_LNA_A0);
-+ 	} else if (libconf->rf.channel <= 128) {
-+-		if (rt2x00_rt(rt2x00dev, RT3593)) {
-++		if (rt2x00_rt(rt2x00dev, RT3593) ||
-++		    rt2x00_rt(rt2x00dev, RT3883)) {
-+ 			rt2800_eeprom_read(rt2x00dev, EEPROM_EXT_LNA2, &eeprom);
-+ 			lna_gain = rt2x00_get_field16(eeprom,
-+ 						      EEPROM_EXT_LNA2_A1);
-+@@ -1994,7 +1995,8 @@ static void rt2800_config_lna_gain(struc
-+ 						      EEPROM_RSSI_BG2_LNA_A1);
-+ 		}
-+ 	} else {
-+-		if (rt2x00_rt(rt2x00dev, RT3593)) {
-++		if (rt2x00_rt(rt2x00dev, RT3593) ||
-++		    rt2x00_rt(rt2x00dev, RT3883)) {
-+ 			rt2800_eeprom_read(rt2x00dev, EEPROM_EXT_LNA2, &eeprom);
-+ 			lna_gain = rt2x00_get_field16(eeprom,
-+ 						      EEPROM_EXT_LNA2_A2);
-diff --git a/package/mac80211/patches/600-0029-rt2x00-rt2800lib-fix-VGC-setup-for-RT3883.patch b/package/mac80211/patches/600-0029-rt2x00-rt2800lib-fix-VGC-setup-for-RT3883.patch
-new file mode 100644
-index 0000000..80b3668
---- /dev/null
-+++ b/package/mac80211/patches/600-0029-rt2x00-rt2800lib-fix-VGC-setup-for-RT3883.patch
-@@ -0,0 +1,44 @@
-+From c49b2d829aa1c816a46a577cdec6d2ff14d9f06e Mon Sep 17 00:00:00 2001
-+From: Gabor Juhos <juhosg@openwrt.org>
-+Date: Tue, 1 Oct 2013 15:40:08 +0200
-+Subject: [PATCH] rt2x00: rt2800lib: fix VGC setup for RT3883
-+
-+Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
-+---
-+ drivers/net/wireless/rt2x00/rt2800lib.c |   11 +++++++++--
-+ 1 file changed, 9 insertions(+), 2 deletions(-)
-+
-+--- a/drivers/net/wireless/rt2x00/rt2800lib.c
-++++ b/drivers/net/wireless/rt2x00/rt2800lib.c
-+@@ -4825,7 +4825,8 @@ static u8 rt2800_get_default_vgc(struct 
-+ 		else
-+ 			vgc = 0x2e + rt2x00dev->lna_gain;
-+ 	} else { /* 5GHZ band */
-+-		if (rt2x00_rt(rt2x00dev, RT3593))
-++		if (rt2x00_rt(rt2x00dev, RT3593) ||
-++		    rt2x00_rt(rt2x00dev, RT3883))
-+ 			vgc = 0x20 + (rt2x00dev->lna_gain * 5) / 3;
-+ 		else if (rt2x00_rt(rt2x00dev, RT5592))
-+ 			vgc = 0x24 + (2 * rt2x00dev->lna_gain);
-+@@ -4845,7 +4846,8 @@ static inline void rt2800_set_vgc(struct
-+ {
-+ 	if (qual->vgc_level != vgc_level) {
-+ 		if (rt2x00_rt(rt2x00dev, RT3572) ||
-+-		    rt2x00_rt(rt2x00dev, RT3593)) {
-++		    rt2x00_rt(rt2x00dev, RT3593) ||
-++		    rt2x00_rt(rt2x00dev, RT3883)) {
-+ 			rt2800_bbp_write_with_rx_chain(rt2x00dev, 66,
-+ 						       vgc_level);
-+ 		} else if (rt2x00_rt(rt2x00dev, RT5592)) {
-+@@ -4892,6 +4894,11 @@ void rt2800_link_tuner(struct rt2x00_dev
-+ 		}
-+ 		break;
-+ 
-++	case RT3883:
-++		if (qual->rssi > -65)
-++			vgc += 0x10;
-++		break;
-++
-+ 	case RT5592:
-+ 		if (qual->rssi > -65)
-+ 			vgc += 0x20;
-diff --git a/package/mac80211/patches/600-0030-rt2x00-rt2800lib-fix-EEPROM-LNA-validation-for-RT388.patch b/package/mac80211/patches/600-0030-rt2x00-rt2800lib-fix-EEPROM-LNA-validation-for-RT388.patch
-new file mode 100644
-index 0000000..424acff
---- /dev/null
-+++ b/package/mac80211/patches/600-0030-rt2x00-rt2800lib-fix-EEPROM-LNA-validation-for-RT388.patch
-@@ -0,0 +1,42 @@
-+From 1616650aea676541d4dc8adc6f4219856d193c8b Mon Sep 17 00:00:00 2001
-+From: Gabor Juhos <juhosg@openwrt.org>
-+Date: Tue, 1 Oct 2013 17:27:57 +0200
-+Subject: [PATCH] rt2x00: rt2800lib: fix EEPROM LNA validation for RT3883
-+
-+Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
-+---
-+ drivers/net/wireless/rt2x00/rt2800lib.c |    9 ++++++---
-+ 1 file changed, 6 insertions(+), 3 deletions(-)
-+
-+--- a/drivers/net/wireless/rt2x00/rt2800lib.c
-++++ b/drivers/net/wireless/rt2x00/rt2800lib.c
-+@@ -7620,7 +7620,8 @@ static int rt2800_validate_eeprom(struct
-+ 	rt2800_eeprom_read(rt2x00dev, EEPROM_RSSI_BG2, &word);
-+ 	if (abs(rt2x00_get_field16(word, EEPROM_RSSI_BG2_OFFSET2)) > 10)
-+ 		rt2x00_set_field16(&word, EEPROM_RSSI_BG2_OFFSET2, 0);
-+-	if (!rt2x00_rt(rt2x00dev, RT3593)) {
-++	if (!rt2x00_rt(rt2x00dev, RT3593) &&
-++	    !rt2x00_rt(rt2x00dev, RT3883)) {
-+ 		if (rt2x00_get_field16(word, EEPROM_RSSI_BG2_LNA_A1) == 0x00 ||
-+ 		    rt2x00_get_field16(word, EEPROM_RSSI_BG2_LNA_A1) == 0xff)
-+ 			rt2x00_set_field16(&word, EEPROM_RSSI_BG2_LNA_A1,
-+@@ -7640,7 +7641,8 @@ static int rt2800_validate_eeprom(struct
-+ 	rt2800_eeprom_read(rt2x00dev, EEPROM_RSSI_A2, &word);
-+ 	if (abs(rt2x00_get_field16(word, EEPROM_RSSI_A2_OFFSET2)) > 10)
-+ 		rt2x00_set_field16(&word, EEPROM_RSSI_A2_OFFSET2, 0);
-+-	if (!rt2x00_rt(rt2x00dev, RT3593)) {
-++	if (!rt2x00_rt(rt2x00dev, RT3593) &&
-++	    !rt2x00_rt(rt2x00dev, RT3883)) {
-+ 		if (rt2x00_get_field16(word, EEPROM_RSSI_A2_LNA_A2) == 0x00 ||
-+ 		    rt2x00_get_field16(word, EEPROM_RSSI_A2_LNA_A2) == 0xff)
-+ 			rt2x00_set_field16(&word, EEPROM_RSSI_A2_LNA_A2,
-+@@ -7648,7 +7650,8 @@ static int rt2800_validate_eeprom(struct
-+ 	}
-+ 	rt2800_eeprom_write(rt2x00dev, EEPROM_RSSI_A2, word);
-+ 
-+-	if (rt2x00_rt(rt2x00dev, RT3593)) {
-++	if (rt2x00_rt(rt2x00dev, RT3593) ||
-++	    rt2x00_rt(rt2x00dev, RT3883)) {
-+ 		rt2800_eeprom_read(rt2x00dev, EEPROM_EXT_LNA2, &word);
-+ 		if (rt2x00_get_field16(word, EEPROM_EXT_LNA2_A1) == 0x00 ||
-+ 		    rt2x00_get_field16(word, EEPROM_EXT_LNA2_A1) == 0xff)
-diff --git a/package/mac80211/patches/600-0031-rt2x00-rt2800lib-fix-txpower-compensation-for-RT3883.patch b/package/mac80211/patches/600-0031-rt2x00-rt2800lib-fix-txpower-compensation-for-RT3883.patch
-new file mode 100644
-index 0000000..00be526
---- /dev/null
-+++ b/package/mac80211/patches/600-0031-rt2x00-rt2800lib-fix-txpower-compensation-for-RT3883.patch
-@@ -0,0 +1,22 @@
-+From e3871034a0e7c8a95152dc3eafbcc4535398cbdc Mon Sep 17 00:00:00 2001
-+From: Gabor Juhos <juhosg@openwrt.org>
-+Date: Wed, 2 Oct 2013 10:11:59 +0200
-+Subject: [PATCH] rt2x00: rt2800lib: fix txpower compensation for RT3883
-+
-+Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
-+---
-+ drivers/net/wireless/rt2x00/rt2800lib.c |    3 +++
-+ 1 file changed, 3 insertions(+)
-+
-+--- a/drivers/net/wireless/rt2x00/rt2800lib.c
-++++ b/drivers/net/wireless/rt2x00/rt2800lib.c
-+@@ -4003,6 +4003,9 @@ static u8 rt2800_compensate_txpower(stru
-+ 	if (rt2x00_rt(rt2x00dev, RT3593))
-+ 		return min_t(u8, txpower, 0xc);
-+ 
-++	if (rt2x00_rt(rt2x00dev, RT3883))
-++		return min_t(u8, txpower, 0xf);
-++
-+ 	if (rt2x00_has_cap_power_limit(rt2x00dev)) {
-+ 		/*
-+ 		 * Check if eirp txpower exceed txpower_limit.
-diff --git a/package/mac80211/patches/600-0032-rt2x00-rt2800lib-enable-RT2800_HAS_HIGH_SHARED_MEM-f.patch b/package/mac80211/patches/600-0032-rt2x00-rt2800lib-enable-RT2800_HAS_HIGH_SHARED_MEM-f.patch
-new file mode 100644
-index 0000000..7c4c1ab
---- /dev/null
-+++ b/package/mac80211/patches/600-0032-rt2x00-rt2800lib-enable-RT2800_HAS_HIGH_SHARED_MEM-f.patch
-@@ -0,0 +1,23 @@
-+From f6734ec72da936989a8ce4186b3ede28fbc47836 Mon Sep 17 00:00:00 2001
-+From: Gabor Juhos <juhosg@openwrt.org>
-+Date: Sun, 18 Aug 2013 21:57:34 +0200
-+Subject: [PATCH] rt2x00: rt2800lib: enable RT2800_HAS_HIGH_SHARED_MEM for
-+ RT3883
-+
-+Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
-+---
-+ drivers/net/wireless/rt2x00/rt2800lib.c |    3 ++-
-+ 1 file changed, 2 insertions(+), 1 deletion(-)
-+
-+--- a/drivers/net/wireless/rt2x00/rt2800lib.c
-++++ b/drivers/net/wireless/rt2x00/rt2800lib.c
-+@@ -8428,7 +8428,8 @@ int rt2800_probe_hw(struct rt2x00_dev *r
-+ 	if (retval)
-+ 		return retval;
-+ 
-+-	if (rt2x00_rt(rt2x00dev, RT3593))
-++	if (rt2x00_rt(rt2x00dev, RT3593) ||
-++	    rt2x00_rt(rt2x00dev, RT3883))
-+ 		__set_bit(RT2800_HAS_HIGH_SHARED_MEM, &drv_data->rt2800_flags);
-+ 
-+ 	if (rt2x00_rt(rt2x00dev, RT3593) ||
-diff --git a/package/mac80211/patches/600-0033-rt2x00-rt2800lib-use-high-memory-for-beacons-on-RT38.patch b/package/mac80211/patches/600-0033-rt2x00-rt2800lib-use-high-memory-for-beacons-on-RT38.patch
-new file mode 100644
-index 0000000..dc06e6a
---- /dev/null
-+++ b/package/mac80211/patches/600-0033-rt2x00-rt2800lib-use-high-memory-for-beacons-on-RT38.patch
-@@ -0,0 +1,22 @@
-+From f1acfc2f397e86548ae1b479c198d4bef57050f6 Mon Sep 17 00:00:00 2001
-+From: Gabor Juhos <juhosg@openwrt.org>
-+Date: Sun, 29 Sep 2013 18:10:34 +0200
-+Subject: [PATCH] rt2x00: rt2800lib: use high memory for beacons on RT3883
-+
-+Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
-+---
-+ drivers/net/wireless/rt2x00/rt2800lib.c |    3 ++-
-+ 1 file changed, 2 insertions(+), 1 deletion(-)
-+
-+--- a/drivers/net/wireless/rt2x00/rt2800lib.c
-++++ b/drivers/net/wireless/rt2x00/rt2800lib.c
-+@@ -97,7 +97,8 @@ static inline void rt2800_shared_mem_sel
-+ 
-+ static inline bool rt2800_beacon_uses_high_mem(struct rt2x00_dev *rt2x00dev)
-+ {
-+-	if (rt2x00_rt(rt2x00dev, RT3593))
-++	if (rt2x00_rt(rt2x00dev, RT3593) ||
-++	    rt2x00_rt(rt2x00dev, RT3883))
-+ 		return true;
-+ 
-+ 	return false;
-diff --git a/package/mac80211/patches/600-0034-rt2x00-rt2800mmio-add-a-workaround-for-spurious-TX_F.patch b/package/mac80211/patches/600-0034-rt2x00-rt2800mmio-add-a-workaround-for-spurious-TX_F.patch
-new file mode 100644
-index 0000000..79334dd
---- /dev/null
-+++ b/package/mac80211/patches/600-0034-rt2x00-rt2800mmio-add-a-workaround-for-spurious-TX_F.patch
-@@ -0,0 +1,136 @@
-+From 5e67d4f8a46d19748b501c2ef86de3f50d3cfd51 Mon Sep 17 00:00:00 2001
-+From: Gabor Juhos <juhosg@openwrt.org>
-+Date: Sun, 24 Mar 2013 19:26:27 +0100
-+Subject: [PATCH] rt2x00: rt2800mmio: add a workaround for spurious
-+ TX_FIFO_STATUS interrupts
-+
-+Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
-+---
-+ drivers/net/wireless/rt2x00/rt2800mmio.c |   72 +++++++++++++++++++++++++-----
-+ drivers/net/wireless/rt2x00/rt2x00.h     |    5 +++
-+ 2 files changed, 65 insertions(+), 12 deletions(-)
-+
-+--- a/drivers/net/wireless/rt2x00/rt2800mmio.c
-++++ b/drivers/net/wireless/rt2x00/rt2800mmio.c
-+@@ -415,9 +415,9 @@ void rt2800mmio_autowake_tasklet(unsigne
-+ }
-+ EXPORT_SYMBOL_GPL(rt2800mmio_autowake_tasklet);
-+ 
-+-static void rt2800mmio_txstatus_interrupt(struct rt2x00_dev *rt2x00dev)
-++static void rt2800mmio_txstatus_interrupt(struct rt2x00_dev *rt2x00dev,
-++					  u32 status)
-+ {
-+-	u32 status;
-+ 	int i;
-+ 
-+ 	/*
-+@@ -438,29 +438,77 @@ static void rt2800mmio_txstatus_interrup
-+ 	 * Since we have only one producer and one consumer we don't
-+ 	 * need to lock the kfifo.
-+ 	 */
-+-	for (i = 0; i < rt2x00dev->tx->limit; i++) {
-+-		rt2x00mmio_register_read(rt2x00dev, TX_STA_FIFO, &status);
-+-
-+-		if (!rt2x00_get_field32(status, TX_STA_FIFO_VALID))
-+-			break;
-+-
-++	i = 0;
-++	do {
-+ 		if (!kfifo_put(&rt2x00dev->txstatus_fifo, status)) {
-+-			rt2x00_warn(rt2x00dev, "TX status FIFO overrun, drop tx status report\n");
-++			rt2x00_warn(rt2x00dev,
-++				    "TX status FIFO overrun, drop TX status report\n");
-+ 			break;
-+ 		}
-+-	}
-++
-++		if (++i >= rt2x00dev->tx->limit)
-++			break;
-++
-++ 		rt2x00mmio_register_read(rt2x00dev, TX_STA_FIFO, &status);
-++	} while (rt2x00_get_field32(status, TX_STA_FIFO_VALID));
-+ 
-+ 	/* Schedule the tasklet for processing the tx status. */
-+ 	tasklet_schedule(&rt2x00dev->txstatus_tasklet);
-+ }
-+ 
-++#define RT2800MMIO_TXSTATUS_IRQ_MAX_RETRIES	4
-++
-++static bool rt2800mmio_txstatus_is_spurious(struct rt2x00_dev *rt2x00dev,
-++					   u32 txstatus)
-++{
-++	if (likely(rt2x00_get_field32(txstatus, TX_STA_FIFO_VALID))) {
-++		rt2x00dev->txstatus_irq_retries = 0;
-++		return false;
-++	}
-++
-++	rt2x00dev->txstatus_irq_retries++;
-++
-++	/* Ensure that we don't go into an infinite IRQ loop. */
-++	if (rt2x00dev->txstatus_irq_retries >=
-++	    RT2800MMIO_TXSTATUS_IRQ_MAX_RETRIES) {
-++		rt2x00_warn(rt2x00dev,
-++			    "%u spurious TX_FIFO_STATUS interrupt(s)\n",
-++			    rt2x00dev->txstatus_irq_retries);
-++		rt2x00dev->txstatus_irq_retries = 0;
-++		return false;
-++	}
-++
-++	return true;
-++}
-++
-+ irqreturn_t rt2800mmio_interrupt(int irq, void *dev_instance)
-+ {
-+ 	struct rt2x00_dev *rt2x00dev = dev_instance;
-+ 	u32 reg, mask;
-++	u32 txstatus = 0;
-+ 
-+-	/* Read status and ACK all interrupts */
-++	/* Read status */
-+ 	rt2x00mmio_register_read(rt2x00dev, INT_SOURCE_CSR, &reg);
-++
-++	if (rt2x00_get_field32(reg, INT_SOURCE_CSR_TX_FIFO_STATUS)) {
-++		/* Due to unknown reason the hardware generates a
-++		 * TX_FIFO_STATUS interrupt before the TX_STA_FIFO
-++		 * register contain valid data. Read the TX status
-++		 * here to see if we have to process the actual
-++		 * request.
-++		 */
-++		rt2x00mmio_register_read(rt2x00dev, TX_STA_FIFO, &txstatus);
-++		if (rt2800mmio_txstatus_is_spurious(rt2x00dev, txstatus)) {
-++			/* Remove the TX_FIFO_STATUS bit so it won't be
-++			 * processed in this turn. The hardware will
-++			 * generate another IRQ for us.
-++			 */
-++			rt2x00_set_field32(&reg,
-++					   INT_SOURCE_CSR_TX_FIFO_STATUS, 0);
-++		}
-++	}
-++
-++	/* ACK interrupts */
-+ 	rt2x00mmio_register_write(rt2x00dev, INT_SOURCE_CSR, reg);
-+ 
-+ 	if (!reg)
-+@@ -477,7 +525,7 @@ irqreturn_t rt2800mmio_interrupt(int irq
-+ 	mask = ~reg;
-+ 
-+ 	if (rt2x00_get_field32(reg, INT_SOURCE_CSR_TX_FIFO_STATUS)) {
-+-		rt2800mmio_txstatus_interrupt(rt2x00dev);
-++		rt2800mmio_txstatus_interrupt(rt2x00dev, txstatus);
-+ 		/*
-+ 		 * Never disable the TX_FIFO_STATUS interrupt.
-+ 		 */
-+--- a/drivers/net/wireless/rt2x00/rt2x00.h
-++++ b/drivers/net/wireless/rt2x00/rt2x00.h
-+@@ -986,6 +986,11 @@ struct rt2x00_dev {
-+ 	int rf_channel;
-+ 
-+ 	/*
-++	 * Counter for tx status irq retries (rt2800pci).
-++	 */
-++	unsigned int txstatus_irq_retries;
-++
-++	/*
-+ 	 * Protect the interrupt mask register.
-+ 	 */
-+ 	spinlock_t irqmask_lock;
-diff --git a/package/mac80211/patches/603-rt2x00-introduce-rt2x00eeprom.patch b/package/mac80211/patches/603-rt2x00-introduce-rt2x00eeprom.patch
-index 2bbc6f1..e5ba10e 100644
---- a/package/mac80211/patches/603-rt2x00-introduce-rt2x00eeprom.patch
-+++ b/package/mac80211/patches/603-rt2x00-introduce-rt2x00eeprom.patch
-@@ -1,6 +1,6 @@
- --- a/.local-symbols
- +++ b/.local-symbols
--@@ -279,6 +279,7 @@ RT2X00_LIB_FIRMWARE=
-+@@ -281,6 +281,7 @@ RT2X00_LIB_FIRMWARE=
-  RT2X00_LIB_CRYPTO=
-  RT2X00_LIB_LEDS=
-  RT2X00_LIB_DEBUGFS=
-@@ -48,16 +48,16 @@
-  obj-$(CPTCFG_RT2X00_LIB_MMIO)		+= rt2x00mmio.o
- --- a/drivers/net/wireless/rt2x00/rt2800lib.h
- +++ b/drivers/net/wireless/rt2x00/rt2800lib.h
--@@ -20,6 +20,8 @@
-- #ifndef RT2800LIB_H
-- #define RT2800LIB_H
-+@@ -43,6 +43,8 @@ struct rt2800_drv_data {
-+ 	} shmem_lock;
-+ };
-  
- +#include "rt2800.h"
- +
-  struct rt2800_ops {
-  	void (*register_read)(struct rt2x00_dev *rt2x00dev,
-  			      const unsigned int offset, u32 *value);
--@@ -119,6 +121,15 @@ static inline int rt2800_read_eeprom(str
-+@@ -176,6 +178,15 @@ static inline int rt2800_read_eeprom(str
-  {
-  	const struct rt2800_ops *rt2800ops = rt2x00dev->ops->drv;
-  
-@@ -75,7 +75,7 @@
-  
- --- a/drivers/net/wireless/rt2x00/rt2800soc.c
- +++ b/drivers/net/wireless/rt2x00/rt2800soc.c
--@@ -95,19 +95,6 @@ static int rt2800soc_set_device_state(st
-+@@ -102,19 +102,6 @@ static int rt2800soc_set_device_state(st
-  	return retval;
-  }
-  
-@@ -95,7 +95,7 @@
-  /* Firmware functions */
-  static char *rt2800soc_get_firmware_name(struct rt2x00_dev *rt2x00dev)
-  {
--@@ -171,7 +158,6 @@ static const struct rt2800_ops rt2800soc
-+@@ -178,7 +165,6 @@ static const struct rt2800_ops rt2800soc
-  	.register_multiread	= rt2x00mmio_register_multiread,
-  	.register_multiwrite	= rt2x00mmio_register_multiwrite,
-  	.regbusy_read		= rt2x00mmio_regbusy_read,
-@@ -127,7 +127,7 @@
-  	DECLARE_KFIFO_PTR(txstatus_fifo, u32);
- --- a/drivers/net/wireless/rt2x00/rt2x00dev.c
- +++ b/drivers/net/wireless/rt2x00/rt2x00dev.c
--@@ -1324,6 +1324,10 @@ int rt2x00lib_probe_dev(struct rt2x00_de
-+@@ -1327,6 +1327,10 @@ int rt2x00lib_probe_dev(struct rt2x00_de
-  	INIT_DELAYED_WORK(&rt2x00dev->autowakeup_work, rt2x00lib_autowakeup);
-  	INIT_WORK(&rt2x00dev->sleep_work, rt2x00lib_sleep);
-  
-@@ -138,7 +138,7 @@
-  	/*
-  	 * Let the driver probe the device to detect the capabilities.
-  	 */
--@@ -1454,6 +1458,11 @@ void rt2x00lib_remove_dev(struct rt2x00_
-+@@ -1457,6 +1461,11 @@ void rt2x00lib_remove_dev(struct rt2x00_
-  	 */
-  	if (rt2x00dev->drv_data)
-  		kfree(rt2x00dev->drv_data);
-diff --git a/package/mac80211/patches/607-rt2x00-allow_disabling_bands_through_platform_data.patch b/package/mac80211/patches/607-rt2x00-allow_disabling_bands_through_platform_data.patch
-index 4116735..70f7b78 100644
---- a/package/mac80211/patches/607-rt2x00-allow_disabling_bands_through_platform_data.patch
-+++ b/package/mac80211/patches/607-rt2x00-allow_disabling_bands_through_platform_data.patch
-@@ -12,7 +12,7 @@
-  #endif /* _RT2X00_PLATFORM_H */
- --- a/drivers/net/wireless/rt2x00/rt2x00dev.c
- +++ b/drivers/net/wireless/rt2x00/rt2x00dev.c
--@@ -937,6 +937,22 @@ static int rt2x00lib_probe_hw_modes(stru
-+@@ -940,6 +940,22 @@ static int rt2x00lib_probe_hw_modes(stru
-  	unsigned int num_rates;
-  	unsigned int i;
-  
-diff --git a/package/mac80211/patches/608-add_platform_data_mac_addr.patch b/package/mac80211/patches/608-add_platform_data_mac_addr.patch
-index a910cc3..4c2a8b8 100644
---- a/package/mac80211/patches/608-add_platform_data_mac_addr.patch
-+++ b/package/mac80211/patches/608-add_platform_data_mac_addr.patch
-@@ -10,7 +10,7 @@
-  	int disable_5ghz;
- --- a/drivers/net/wireless/rt2x00/rt2x00dev.c
- +++ b/drivers/net/wireless/rt2x00/rt2x00dev.c
--@@ -928,6 +928,18 @@ static void rt2x00lib_rate(struct ieee80
-+@@ -931,6 +931,18 @@ static void rt2x00lib_rate(struct ieee80
-  		entry->flags |= IEEE80211_RATE_SHORT_PREAMBLE;
-  }
-  
-@@ -31,7 +31,7 @@
-  {
- --- a/drivers/net/wireless/rt2x00/rt2x00.h
- +++ b/drivers/net/wireless/rt2x00/rt2x00.h
--@@ -1401,6 +1401,7 @@ static inline void rt2x00debug_dump_fram
-+@@ -1406,6 +1406,7 @@ static inline void rt2x00debug_dump_fram
-   */
-  u32 rt2x00lib_get_bssidx(struct rt2x00_dev *rt2x00dev,
-  			 struct ieee80211_vif *vif);
-diff --git a/package/mac80211/patches/610-rt2x00-fix-rt3352-ext-pa.patch b/package/mac80211/patches/610-rt2x00-fix-rt3352-ext-pa.patch
-index 83fbcd0..010a9e2 100644
---- a/package/mac80211/patches/610-rt2x00-fix-rt3352-ext-pa.patch
-+++ b/package/mac80211/patches/610-rt2x00-fix-rt3352-ext-pa.patch
-@@ -1,14 +1,15 @@
- --- a/drivers/net/wireless/rt2x00/rt2800lib.c
- +++ b/drivers/net/wireless/rt2x00/rt2800lib.c
--@@ -3176,11 +3176,17 @@ static void rt2800_config_channel(struct
-+@@ -3550,11 +3550,18 @@ static void rt2800_config_channel(struct
-  	/*
-  	 * Change BBP settings
-  	 */
--+	rt2800_bbp_write(rt2x00dev, 62, 0x37 - rt2x00dev->lna_gain);
--+	rt2800_bbp_write(rt2x00dev, 63, 0x37 - rt2x00dev->lna_gain);
--+	rt2800_bbp_write(rt2x00dev, 64, 0x37 - rt2x00dev->lna_gain);
- +
-  	if (rt2x00_rt(rt2x00dev, RT3352)) {
-++		rt2800_bbp_write(rt2x00dev, 62, 0x37 - rt2x00dev->lna_gain);
-++		rt2800_bbp_write(rt2x00dev, 63, 0x37 - rt2x00dev->lna_gain);
-++		rt2800_bbp_write(rt2x00dev, 64, 0x37 - rt2x00dev->lna_gain);
-++
-  		rt2800_bbp_write(rt2x00dev, 27, 0x0);
-  		rt2800_bbp_write(rt2x00dev, 66, 0x26 + rt2x00dev->lna_gain);
-  		rt2800_bbp_write(rt2x00dev, 27, 0x20);
-@@ -18,22 +19,7 @@
-  	} else if (rt2x00_rt(rt2x00dev, RT3593)) {
-  		if (rf->channel > 14) {
-  			/* Disable CCK Packet detection on 5GHz */
--@@ -3194,14 +3200,8 @@ static void rt2800_config_channel(struct
-- 		else
-- 			rt2800_bbp_write(rt2x00dev, 105, 0x34);
-- 
---		rt2800_bbp_write(rt2x00dev, 62, 0x37 - rt2x00dev->lna_gain);
---		rt2800_bbp_write(rt2x00dev, 63, 0x37 - rt2x00dev->lna_gain);
---		rt2800_bbp_write(rt2x00dev, 64, 0x37 - rt2x00dev->lna_gain);
-- 		rt2800_bbp_write(rt2x00dev, 77, 0x98);
-- 	} else {
---		rt2800_bbp_write(rt2x00dev, 62, 0x37 - rt2x00dev->lna_gain);
---		rt2800_bbp_write(rt2x00dev, 63, 0x37 - rt2x00dev->lna_gain);
---		rt2800_bbp_write(rt2x00dev, 64, 0x37 - rt2x00dev->lna_gain);
-- 		rt2800_bbp_write(rt2x00dev, 86, 0);
-- 	}
-- 
--@@ -6125,6 +6125,12 @@ static void rt2800_init_rfcsr_3290(struc
-+@@ -6608,6 +6615,12 @@ static void rt2800_init_rfcsr_3290(struc
-  
-  static void rt2800_init_rfcsr_3352(struct rt2x00_dev *rt2x00dev)
-  {
-@@ -46,7 +32,7 @@
-  	rt2800_rf_init_calibration(rt2x00dev, 30);
-  
-  	rt2800_rfcsr_write(rt2x00dev, 0, 0xf0);
--@@ -6160,15 +6166,30 @@ static void rt2800_init_rfcsr_3352(struc
-+@@ -6643,15 +6656,30 @@ static void rt2800_init_rfcsr_3352(struc
-  	rt2800_rfcsr_write(rt2x00dev, 31, 0x80);
-  	rt2800_rfcsr_write(rt2x00dev, 32, 0x80);
-  	rt2800_rfcsr_write(rt2x00dev, 33, 0x00);
-@@ -80,7 +66,7 @@
-  	rt2800_rfcsr_write(rt2x00dev, 43, 0xdb);
-  	rt2800_rfcsr_write(rt2x00dev, 44, 0xdb);
-  	rt2800_rfcsr_write(rt2x00dev, 45, 0xdb);
--@@ -6176,15 +6197,20 @@ static void rt2800_init_rfcsr_3352(struc
-+@@ -6659,15 +6687,20 @@ static void rt2800_init_rfcsr_3352(struc
-  	rt2800_rfcsr_write(rt2x00dev, 47, 0x0d);
-  	rt2800_rfcsr_write(rt2x00dev, 48, 0x14);
-  	rt2800_rfcsr_write(rt2x00dev, 49, 0x00);
-@@ -110,7 +96,7 @@
-  	rt2800_rfcsr_write(rt2x00dev, 59, 0x00);
-  	rt2800_rfcsr_write(rt2x00dev, 60, 0x00);
-  	rt2800_rfcsr_write(rt2x00dev, 61, 0x00);
--@@ -7051,6 +7077,7 @@ static int rt2800_init_eeprom(struct rt2
-+@@ -7688,6 +7721,7 @@ static int rt2800_init_eeprom(struct rt2
-  	 * RT53xx: defined in "EEPROM_CHIP_ID" field
-  	 */
-  	if (rt2x00_rt(rt2x00dev, RT3290) ||
-@@ -118,7 +104,7 @@
-  	    rt2x00_rt(rt2x00dev, RT5390) ||
-  	    rt2x00_rt(rt2x00dev, RT5392))
-  		rt2800_eeprom_read(rt2x00dev, EEPROM_CHIP_ID, &rf);
--@@ -7142,7 +7169,8 @@ static int rt2800_init_eeprom(struct rt2
-+@@ -7782,7 +7816,8 @@ static int rt2800_init_eeprom(struct rt2
-  	/*
-  	 * Detect if this device has Bluetooth co-existence.
-  	 */
-@@ -128,7 +114,7 @@
-  		__set_bit(CAPABILITY_BT_COEXIST, &rt2x00dev->cap_flags);
-  
-  	/*
--@@ -7171,6 +7199,22 @@ static int rt2800_init_eeprom(struct rt2
-+@@ -7811,6 +7846,22 @@ static int rt2800_init_eeprom(struct rt2
-  					EIRP_MAX_TX_POWER_LIMIT)
-  		__set_bit(CAPABILITY_POWER_LIMIT, &rt2x00dev->cap_flags);
-  
-@@ -153,7 +139,7 @@
-  
- --- a/drivers/net/wireless/rt2x00/rt2800.h
- +++ b/drivers/net/wireless/rt2x00/rt2800.h
--@@ -2299,6 +2299,12 @@ struct mac_iveiv_entry {
-+@@ -2333,6 +2333,12 @@ struct mac_iveiv_entry {
-  #define RFCSR36_RF_BS			FIELD8(0x80)
-  
-  /*
-@@ -166,7 +152,7 @@
-   * RFCSR 38:
-   */
-  #define RFCSR38_RX_LO1_EN		FIELD8(0x20)
--@@ -2310,6 +2316,18 @@ struct mac_iveiv_entry {
-+@@ -2344,6 +2350,18 @@ struct mac_iveiv_entry {
-  #define RFCSR39_RX_LO2_EN		FIELD8(0x80)
-  
-  /*
-@@ -185,7 +171,7 @@
-   * RFCSR 49:
-   */
-  #define RFCSR49_TX			FIELD8(0x3f)
--@@ -2322,6 +2340,8 @@ struct mac_iveiv_entry {
-+@@ -2356,6 +2374,8 @@ struct mac_iveiv_entry {
-   * RFCSR 50:
-   */
-  #define RFCSR50_TX			FIELD8(0x3f)
-@@ -194,7 +180,7 @@
-  #define RFCSR50_EP			FIELD8(0xc0)
-  /* bits for RT3593 */
-  #define RFCSR50_TX_LO1_EN		FIELD8(0x20)
--@@ -2469,6 +2489,8 @@ enum rt2800_eeprom_word {
-+@@ -2503,6 +2523,8 @@ enum rt2800_eeprom_word {
-   * INTERNAL_TX_ALC: 0: disable, 1: enable
-   * BT_COEXIST: 0: disable, 1: enable
-   * DAC_TEST: 0: disable, 1: enable
-@@ -203,7 +189,7 @@
-   */
-  #define EEPROM_NIC_CONF1_HW_RADIO		FIELD16(0x0001)
-  #define EEPROM_NIC_CONF1_EXTERNAL_TX_ALC	FIELD16(0x0002)
--@@ -2485,6 +2507,8 @@ enum rt2800_eeprom_word {
-+@@ -2519,6 +2541,8 @@ enum rt2800_eeprom_word {
-  #define EEPROM_NIC_CONF1_INTERNAL_TX_ALC	FIELD16(0x2000)
-  #define EEPROM_NIC_CONF1_BT_COEXIST		FIELD16(0x4000)
-  #define EEPROM_NIC_CONF1_DAC_TEST		FIELD16(0x8000)
-diff --git a/package/mac80211/patches/611-rt2x00-rf_vals-rt3352-xtal20.patch b/package/mac80211/patches/611-rt2x00-rf_vals-rt3352-xtal20.patch
-index 478a0f2..65af89a 100644
---- a/package/mac80211/patches/611-rt2x00-rf_vals-rt3352-xtal20.patch
-+++ b/package/mac80211/patches/611-rt2x00-rf_vals-rt3352-xtal20.patch
-@@ -1,6 +1,6 @@
- --- a/drivers/net/wireless/rt2x00/rt2800lib.c
- +++ b/drivers/net/wireless/rt2x00/rt2800lib.c
--@@ -7491,6 +7491,27 @@ static const struct rf_channel rf_vals_5
-+@@ -8198,6 +8198,27 @@ static const struct rf_channel rf_vals_5
-  	{196, 83, 0, 12, 1},
-  };
-  
-@@ -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
-+@@ -8285,7 +8306,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
-+@@ -8468,6 +8492,19 @@ static int rt2800_probe_rt(struct rt2x00
-  	return 0;
-  }
-  
-@@ -59,8 +59,8 @@
- +
-  int rt2800_probe_hw(struct rt2x00_dev *rt2x00dev)
-  {
-- 	int retval;
--@@ -7784,6 +7821,15 @@ int rt2800_probe_hw(struct rt2x00_dev *r
-+ 	struct rt2800_drv_data *drv_data = rt2x00dev->drv_data;
-+@@ -8510,6 +8547,15 @@ int rt2800_probe_hw(struct rt2x00_dev *r
-  	rt2800_register_write(rt2x00dev, GPIO_CTRL, reg);
-  
-  	/*
-diff --git a/package/mac80211/patches/612-rt2x00-make-wmac-loadable-via-OF-on-rt288x-305x-SoC.patch b/package/mac80211/patches/612-rt2x00-make-wmac-loadable-via-OF-on-rt288x-305x-SoC.patch
-index f6b4808..119e95c 100644
---- a/package/mac80211/patches/612-rt2x00-make-wmac-loadable-via-OF-on-rt288x-305x-SoC.patch
-+++ b/package/mac80211/patches/612-rt2x00-make-wmac-loadable-via-OF-on-rt288x-305x-SoC.patch
-@@ -13,7 +13,7 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
- 
- --- a/drivers/net/wireless/rt2x00/rt2800soc.c
- +++ b/drivers/net/wireless/rt2x00/rt2800soc.c
--@@ -227,11 +227,18 @@ static int rt2800soc_probe(struct platfo
-+@@ -237,11 +237,18 @@ static int rt2800soc_probe(struct platfo
-  	return rt2x00soc_probe(pdev, &rt2800soc_ops);
-  }
-  
-diff --git a/package/mac80211/patches/616-rt2x00-support-rt5350.patch b/package/mac80211/patches/616-rt2x00-support-rt5350.patch
-index 3bafa16..41a7f34 100644
---- a/package/mac80211/patches/616-rt2x00-support-rt5350.patch
-+++ b/package/mac80211/patches/616-rt2x00-support-rt5350.patch
-@@ -1,16 +1,16 @@
- --- a/drivers/net/wireless/rt2x00/rt2800.h
- +++ b/drivers/net/wireless/rt2x00/rt2800.h
--@@ -71,6 +71,7 @@
-- #define RF5592				0x000f
-+@@ -73,6 +73,7 @@
-  #define RF3070				0x3070
-  #define RF3290				0x3290
-+ #define RF3853				0x3853
- +#define RF5350				0x5350
-  #define RF5360				0x5360
-  #define RF5370				0x5370
-  #define RF5372				0x5372
- --- a/drivers/net/wireless/rt2x00/rt2800lib.c
- +++ b/drivers/net/wireless/rt2x00/rt2800lib.c
--@@ -2704,6 +2704,13 @@ static void rt2800_config_channel_rf53xx
-+@@ -3038,6 +3038,13 @@ static void rt2800_config_channel_rf53xx
-  
-  				rt2800_rfcsr_write(rt2x00dev, 59,
-  						   r59_non_bt[idx]);
-@@ -24,15 +24,15 @@
-  			}
-  		}
-  	}
--@@ -3141,6 +3148,7 @@ static void rt2800_config_channel(struct
-- 		rt2800_config_channel_rf3322(rt2x00dev, conf, rf, info);
-+@@ -3516,6 +3523,7 @@ static void rt2800_config_channel(struct
-+ 		rt2800_config_channel_rf3853(rt2x00dev, conf, rf, info);
-  		break;
-  	case RF3070:
- +	case RF5350:
-  	case RF5360:
-  	case RF5370:
-  	case RF5372:
--@@ -3158,6 +3166,7 @@ static void rt2800_config_channel(struct
-+@@ -3533,6 +3541,7 @@ static void rt2800_config_channel(struct
-  	if (rt2x00_rf(rt2x00dev, RF3070) ||
-  	    rt2x00_rf(rt2x00dev, RF3290) ||
-  	    rt2x00_rf(rt2x00dev, RF3322) ||
-@@ -40,7 +40,7 @@
-  	    rt2x00_rf(rt2x00dev, RF5360) ||
-  	    rt2x00_rf(rt2x00dev, RF5370) ||
-  	    rt2x00_rf(rt2x00dev, RF5372) ||
--@@ -3398,7 +3407,8 @@ static void rt2800_config_channel(struct
-+@@ -3810,7 +3819,8 @@ static void rt2800_config_channel(struct
-  	/*
-  	 * Clear update flag
-  	 */
-@@ -50,15 +50,15 @@
-  		rt2800_bbp_read(rt2x00dev, 49, &bbp);
-  		rt2x00_set_field8(&bbp, BBP49_UPDATE_FLAG, 0);
-  		rt2800_bbp_write(rt2x00dev, 49, bbp);
--@@ -4272,6 +4282,7 @@ void rt2800_vco_calibration(struct rt2x0
-- 	case RF3053:
-+@@ -4689,6 +4699,7 @@ void rt2800_vco_calibration(struct rt2x0
-  	case RF3070:
-  	case RF3290:
-+ 	case RF3853:
- +	case RF5350:
-  	case RF5360:
-  	case RF5370:
-  	case RF5372:
--@@ -4668,6 +4679,8 @@ static int rt2800_init_registers(struct 
-+@@ -5101,6 +5112,8 @@ static int rt2800_init_registers(struct 
-  		rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000404);
-  		rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00080606);
-  		rt2800_register_write(rt2x00dev, TX_SW_CFG2, 0x00000000);
-@@ -67,7 +67,7 @@
-  	} else {
-  		rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000000);
-  		rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00080606);
--@@ -5309,9 +5322,13 @@ static void rt2800_init_bbp_3352(struct 
-+@@ -5756,9 +5769,13 @@ static void rt2800_init_bbp_3352(struct 
-  
-  	rt2800_bbp_write(rt2x00dev, 82, 0x62);
-  
-@@ -84,7 +84,7 @@
-  
-  	rt2800_bbp_write(rt2x00dev, 86, 0x38);
-  
--@@ -5325,9 +5342,13 @@ static void rt2800_init_bbp_3352(struct 
-+@@ -5772,9 +5789,13 @@ static void rt2800_init_bbp_3352(struct 
-  
-  	rt2800_bbp_write(rt2x00dev, 104, 0x92);
-  
-@@ -101,7 +101,7 @@
-  
-  	rt2800_bbp_write(rt2x00dev, 120, 0x50);
-  
--@@ -5352,6 +5373,13 @@ static void rt2800_init_bbp_3352(struct 
-+@@ -5799,6 +5820,13 @@ static void rt2800_init_bbp_3352(struct 
-  	rt2800_bbp_write(rt2x00dev, 143, 0xa2);
-  
-  	rt2800_bbp_write(rt2x00dev, 148, 0xc8);
-@@ -115,7 +115,7 @@
-  }
-  
-  static void rt2800_init_bbp_3390(struct rt2x00_dev *rt2x00dev)
--@@ -5652,6 +5680,7 @@ static void rt2800_init_bbp(struct rt2x0
-+@@ -6140,6 +6168,7 @@ static void rt2800_init_bbp(struct rt2x0
-  		rt2800_init_bbp_3290(rt2x00dev);
-  		break;
-  	case RT3352:
-@@ -123,8 +123,8 @@
-  		rt2800_init_bbp_3352(rt2x00dev);
-  		break;
-  	case RT3390:
--@@ -6462,6 +6491,76 @@ static void rt2800_init_rfcsr_3593(struc
-- 	/* TODO: enable stream mode support */
-+@@ -7091,6 +7120,76 @@ static void rt2800_init_rfcsr_3883(struc
-+ 	rt2800_rfcsr_write(rt2x00dev, 20, rfcsr);
-  }
-  
- +static void rt2800_init_rfcsr_5350(struct rt2x00_dev *rt2x00dev)
-@@ -200,7 +200,7 @@
-  static void rt2800_init_rfcsr_5390(struct rt2x00_dev *rt2x00dev)
-  {
-  	rt2800_rf_init_calibration(rt2x00dev, 2);
--@@ -6699,6 +6798,9 @@ static void rt2800_init_rfcsr(struct rt2
-+@@ -7331,6 +7430,9 @@ static void rt2800_init_rfcsr(struct rt2
-  	case RT3593:
-  		rt2800_init_rfcsr_3593(rt2x00dev);
-  		break;
-@@ -210,7 +210,7 @@
-  	case RT5390:
-  		rt2800_init_rfcsr_5390(rt2x00dev);
-  		break;
--@@ -6948,6 +7050,12 @@ static int rt2800_validate_eeprom(struct
-+@@ -7590,6 +7692,12 @@ static int rt2800_validate_eeprom(struct
-  		rt2x00_set_field16(&word, EEPROM_NIC_CONF0_RF_TYPE, RF2820);
-  		rt2800_eeprom_write(rt2x00dev, EEPROM_NIC_CONF0, word);
-  		rt2x00_eeprom_dbg(rt2x00dev, "Antenna: 0x%04x\n", word);
-@@ -223,24 +223,24 @@
-  	} else if (rt2x00_rt(rt2x00dev, RT2860) ||
-  		   rt2x00_rt(rt2x00dev, RT2872)) {
-  		/*
--@@ -7081,6 +7189,8 @@ static int rt2800_init_eeprom(struct rt2
-- 	    rt2x00_rt(rt2x00dev, RT5390) ||
-- 	    rt2x00_rt(rt2x00dev, RT5392))
-+@@ -7728,6 +7836,8 @@ static int rt2800_init_eeprom(struct rt2
-  		rt2800_eeprom_read(rt2x00dev, EEPROM_CHIP_ID, &rf);
-+ 	else if (rt2x00_rt(rt2x00dev, RT3883))
-+ 		rf = RF3853;
- +	else if (rt2x00_rt(rt2x00dev, RT5350))
- +		rf = RF5350;
-  	else
-  		rf = rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_RF_TYPE);
-  
--@@ -7099,6 +7209,7 @@ static int rt2800_init_eeprom(struct rt2
-- 	case RF3290:
-+@@ -7747,6 +7857,7 @@ static int rt2800_init_eeprom(struct rt2
-  	case RF3320:
-  	case RF3322:
-+ 	case RF3853:
- +	case RF5350:
-  	case RF5360:
-  	case RF5370:
-  	case RF5372:
--@@ -7594,6 +7705,7 @@ static int rt2800_probe_hw_mode(struct r
-+@@ -8301,6 +8412,7 @@ static int rt2800_probe_hw_mode(struct r
-  	case RF3290:
-  	case RF3320:
-  	case RF3322:
-@@ -248,18 +248,18 @@
-  	case RF5360:
-  	case RF5370:
-  	case RF5372:
--@@ -7726,6 +7838,7 @@ static int rt2800_probe_hw_mode(struct r
-- 	case RF3053:
-+@@ -8439,6 +8551,7 @@ static int rt2800_probe_hw_mode(struct r
-  	case RF3070:
-  	case RF3290:
-+ 	case RF3853:
- +	case RF5350:
-  	case RF5360:
-  	case RF5370:
-  	case RF5372:
--@@ -7764,6 +7877,7 @@ static int rt2800_probe_rt(struct rt2x00
-- 	case RT3390:
-+@@ -8478,6 +8591,7 @@ static int rt2800_probe_rt(struct rt2x00
-  	case RT3572:
-  	case RT3593:
-+ 	case RT3883:
- +	case RT5350:
-  	case RT5390:
-  	case RT5392:
-diff --git a/package/mac80211/patches/619-rt2x00-change-led-polarity-from-OF.patch b/package/mac80211/patches/619-rt2x00-change-led-polarity-from-OF.patch
-index f9186d8..d966321 100644
---- a/package/mac80211/patches/619-rt2x00-change-led-polarity-from-OF.patch
-+++ b/package/mac80211/patches/619-rt2x00-change-led-polarity-from-OF.patch
-@@ -1,6 +1,6 @@
- --- a/drivers/net/wireless/rt2x00/rt2800lib.c
- +++ b/drivers/net/wireless/rt2x00/rt2800lib.c
--@@ -36,6 +36,7 @@
-+@@ -37,6 +37,7 @@
-  #include <linux/kernel.h>
-  #include <linux/module.h>
-  #include <linux/slab.h>
-@@ -8,7 +8,7 @@
-  
-  #include "rt2x00.h"
-  #include "rt2800lib.h"
--@@ -7298,6 +7299,17 @@ static int rt2800_init_eeprom(struct rt2
-+@@ -7946,6 +7947,17 @@ static int rt2800_init_eeprom(struct rt2
-  	rt2800_init_led(rt2x00dev, &rt2x00dev->led_assoc, LED_TYPE_ASSOC);
-  	rt2800_init_led(rt2x00dev, &rt2x00dev->led_qual, LED_TYPE_QUALITY);
-  
-diff --git a/package/mac80211/patches/620-rt2x00-add-AP+STA-support.patch b/package/mac80211/patches/620-rt2x00-add-AP+STA-support.patch
-index 419cb60..ce667b8 100644
---- a/package/mac80211/patches/620-rt2x00-add-AP+STA-support.patch
-+++ b/package/mac80211/patches/620-rt2x00-add-AP+STA-support.patch
-@@ -1,6 +1,6 @@
- --- a/drivers/net/wireless/rt2x00/rt2x00dev.c
- +++ b/drivers/net/wireless/rt2x00/rt2x00dev.c
--@@ -1262,7 +1262,7 @@ static inline void rt2x00lib_set_if_comb
-+@@ -1265,7 +1265,7 @@ static inline void rt2x00lib_set_if_comb
-  	 */
-  	if_limit = &rt2x00dev->if_limits_ap;
-  	if_limit->max = rt2x00dev->ops->max_ap_intf;
-diff --git a/package/mac80211/patches/620-rt2x00-rt3352-rf-id.patch b/package/mac80211/patches/620-rt2x00-rt3352-rf-id.patch
-index 5e67344..90eab13 100644
---- a/package/mac80211/patches/620-rt2x00-rt3352-rf-id.patch
-+++ b/package/mac80211/patches/620-rt2x00-rt3352-rf-id.patch
-@@ -1,6 +1,6 @@
- --- a/drivers/net/wireless/rt2x00/rt2800lib.c
- +++ b/drivers/net/wireless/rt2x00/rt2800lib.c
--@@ -7186,10 +7186,11 @@ static int rt2800_init_eeprom(struct rt2
-+@@ -7831,10 +7831,11 @@ static int rt2800_init_eeprom(struct rt2
-  	 * RT53xx: defined in "EEPROM_CHIP_ID" field
-  	 */
-  	if (rt2x00_rt(rt2x00dev, RT3290) ||
-@@ -10,6 +10,6 @@
-  		rt2800_eeprom_read(rt2x00dev, EEPROM_CHIP_ID, &rf);
- +	else if (rt2x00_rt(rt2x00dev, RT3352))
- +		rf = RF3322;
-+ 	else if (rt2x00_rt(rt2x00dev, RT3883))
-+ 		rf = RF3853;
-  	else if (rt2x00_rt(rt2x00dev, RT5350))
-- 		rf = RF5350;
-- 	else
-diff --git a/package/mac80211/patches/700-mwl8k-missing-pci-id-for-WNR854T.patch b/package/mac80211/patches/700-mwl8k-missing-pci-id-for-WNR854T.patch
-index 484c075..ae7e927 100644
---- a/package/mac80211/patches/700-mwl8k-missing-pci-id-for-WNR854T.patch
-+++ b/package/mac80211/patches/700-mwl8k-missing-pci-id-for-WNR854T.patch
-@@ -1,6 +1,6 @@
- --- a/drivers/net/wireless/mwl8k.c
- +++ b/drivers/net/wireless/mwl8k.c
--@@ -5529,6 +5529,7 @@ MODULE_FIRMWARE("mwl8k/fmimage_8366.fw")
-+@@ -5682,6 +5682,7 @@ MODULE_FIRMWARE("mwl8k/fmimage_8366.fw")
-  MODULE_FIRMWARE(MWL8K_8366_AP_FW(MWL8K_8366_AP_FW_API));
-  
-  static DEFINE_PCI_DEVICE_TABLE(mwl8k_pci_id_table) = {
-diff --git a/package/mac80211/patches/800-b43-gpio-mask-module-option.patch b/package/mac80211/patches/800-b43-gpio-mask-module-option.patch
-index fc874ad..7c56369 100644
---- a/package/mac80211/patches/800-b43-gpio-mask-module-option.patch
-+++ b/package/mac80211/patches/800-b43-gpio-mask-module-option.patch
-@@ -22,7 +22,7 @@
-  static int modparam_bad_frames_preempt;
-  module_param_named(bad_frames_preempt, modparam_bad_frames_preempt, int, 0444);
-  MODULE_PARM_DESC(bad_frames_preempt,
--@@ -2747,10 +2752,10 @@ static int b43_gpio_init(struct b43_wlde
-+@@ -2749,10 +2754,10 @@ static int b43_gpio_init(struct b43_wlde
-  	u32 mask, set;
-  
-  	b43_maskset32(dev, B43_MMIO_MACCTL, ~B43_MACCTL_GPOUTSMSK, 0);
-diff --git a/package/mac80211/patches/810-b43_no_pio.patch b/package/mac80211/patches/810-b43_no_pio.patch
-index 5cd1b8b..2023bf6 100644
---- a/package/mac80211/patches/810-b43_no_pio.patch
-+++ b/package/mac80211/patches/810-b43_no_pio.patch
-@@ -11,7 +11,7 @@
-  b43-$(CPTCFG_B43_PCMCIA)	+= pcmcia.o
- --- a/drivers/net/wireless/b43/main.c
- +++ b/drivers/net/wireless/b43/main.c
--@@ -1915,10 +1915,12 @@ static void b43_do_interrupt_thread(stru
-+@@ -1909,10 +1909,12 @@ static void b43_do_interrupt_thread(stru
-  			dma_reason[0], dma_reason[1],
-  			dma_reason[2], dma_reason[3],
-  			dma_reason[4], dma_reason[5]);
-@@ -75,12 +75,12 @@
-  #endif /* B43_PIO_H_ */
- --- a/drivers/net/wireless/b43/Kconfig
- +++ b/drivers/net/wireless/b43/Kconfig
--@@ -98,7 +98,7 @@ config B43_BCMA_PIO
-+@@ -118,7 +118,7 @@ config B43_BCMA_PIO
-  	default y
-  
-  config B43_PIO
- -	bool
- +	bool "Broadcom 43xx PIO support"
-- 	depends on B43
-+ 	depends on B43 && B43_SSB
-  	select SSB_BLOCKIO
-  	default y
-diff --git a/package/mac80211/patches/820-b43-add-antenna-control.patch b/package/mac80211/patches/820-b43-add-antenna-control.patch
-index dea9830..5a23967 100644
---- a/package/mac80211/patches/820-b43-add-antenna-control.patch
-+++ b/package/mac80211/patches/820-b43-add-antenna-control.patch
-@@ -1,6 +1,6 @@
- --- a/drivers/net/wireless/b43/main.c
- +++ b/drivers/net/wireless/b43/main.c
--@@ -1562,7 +1562,7 @@ static void b43_write_beacon_template(st
-+@@ -1556,7 +1556,7 @@ static void b43_write_beacon_template(st
-  				  len, ram_offset, shm_size_offset, rate);
-  
-  	/* Write the PHY TX control parameters. */
-@@ -9,7 +9,7 @@
-  	antenna = b43_antenna_to_phyctl(antenna);
-  	ctl = b43_shm_read16(dev, B43_SHM_SHARED, B43_SHM_SH_BEACPHYCTL);
-  	/* We can't send beacons with short preamble. Would get PHY errors. */
--@@ -3105,8 +3105,8 @@ static int b43_chip_init(struct b43_wlde
-+@@ -3113,8 +3113,8 @@ static int b43_chip_init(struct b43_wlde
-  
-  	/* Select the antennae */
-  	if (phy->ops->set_rx_antenna)
-@@ -20,7 +20,7 @@
-  
-  	if (phy->type == B43_PHYTYPE_B) {
-  		value16 = b43_read16(dev, 0x005E);
--@@ -3850,7 +3850,6 @@ static int b43_op_config(struct ieee8021
-+@@ -3806,7 +3806,6 @@ static int b43_op_config(struct ieee8021
-  	struct b43_wldev *dev;
-  	struct b43_phy *phy;
-  	struct ieee80211_conf *conf = &hw->conf;
-@@ -28,7 +28,7 @@
-  	int err = 0;
-  	bool reload_bss = false;
-  
--@@ -3904,11 +3903,9 @@ static int b43_op_config(struct ieee8021
-+@@ -3860,11 +3859,9 @@ static int b43_op_config(struct ieee8021
-  	}
-  
-  	/* Antennas for RX and management frame TX. */
-@@ -42,7 +42,7 @@
-  
-  	if (wl->radio_enabled != phy->radio_on) {
-  		if (wl->radio_enabled) {
--@@ -5041,6 +5038,47 @@ static int b43_op_get_survey(struct ieee
-+@@ -4988,6 +4985,47 @@ static int b43_op_get_survey(struct ieee
-  	return 0;
-  }
-  
-@@ -90,7 +90,7 @@
-  static const struct ieee80211_ops b43_hw_ops = {
-  	.tx			= b43_op_tx,
-  	.conf_tx		= b43_op_conf_tx,
--@@ -5062,6 +5100,8 @@ static const struct ieee80211_ops b43_hw
-+@@ -5009,6 +5047,8 @@ static const struct ieee80211_ops b43_hw
-  	.sw_scan_complete	= b43_op_sw_scan_complete_notifier,
-  	.get_survey		= b43_op_get_survey,
-  	.rfkill_poll		= b43_rfkill_poll,
-@@ -99,7 +99,7 @@
-  };
-  
-  /* Hard-reset the chip. Do not call this directly.
--@@ -5308,6 +5348,8 @@ static int b43_one_core_attach(struct b4
-+@@ -5295,6 +5335,8 @@ static int b43_one_core_attach(struct b4
-  	if (!wldev)
-  		goto out;
-  
-@@ -108,7 +108,7 @@
-  	wldev->use_pio = b43_modparam_pio;
-  	wldev->dev = dev;
-  	wldev->wl = wl;
--@@ -5398,6 +5440,9 @@ static struct b43_wl *b43_wireless_init(
-+@@ -5385,6 +5427,9 @@ static struct b43_wl *b43_wireless_init(
-  
-  	hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN;
-  
-diff --git a/package/mac80211/patches/830-b43-workaround-pcie-bcm4716.patch b/package/mac80211/patches/830-b43-workaround-pcie-bcm4716.patch
-index e76758c..b6db3ac 100644
---- a/package/mac80211/patches/830-b43-workaround-pcie-bcm4716.patch
-+++ b/package/mac80211/patches/830-b43-workaround-pcie-bcm4716.patch
-@@ -19,7 +19,7 @@ Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
- 
- --- a/drivers/net/wireless/b43/b43.h
- +++ b/drivers/net/wireless/b43/b43.h
--@@ -1061,6 +1061,31 @@ static inline bool b43_using_pio_transfe
-+@@ -1054,6 +1054,31 @@ static inline bool b43_using_pio_transfe
-  	return dev->__using_pio_transfers;
-  }
-  
-@@ -53,18 +53,20 @@ Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
-  __printf(2, 3) void b43err(struct b43_wl *wl, const char *fmt, ...);
- --- a/drivers/net/wireless/b43/bus.h
- +++ b/drivers/net/wireless/b43/bus.h
--@@ -60,6 +60,16 @@ static inline bool b43_bus_host_is_sdio(
-- 	return (dev->bus_type == B43_BUS_SSB &&
-- 		dev->sdev->bus->bustype == SSB_BUSTYPE_SDIO);
-+@@ -70,6 +70,18 @@ static inline bool b43_bus_host_is_sdio(
-+ 	return false;
-+ #endif
-  }
- +static inline bool b43_bus_host_is_pci(struct b43_bus_dev *dev)
- +{
--+	if (dev->bus_type == B43_BUS_SSB)
--+		return (dev->sdev->bus->bustype == SSB_BUSTYPE_PCI);
- +#ifdef CPTCFG_B43_BCMA
- +	if (dev->bus_type == B43_BUS_BCMA)
- +		return (dev->bdev->bus->hosttype == BCMA_HOSTTYPE_PCI);
- +#endif
-++#ifdef CPTCFG_B43_SSB
-++	if (dev->bus_type == B43_BUS_SSB)
-++		return (dev->sdev->bus->bustype == SSB_BUSTYPE_PCI);
-++#endif
- +	return false;
- +}
-  
-@@ -72,7 +74,7 @@ Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
-  struct b43_bus_dev *b43_bus_dev_ssb_init(struct ssb_device *sdev);
- --- a/drivers/net/wireless/b43/main.c
- +++ b/drivers/net/wireless/b43/main.c
--@@ -4437,7 +4437,7 @@ static int b43_phy_versioning(struct b43
-+@@ -4380,7 +4380,7 @@ static int b43_phy_versioning(struct b43
-  		u16 radio24[3];
-  
-  		for (tmp = 0; tmp < 3; tmp++) {
-@@ -81,7 +83,7 @@ Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
-  			radio24[tmp] = b43_read16(dev, B43_MMIO_RADIO24_DATA);
-  		}
-  
--@@ -4456,10 +4456,10 @@ static int b43_phy_versioning(struct b43
-+@@ -4399,10 +4399,10 @@ static int b43_phy_versioning(struct b43
-  			else
-  				tmp = 0x5205017F;
-  		} else {
-@@ -96,7 +98,7 @@ Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
-  				<< 16;
- --- a/drivers/net/wireless/b43/phy_common.c
- +++ b/drivers/net/wireless/b43/phy_common.c
--@@ -266,6 +266,12 @@ void b43_phy_write(struct b43_wldev *dev
-+@@ -267,6 +267,12 @@ void b43_phy_write(struct b43_wldev *dev
-  {
-  	assert_mac_suspended(dev);
-  	dev->phy.ops->phy_write(dev, reg, value);
-@@ -197,7 +199,7 @@ Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
-  
- --- a/drivers/net/wireless/b43/phy_n.c
- +++ b/drivers/net/wireless/b43/phy_n.c
--@@ -5418,14 +5418,14 @@ static inline void check_phyreg(struct b
-+@@ -5641,14 +5641,14 @@ static inline void check_phyreg(struct b
-  static u16 b43_nphy_op_read(struct b43_wldev *dev, u16 reg)
-  {
-  	check_phyreg(dev, reg);
-@@ -214,7 +216,7 @@ Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
-  	b43_write16(dev, B43_MMIO_PHY_DATA, value);
-  }
-  
--@@ -5433,7 +5433,7 @@ static void b43_nphy_op_maskset(struct b
-+@@ -5656,7 +5656,7 @@ static void b43_nphy_op_maskset(struct b
-  				 u16 set)
-  {
-  	check_phyreg(dev, reg);
-@@ -223,16 +225,16 @@ Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
-  	b43_maskset16(dev, B43_MMIO_PHY_DATA, mask, set);
-  }
-  
--@@ -5444,7 +5444,7 @@ static u16 b43_nphy_op_radio_read(struct
-- 	/* N-PHY needs 0x100 for read access */
-- 	reg |= 0x100;
-+@@ -5670,7 +5670,7 @@ static u16 b43_nphy_op_radio_read(struct
-+ 	else
-+ 		reg |= 0x100;
-  
- -	b43_write16(dev, B43_MMIO_RADIO_CONTROL, reg);
- +	b43_wflush16(dev, B43_MMIO_RADIO_CONTROL, reg);
-  	return b43_read16(dev, B43_MMIO_RADIO_DATA_LOW);
-  }
-  
--@@ -5453,7 +5453,7 @@ static void b43_nphy_op_radio_write(stru
-+@@ -5679,7 +5679,7 @@ static void b43_nphy_op_radio_write(stru
-  	/* Register 1 is a 32-bit register. */
-  	B43_WARN_ON(reg == 1);
-  
-diff --git a/package/mac80211/patches/845-b43-only-use-gpio-0-1-for-led.patch b/package/mac80211/patches/845-b43-only-use-gpio-0-1-for-led.patch
-index 50347cd..efc3451 100644
---- a/package/mac80211/patches/845-b43-only-use-gpio-0-1-for-led.patch
-+++ b/package/mac80211/patches/845-b43-only-use-gpio-0-1-for-led.patch
-@@ -1,6 +1,6 @@
- --- a/drivers/net/wireless/b43/main.c
- +++ b/drivers/net/wireless/b43/main.c
--@@ -2764,6 +2764,14 @@ static int b43_gpio_init(struct b43_wlde
-+@@ -2766,6 +2766,14 @@ static int b43_gpio_init(struct b43_wlde
-  	} else if (dev->dev->chip_id == 0x5354) {
-  		/* Don't allow overtaking buttons GPIOs */
-  		set &= 0x2; /* 0x2 is LED GPIO on BCM5354 */
-diff --git a/package/mac80211/patches/900-wl1251-split-wl251-platform-data-to-a-separate-structure.patch b/package/mac80211/patches/900-wl1251-split-wl251-platform-data-to-a-separate-structure.patch
-deleted file mode 100644
-index a8af257..0000000
---- a/package/mac80211/patches/900-wl1251-split-wl251-platform-data-to-a-separate-structure.patch
-+++ /dev/null
-@@ -1,109 +0,0 @@
--Move the wl1251 part of the wl12xx platform data structure into a new
--structure specifically for wl1251.  Change the platform data built-in
--block and board files accordingly.
--
--Cc: Tony Lindgren <tony@atomide.com>
--Signed-off-by: Luciano Coelho <coelho@ti.com>
--Acked-by: Tony Lindgren <tony@atomide.com>
--Reviewed-by: Felipe Balbi <balbi@ti.com>
--
----- a/drivers/net/wireless/ti/wilink_platform_data.c
--+++ b/drivers/net/wireless/ti/wilink_platform_data.c
--@@ -23,17 +23,17 @@
-- #include <linux/err.h>
-- #include <linux/wl12xx.h>
-- 
---static struct wl12xx_platform_data *platform_data;
--+static struct wl12xx_platform_data *wl12xx_platform_data;
-- 
-- int __init wl12xx_set_platform_data(const struct wl12xx_platform_data *data)
-- {
---	if (platform_data)
--+	if (wl12xx_platform_data)
-- 		return -EBUSY;
-- 	if (!data)
-- 		return -EINVAL;
-- 
---	platform_data = kmemdup(data, sizeof(*data), GFP_KERNEL);
---	if (!platform_data)
--+	wl12xx_platform_data = kmemdup(data, sizeof(*data), GFP_KERNEL);
--+	if (!wl12xx_platform_data)
-- 		return -ENOMEM;
-- 
-- 	return 0;
--@@ -41,9 +41,34 @@ int __init wl12xx_set_platform_data(cons
-- 
-- struct wl12xx_platform_data *wl12xx_get_platform_data(void)
-- {
---	if (!platform_data)
--+	if (!wl12xx_platform_data)
-- 		return ERR_PTR(-ENODEV);
-- 
---	return platform_data;
--+	return wl12xx_platform_data;
-- }
-- EXPORT_SYMBOL(wl12xx_get_platform_data);
--+
--+static struct wl1251_platform_data *wl1251_platform_data;
--+
--+int __init wl1251_set_platform_data(const struct wl1251_platform_data *data)
--+{
--+	if (wl1251_platform_data)
--+		return -EBUSY;
--+	if (!data)
--+		return -EINVAL;
--+
--+	wl1251_platform_data = kmemdup(data, sizeof(*data), GFP_KERNEL);
--+	if (!wl1251_platform_data)
--+		return -ENOMEM;
--+
--+	return 0;
--+}
--+
--+struct wl1251_platform_data *wl1251_get_platform_data(void)
--+{
--+	if (!wl1251_platform_data)
--+		return ERR_PTR(-ENODEV);
--+
--+	return wl1251_platform_data;
--+}
--+EXPORT_SYMBOL(wl1251_get_platform_data);
----- a/drivers/net/wireless/ti/wl1251/sdio.c
--+++ b/drivers/net/wireless/ti/wl1251/sdio.c
--@@ -227,7 +227,7 @@ static int wl1251_sdio_probe(struct sdio
-- 	struct wl1251 *wl;
-- 	struct ieee80211_hw *hw;
-- 	struct wl1251_sdio *wl_sdio;
---	const struct wl12xx_platform_data *wl12xx_board_data;
--+	const struct wl1251_platform_data *wl1251_board_data;
-- 
-- 	hw = wl1251_alloc_hw();
-- 	if (IS_ERR(hw))
--@@ -254,11 +254,11 @@ static int wl1251_sdio_probe(struct sdio
-- 	wl->if_priv = wl_sdio;
-- 	wl->if_ops = &wl1251_sdio_ops;
-- 
---	wl12xx_board_data = wl12xx_get_platform_data();
---	if (!IS_ERR(wl12xx_board_data)) {
---		wl->set_power = wl12xx_board_data->set_power;
---		wl->irq = wl12xx_board_data->irq;
---		wl->use_eeprom = wl12xx_board_data->use_eeprom;
--+	wl1251_board_data = wl1251_get_platform_data();
--+	if (!IS_ERR(wl1251_board_data)) {
--+		wl->set_power = wl1251_board_data->set_power;
--+		wl->irq = wl1251_board_data->irq;
--+		wl->use_eeprom = wl1251_board_data->use_eeprom;
-- 	}
-- 
-- 	if (wl->irq) {
----- a/drivers/net/wireless/ti/wl1251/spi.c
--+++ b/drivers/net/wireless/ti/wl1251/spi.c
--@@ -241,7 +241,7 @@ static const struct wl1251_if_operations
-- 
-- static int wl1251_spi_probe(struct spi_device *spi)
-- {
---	struct wl12xx_platform_data *pdata;
--+	struct wl1251_platform_data *pdata;
-- 	struct ieee80211_hw *hw;
-- 	struct wl1251 *wl;
-- 	int ret;
-diff --git a/package/mac80211/patches/900-wlcore-Add-support-for-DT-platform-data.patch b/package/mac80211/patches/900-wlcore-Add-support-for-DT-platform-data.patch
-new file mode 100644
-index 0000000..856dea8
---- /dev/null
-+++ b/package/mac80211/patches/900-wlcore-Add-support-for-DT-platform-data.patch
-@@ -0,0 +1,139 @@
-+When running with DT, we no longer have a board file that can set up the
-+platform data for wlcore. Allow this data to be passed from DT.
-+
-+Since some platforms use a gpio-irq, add support for passing either the
-+irq number or the gpio number. For the latter case, the driver will
-+request the gpio and convert it to the irq number. If an irq is
-+specified, it'll be used as is.
-+
-+[Arik - the pdev_data pointer does not belong to us and is freed when
-+the device is released. Dereference to our private data first.]
-+
-+Signed-off-by: Ido Yariv <ido@wizery.com>
-+Signed-off-by: Arik Nemtsov <arik@wizery.com>
-+---
-+ drivers/net/wireless/ti/wlcore/sdio.c | 71 ++++++++++++++++++++++++++++++++---
-+ include/linux/wl12xx.h                |  3 +-
-+ 2 files changed, 67 insertions(+), 7 deletions(-)
-+
-+--- a/drivers/net/wireless/ti/wlcore/sdio.c
-++++ b/drivers/net/wireless/ti/wlcore/sdio.c
-+@@ -34,6 +34,7 @@
-+ #include <linux/wl12xx.h>
-+ #include <linux/pm_runtime.h>
-+ #include <linux/printk.h>
-++#include <linux/of.h>
-+ 
-+ #include "wlcore.h"
-+ #include "wl12xx_80211.h"
-+@@ -214,6 +215,61 @@ static struct wl1271_if_operations sdio_
-+ 	.set_block_size = wl1271_sdio_set_block_size,
-+ };
-+ 
-++static const struct of_device_id wlcore_of_match[] = {
-++	{
-++		.compatible = "wlcore",
-++	},
-++	{}
-++};
-++MODULE_DEVICE_TABLE(of, wlcore_of_match);
-++
-++static struct wl12xx_platform_data *get_platform_data(struct device *dev)
-++{
-++	struct wl12xx_platform_data *pdata;
-++	struct device_node *np;
-++	u32 gpio;
-++
-++	pdata = wl12xx_get_platform_data();
-++	if (!IS_ERR(pdata))
-++		return kmemdup(pdata, sizeof(*pdata), GFP_KERNEL);
-++
-++	np = of_find_matching_node(NULL, wlcore_of_match);
-++	if (!np) {
-++		dev_err(dev, "No platform data set\n");
-++		return NULL;
-++	}
-++
-++	pdata = kzalloc(sizeof(*pdata), GFP_KERNEL);
-++	if (!pdata) {
-++		dev_err(dev, "Can't allocate platform data\n");
-++		return NULL;
-++	}
-++
-++	if (of_property_read_u32(np, "irq", &pdata->irq)) {
-++		if (!of_property_read_u32(np, "gpio", &gpio) &&
-++		    !gpio_request_one(gpio, GPIOF_IN, "wlcore_irq")) {
-++			pdata->gpio = gpio;
-++			pdata->irq = gpio_to_irq(gpio);
-++		}
-++	}
-++
-++	/* Optional fields */
-++	pdata->use_eeprom = of_property_read_bool(np, "use-eeprom");
-++	of_property_read_u32(np, "board-ref-clock", &pdata->board_ref_clock);
-++	of_property_read_u32(np, "board-tcxo-clock", &pdata->board_tcxo_clock);
-++	of_property_read_u32(np, "platform-quirks", &pdata->platform_quirks);
-++
-++	return pdata;
-++}
-++
-++static void del_platform_data(struct wl12xx_platform_data *pdata)
-++{
-++	if (pdata->gpio)
-++		gpio_free(pdata->gpio);
-++
-++	kfree(pdata);
-++}
-++
-+ static int wl1271_probe(struct sdio_func *func,
-+ 				  const struct sdio_device_id *id)
-+ {
-+@@ -245,10 +301,10 @@ static int wl1271_probe(struct sdio_func
-+ 	/* Use block mode for transferring over one block size of data */
-+ 	func->card->quirks |= MMC_QUIRK_BLKSZ_FOR_BYTE_MODE;
-+ 
-+-	pdev_data.pdata = wl12xx_get_platform_data();
-+-	if (IS_ERR(pdev_data.pdata)) {
-+-		ret = PTR_ERR(pdev_data.pdata);
-+-		dev_err(glue->dev, "missing wlan platform data: %d\n", ret);
-++	pdev_data.pdata = get_platform_data(&func->dev);
-++	if (!pdev_data.pdata) {
-++		ret = -EINVAL;
-++		dev_err(glue->dev, "missing wlan platform data\n");
-+ 		goto out_free_glue;
-+ 	}
-+ 
-+@@ -279,7 +335,7 @@ static int wl1271_probe(struct sdio_func
-+ 	if (!glue->core) {
-+ 		dev_err(glue->dev, "can't allocate platform_device");
-+ 		ret = -ENOMEM;
-+-		goto out_free_glue;
-++		goto out_free_pdata;
-+ 	}
-+ 
-+ 	glue->core->dev.parent = &func->dev;
-+@@ -313,6 +369,9 @@ static int wl1271_probe(struct sdio_func
-+ out_dev_put:
-+ 	platform_device_put(glue->core);
-+ 
-++out_free_pdata:
-++	del_platform_data(pdev_data->pdata);
-++
-+ out_free_glue:
-+ 	kfree(glue);
-+ 
-+@@ -323,11 +382,14 @@ out:
-+ static void wl1271_remove(struct sdio_func *func)
-+ {
-+ 	struct wl12xx_sdio_glue *glue = sdio_get_drvdata(func);
-++	struct wlcore_platdev_data *pdev_data = glue->core->dev.platform_data;
-++	struct wl12xx_platform_data *pdata = pdev_data->pdata;
-+ 
-+ 	/* Undo decrement done above in wl1271_probe */
-+ 	pm_runtime_get_noresume(&func->dev);
-+ 
-+ 	platform_device_unregister(glue->core);
-++	del_platform_data(pdata);
-+ 	kfree(glue);
-+ }
-+ 
-diff --git a/package/mac80211/patches/901-wlcore-don-t-switch-channels-on-disconnected-STA-vif.patch b/package/mac80211/patches/901-wlcore-don-t-switch-channels-on-disconnected-STA-vif.patch
-new file mode 100644
-index 0000000..d90508e
---- /dev/null
-+++ b/package/mac80211/patches/901-wlcore-don-t-switch-channels-on-disconnected-STA-vif.patch
-@@ -0,0 +1,36 @@
-+From 4101e8dc540d19f1f6c24930629149191786e4cd Mon Sep 17 00:00:00 2001
-+From: Arik Nemtsov <arik@wizery.com>
-+Date: Mon, 9 Sep 2013 16:48:59 +0300
-+Subject: [PATCH 27/75] wlcore: don't switch channels on disconnected STA vifs
-+
-+Sending the FW a channel switch command on a disconnected vif may result
-+in a beacon loss event. Avoid this edge case.
-+
-+Signed-off-by: Arik Nemtsov <arik@wizery.com>
-+---
-+ drivers/net/wireless/ti/wlcore/main.c | 7 +++++++
-+ 1 file changed, 7 insertions(+)
-+
-+--- a/drivers/net/wireless/ti/wlcore/main.c
-++++ b/drivers/net/wireless/ti/wlcore/main.c
-+@@ -5148,6 +5148,10 @@ static void wl12xx_op_channel_switch(str
-+ 	if (unlikely(wl->state == WLCORE_STATE_OFF)) {
-+ 		wl12xx_for_each_wlvif_sta(wl, wlvif) {
-+ 			struct ieee80211_vif *vif = wl12xx_wlvif_to_vif(wlvif);
-++
-++			if (!test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags))
-++				continue;
-++
-+ 			ieee80211_chswitch_done(vif, false);
-+ 		}
-+ 		goto out;
-+@@ -5163,6 +5167,9 @@ static void wl12xx_op_channel_switch(str
-+ 	wl12xx_for_each_wlvif_sta(wl, wlvif) {
-+ 		unsigned long delay_usec;
-+ 
-++		if (!test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags))
-++			continue;
-++
-+ 		ret = wl->ops->channel_switch(wl, wlvif, ch_switch);
-+ 		if (ret)
-+ 			goto out_sleep;
-diff --git a/package/mac80211/patches/901-wlcore-set-irq_flags-in-the-board-files.patch b/package/mac80211/patches/901-wlcore-set-irq_flags-in-the-board-files.patch
-deleted file mode 100644
-index f2789a9..0000000
---- a/package/mac80211/patches/901-wlcore-set-irq_flags-in-the-board-files.patch
-+++ /dev/null
-@@ -1,118 +0,0 @@
--The platform_quirk element in the platform data was used to change the
--way the IRQ is triggered.  When set, the EDGE_IRQ quirk would change
--the irqflags used and treat edge trigger differently from the rest.
--
--Instead of hiding this irq flag setting behind the quirk, have the
--board files set the flags during initialization.  This will be more
--meaningful than driver-specific quirks when we switch to DT.
--
--Additionally, fix missing gpio_request() calls in the boarding files
--(so that setting the flags actually works).
--
--Cc: Tony Lindgren <tony@atomide.com>
--Cc: Sekhar Nori <nsekhar@ti.com>
--Signed-off-by: Luciano Coelho <coelho@ti.com>
--Reviewed-by: Felipe Balbi <balbi@ti.com>
--Acked-by: Sekhar Nori <nsekhar@ti.com>
--
----- a/drivers/net/wireless/ti/wlcore/debugfs.c
--+++ b/drivers/net/wireless/ti/wlcore/debugfs.c
--@@ -502,7 +502,7 @@ static ssize_t driver_state_read(struct 
-- 	DRIVER_STATE_PRINT_HEX(irq);
-- 	/* TODO: ref_clock and tcxo_clock were moved to wl12xx priv */
-- 	DRIVER_STATE_PRINT_HEX(hw_pg_ver);
---	DRIVER_STATE_PRINT_HEX(platform_quirks);
--+	DRIVER_STATE_PRINT_HEX(irq_flags);
-- 	DRIVER_STATE_PRINT_HEX(chip.id);
-- 	DRIVER_STATE_PRINT_STR(chip.fw_ver_str);
-- 	DRIVER_STATE_PRINT_STR(chip.phy_fw_ver_str);
----- a/drivers/net/wireless/ti/wlcore/main.c
--+++ b/drivers/net/wireless/ti/wlcore/main.c
--@@ -27,6 +27,7 @@
-- #include <linux/vmalloc.h>
-- #include <linux/wl12xx.h>
-- #include <linux/interrupt.h>
--+#include <linux/irq.h>
-- 
-- #include "wlcore.h"
-- #include "debug.h"
--@@ -528,7 +529,7 @@ static int wlcore_irq_locked(struct wl12
-- 	 * In case edge triggered interrupt must be used, we cannot iterate
-- 	 * more than once without introducing race conditions with the hardirq.
-- 	 */
---	if (wl->platform_quirks & WL12XX_PLATFORM_QUIRK_EDGE_IRQ)
--+	if (wl->irq_flags & IRQF_TRIGGER_RISING)
-- 		loopcount = 1;
-- 
-- 	wl1271_debug(DEBUG_IRQ, "IRQ work");
--@@ -5934,7 +5935,6 @@ struct ieee80211_hw *wlcore_alloc_hw(siz
-- 	wl->ap_ps_map = 0;
-- 	wl->ap_fw_ps_map = 0;
-- 	wl->quirks = 0;
---	wl->platform_quirks = 0;
-- 	wl->system_hlid = WL12XX_SYSTEM_HLID;
-- 	wl->active_sta_count = 0;
-- 	wl->active_link_count = 0;
--@@ -6075,7 +6075,7 @@ static void wlcore_nvs_cb(const struct f
-- 	struct platform_device *pdev = wl->pdev;
-- 	struct wlcore_platdev_data *pdev_data = dev_get_platdata(&pdev->dev);
-- 	struct wl12xx_platform_data *pdata = pdev_data->pdata;
---	unsigned long irqflags;
--+
-- 	int ret;
-- 	irq_handler_t hardirq_fn = NULL;
-- 
--@@ -6103,29 +6103,19 @@ static void wlcore_nvs_cb(const struct f
-- 	wlcore_adjust_conf(wl);
-- 
-- 	wl->irq = platform_get_irq(pdev, 0);
---	wl->platform_quirks = pdata->platform_quirks;
-- 	wl->if_ops = pdev_data->if_ops;
-- 
---#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,32)
---	irqflags = IRQF_TRIGGER_RISING;
--+	wl->irq_flags = irq_get_trigger_type(wl->irq) | IRQF_ONESHOT;
-- 	hardirq_fn = wlcore_hardirq;
---#else
---	if (wl->platform_quirks & WL12XX_PLATFORM_QUIRK_EDGE_IRQ) {
---		irqflags = IRQF_TRIGGER_RISING;
---		hardirq_fn = wlcore_hardirq;
---	} else {
---		irqflags = IRQF_TRIGGER_HIGH | IRQF_ONESHOT;
---	}
---#endif
-- 
-- #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,31)
-- 	ret = compat_request_threaded_irq(&wl->irq_compat, wl->irq,
-- 					  hardirq_fn, wlcore_irq,
---					  irqflags,
--+					  wl->irqflags,
-- 					  pdev->name, wl);
-- #else
-- 	ret = request_threaded_irq(wl->irq, hardirq_fn, wlcore_irq,
---				   irqflags, pdev->name, wl);
--+				   wl->irq_flags, pdev->name, wl);
-- #endif
-- 	if (ret < 0) {
-- 		wl1271_error("request_irq() failed: %d", ret);
----- a/drivers/net/wireless/ti/wlcore/wlcore.h
--+++ b/drivers/net/wireless/ti/wlcore/wlcore.h
--@@ -188,6 +188,8 @@ struct wl1271 {
-- 
-- 	int irq;
-- 
--+	int irq_flags;
--+
-- 	spinlock_t wl_lock;
-- 
-- 	enum wlcore_state state;
--@@ -395,9 +397,6 @@ struct wl1271 {
-- 	/* Quirks of specific hardware revisions */
-- 	unsigned int quirks;
-- 
---	/* Platform limitations */
---	unsigned int platform_quirks;
---
-- 	/* number of currently active RX BA sessions */
-- 	int ba_rx_session_count;
-- 
-diff --git a/package/mac80211/patches/902-wlcore-remove-pwr_in_suspend-from-platform-data.patch b/package/mac80211/patches/902-wlcore-remove-pwr_in_suspend-from-platform-data.patch
-deleted file mode 100644
-index 6394377..0000000
---- a/package/mac80211/patches/902-wlcore-remove-pwr_in_suspend-from-platform-data.patch
-+++ /dev/null
-@@ -1,48 +0,0 @@
--The pwr_in_suspend flag depends on the MMC settings which can be
--retrieved from the SDIO subsystem, so it doesn't need to be part of
--the platform data structure.  Move it to the platform device data that
--is passed from SDIO to wlcore.
--
--Signed-off-by: Luciano Coelho <coelho@ti.com>
--Reviewed-by: Felipe Balbi <balbi@ti.com>
--
----- a/drivers/net/wireless/ti/wlcore/main.c
--+++ b/drivers/net/wireless/ti/wlcore/main.c
--@@ -6074,7 +6074,6 @@ static void wlcore_nvs_cb(const struct f
-- 	struct wl1271 *wl = context;
-- 	struct platform_device *pdev = wl->pdev;
-- 	struct wlcore_platdev_data *pdev_data = dev_get_platdata(&pdev->dev);
---	struct wl12xx_platform_data *pdata = pdev_data->pdata;
-- 
-- 	int ret;
-- 	irq_handler_t hardirq_fn = NULL;
--@@ -6127,7 +6126,7 @@ static void wlcore_nvs_cb(const struct f
-- 	if (!ret) {
-- 		wl->irq_wake_enabled = true;
-- 		device_init_wakeup(wl->dev, 1);
---		if (pdata->pwr_in_suspend)
--+		if (pdev_data->pwr_in_suspend)
-- 			wl->hw->wiphy->wowlan = &wlcore_wowlan_support;
-- 	}
-- #endif
----- a/drivers/net/wireless/ti/wlcore/sdio.c
--+++ b/drivers/net/wireless/ti/wlcore/sdio.c
--@@ -260,7 +260,7 @@ static int wl1271_probe(struct sdio_func
-- 	dev_dbg(glue->dev, "sdio PM caps = 0x%x\n", mmcflags);
-- 
-- 	if (mmcflags & MMC_PM_KEEP_POWER)
---		pdev_data->pdata->pwr_in_suspend = true;
--+		pdev_data->pwr_in_suspend = true;
-- 
-- 	sdio_set_drvdata(func, glue);
-- 
----- a/drivers/net/wireless/ti/wlcore/wlcore_i.h
--+++ b/drivers/net/wireless/ti/wlcore/wlcore_i.h
--@@ -209,6 +209,7 @@ struct wl1271_if_operations {
-- struct wlcore_platdev_data {
-- 	struct wl12xx_platform_data *pdata;
-- 	struct wl1271_if_operations *if_ops;
--+	bool pwr_in_suspend;
-- };
-- 
-- #define MAX_NUM_KEYS 14
-diff --git a/package/mac80211/patches/903-wl12xx-use-frequency-instead-of-enumerations-for-pdata-clocks.patch b/package/mac80211/patches/903-wl12xx-use-frequency-instead-of-enumerations-for-pdata-clocks.patch
-deleted file mode 100644
-index 4b20932..0000000
---- a/package/mac80211/patches/903-wl12xx-use-frequency-instead-of-enumerations-for-pdata-clocks.patch
-+++ /dev/null
-@@ -1,131 +0,0 @@
--Instead of defining an enumeration with the FW specific values for the
--different clock rates, use the actual frequency instead.  Also add a
--boolean to specify whether the clock is XTAL or not.
--
--Change all board files to reflect this.
--
--Additionally, this reverts commit 26f45c (ARM: OMAP2+: Legacy support
--for wl12xx when booted with devicetree), since this is not be needed
--anymore, now that DT support for WiLink is implemented.
--
--Cc: Tony Lindgren <tony@atomide.com>
--Cc: Sekhar Nori <nsekhar@ti.com>
--Signed-off-by: Luciano Coelho <coelho@ti.com>
--Reviewed-by: Felipe Balbi <balbi@ti.com>
--
----- a/drivers/net/wireless/ti/wl12xx/main.c
--+++ b/drivers/net/wireless/ti/wl12xx/main.c
--@@ -1711,6 +1711,43 @@ static struct ieee80211_sta_ht_cap wl12x
-- 		},
-- };
-- 
--+static const struct wl12xx_clock wl12xx_refclock_table[] = {
--+	{ 19200000,	false,	WL12XX_REFCLOCK_19	},
--+	{ 26000000,	false,	WL12XX_REFCLOCK_26	},
--+	{ 26000000,	true,	WL12XX_REFCLOCK_26_XTAL	},
--+	{ 38400000,	false,	WL12XX_REFCLOCK_38	},
--+	{ 38400000,	true,	WL12XX_REFCLOCK_38_XTAL	},
--+	{ 52000000,	false,	WL12XX_REFCLOCK_52	},
--+	{ 0,		false,	0 }
--+};
--+
--+static const struct wl12xx_clock wl12xx_tcxoclock_table[] = {
--+	{ 16368000,	true,	WL12XX_TCXOCLOCK_16_368	},
--+	{ 16800000,	true,	WL12XX_TCXOCLOCK_16_8	},
--+	{ 19200000,	true,	WL12XX_TCXOCLOCK_19_2	},
--+	{ 26000000,	true,	WL12XX_TCXOCLOCK_26	},
--+	{ 32736000,	true,	WL12XX_TCXOCLOCK_32_736	},
--+	{ 33600000,	true,	WL12XX_TCXOCLOCK_33_6	},
--+	{ 38400000,	true,	WL12XX_TCXOCLOCK_38_4	},
--+	{ 52000000,	true,	WL12XX_TCXOCLOCK_52	},
--+	{ 0,		false,	0 }
--+};
--+
--+static int wl12xx_get_clock_idx(const struct wl12xx_clock *table,
--+				u32 freq, bool xtal)
--+{
--+	int i = 0;
--+
--+	while(table[i].freq != 0) {
--+		if ((table[i].freq == freq) &&
--+		    (table[i].xtal == xtal))
--+			return table[i].hw_idx;
--+		i++;
--+	};
--+
--+	return -EINVAL;
--+}
--+
-- static int wl12xx_setup(struct wl1271 *wl)
-- {
-- 	struct wl12xx_priv *priv = wl->priv;
--@@ -1732,7 +1769,16 @@ static int wl12xx_setup(struct wl1271 *w
-- 	wl12xx_conf_init(wl);
-- 
-- 	if (!fref_param) {
---		priv->ref_clock = pdata->board_ref_clock;
--+		priv->ref_clock = wl12xx_get_clock_idx(wl12xx_refclock_table,
--+						       pdata->ref_clock_freq,
--+						       pdata->ref_clock_xtal);
--+		if (priv->ref_clock < 0) {
--+			wl1271_error("Invalid ref_clock frequency (%d Hz, %s)",
--+				pdata->ref_clock_freq,
--+				pdata->ref_clock_xtal ? "XTAL" : "not XTAL");
--+
--+			return priv->ref_clock;
--+		}
-- 	} else {
-- 		if (!strcmp(fref_param, "19.2"))
-- 			priv->ref_clock = WL12XX_REFCLOCK_19;
--@@ -1751,7 +1797,15 @@ static int wl12xx_setup(struct wl1271 *w
-- 	}
-- 
-- 	if (!tcxo_param) {
---		priv->tcxo_clock = pdata->board_tcxo_clock;
--+		priv->tcxo_clock = wl12xx_get_clock_idx(wl12xx_tcxoclock_table,
--+							pdata->tcxo_clock_freq,
--+							true);
--+		if (priv->tcxo_clock < 0) {
--+			wl1271_error("Invalid tcxo_clock frequency (%d Hz)",
--+				pdata->tcxo_clock_freq);
--+
--+			return priv->tcxo_clock;
--+		}
-- 	} else {
-- 		if (!strcmp(tcxo_param, "19.2"))
-- 			priv->tcxo_clock = WL12XX_TCXOCLOCK_19_2;
----- a/drivers/net/wireless/ti/wl12xx/wl12xx.h
--+++ b/drivers/net/wireless/ti/wl12xx/wl12xx.h
--@@ -79,4 +79,32 @@ struct wl12xx_priv {
-- 	struct wl127x_rx_mem_pool_addr *rx_mem_addr;
-- };
-- 
--+/* Reference clock values */
--+enum {
--+	WL12XX_REFCLOCK_19	= 0, /* 19.2 MHz */
--+	WL12XX_REFCLOCK_26	= 1, /* 26 MHz */
--+	WL12XX_REFCLOCK_38	= 2, /* 38.4 MHz */
--+	WL12XX_REFCLOCK_52	= 3, /* 52 MHz */
--+	WL12XX_REFCLOCK_38_XTAL = 4, /* 38.4 MHz, XTAL */
--+	WL12XX_REFCLOCK_26_XTAL = 5, /* 26 MHz, XTAL */
--+};
--+
--+/* TCXO clock values */
--+enum {
--+	WL12XX_TCXOCLOCK_19_2	= 0, /* 19.2MHz */
--+	WL12XX_TCXOCLOCK_26	= 1, /* 26 MHz */
--+	WL12XX_TCXOCLOCK_38_4	= 2, /* 38.4MHz */
--+	WL12XX_TCXOCLOCK_52	= 3, /* 52 MHz */
--+	WL12XX_TCXOCLOCK_16_368	= 4, /* 16.368 MHz */
--+	WL12XX_TCXOCLOCK_32_736	= 5, /* 32.736 MHz */
--+	WL12XX_TCXOCLOCK_16_8	= 6, /* 16.8 MHz */
--+	WL12XX_TCXOCLOCK_33_6	= 7, /* 33.6 MHz */
--+};
--+
--+struct wl12xx_clock {
--+	u32	freq;
--+	bool	xtal;
--+	u8	hw_idx;
--+};
--+
-- #endif /* __WL12XX_PRIV_H__ */
-diff --git a/package/mac80211/patches/904-wlcore-add-initial-device-tree-support-to-the-sdio-module.patch b/package/mac80211/patches/904-wlcore-add-initial-device-tree-support-to-the-sdio-module.patch
-deleted file mode 100644
-index 9e1d190..0000000
---- a/package/mac80211/patches/904-wlcore-add-initial-device-tree-support-to-the-sdio-module.patch
-+++ /dev/null
-@@ -1,118 +0,0 @@
--If platform data is not available, try to get the required information
--from the device tree.  Register an OF match table and parse the
--appropriate device tree nodes.
--
--Parse interrupt property only, for now.
--
--Signed-off-by: Luciano Coelho <coelho@ti.com>
--Reviewed-by: Felipe Balbi <balbi@ti.com>
--
----- a/drivers/net/wireless/ti/wlcore/sdio.c
--+++ b/drivers/net/wireless/ti/wlcore/sdio.c
--@@ -30,7 +30,7 @@
-- #include <linux/mmc/sdio_ids.h>
-- #include <linux/mmc/card.h>
-- #include <linux/mmc/host.h>
---#include <linux/gpio.h>
--+#include <linux/of_irq.h>
-- #include <linux/wl12xx.h>
-- #include <linux/pm_runtime.h>
-- #include <linux/printk.h>
--@@ -214,6 +214,43 @@ static struct wl1271_if_operations sdio_
-- 	.set_block_size = wl1271_sdio_set_block_size,
-- };
-- 
--+static struct wl12xx_platform_data *wlcore_get_pdata_from_of(struct device *dev)
--+{
--+	struct wl12xx_platform_data *pdata;
--+	struct device_node *np = dev->of_node;
--+
--+	if (!np) {
--+		np = of_find_matching_node(NULL, dev->driver->of_match_table);
--+		if (!np) {
--+			dev_notice(dev, "device tree node not available\n");
--+			pdata = ERR_PTR(-ENODEV);
--+			goto out;
--+		}
--+	}
--+
--+	pdata = kzalloc(sizeof(*pdata), GFP_KERNEL);
--+	if (!pdata) {
--+		dev_err(dev, "can't allocate platform data\n");
--+		pdata = ERR_PTR(-ENODEV);
--+		goto out;
--+	}
--+
--+	pdata->irq = irq_of_parse_and_map(np, 0);
--+	if (pdata->irq < 0) {
--+		dev_err(dev, "can't get interrupt gpio from the device tree\n");
--+		goto out_free;
--+	}
--+
--+	goto out;
--+
--+out_free:
--+	kfree(pdata);
--+	pdata = ERR_PTR(-ENODEV);
--+
--+out:
--+	return pdata;
--+}
--+
-- static int wl1271_probe(struct sdio_func *func,
-- 				  const struct sdio_device_id *id)
-- {
--@@ -248,11 +285,22 @@ static int wl1271_probe(struct sdio_func
-- 	/* Use block mode for transferring over one block size of data */
-- 	func->card->quirks |= MMC_QUIRK_BLKSZ_FOR_BYTE_MODE;
-- 
--+	/* The pdata allocated here is freed when the device is freed,
--+	 * so we don't need an additional out label to free it in case
--+	 * of error further on.
--+	 */
--+
--+	/* Try to get legacy platform data from the board file */
-- 	pdev_data->pdata = wl12xx_get_platform_data();
-- 	if (IS_ERR(pdev_data->pdata)) {
---		ret = PTR_ERR(pdev_data->pdata);
---		dev_err(glue->dev, "missing wlan platform data: %d\n", ret);
---		goto out_free_glue;
--+		dev_info(&func->dev,
--+			 "legacy platform data not found, trying device tree\n");
--+
--+		pdev_data->pdata = wlcore_get_pdata_from_of(&func->dev);
--+		if (IS_ERR(pdev_data->pdata)) {
--+			dev_err(&func->dev, "can't get platform data\n");
--+			goto out_free_glue;
--+		}
-- 	}
-- 
-- 	/* if sdio can keep power while host is suspended, enable wow */
--@@ -386,16 +434,25 @@ static const struct dev_pm_ops wl1271_sd
-- };
-- #endif
-- 
--+static const struct of_device_id wlcore_sdio_of_match_table[] = {
--+	{ .compatible = "ti,wilink6" },
--+	{ .compatible = "ti,wilink7" },
--+	{ .compatible = "ti,wilink8" },
--+	{ }
--+};
--+MODULE_DEVICE_TABLE(of, wlcore_sdio_of_match_table);
--+
-- static struct sdio_driver wl1271_sdio_driver = {
-- 	.name		= "wl1271_sdio",
-- 	.id_table	= wl1271_devices,
-- 	.probe		= wl1271_probe,
-- 	.remove		= wl1271_remove,
---#ifdef CONFIG_PM
-- 	.drv = {
--+#ifdef CONFIG_PM
-- 		.pm = &wl1271_sdio_pm_ops,
---	},
-- #endif
--+		.of_match_table = of_match_ptr(wlcore_sdio_of_match_table),
--+	},
-- };
-- 
-- static int __init wl1271_init(void)
-diff --git a/package/mac80211/patches/905-wlcore-sdio-add-wilink-clock-providers.patch b/package/mac80211/patches/905-wlcore-sdio-add-wilink-clock-providers.patch
-deleted file mode 100644
-index be1f9ad..0000000
---- a/package/mac80211/patches/905-wlcore-sdio-add-wilink-clock-providers.patch
-+++ /dev/null
-@@ -1,50 +0,0 @@
--Add refclock and tcxoclock as clock providers in WiLink.  These clocks
--are not accesible outside the WiLink module, but they are registered
--in the clock framework anyway.  Only the WiLink chip consumes these
--clocks.
--
--In theory, the WiLink chip could be connected to external clocks
--instead of using these internal clocks, so make the clock consumer
--code generic enough.  If external clocks are used, then the internal
--clock device tree nodes are not necessary, but the external ones must
--be specified.
--
--Signed-off-by: Luciano Coelho <coelho@ti.com>
--Reviewed-by: Felipe Balbi <balbi@ti.com>
--
----- a/drivers/net/wireless/ti/wlcore/sdio.c
--+++ b/drivers/net/wireless/ti/wlcore/sdio.c
--@@ -34,6 +34,7 @@
-- #include <linux/wl12xx.h>
-- #include <linux/pm_runtime.h>
-- #include <linux/printk.h>
--+#include <linux/clk-provider.h>
-- 
-- #include "wlcore.h"
-- #include "wl12xx_80211.h"
--@@ -214,10 +215,15 @@ static struct wl1271_if_operations sdio_
-- 	.set_block_size = wl1271_sdio_set_block_size,
-- };
-- 
--+static const struct of_device_id wlcore_sdio_of_clk_match_table[] = {
--+	{ .compatible = "ti,wilink-clock" },
--+};
--+
-- static struct wl12xx_platform_data *wlcore_get_pdata_from_of(struct device *dev)
-- {
-- 	struct wl12xx_platform_data *pdata;
-- 	struct device_node *np = dev->of_node;
--+	struct device_node *clock_node;
-- 
-- 	if (!np) {
-- 		np = of_find_matching_node(NULL, dev->driver->of_match_table);
--@@ -241,6 +247,9 @@ static struct wl12xx_platform_data *wlco
-- 		goto out_free;
-- 	}
-- 
--+	for_each_matching_node(clock_node, wlcore_sdio_of_clk_match_table)
--+		of_fixed_clk_setup(clock_node);
--+
-- 	goto out;
-- 
-- out_free:
-diff --git a/package/mac80211/patches/906-wlcore-sdio-get-clocks-from-device-tree.patch b/package/mac80211/patches/906-wlcore-sdio-get-clocks-from-device-tree.patch
-deleted file mode 100644
-index 09ff4af..0000000
---- a/package/mac80211/patches/906-wlcore-sdio-get-clocks-from-device-tree.patch
-+++ /dev/null
-@@ -1,90 +0,0 @@
--Read the clock nodes from the device tree and use them to set the
--frequency for the refclock and the tcxo clock.
--
--Also, call sdio_set_drvdata() earlier, so the glue is already set in
--the driver data when we call wlcore_get_pdata_from_of() and we don't
--need to pass it as a parameter.
--
--Signed-off-by: Luciano Coelho <coelho@ti.com>
--Reviewed-by: Felipe Balbi <balbi@ti.com>
--
----- a/drivers/net/wireless/ti/wlcore/sdio.c
--+++ b/drivers/net/wireless/ti/wlcore/sdio.c
--@@ -53,6 +53,7 @@ static bool dump = false;
-- struct wl12xx_sdio_glue {
-- 	struct device *dev;
-- 	struct platform_device *core;
--+	struct clk *refclock, *tcxoclock;
-- };
-- 
-- static const struct sdio_device_id wl1271_devices[] = {
--@@ -224,6 +225,7 @@ static struct wl12xx_platform_data *wlco
-- 	struct wl12xx_platform_data *pdata;
-- 	struct device_node *np = dev->of_node;
-- 	struct device_node *clock_node;
--+	struct wl12xx_sdio_glue *glue = sdio_get_drvdata(dev_to_sdio_func(dev));
-- 
-- 	if (!np) {
-- 		np = of_find_matching_node(NULL, dev->driver->of_match_table);
--@@ -250,6 +252,26 @@ static struct wl12xx_platform_data *wlco
-- 	for_each_matching_node(clock_node, wlcore_sdio_of_clk_match_table)
-- 		of_fixed_clk_setup(clock_node);
-- 
--+	/* TODO: make sure we have this when needed (ie. for WL6 and WL7) */
--+	glue->refclock = of_clk_get_by_name(np, "refclock");
--+	if (IS_ERR(glue->refclock)) {
--+		dev_err(dev, "couldn't find refclock on the device tree\n");
--+		glue->refclock = NULL;
--+	} else {
--+		clk_prepare_enable(glue->refclock);
--+		pdata->ref_clock_freq = clk_get_rate(glue->refclock);
--+	}
--+
--+	/* TODO: make sure we have this when needed (ie. for WL7) */
--+	glue->tcxoclock = of_clk_get_by_name(np, "tcxoclock");
--+	if (IS_ERR(glue->tcxoclock)) {
--+		dev_err(dev, "couldn't find tcxoclock on the device tree\n");
--+		glue->tcxoclock = NULL;
--+	} else {
--+		clk_prepare_enable(glue->tcxoclock);
--+		pdata->ref_clock_freq = clk_get_rate(glue->tcxoclock);
--+	}
--+
-- 	goto out;
-- 
-- out_free:
--@@ -294,6 +316,8 @@ static int wl1271_probe(struct sdio_func
-- 	/* Use block mode for transferring over one block size of data */
-- 	func->card->quirks |= MMC_QUIRK_BLKSZ_FOR_BYTE_MODE;
-- 
--+	sdio_set_drvdata(func, glue);
--+
-- 	/* The pdata allocated here is freed when the device is freed,
-- 	 * so we don't need an additional out label to free it in case
-- 	 * of error further on.
--@@ -319,8 +343,6 @@ static int wl1271_probe(struct sdio_func
-- 	if (mmcflags & MMC_PM_KEEP_POWER)
-- 		pdev_data->pwr_in_suspend = true;
-- 
---	sdio_set_drvdata(func, glue);
---
-- 	/* Tell PM core that we don't need the card to be powered now */
-- 	pm_runtime_put_noidle(&func->dev);
-- 
--@@ -387,6 +409,16 @@ static void wl1271_remove(struct sdio_fu
-- {
-- 	struct wl12xx_sdio_glue *glue = sdio_get_drvdata(func);
-- 
--+	if (glue->refclock) {
--+		clk_disable_unprepare(glue->refclock);
--+		clk_put(glue->refclock);
--+	}
--+
--+	if (glue->tcxoclock) {
--+		clk_disable_unprepare(glue->tcxoclock);
--+		clk_put(glue->tcxoclock);
--+	}
--+
-- 	/* Undo decrement done above in wl1271_probe */
-- 	pm_runtime_get_noresume(&func->dev);
-- 
-diff --git a/package/mac80211/patches/907-wlcore-wl12xx-check-if-we-got-correct-clock-data-from-DT.patch b/package/mac80211/patches/907-wlcore-wl12xx-check-if-we-got-correct-clock-data-from-DT.patch
-deleted file mode 100644
-index 6b09177..0000000
---- a/package/mac80211/patches/907-wlcore-wl12xx-check-if-we-got-correct-clock-data-from-DT.patch
-+++ /dev/null
-@@ -1,96 +0,0 @@
--The fref and the tcxo clocks settings are optional in some platforms.
--WiLink8 doesn't need either, so we don't check the values.  WiLink 6
--only needs the fref clock, so we check that it is valid or return with
--an error.  WiLink7 needs both clocks, if either is not available we
--return with an error.
--
--Signed-off-by: Luciano Coelho <coelho@ti.com>
--Reviewed-by: Felipe Balbi <balbi@ti.com>
--
----- a/drivers/net/wireless/ti/wl12xx/main.c
--+++ b/drivers/net/wireless/ti/wl12xx/main.c
--@@ -930,6 +930,11 @@ static int wl128x_boot_clk(struct wl1271
-- 	u16 sys_clk_cfg;
-- 	int ret;
-- 
--+	if ((priv->ref_clock < 0) || (priv->tcxo_clock < 0)) {
--+		wl1271_error("Missing fref and/or tcxo clock settings\n");
--+		return -EINVAL;
--+	}
--+
-- 	/* For XTAL-only modes, FREF will be used after switching from TCXO */
-- 	if (priv->ref_clock == WL12XX_REFCLOCK_26_XTAL ||
-- 	    priv->ref_clock == WL12XX_REFCLOCK_38_XTAL) {
--@@ -979,6 +984,11 @@ static int wl127x_boot_clk(struct wl1271
-- 	u32 clk;
-- 	int ret;
-- 
--+	if (priv->ref_clock < 0) {
--+		wl1271_error("Missing fref clock settings\n");
--+		return -EINVAL;
--+	}
--+
-- 	if (WL127X_PG_GET_MAJOR(wl->hw_pg_ver) < 3)
-- 		wl->quirks |= WLCORE_QUIRK_END_OF_TRANSACTION;
-- 
--@@ -1768,7 +1778,7 @@ static int wl12xx_setup(struct wl1271 *w
-- 	wlcore_set_ht_cap(wl, IEEE80211_BAND_5GHZ, &wl12xx_ht_cap);
-- 	wl12xx_conf_init(wl);
-- 
---	if (!fref_param) {
--+	if (!fref_param && (pdata->ref_clock_freq > 0)) {
-- 		priv->ref_clock = wl12xx_get_clock_idx(wl12xx_refclock_table,
-- 						       pdata->ref_clock_freq,
-- 						       pdata->ref_clock_xtal);
--@@ -1779,6 +1789,8 @@ static int wl12xx_setup(struct wl1271 *w
-- 
-- 			return priv->ref_clock;
-- 		}
--+	} else if (!fref_param) {
--+		priv->ref_clock = -EINVAL;
-- 	} else {
-- 		if (!strcmp(fref_param, "19.2"))
-- 			priv->ref_clock = WL12XX_REFCLOCK_19;
--@@ -1796,7 +1808,7 @@ static int wl12xx_setup(struct wl1271 *w
-- 			wl1271_error("Invalid fref parameter %s", fref_param);
-- 	}
-- 
---	if (!tcxo_param) {
--+	if (!fref_param && (pdata->tcxo_clock_freq > 0)) {
-- 		priv->tcxo_clock = wl12xx_get_clock_idx(wl12xx_tcxoclock_table,
-- 							pdata->tcxo_clock_freq,
-- 							true);
--@@ -1806,7 +1818,9 @@ static int wl12xx_setup(struct wl1271 *w
-- 
-- 			return priv->tcxo_clock;
-- 		}
---	} else {
--+	} else if (!fref_param) {
--+		priv->tcxo_clock = -EINVAL;
--+	}else {
-- 		if (!strcmp(tcxo_param, "19.2"))
-- 			priv->tcxo_clock = WL12XX_TCXOCLOCK_19_2;
-- 		else if (!strcmp(tcxo_param, "26"))
----- a/drivers/net/wireless/ti/wlcore/sdio.c
--+++ b/drivers/net/wireless/ti/wlcore/sdio.c
--@@ -252,20 +252,16 @@ static struct wl12xx_platform_data *wlco
-- 	for_each_matching_node(clock_node, wlcore_sdio_of_clk_match_table)
-- 		of_fixed_clk_setup(clock_node);
-- 
---	/* TODO: make sure we have this when needed (ie. for WL6 and WL7) */
-- 	glue->refclock = of_clk_get_by_name(np, "refclock");
-- 	if (IS_ERR(glue->refclock)) {
---		dev_err(dev, "couldn't find refclock on the device tree\n");
-- 		glue->refclock = NULL;
-- 	} else {
-- 		clk_prepare_enable(glue->refclock);
-- 		pdata->ref_clock_freq = clk_get_rate(glue->refclock);
-- 	}
-- 
---	/* TODO: make sure we have this when needed (ie. for WL7) */
-- 	glue->tcxoclock = of_clk_get_by_name(np, "tcxoclock");
-- 	if (IS_ERR(glue->tcxoclock)) {
---		dev_err(dev, "couldn't find tcxoclock on the device tree\n");
-- 		glue->tcxoclock = NULL;
-- 	} else {
-- 		clk_prepare_enable(glue->tcxoclock);
-diff --git a/package/mac80211/patches/a01-compat_fix_compile.patch b/package/mac80211/patches/a01-compat_fix_compile.patch
-new file mode 100644
-index 0000000..9e9e6c7
---- /dev/null
-+++ b/package/mac80211/patches/a01-compat_fix_compile.patch
-@@ -0,0 +1,15 @@
-+--- a/compat/compat-3.6.c
-++++ b/compat/compat-3.6.c
-+@@ -148,6 +148,7 @@ int sg_alloc_table_from_pages(struct sg_
-+ }
-+ EXPORT_SYMBOL_GPL(sg_alloc_table_from_pages);
-+ 
-++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
-+ /* whoopsie ! */
-+ #ifndef CONFIG_COMMON_CLK
-+ int clk_enable(struct clk *clk)
-+@@ -161,3 +162,4 @@ void clk_disable(struct clk *clk)
-+ }
-+ EXPORT_SYMBOL_GPL(clk_disable);
-+ #endif
-++#endif
-diff --git a/target/linux/generic/files/include/linux/ath9k_platform.h b/target/linux/generic/files/include/linux/ath9k_platform.h
-index a0b7531..03aa636 100644
---- a/target/linux/generic/files/include/linux/ath9k_platform.h
-+++ b/target/linux/generic/files/include/linux/ath9k_platform.h
-@@ -39,6 +39,8 @@ struct ath9k_platform_data {
- 	int (*get_mac_revision)(void);
- 	int (*external_reset)(void);
- 
-+	bool use_eeprom;
-+
- 	int num_leds;
- 	const struct gpio_led *leds;
- };

+ 0 - 0
patches/openwrt/0019-ar71xx-add-support-for-QCA953x-SoC.patch → patches/openwrt/0018-ar71xx-add-support-for-QCA953x-SoC.patch


+ 0 - 0
patches/openwrt/0020-ar71xx-add-support-for-the-TP-LINK-TL-WR841N-ND-v9.patch → patches/openwrt/0019-ar71xx-add-support-for-the-TP-LINK-TL-WR841N-ND-v9.patch


+ 0 - 0
patches/openwrt/0021-Backport-support-for-TL-WR842N-v2-and-TL-MR3420-v2.patch → patches/openwrt/0020-Backport-support-for-TL-WR842N-v2-and-TL-MR3420-v2.patch


+ 0 - 0
patches/openwrt/0022-x86-add-grub2-iso-support.patch → patches/openwrt/0021-x86-add-grub2-iso-support.patch


+ 0 - 0
patches/openwrt/0023-x86-explicitely-pass-staging-directory-to-grub-mkimage-instead-of-relying-on-build-time-defaults-12821.patch → patches/openwrt/0022-x86-explicitely-pass-staging-directory-to-grub-mkimage-instead-of-relying-on-build-time-defaults-12821.patch


+ 0 - 0
patches/openwrt/0024-grub2-Add-sub-package-grub-editenv-for-target-installation.patch → patches/openwrt/0023-grub2-Add-sub-package-grub-editenv-for-target-installation.patch


+ 0 - 0
patches/openwrt/0025-x86-Fix-CONFIG_X86_GRUB_SERIAL.patch → patches/openwrt/0024-x86-Fix-CONFIG_X86_GRUB_SERIAL.patch


+ 0 - 0
patches/openwrt/0026-grub2-update-to-2.02-beta2-fixes-mac-os-x-10.9-support-and-many-other-things.patch → patches/openwrt/0025-grub2-update-to-2.02-beta2-fixes-mac-os-x-10.9-support-and-many-other-things.patch


+ 0 - 0
patches/openwrt/0027-grub2-disable-libdevmapper-fix-build-when-it-s-available.patch → patches/openwrt/0026-grub2-disable-libdevmapper-fix-build-when-it-s-available.patch


+ 0 - 0
patches/openwrt/0028-grub2-disable-mkfont-fix-build-on-Archlinux.patch → patches/openwrt/0027-grub2-disable-mkfont-fix-build-on-Archlinux.patch


+ 0 - 0
patches/openwrt/0029-ar71xx-add-support-for-dlink-dir-615-e1.patch → patches/openwrt/0028-ar71xx-add-support-for-dlink-dir-615-e1.patch