Browse Source

Revert "mac80211: backport from trunk r46760"

This reverts commit 91b3c1d371571cd67599a0f5649135d1e0899fcd.
Matthias Schiffer 8 years ago
parent
commit
501affad08

+ 41 - 20
patches/openwrt/0023-ath10k-add-Candelatech-community-firmware-as-an-additional-choice.patch → patches/openwrt/0005-ath10k-add-Candelatech-community-firmware-as-an-additional-choice.patch

@@ -3,10 +3,10 @@ Date: Tue, 10 Mar 2015 13:17:14 +0100
 Subject: ath10k: add Candelatech community firmware as an additional choice
 Subject: ath10k: add Candelatech community firmware as an additional choice
 
 
 diff --git a/package/kernel/mac80211/Makefile b/package/kernel/mac80211/Makefile
 diff --git a/package/kernel/mac80211/Makefile b/package/kernel/mac80211/Makefile
-index 04dfd3b..5d77ebf 100644
+index a1eedce..1c0aebe 100644
 --- a/package/kernel/mac80211/Makefile
 --- a/package/kernel/mac80211/Makefile
 +++ b/package/kernel/mac80211/Makefile
 +++ b/package/kernel/mac80211/Makefile
-@@ -603,6 +603,14 @@ This module adds support for wireless adapters based on
+@@ -604,6 +604,14 @@ This module adds support for wireless adapters based on
  Atheros USB AR9271 and AR7010 family of chipsets.
  Atheros USB AR9271 and AR7010 family of chipsets.
  endef
  endef
  
  
@@ -21,10 +21,10 @@ index 04dfd3b..5d77ebf 100644
  define KernelPackage/ath10k
  define KernelPackage/ath10k
    $(call KernelPackage/mac80211/Default)
    $(call KernelPackage/mac80211/Default)
    TITLE:=Atheros 802.11ac wireless cards support
    TITLE:=Atheros 802.11ac wireless cards support
-@@ -622,6 +630,17 @@ endef
- 
+@@ -624,21 +632,37 @@ endef
  define KernelPackage/ath10k/config
  define KernelPackage/ath10k/config
    if PACKAGE_kmod-ath10k
    if PACKAGE_kmod-ath10k
+ 
 +	choice
 +	choice
 +		prompt "ath10k firmware flavour"
 +		prompt "ath10k firmware flavour"
 +		default ATH10K_AP_FW
 +		default ATH10K_AP_FW
@@ -36,39 +36,60 @@ index 04dfd3b..5d77ebf 100644
 +		help
 +		help
 +		  Use the ath10k firmware optimized for access point operation.
 +		  Use the ath10k firmware optimized for access point operation.
 +		  Supports only AP mode, will crash in IBSS (ad-hoc) mode.
 +		  Supports only AP mode, will crash in IBSS (ad-hoc) mode.
++
+ 	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.
++		  of access point operation. Might be unstable in AP mode.
++
++	config ATH10K_CT_COMMUNITY_FW
++		bool "Firmware by Candela Technologies (community version)"
++		help
++		  Supports both AP and IBSS (ad-hoc) mode. Doesn't support
++		  encryption when using multiple VIFs.
  
  
  	config ATH10K_API2_FW
  	config ATH10K_API2_FW
  		bool "Firmware optimized for AP operation (v10.1 / API v2)"
  		bool "Firmware optimized for AP operation (v10.1 / API v2)"
-@@ -630,6 +649,13 @@ define KernelPackage/ath10k/config
+-		default n
+-		depends on !ATH10K_STA_FW
+ 		help
  		  Use the ath10k firmware from the 10.1 SDK using API v2 optimized
  		  Use the ath10k firmware from the 10.1 SDK using API v2 optimized
  		  for access point operation if the default firmware keeps crashing.
  		  for access point operation if the default firmware keeps crashing.
  
  
-+	config ATH10K_CT_COMMUNITY_FW
-+		bool "Firmware by Candela Technologies (community version)"
-+		help
-+		  Supports both AP and IBSS (ad-hoc) mode. Doesn't support
-+		  encryption when using multiple VIFs.
-+
 +	endchoice
 +	endchoice
    endif
    endif
  endef
  endef
  
  
-@@ -1885,11 +1911,17 @@ ifeq ($(CONFIG_ATH10K_API2_FW),y)
+@@ -1866,18 +1890,25 @@ define KernelPackage/ath10k/install
+ 	$(INSTALL_DATA) \
+ 		$(PKG_BUILD_DIR)/$(PKG_ATH10K_LINUX_FIRMWARE_SUBDIR)/ath10k/QCA988X/hw2.0/board.bin \
+ 		$(1)/lib/firmware/ath10k/QCA988X/hw2.0/
++ifeq ($(CONFIG_ATH10K_AP_FW),y)
++	$(INSTALL_DATA) \
++		$(PKG_BUILD_DIR)/$(PKG_ATH10K_LINUX_FIRMWARE_SUBDIR)/10.2.4/firmware-4.bin_10.2.4.45 \
++		$(1)/lib/firmware/ath10k/QCA988X/hw2.0/firmware-4.bin
++endif
+ ifeq ($(CONFIG_ATH10K_STA_FW),y)
+ 	$(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 ifeq ($(CONFIG_ATH10K_API2_FW),y)
++endif
++ifeq ($(CONFIG_ATH10K_API2_FW),y)
  	$(INSTALL_DATA) \
  	$(INSTALL_DATA) \
  		$(PKG_BUILD_DIR)/$(PKG_ATH10K_LINUX_FIRMWARE_SUBDIR)/10.1/firmware-2.bin_10.1.467.2-1 \
  		$(PKG_BUILD_DIR)/$(PKG_ATH10K_LINUX_FIRMWARE_SUBDIR)/10.1/firmware-2.bin_10.1.467.2-1 \
  		$(1)/lib/firmware/ath10k/QCA988X/hw2.0/firmware-2.bin
  		$(1)/lib/firmware/ath10k/QCA988X/hw2.0/firmware-2.bin
 -else
 -else
 +endif
 +endif
-+ifeq ($(CONFIG_ATH10K_AP_FW),y)
- 	$(INSTALL_DATA) \
- 		$(PKG_BUILD_DIR)/$(PKG_ATH10K_LINUX_FIRMWARE_SUBDIR)/10.2.4/untested/firmware-5.bin_10.2.4.70-2 \
- 		$(1)/lib/firmware/ath10k/QCA988X/hw2.0/firmware-5.bin
- endif
 +ifeq ($(CONFIG_ATH10K_CT_COMMUNITY_FW),y)
 +ifeq ($(CONFIG_ATH10K_CT_COMMUNITY_FW),y)
-+	$(INSTALL_DATA) \
+ 	$(INSTALL_DATA) \
+-		$(PKG_BUILD_DIR)/$(PKG_ATH10K_LINUX_FIRMWARE_SUBDIR)/10.2.4/firmware-4.bin_10.2.4.45 \
+-		$(1)/lib/firmware/ath10k/QCA988X/hw2.0/firmware-4.bin
 +		$(DL_DIR)/$(ATH10K_CT_COMMUNITY_FW) \
 +		$(DL_DIR)/$(ATH10K_CT_COMMUNITY_FW) \
 +		$(1)/lib/firmware/ath10k/QCA988X/hw2.0/firmware-2.bin
 +		$(1)/lib/firmware/ath10k/QCA988X/hw2.0/firmware-2.bin
-+endif
+ endif
  endef
  endef
  
  
- define KernelPackage/mt7601u/install

+ 0 - 0
patches/openwrt/0005-base-files-disable-reset-button-handling.patch → patches/openwrt/0006-base-files-disable-reset-button-handling.patch


+ 0 - 20504
patches/openwrt/0006-mac80211-backport-from-trunk-r46760.patch

@@ -1,20504 +0,0 @@
-From: Matthias Schiffer <mschiffer@universe-factory.net>
-Date: Tue, 1 Sep 2015 18:50:16 +0200
-Subject: mac80211: backport from trunk r46760
-
-diff --git a/package/kernel/mac80211/Makefile b/package/kernel/mac80211/Makefile
-index a1eedce..04dfd3b 100644
---- a/package/kernel/mac80211/Makefile
-+++ b/package/kernel/mac80211/Makefile
-@@ -10,11 +10,11 @@ include $(INCLUDE_DIR)/kernel.mk
- 
- PKG_NAME:=mac80211
- 
--PKG_VERSION:=2015-03-09
--PKG_RELEASE:=3
-+PKG_VERSION:=2015-07-21
-+PKG_RELEASE:=1
- PKG_SOURCE_URL:=http://mirror2.openwrt.org/sources
- PKG_BACKPORT_VERSION:=
--PKG_MD5SUM:=6d4b04e4ce8a1f54dabfb04f4709453c
-+PKG_MD5SUM:=ec529acfb9c942daf8116e5cff47c999
- 
- PKG_SOURCE:=compat-wireless-$(PKG_VERSION)$(PKG_BACKPORT_VERSION).tar.bz2
- PKG_BUILD_DIR:=$(KERNEL_BUILD_DIR)/compat-wireless-$(PKG_VERSION)
-@@ -31,7 +31,7 @@ PKG_DRIVERS = \
- 	mwl8k mwifiex-pcie net-hermes net-hermes-pci net-hermes-plx net-hermes-pcmcia \
- 	iwl-legacy iwl3945 iwl4965 iwlagn wlcore wl12xx wl18xx lib80211 \
- 	rtlwifi rtlwifi-pci rtlwifi-usb rtl8192c-common rtl8192ce rtl8192se \
--	rtl8192de rtl8192cu
-+	rtl8192de rtl8192cu mt7601u
- 
- PKG_CONFIG_DEPENDS:= \
- 	CONFIG_PACKAGE_kmod-mac80211 \
-@@ -60,7 +60,6 @@ define KernelPackage/mac80211/Default
-   SUBMENU:=$(WMENU)
-   URL:=https://wireless.wiki.kernel.org/
-   MAINTAINER:=Felix Fietkau <nbd@openwrt.org>
--  DEPENDS:=@!TARGET_uml
- endef
- 
- define KernelPackage/cfg80211
-@@ -79,7 +78,7 @@ endef
- define KernelPackage/mac80211
-   $(call KernelPackage/mac80211/Default)
-   TITLE:=Linux 802.11 Wireless Networking Stack
--  DEPENDS+= +kmod-crypto-core +kmod-crypto-arc4 +kmod-crypto-aes +kmod-cfg80211 +hostapd-common
-+  DEPENDS+= +kmod-crypto-core +kmod-crypto-arc4 +kmod-cfg80211 +hostapd-common
-   KCONFIG:=\
- 	CONFIG_AVERAGE=y
-   FILES:= $(PKG_BUILD_DIR)/net/mac80211/mac80211.ko
-@@ -128,7 +127,7 @@ endef
- $(eval $(call Download,linux-firmware))
- 
- PKG_ATH10K_LINUX_FIRMWARE_NAME:=ath10k-firmware
--PKG_ATH10K_LINUX_FIRMWARE_VERSION:=da0f85d924226ee30c46e037120621c9e192b39e
-+PKG_ATH10K_LINUX_FIRMWARE_VERSION:=b46f3e01a6c1f9150fb4612ef53611d714565842
- 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
-@@ -516,7 +515,7 @@ define KernelPackage/ath/config
- 		bool "Atheros wireless debugging"
- 		help
- 		  Say Y, if you want to debug atheros wireless drivers.
--		  Right now only ath9k makes use of this.
-+		  Only ath9k & ath10k make use of this.
- 
- 	config PACKAGE_ATH_DFS
- 		bool "Enable DFS support"
-@@ -624,17 +623,9 @@ 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.
--
- 	config ATH10K_API2_FW
- 		bool "Firmware optimized for AP operation (v10.1 / API v2)"
- 		default n
--		depends on !ATH10K_STA_FW
- 		help
- 		  Use the ath10k firmware from the 10.1 SDK using API v2 optimized
- 		  for access point operation if the default firmware keeps crashing.
-@@ -704,10 +695,31 @@ define KernelPackage/mac80211-hwsim
-   AUTOLOAD:=$(call AutoProbe,mac80211_hwsim)
- endef
- 
-+PKG_MT7601U_FW_NAME:=DPO_MT7601U_LinuxSTA
-+PKG_MT7601U_FW_VERSION:=3.0.0.4_20130913
-+PKG_MT7601U_FW_MD5SUM:=5f440dccc8bc952745a191994fc34699
-+PKG_MT7601U_FW_SOURCE:=$(PKG_MT7601U_FW_NAME)_$(PKG_MT7601U_FW_VERSION).tar.bz2
-+PKG_MT7601U_FW_SOURCE_URL:=http://www.mediatek.com/AmazonS3/Downloads/linux/
-+define Download/mt7601u-firmware
-+  FILE:=$(PKG_MT7601U_FW_SOURCE)
-+  URL:=$(PKG_MT7601U_FW_SOURCE_URL)
-+  MD5SUM:=$(PKG_MT7601U_FW_MD5SUM)
-+  SUBDIR:=$(PKG_MT7601U_FW_NAME)_$(PKG_MT7601U_FW_VERSION)
-+endef
-+$(eval $(call Download,mt7601u-firmware))
-+
-+define KernelPackage/mt7601u
-+  $(call KernelPackage/mac80211/Default)
-+  TITLE:=MT7601U-based USB dongles Wireless Driver
-+  DEPENDS+= +kmod-mac80211 +@DRIVER_11N_SUPPORT @USB_SUPPORT +kmod-usb-core
-+  FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/mediatek/mt7601u/mt7601u.ko
-+  AUTOLOAD:=$(call AutoProbe,mt7601)
-+endef
-+
- define KernelPackage/net-libipw
-   $(call KernelPackage/mac80211/Default)
-   TITLE:=libipw for ipw2100 and ipw2200
--  DEPENDS:=@PCI_SUPPORT +kmod-crypto-core +kmod-crypto-arc4 +kmod-crypto-aes +kmod-crypto-michael-mic +kmod-lib80211 +kmod-cfg80211 +@DRIVER_WEXT_SUPPORT @!BIG_ENDIAN
-+  DEPENDS:=@PCI_SUPPORT +kmod-crypto-core +kmod-crypto-arc4 +kmod-crypto-michael-mic +kmod-lib80211 +kmod-cfg80211 +@DRIVER_WEXT_SUPPORT @!BIG_ENDIAN
-   FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/ipw2x00/libipw.ko
-   AUTOLOAD:=$(call AutoProbe,libipw)
- endef
-@@ -1602,6 +1614,8 @@ config-$(CONFIG_BRCMFMAC_PCIE) += BRCMFMAC_PCIE
- config-$(CONFIG_PACKAGE_BRCM80211_DEBUG) += BRCMDBG
- 
- config-$(call config_package,mac80211-hwsim) += MAC80211_HWSIM
-+config-$(call config_package,mt7601u) += MT7601U
-+config-y += WL_MEDIATEK
- 
- config-$(call config_package,rt2x00-lib) += RT2X00 RT2X00_LIB
- config-$(call config_package,rt2x00-pci) += RT2X00_LIB_PCI
-@@ -1704,6 +1718,7 @@ define Build/Prepare
- 	$(TAR) -C $(PKG_BUILD_DIR) -xjf $(DL_DIR)/$(ZD1211FW_NAME)-$(ZD1211FW_VERSION).tar.bz2
- 	$(TAR) -C $(PKG_BUILD_DIR) -xjf $(DL_DIR)/$(PKG_LINUX_FIRMWARE_SOURCE)
- 	$(TAR) -C $(PKG_BUILD_DIR) -xjf $(DL_DIR)/$(PKG_ATH10K_LINUX_FIRMWARE_SOURCE)
-+	$(TAR) -C $(PKG_BUILD_DIR) -xjf $(DL_DIR)/$(PKG_MT7601U_FW_SOURCE)
- 	rm -rf \
- 		$(PKG_BUILD_DIR)/include/linux/ssb \
- 		$(PKG_BUILD_DIR)/include/linux/bcma \
-@@ -1866,21 +1881,24 @@ define KernelPackage/ath10k/install
- 	$(INSTALL_DATA) \
- 		$(PKG_BUILD_DIR)/$(PKG_ATH10K_LINUX_FIRMWARE_SUBDIR)/ath10k/QCA988X/hw2.0/board.bin \
- 		$(1)/lib/firmware/ath10k/QCA988X/hw2.0/
--ifeq ($(CONFIG_ATH10K_STA_FW),y)
--	$(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 ifeq ($(CONFIG_ATH10K_API2_FW),y)
-+ifeq ($(CONFIG_ATH10K_API2_FW),y)
- 	$(INSTALL_DATA) \
- 		$(PKG_BUILD_DIR)/$(PKG_ATH10K_LINUX_FIRMWARE_SUBDIR)/10.1/firmware-2.bin_10.1.467.2-1 \
- 		$(1)/lib/firmware/ath10k/QCA988X/hw2.0/firmware-2.bin
- else
- 	$(INSTALL_DATA) \
--		$(PKG_BUILD_DIR)/$(PKG_ATH10K_LINUX_FIRMWARE_SUBDIR)/10.2.4/firmware-4.bin_10.2.4.45 \
--		$(1)/lib/firmware/ath10k/QCA988X/hw2.0/firmware-4.bin
-+		$(PKG_BUILD_DIR)/$(PKG_ATH10K_LINUX_FIRMWARE_SUBDIR)/10.2.4/untested/firmware-5.bin_10.2.4.70-2 \
-+		$(1)/lib/firmware/ath10k/QCA988X/hw2.0/firmware-5.bin
- endif
- endef
- 
-+define KernelPackage/mt7601u/install
-+	$(INSTALL_DIR) $(1)/lib/firmware
-+	$(INSTALL_DATA) \
-+		$(PKG_BUILD_DIR)/$(PKG_MT7601U_FW_NAME)_$(PKG_MT7601U_FW_VERSION)/mcu/bin/MT7601.bin \
-+		$(1)/lib/firmware/mt7601u.bin
-+endef
-+
- define KernelPackage/mwl8k/install
- 	$(INSTALL_DIR) $(1)/lib/firmware/mwl8k
- 	$(INSTALL_DATA) \
-@@ -2065,6 +2083,7 @@ $(eval $(call KernelPackage,rtl8192de))
- $(eval $(call KernelPackage,rtl8192cu))
- $(eval $(call KernelPackage,zd1211rw))
- $(eval $(call KernelPackage,mac80211-hwsim))
-+$(eval $(call KernelPackage,mt7601u))
- $(eval $(call KernelPackage,ath9k-common))
- $(eval $(call KernelPackage,ath9k))
- $(eval $(call KernelPackage,ath9k-htc))
-diff --git a/package/kernel/mac80211/files/regdb.txt b/package/kernel/mac80211/files/regdb.txt
-index ba95fc6..84413fd 100644
---- a/package/kernel/mac80211/files/regdb.txt
-+++ b/package/kernel/mac80211/files/regdb.txt
-@@ -6,7 +6,7 @@ country 00:
- 	# Channel 14. Only JP enables this and for 802.11b only
- 	(2474 - 2494 @ 20), (20), NO-IR, NO-OFDM
- 	# Channel 36 - 48
--	(5170 - 5250 @ 80), (20)
-+	(5170 - 5250 @ 80), (20), AUTO-BW
- 	# Channel 52 - 64
- 	(5250 - 5330 @ 80), (20), NO-IR, DFS, AUTO-BW
- 	# Channel 100 - 144
-@@ -54,8 +54,8 @@ country AL: DFS-ETSI
- 
- country AM: DFS-ETSI
- 	(2402 - 2482 @ 40), (20)
--	(5170 - 5250 @ 80), (18)
--	(5250 - 5330 @ 80), (18), DFS
-+	(5170 - 5250 @ 20), (18)
-+	(5250 - 5330 @ 20), (18), DFS
- 
- country AN: DFS-ETSI
- 	(2402 - 2482 @ 40), (20)
-@@ -85,7 +85,7 @@ country AT: DFS-ETSI
- 	# 60 gHz band channels 1-4, ref: Etsi En 302 567
- 	(57000 - 66000 @ 2160), (40)
- 
--country AU:
-+country AU: DFS-ETSI
- 	(2402 - 2482 @ 40), (20)
- 	(5170 - 5250 @ 80), (17), AUTO-BW
- 	(5250 - 5330 @ 80), (24), DFS, AUTO-BW
-@@ -141,14 +141,20 @@ country BG: DFS-ETSI
- 	(5170 - 5250 @ 80), (20), AUTO-BW
- 	(5250 - 5330 @ 80), (20), DFS, AUTO-BW
- 	(5490 - 5710 @ 160), (27), DFS
-+	# 5 gHz Short Range Devices, ref:
-+	# Etsi EN 300 440-1
-+	# Etsi EN 300 440-2
-+	# http://crc.bg/files/_bg/Spisak_2015.pdf
-+	# http://crc.bg/files/_bg/Pravila_2015_resh24.pdf
-+	(5725 - 5875 @ 80), (14)
- 	# 60 gHz band channels 1-4, ref: Etsi En 302 567
- 	(57000 - 66000 @ 2160), (40)
- 
- country BH: DFS-JP
- 	(2402 - 2482 @ 40), (20)
--	(5170 - 5250 @ 80), (20)
--	(5250 - 5330 @ 80), (20), DFS
--	(5735 - 5835 @ 80), (20)
-+	(5170 - 5250 @ 20), (20)
-+	(5250 - 5330 @ 20), (20), DFS
-+	(5735 - 5835 @ 20), (20)
- 
- country BL: DFS-ETSI
- 	(2402 - 2482 @ 40), (20)
-@@ -263,10 +269,10 @@ country CO: DFS-FCC
- 
- 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)
-+	(5170 - 5250 @ 20), (17)
-+	(5250 - 5330 @ 20), (24), DFS
-+	(5490 - 5730 @ 20), (24), DFS
-+	(5735 - 5835 @ 20), (30)
- 
- country CX: DFS-FCC
- 	(2402 - 2482 @ 40), (20)
-@@ -349,10 +355,10 @@ country DZ: DFS-JP
- 
- 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)
-+	(5170 - 5250 @ 20), (17)
-+	(5250 - 5330 @ 20), (24), DFS
-+	(5490 - 5730 @ 20), (24), DFS
-+	(5735 - 5835 @ 20), (30)
- 
- country EE: DFS-ETSI
- 	(2402 - 2482 @ 40), (20)
-@@ -364,8 +370,8 @@ country EE: DFS-ETSI
- 
- country EG: DFS-ETSI
- 	(2402 - 2482 @ 40), (20)
--	(5170 - 5250 @ 80), (20)
--	(5250 - 5330 @ 80), (20), DFS
-+	(5170 - 5250 @ 40), (20)
-+	(5250 - 5330 @ 40), (20), DFS
- 
- # Orden IET/787/2013, de 25 de abril, por la que se aprueba
- # el cuadro nacional de atribución de frecuencias.
-@@ -474,10 +480,10 @@ country GT: DFS-FCC
- 
- 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)
-+	(5170 - 5250 @ 20), (17)
-+	(5250 - 5330 @ 20), (24), DFS
-+	(5490 - 5730 @ 20), (24), DFS
-+	(5735 - 5835 @ 20), (30)
- 
- country GY:
- 	(2402 - 2482 @ 40), (30)
-@@ -522,8 +528,8 @@ country HU: DFS-ETSI
- 
- country ID: DFS-JP
- 	# ref: http://www.postel.go.id/content/ID/regulasi/standardisasi/kepdir/bwa%205,8%20ghz.pdf
--	(2402 - 2482 @ 40), (20)
--	(5735 - 5815 @ 80), (23)
-+	(2402 - 2482 @ 20), (20)
-+	(5735 - 5815 @ 20), (23)
- 
- country IE: DFS-ETSI
- 	(2402 - 2482 @ 40), (20)
-@@ -584,6 +590,9 @@ country JP: DFS-JP
- 	(5170 - 5250 @ 80), (20), AUTO-BW
- 	(5250 - 5330 @ 80), (20), DFS, AUTO-BW
- 	(5490 - 5710 @ 160), (23), DFS
-+	# 60 GHz band channels 2-4 at 10mW,
-+	# ref: http://www.arib.or.jp/english/html/overview/doc/1-STD-T74v1_1.pdf
-+	(59000 - 66000 @ 2160), (10 mW)
- 
- country KE: DFS-JP
- 	(2402 - 2482 @ 40), (20)
-@@ -607,11 +616,11 @@ country KN: DFS-ETSI
- 	(5735 - 5815 @ 80), (30)
- 
- country KP: DFS-JP
--	(2402 - 2482 @ 40), (20)
--	(5170 - 5250 @ 80), (20), AUTO-BW
--	(5250 - 5330 @ 80), (20), DFS, AUTO-BW
--	(5490 - 5630 @ 80), (30), DFS
--	(5735 - 5815 @ 80), (30)
-+	(2402 - 2482 @ 20), (20)
-+	(5170 - 5250 @ 20), (20)
-+	(5250 - 5330 @ 20), (20), DFS
-+	(5490 - 5630 @ 20), (30), DFS
-+	(5735 - 5815 @ 20), (30)
- 
- country KR: DFS-JP
- 	(2402 - 2482 @ 40), (20)
-@@ -659,10 +668,10 @@ country LI: DFS-ETSI
- 
- 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)
-+	(5170 - 5250 @ 20), (17)
-+	(5250 - 5330 @ 20), (24), DFS
-+	(5490 - 5730 @ 20), (24), DFS
-+	(5735 - 5835 @ 20), (30)
- 
- # Source:
- # http://lca.org.ls/images/documents/lesotho_national_frequency_allocation_plan.pdf
-@@ -751,11 +760,12 @@ country MN: DFS-FCC
- 	(5490 - 5730 @ 160), (24), DFS
- 	(5735 - 5835 @ 80), (30)
- 
--country MO:
--	(2402 - 2482 @ 40), (20)
--	(5170 - 5250 @ 40), (23)
--	(5250 - 5330 @ 40), (23), DFS
--	(5735 - 5835 @ 40), (30)
-+country MO: DFS-FCC
-+	(2402 - 2482 @ 40), (23)
-+	(5170 - 5250 @ 80), (23), AUTO-BW
-+	(5250 - 5330 @ 80), (23), DFS, AUTO-BW
-+	(5490 - 5730 @ 160), (30), DFS
-+	(5735 - 5835 @ 80), (30)
- 
- country MP: DFS-FCC
- 	(2402 - 2472 @ 40), (30)
-@@ -793,6 +803,14 @@ country MU: DFS-FCC
- 	(5490 - 5730 @ 160), (24), DFS
- 	(5735 - 5835 @ 80), (30)
- 
-+# Source:
-+# http://www.cam.gov.mv/docs/tech_standards/TAM-TS-100-2004-WLAN.pdf
-+country MV: DFS-ETSI
-+	(2400 - 2483.5 @ 40), (100 mW)
-+	(5150 - 5250 @ 80), (200 mW), AUTO-BW
-+	(5250 - 5350 @ 80), (100 mW), DFS, AUTO-BW
-+	(5725 - 5850 @ 80), (100 mW)
-+
- country MW: DFS-ETSI
- 	(2402 - 2482 @ 40), (20)
- 	(5170 - 5250 @ 80), (20), AUTO-BW
-@@ -812,6 +830,11 @@ country MY: DFS-FCC
- 	(5250 - 5330 @ 80), (23), DFS, AUTO-BW
- 	(5735 - 5835 @ 80), (30)
- 
-+country NG: DFS-ETSI
-+	(2402 - 2482 @ 40), (20)
-+	(5250 - 5330 @ 80), (30), DFS
-+	(5735 - 5835 @ 80), (30)
-+
- country NI: DFS-FCC
- 	(2402 - 2472 @ 40), (30)
- 	(5170 - 5250 @ 80), (24), AUTO-BW
-@@ -848,7 +871,7 @@ country NP: DFS-JP
- 	(5250 - 5330 @ 80), (20), DFS, AUTO-BW
- 	(5735 - 5835 @ 80), (20)
- 
--country NZ: DFS-FCC
-+country NZ: DFS-ETSI
- 	(2402 - 2482 @ 40), (30)
- 	(5170 - 5250 @ 80), (17), AUTO-BW
- 	(5250 - 5330 @ 80), (24), DFS, AUTO-BW
-@@ -971,10 +994,12 @@ country RS: DFS-ETSI
- 
- 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)
-+	(5170 - 5250 @ 40), (20)
-+	(5250 - 5330 @ 40), (20), DFS
-+	(5650 - 5730 @ 40), (30), DFS
-+	(5735 - 5835 @ 40), (30)
-+	# 60 GHz band channels 1-4, ref: Changes to NLA 124_Order №129_22042015.pdf
-+	(57000 - 66000 @ 2160), (40)
- 
- country RW: DFS-FCC
- 	(2402 - 2482 @ 40), (20)
-@@ -1037,9 +1062,9 @@ country SR: DFS-ETSI
- 
- country SV: DFS-FCC
- 	(2402 - 2482 @ 40), (20)
--	(5170 - 5250 @ 80), (17)
--	(5250 - 5330 @ 80), (23), DFS
--	(5735 - 5835 @ 80), (30)
-+	(5170 - 5250 @ 20), (17)
-+	(5250 - 5330 @ 20), (23), DFS
-+	(5735 - 5835 @ 20), (30)
- 
- country SY:
- 	(2402 - 2482 @ 40), (20)
-@@ -1099,6 +1124,10 @@ country TW: DFS-JP
- 	(5650 - 5710 @ 40), (30), DFS
- 	(5735 - 5835 @ 80), (30)
-  
-+country TZ:
-+	(2402 - 2482 @ 40), (20)
-+	(5735 - 5835 @ 80), (30)
-+
- # Source:
- # #914 / 06 Sep 2007: http://www.ucrf.gov.ua/uk/doc/nkrz/1196068874
- # #1174 / 23 Oct 2008: http://www.nkrz.gov.ua/uk/activities/ruling/1225269361
-@@ -1125,6 +1154,7 @@ country US: DFS-FCC
- 	(2402 - 2472 @ 40), (30)
- 	(5170 - 5250 @ 80), (17), AUTO-BW
- 	(5250 - 5330 @ 80), (23), DFS, AUTO-BW
-+	(5490 - 5730 @ 160), (23), DFS
- 	(5735 - 5835 @ 80), (30)
- 	# 60g band
- 	# reference: http://cfr.regstoday.com/47cfr15.aspx#47_CFR_15p255
-@@ -1192,6 +1222,12 @@ country WF: DFS-ETSI
- 	(5250 - 5330 @ 80), (20), DFS, AUTO-BW
- 	(5490 - 5710 @ 160), (27), DFS
- 
-+country WS: DFS-ETSI
-+	(2402 - 2482 @ 40), (20)
-+	(5170 - 5250 @ 40), (20)
-+	(5250 - 5330 @ 40), (20), DFS
-+	(5490 - 5710 @ 40), (27), DFS
-+
- country YE:
- 	(2402 - 2482 @ 40), (20)
- 
-diff --git a/package/kernel/mac80211/patches/001-fix_build.patch b/package/kernel/mac80211/patches/001-fix_build.patch
-index 818983e..402649d 100644
---- a/package/kernel/mac80211/patches/001-fix_build.patch
-+++ b/package/kernel/mac80211/patches/001-fix_build.patch
-@@ -27,7 +27,7 @@
-  	@set -e ; test -f .local-symbols || (						\
-  	echo "/--------------"								;\
-  	echo "| You shouldn't run make in the backports tree, but only in"		;\
--@@ -60,56 +62,60 @@ mrproper:
-+@@ -60,57 +62,61 @@ mrproper:
-  	echo "| (that isn't currently running.)"					;\
-  	echo "\\--"									;\
-  	false)
-@@ -56,11 +56,12 @@
- -			done								\
- -		) > Kconfig.kernel							;\
- -		kver=$$($(MAKE) --no-print-directory -C $(KLIB_BUILD) kernelversion |	\
---			sed 's/^\(\(3\|2\.6\)\.[0-9]\+\).*/\1/;t;d')			;\
-+-			sed 's/^\(\([3-4]\|2\.6\)\.[0-9]\+\).*/\1/;t;d')		;\
- -		test "$$kver" != "" || echo "Kernel version parse failed!"		;\
- -		test "$$kver" != ""							;\
- -		kvers="$$(seq 14 39 | sed 's/^/2.6./')"					;\
---		kvers="$$kvers $$(seq 0 99 | sed 's/^/3./')"				;\
-+-		kvers="$$kvers $$(seq 0 19 | sed 's/^/3./')"				;\
-+-		kvers="$$kvers $$(seq 0 99 | sed 's/^/4./')"				;\
- -		print=0									;\
- -		for v in $$kvers ; do							\
- -			if [ "$$print" = "1" ] ; then					\
-@@ -111,11 +112,12 @@
- +
- +Kconfig.versions: Kconfig.kernel
- +	@kver=$$($(MAKE) --no-print-directory -C $(KLIB_BUILD) kernelversion |	\
--+		sed 's/^\(\(3\|2\.6\)\.[0-9]\+\).*/\1/;t;d')			;\
-++		sed 's/^\(\([3-4]\|2\.6\)\.[0-9]\+\).*/\1/;t;d')		;\
- +	test "$$kver" != "" || echo "Kernel version parse failed!"		;\
- +	test "$$kver" != ""							;\
- +	kvers="$$(seq 14 39 | sed 's/^/2.6./')"					;\
--+	kvers="$$kvers $$(seq 0 99 | sed 's/^/3./')"				;\
-++	kvers="$$kvers $$(seq 0 19 | sed 's/^/3./')"				;\
-++	kvers="$$kvers $$(seq 0 99 | sed 's/^/4./')"				;\
- +	print=0									;\
- +	for v in $$kvers ; do							\
- +		if [ "$$print" = "1" ] ; then					\
-diff --git a/package/kernel/mac80211/patches/004-backports_debugfs_fix.patch b/package/kernel/mac80211/patches/004-backports_debugfs_fix.patch
-deleted file mode 100644
-index d48a723..0000000
---- a/package/kernel/mac80211/patches/004-backports_debugfs_fix.patch
-+++ /dev/null
-@@ -1,10 +0,0 @@
----- a/backport-include/linux/debugfs.h
--+++ b/backport-include/linux/debugfs.h
--@@ -3,6 +3,7 @@
-- #include_next <linux/debugfs.h>
-- #include <linux/version.h>
-- #include <generated/utsrelease.h>
--+#include <linux/device.h>
-- 
-- #if defined(CONFIG_DEBUG_FS)
-- struct dentry *debugfs_create_devm_seqfile(struct device *dev, const char *name,
-diff --git a/package/kernel/mac80211/patches/008-fix_netdev_unregister.patch b/package/kernel/mac80211/patches/008-fix_netdev_unregister.patch
-deleted file mode 100644
-index e07f323..0000000
---- a/package/kernel/mac80211/patches/008-fix_netdev_unregister.patch
-+++ /dev/null
-@@ -1,16 +0,0 @@
----- a/net/mac80211/iface.c
--+++ b/net/mac80211/iface.c
--@@ -1858,6 +1858,13 @@ void ieee80211_remove_interfaces(struct
-- 	}
-- 	mutex_unlock(&local->iflist_mtx);
-- 	unregister_netdevice_many(&unreg_list);
--+#if (!(LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,45) && \
--+       LINUX_VERSION_CODE < KERNEL_VERSION(3,11,0)) && \
--+     !(LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,9) && \
--+       LINUX_VERSION_CODE < KERNEL_VERSION(3,15,0)) && \
--+     (LINUX_VERSION_CODE < KERNEL_VERSION(3,16,0)))
--+	list_del(&unreg_list);
--+#endif
-- 
-- 	list_for_each_entry_safe(sdata, tmp, &wdev_list, list) {
-- 		list_del(&sdata->list);
-diff --git a/package/kernel/mac80211/patches/020-add_mpls_h.patch b/package/kernel/mac80211/patches/020-add_mpls_h.patch
-deleted file mode 100644
-index e5310bc..0000000
---- a/package/kernel/mac80211/patches/020-add_mpls_h.patch
-+++ /dev/null
-@@ -1,37 +0,0 @@
----- /dev/null
--+++ b/include/uapi/linux/mpls.h
--@@ -0,0 +1,34 @@
--+#ifndef _UAPI_MPLS_H
--+#define _UAPI_MPLS_H
--+
--+#include <linux/types.h>
--+#include <asm/byteorder.h>
--+
--+/* Reference: RFC 5462, RFC 3032
--+ *
--+ *  0                   1                   2                   3
--+ *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
--+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
--+ * |                Label                  | TC  |S|       TTL     |
--+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
--+ *
--+ *	Label:  Label Value, 20 bits
--+ *	TC:     Traffic Class field, 3 bits
--+ *	S:      Bottom of Stack, 1 bit
--+ *	TTL:    Time to Live, 8 bits
--+ */
--+
--+struct mpls_label {
--+	__be32 entry;
--+};
--+
--+#define MPLS_LS_LABEL_MASK      0xFFFFF000
--+#define MPLS_LS_LABEL_SHIFT     12
--+#define MPLS_LS_TC_MASK         0x00000E00
--+#define MPLS_LS_TC_SHIFT        9
--+#define MPLS_LS_S_MASK          0x00000100
--+#define MPLS_LS_S_SHIFT         8
--+#define MPLS_LS_TTL_MASK        0x000000FF
--+#define MPLS_LS_TTL_SHIFT       0
--+
--+#endif /* _UAPI_MPLS_H */
-diff --git a/package/kernel/mac80211/patches/020-backports-do-not-add-debugfs_create_devm_seqfile-on-.patch b/package/kernel/mac80211/patches/020-backports-do-not-add-debugfs_create_devm_seqfile-on-.patch
-new file mode 100644
-index 0000000..97f678c
---- /dev/null
-+++ b/package/kernel/mac80211/patches/020-backports-do-not-add-debugfs_create_devm_seqfile-on-.patch
-@@ -0,0 +1,33 @@
-+From e15e9231e7a9f81f5264d294fd3fd96a20d92516 Mon Sep 17 00:00:00 2001
-+From: Hauke Mehrtens <hauke@hauke-m.de>
-+Date: Sat, 25 Jul 2015 15:19:17 +0200
-+Subject: [PATCH 3/3] backports: do not add debugfs_create_devm_seqfile() on
-+ recent kernel versions
-+
-+An #ifdef for the kernel version was missing around the header of
-+debugfs_create_devm_seqfile() and the LINUX_BACKPORT() was also not
-+done.
-+
-+Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
-+---
-+ backport/backport-include/linux/debugfs.h | 3 +++
-+ 1 file changed, 3 insertions(+)
-+
-+--- a/backport-include/linux/debugfs.h
-++++ b/backport-include/linux/debugfs.h
-+@@ -5,6 +5,8 @@
-+ #include <linux/device.h>
-+ #include <generated/utsrelease.h>
-+ 
-++#if LINUX_VERSION_CODE < KERNEL_VERSION(3,19,0)
-++#define debugfs_create_devm_seqfile LINUX_BACKPORT(debugfs_create_devm_seqfile)
-+ #if defined(CONFIG_DEBUG_FS)
-+ struct dentry *debugfs_create_devm_seqfile(struct device *dev, const char *name,
-+ 					   struct dentry *parent,
-+@@ -20,5 +22,6 @@ static inline struct dentry *debugfs_cre
-+ 	return ERR_PTR(-ENODEV);
-+ }
-+ #endif /* CONFIG_DEBUG_FS */
-++#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(3,19,0) */
-+ 
-+ #endif /* __BACKPORT_DEBUGFS_H_ */
-diff --git a/package/kernel/mac80211/patches/045-bcma-from-4.1.patch b/package/kernel/mac80211/patches/045-bcma-from-4.1.patch
-deleted file mode 100644
-index dce217f..0000000
---- a/package/kernel/mac80211/patches/045-bcma-from-4.1.patch
-+++ /dev/null
-@@ -1,104 +0,0 @@
----- a/drivers/bcma/driver_pci.c
--+++ b/drivers/bcma/driver_pci.c
--@@ -282,39 +282,6 @@ void bcma_core_pci_power_save(struct bcm
-- }
-- EXPORT_SYMBOL_GPL(bcma_core_pci_power_save);
-- 
---int bcma_core_pci_irq_ctl(struct bcma_bus *bus, struct bcma_device *core,
---			  bool enable)
---{
---	struct pci_dev *pdev;
---	u32 coremask, tmp;
---	int err = 0;
---
---	if (bus->hosttype != BCMA_HOSTTYPE_PCI) {
---		/* This bcma device is not on a PCI host-bus. So the IRQs are
---		 * not routed through the PCI core.
---		 * So we must not enable routing through the PCI core. */
---		goto out;
---	}
---
---	pdev = bus->host_pci;
---
---	err = pci_read_config_dword(pdev, BCMA_PCI_IRQMASK, &tmp);
---	if (err)
---		goto out;
---
---	coremask = BIT(core->core_index) << 8;
---	if (enable)
---		tmp |= coremask;
---	else
---		tmp &= ~coremask;
---
---	err = pci_write_config_dword(pdev, BCMA_PCI_IRQMASK, tmp);
---
---out:
---	return err;
---}
---EXPORT_SYMBOL_GPL(bcma_core_pci_irq_ctl);
---
-- static void bcma_core_pci_extend_L1timer(struct bcma_drv_pci *pc, bool extend)
-- {
-- 	u32 w;
----- a/drivers/bcma/host_pci.c
--+++ b/drivers/bcma/host_pci.c
--@@ -351,3 +351,37 @@ void bcma_host_pci_down(struct bcma_bus
-- 		bcma_core_pci_down(&bus->drv_pci[0]);
-- }
-- EXPORT_SYMBOL_GPL(bcma_host_pci_down);
--+
--+/* See also si_pci_setup */
--+int bcma_host_pci_irq_ctl(struct bcma_bus *bus, struct bcma_device *core,
--+			  bool enable)
--+{
--+	struct pci_dev *pdev;
--+	u32 coremask, tmp;
--+	int err = 0;
--+
--+	if (bus->hosttype != BCMA_HOSTTYPE_PCI) {
--+		/* This bcma device is not on a PCI host-bus. So the IRQs are
--+		 * not routed through the PCI core.
--+		 * So we must not enable routing through the PCI core. */
--+		goto out;
--+	}
--+
--+	pdev = bus->host_pci;
--+
--+	err = pci_read_config_dword(pdev, BCMA_PCI_IRQMASK, &tmp);
--+	if (err)
--+		goto out;
--+
--+	coremask = BIT(core->core_index) << 8;
--+	if (enable)
--+		tmp |= coremask;
--+	else
--+		tmp &= ~coremask;
--+
--+	err = pci_write_config_dword(pdev, BCMA_PCI_IRQMASK, tmp);
--+
--+out:
--+	return err;
--+}
--+EXPORT_SYMBOL_GPL(bcma_host_pci_irq_ctl);
----- a/drivers/net/wireless/b43/main.c
--+++ b/drivers/net/wireless/b43/main.c
--@@ -4866,7 +4866,7 @@ static int b43_wireless_core_init(struct
-- 	switch (dev->dev->bus_type) {
-- #ifdef CPTCFG_B43_BCMA
-- 	case B43_BUS_BCMA:
---		bcma_core_pci_irq_ctl(dev->dev->bdev->bus,
--+		bcma_host_pci_irq_ctl(dev->dev->bdev->bus,
-- 				      dev->dev->bdev, true);
-- 		bcma_host_pci_up(dev->dev->bdev->bus);
-- 		break;
----- a/drivers/net/wireless/brcm80211/brcmsmac/main.c
--+++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c
--@@ -4959,7 +4959,7 @@ static int brcms_b_up_prep(struct brcms_
-- 	 * Configure pci/pcmcia here instead of in brcms_c_attach()
-- 	 * to allow mfg hotswap:  down, hotswap (chip power cycle), up.
-- 	 */
---	bcma_core_pci_irq_ctl(wlc_hw->d11core->bus, wlc_hw->d11core,
--+	bcma_host_pci_irq_ctl(wlc_hw->d11core->bus, wlc_hw->d11core,
-- 			      true);
-- 
-- 	/*
-diff --git a/package/kernel/mac80211/patches/060-no_local_ssb_bcma.patch b/package/kernel/mac80211/patches/060-no_local_ssb_bcma.patch
-index d307949..4fbab23 100644
---- a/package/kernel/mac80211/patches/060-no_local_ssb_bcma.patch
-+++ b/package/kernel/mac80211/patches/060-no_local_ssb_bcma.patch
-@@ -1,6 +1,6 @@
- --- a/.local-symbols
- +++ b/.local-symbols
--@@ -344,40 +344,3 @@ USB_CDC_PHONET=
-+@@ -449,43 +449,6 @@ USB_CDC_PHONET=
-  USB_IPHETH=
-  USB_SIERRA_NET=
-  USB_VL600=
-@@ -32,26 +32,18 @@
- -BCMA_BLOCKIO=
- -BCMA_HOST_PCI_POSSIBLE=
- -BCMA_HOST_PCI=
---BCMA_DRIVER_PCI_HOSTMODE=
- -BCMA_HOST_SOC=
- -BCMA_DRIVER_PCI=
-+-BCMA_DRIVER_PCI_HOSTMODE=
- -BCMA_DRIVER_MIPS=
- -BCMA_SFLASH=
- -BCMA_NFLASH=
- -BCMA_DRIVER_GMAC_CMN=
- -BCMA_DRIVER_GPIO=
- -BCMA_DEBUG=
----- a/Makefile.kernel
--+++ b/Makefile.kernel
--@@ -38,8 +38,6 @@ obj-$(CPTCFG_MAC80211) += net/mac80211/
-- obj-$(CPTCFG_WLAN) += drivers/net/wireless/
-- #obj-$(CPTCFG_BT) += net/bluetooth/
-- #obj-$(CPTCFG_BT) += drivers/bluetooth/
---obj-$(CPTCFG_SSB) += drivers/ssb/
---obj-$(CPTCFG_BCMA) += drivers/bcma/
-- #obj-$(CPTCFG_ETHERNET) += drivers/net/ethernet/
-- obj-$(CPTCFG_USB_NET_RNDIS_WLAN) += drivers/net/usb/
-- #obj-$(CPTCFG_NFC) += net/nfc/
-+ NFC=
-+ NFC_DIGITAL=
-+ NFC_NCI=
- --- a/drivers/net/wireless/b43/main.c
- +++ b/drivers/net/wireless/b43/main.c
- @@ -2866,7 +2866,7 @@ static struct ssb_device *b43_ssb_gpio_d
-@@ -63,7 +55,7 @@
-  	return (bus->chipco.dev ? bus->chipco.dev : bus->pcicore.dev);
-  #else
-  	return bus->chipco.dev;
--@@ -4907,7 +4907,7 @@ static int b43_wireless_core_init(struct
-+@@ -4903,7 +4903,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. */
-@@ -116,12 +108,23 @@
- --- a/Kconfig.sources
- +++ b/Kconfig.sources
- @@ -9,9 +9,6 @@ source "$BACKPORT_DIR/drivers/net/wirele
-- #source "$BACKPORT_DIR/drivers/net/ethernet/Kconfig"
-+ source "$BACKPORT_DIR/drivers/net/ethernet/Kconfig"
-  source "$BACKPORT_DIR/drivers/net/usb/Kconfig"
-  
- -source "$BACKPORT_DIR/drivers/ssb/Kconfig"
- -source "$BACKPORT_DIR/drivers/bcma/Kconfig"
- -
-- #source "$BACKPORT_DIR/net/nfc/Kconfig"
-+ source "$BACKPORT_DIR/net/nfc/Kconfig"
-  
-- #source "$BACKPORT_DIR/drivers/media/Kconfig"
-+ source "$BACKPORT_DIR/drivers/media/Kconfig"
-+--- a/Makefile.kernel
-++++ b/Makefile.kernel
-+@@ -38,8 +38,6 @@ obj-$(CPTCFG_MAC80211) += net/mac80211/
-+ obj-$(CPTCFG_WLAN) += drivers/net/wireless/
-+ obj-$(CPTCFG_BT) += net/bluetooth/
-+ obj-$(CPTCFG_BT) += drivers/bluetooth/
-+-obj-$(CPTCFG_SSB) += drivers/ssb/
-+-obj-$(CPTCFG_BCMA) += drivers/bcma/
-+ obj-$(CPTCFG_ETHERNET) += drivers/net/ethernet/
-+ obj-$(CPTCFG_USB_NET_RNDIS_WLAN) += drivers/net/usb/
-+ obj-$(CPTCFG_NFC) += net/nfc/
-diff --git a/package/kernel/mac80211/patches/090-linux_3_18_12_compat.patch b/package/kernel/mac80211/patches/090-linux_3_18_12_compat.patch
-deleted file mode 100644
-index 85c5280..0000000
---- a/package/kernel/mac80211/patches/090-linux_3_18_12_compat.patch
-+++ /dev/null
-@@ -1,29 +0,0 @@
----- a/backport-include/linux/wait.h
--+++ b/backport-include/linux/wait.h
--@@ -23,7 +23,7 @@ backport_wait_on_bit_io(void *word, int
-- 
-- #endif
-- 
---#if LINUX_VERSION_CODE < KERNEL_VERSION(3,19,0)
--+#if LINUX_VERSION_CODE < KERNEL_VERSION(3,18,12)
-- #define WQ_FLAG_WOKEN		0x02
-- 
-- #define wait_woken LINUX_BACKPORT(wait_woken)
----- a/compat/backport-3.19.c
--+++ b/compat/backport-3.19.c
--@@ -15,6 +15,7 @@
-- #include <linux/netdevice.h>
-- #include <linux/debugfs.h>
-- 
--+#if LINUX_VERSION_CODE < KERNEL_VERSION(3,18,12)
-- static inline bool is_kthread_should_stop(void)
-- {
-- 	return (current->flags & PF_KTHREAD) && kthread_should_stop();
--@@ -79,6 +80,7 @@ int woken_wake_function(wait_queue_t *wa
-- 	return default_wake_function(wait, mode, sync, key);
-- }
-- EXPORT_SYMBOL(woken_wake_function);
--+#endif
-- 
-- #ifdef __BACKPORT_NETDEV_RSS_KEY_FILL
-- u8 netdev_rss_key[NETDEV_RSS_KEY_LEN];
-diff --git a/package/kernel/mac80211/patches/100-remove-cryptoapi-dependencies.patch b/package/kernel/mac80211/patches/100-remove-cryptoapi-dependencies.patch
-new file mode 100644
-index 0000000..07dde54
---- /dev/null
-+++ b/package/kernel/mac80211/patches/100-remove-cryptoapi-dependencies.patch
-@@ -0,0 +1,376 @@
-+--- a/net/mac80211/Kconfig
-++++ b/net/mac80211/Kconfig
-+@@ -5,8 +5,6 @@ config MAC80211
-+ 	depends on CRYPTO
-+ 	depends on CRYPTO_ARC4
-+ 	depends on CRYPTO_AES
-+-	select BPAUTO_CRYPTO_CCM
-+-	depends on CRYPTO_GCM
-+ 	depends on CRC32
-+ 	select BPAUTO_AVERAGE
-+ 	---help---
-+--- a/net/mac80211/Makefile
-++++ b/net/mac80211/Makefile
-+@@ -15,9 +15,7 @@ mac80211-y := \
-+ 	michael.o \
-+ 	tkip.o \
-+ 	aes_ccm.o \
-+-	aes_gcm.o \
-+ 	aes_cmac.o \
-+-	aes_gmac.o \
-+ 	cfg.o \
-+ 	ethtool.o \
-+ 	rx.o \
-+--- a/net/mac80211/aes_ccm.c
-++++ b/net/mac80211/aes_ccm.c
-+@@ -13,89 +13,132 @@
-+ #include <linux/types.h>
-+ #include <linux/err.h>
-+ #include <crypto/aead.h>
-++#include <crypto/aes.h>
-+ 
-+ #include <net/mac80211.h>
-+ #include "key.h"
-+ #include "aes_ccm.h"
-+ 
-+-void ieee80211_aes_ccm_encrypt(struct crypto_aead *tfm, u8 *b_0, u8 *aad,
-+-			       u8 *data, size_t data_len, u8 *mic,
-+-			       size_t mic_len)
-++static void aes_ccm_prepare(struct crypto_cipher *tfm, u8 *b_0, u8 *aad, u8 *s_0,
-++			    u8 *a, u8 *b)
-+ {
-+-	struct scatterlist sg[3];
-++	int i;
-++
-++	crypto_cipher_encrypt_one(tfm, b, b_0);
-++
-++	/* Extra Authenticate-only data (always two AES blocks) */
-++	for (i = 0; i < AES_BLOCK_SIZE; i++)
-++		aad[i] ^= b[i];
-++	crypto_cipher_encrypt_one(tfm, b, aad);
-++
-++	aad += AES_BLOCK_SIZE;
-++
-++	for (i = 0; i < AES_BLOCK_SIZE; i++)
-++		aad[i] ^= b[i];
-++	crypto_cipher_encrypt_one(tfm, a, aad);
-+ 
-+-	char aead_req_data[sizeof(struct aead_request) +
-+-			   crypto_aead_reqsize(tfm)]
-+-		__aligned(__alignof__(struct aead_request));
-+-	struct aead_request *aead_req = (void *) aead_req_data;
-++	/* Mask out bits from auth-only-b_0 */
-++	b_0[0] &= 0x07;
-+ 
-+-	memset(aead_req, 0, sizeof(aead_req_data));
-++	/* S_0 is used to encrypt T (= MIC) */
-++	b_0[14] = 0;
-++	b_0[15] = 0;
-++	crypto_cipher_encrypt_one(tfm, s_0, b_0);
-++}
-+ 
-+-	sg_init_table(sg, 3);
-+-	sg_set_buf(&sg[0], &aad[2], be16_to_cpup((__be16 *)aad));
-+-	sg_set_buf(&sg[1], data, data_len);
-+-	sg_set_buf(&sg[2], mic, mic_len);
-+ 
-+-	aead_request_set_tfm(aead_req, tfm);
-+-	aead_request_set_crypt(aead_req, sg, sg, data_len, b_0);
-+-	aead_request_set_ad(aead_req, sg[0].length);
-++void ieee80211_aes_ccm_encrypt(struct crypto_cipher *tfm, u8 *b_0, u8 *aad,
-++			       u8 *data, size_t data_len, u8 *mic,
-++			       size_t mic_len)
-++{
-++	int i, j, last_len, num_blocks;
-++	u8 b[AES_BLOCK_SIZE];
-++	u8 s_0[AES_BLOCK_SIZE];
-++	u8 e[AES_BLOCK_SIZE];
-++	u8 *pos, *cpos;
-++
-++	num_blocks = DIV_ROUND_UP(data_len, AES_BLOCK_SIZE);
-++	last_len = data_len % AES_BLOCK_SIZE;
-++	aes_ccm_prepare(tfm, b_0, aad, s_0, b, b);
-++
-++	/* Process payload blocks */
-++	pos = data;
-++	cpos = data;
-++	for (j = 1; j <= num_blocks; j++) {
-++		int blen = (j == num_blocks && last_len) ?
-++			last_len : AES_BLOCK_SIZE;
-++
-++		/* Authentication followed by encryption */
-++		for (i = 0; i < blen; i++)
-++			b[i] ^= pos[i];
-++		crypto_cipher_encrypt_one(tfm, b, b);
-++
-++		b_0[14] = (j >> 8) & 0xff;
-++		b_0[15] = j & 0xff;
-++		crypto_cipher_encrypt_one(tfm, e, b_0);
-++		for (i = 0; i < blen; i++)
-++			*cpos++ = *pos++ ^ e[i];
-++	}
-+ 
-+-	crypto_aead_encrypt(aead_req);
-++	for (i = 0; i < mic_len; i++)
-++		mic[i] = b[i] ^ s_0[i];
-+ }
-+ 
-+-int ieee80211_aes_ccm_decrypt(struct crypto_aead *tfm, u8 *b_0, u8 *aad,
-++int ieee80211_aes_ccm_decrypt(struct crypto_cipher *tfm, u8 *b_0, u8 *aad,
-+ 			      u8 *data, size_t data_len, u8 *mic,
-+ 			      size_t mic_len)
-+ {
-+-	struct scatterlist sg[3];
-+-	char aead_req_data[sizeof(struct aead_request) +
-+-			   crypto_aead_reqsize(tfm)]
-+-		__aligned(__alignof__(struct aead_request));
-+-	struct aead_request *aead_req = (void *) aead_req_data;
-+-
-+-	if (data_len == 0)
-+-		return -EINVAL;
-+-
-+-	memset(aead_req, 0, sizeof(aead_req_data));
-+-
-+-	sg_init_table(sg, 3);
-+-	sg_set_buf(&sg[0], &aad[2], be16_to_cpup((__be16 *)aad));
-+-	sg_set_buf(&sg[1], data, data_len);
-+-	sg_set_buf(&sg[2], mic, mic_len);
-+-
-+-	aead_request_set_tfm(aead_req, tfm);
-+-	aead_request_set_crypt(aead_req, sg, sg, data_len + mic_len, b_0);
-+-	aead_request_set_ad(aead_req, sg[0].length);
-++	int i, j, last_len, num_blocks;
-++	u8 *pos, *cpos;
-++	u8 a[AES_BLOCK_SIZE];
-++	u8 b[AES_BLOCK_SIZE];
-++	u8 s_0[AES_BLOCK_SIZE];
-++
-++	num_blocks = DIV_ROUND_UP(data_len, AES_BLOCK_SIZE);
-++	last_len = data_len % AES_BLOCK_SIZE;
-++	aes_ccm_prepare(tfm, b_0, aad, s_0, a, b);
-++
-++	/* Process payload blocks */
-++	cpos = data;
-++	pos = data;
-++	for (j = 1; j <= num_blocks; j++) {
-++		int blen = (j == num_blocks && last_len) ?
-++			last_len : AES_BLOCK_SIZE;
-++
-++		/* Decryption followed by authentication */
-++		b_0[14] = (j >> 8) & 0xff;
-++		b_0[15] = j & 0xff;
-++		crypto_cipher_encrypt_one(tfm, b, b_0);
-++		for (i = 0; i < blen; i++) {
-++			*pos = *cpos++ ^ b[i];
-++			a[i] ^= *pos++;
-++		}
-++		crypto_cipher_encrypt_one(tfm, a, a);
-++	}
-++
-++	for (i = 0; i < mic_len; i++) {
-++		if ((mic[i] ^ s_0[i]) != a[i])
-++			return -1;
-++	}
-+ 
-+-	return crypto_aead_decrypt(aead_req);
-++	return 0;
-+ }
-+ 
-+-struct crypto_aead *ieee80211_aes_key_setup_encrypt(const u8 key[],
-+-						    size_t key_len,
-+-						    size_t mic_len)
-++struct crypto_cipher *ieee80211_aes_key_setup_encrypt(const u8 key[],
-++						      size_t key_len,
-++						      size_t mic_len)
-+ {
-+-	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, key_len);
-+-	if (err)
-+-		goto free_aead;
-+-	err = crypto_aead_setauthsize(tfm, mic_len);
-+-	if (err)
-+-		goto free_aead;
-++	tfm = crypto_alloc_cipher("aes", 0, CRYPTO_ALG_ASYNC);
-++	if (!IS_ERR(tfm))
-++		crypto_cipher_setkey(tfm, key, key_len);
-+ 
-+ 	return tfm;
-+-
-+-free_aead:
-+-	crypto_free_aead(tfm);
-+-	return ERR_PTR(err);
-+ }
-+ 
-+-void ieee80211_aes_key_free(struct crypto_aead *tfm)
-++
-++void ieee80211_aes_key_free(struct crypto_cipher *tfm)
-+ {
-+-	crypto_free_aead(tfm);
-++	crypto_free_cipher(tfm);
-+ }
-+--- a/net/mac80211/aes_ccm.h
-++++ b/net/mac80211/aes_ccm.h
-+@@ -12,15 +12,15 @@
-+ 
-+ #include <linux/crypto.h>
-+ 
-+-struct crypto_aead *ieee80211_aes_key_setup_encrypt(const u8 key[],
-+-						    size_t key_len,
-+-						    size_t mic_len);
-+-void ieee80211_aes_ccm_encrypt(struct crypto_aead *tfm, u8 *b_0, u8 *aad,
-++struct crypto_cipher *ieee80211_aes_key_setup_encrypt(const u8 key[],
-++						      size_t key_len,
-++						      size_t mic_len);
-++void ieee80211_aes_ccm_encrypt(struct crypto_cipher *tfm, u8 *b_0, u8 *aad,
-+ 			       u8 *data, size_t data_len, u8 *mic,
-+ 			       size_t mic_len);
-+-int ieee80211_aes_ccm_decrypt(struct crypto_aead *tfm, u8 *b_0, u8 *aad,
-++int ieee80211_aes_ccm_decrypt(struct crypto_cipher *tfm, u8 *b_0, u8 *aad,
-+ 			      u8 *data, size_t data_len, u8 *mic,
-+ 			      size_t mic_len);
-+-void ieee80211_aes_key_free(struct crypto_aead *tfm);
-++void ieee80211_aes_key_free(struct crypto_cipher *tfm);
-+ 
-+ #endif /* AES_CCM_H */
-+--- a/net/mac80211/aes_gcm.h
-++++ b/net/mac80211/aes_gcm.h
-+@@ -11,12 +11,28 @@
-+ 
-+ #include <linux/crypto.h>
-+ 
-+-void ieee80211_aes_gcm_encrypt(struct crypto_aead *tfm, u8 *j_0, u8 *aad,
-+-			       u8 *data, size_t data_len, u8 *mic);
-+-int ieee80211_aes_gcm_decrypt(struct crypto_aead *tfm, u8 *j_0, u8 *aad,
-+-			      u8 *data, size_t data_len, u8 *mic);
-+-struct crypto_aead *ieee80211_aes_gcm_key_setup_encrypt(const u8 key[],
-+-							size_t key_len);
-+-void ieee80211_aes_gcm_key_free(struct crypto_aead *tfm);
-++static inline void
-++ieee80211_aes_gcm_encrypt(struct crypto_aead *tfm, u8 *j_0, u8 *aad,
-++			  u8 *data, size_t data_len, u8 *mic)
-++{
-++}
-++
-++static inline int
-++ieee80211_aes_gcm_decrypt(struct crypto_aead *tfm, u8 *j_0, u8 *aad,
-++			  u8 *data, size_t data_len, u8 *mic)
-++{
-++    return -EOPNOTSUPP;
-++}
-++
-++static inline struct crypto_aead *
-++ieee80211_aes_gcm_key_setup_encrypt(const u8 key[], size_t key_len)
-++{
-++    return NULL;
-++}
-++
-++static inline void
-++ieee80211_aes_gcm_key_free(struct crypto_aead *tfm)
-++{
-++}
-+ 
-+ #endif /* AES_GCM_H */
-+--- a/net/mac80211/aes_gmac.h
-++++ b/net/mac80211/aes_gmac.h
-+@@ -11,10 +11,22 @@
-+ 
-+ #include <linux/crypto.h>
-+ 
-+-struct crypto_aead *ieee80211_aes_gmac_key_setup(const u8 key[],
-+-						 size_t key_len);
-+-int ieee80211_aes_gmac(struct crypto_aead *tfm, const u8 *aad, u8 *nonce,
-+-		       const u8 *data, size_t data_len, u8 *mic);
-+-void ieee80211_aes_gmac_key_free(struct crypto_aead *tfm);
-++static inline struct crypto_aead *
-++ieee80211_aes_gmac_key_setup(const u8 key[], size_t key_len)
-++{
-++	return NULL;
-++}
-++
-++static inline int
-++ieee80211_aes_gmac(struct crypto_aead *tfm, const u8 *aad, u8 *nonce,
-++		   const u8 *data, size_t data_len, u8 *mic)
-++{
-++	return -EOPNOTSUPP;
-++}
-++
-++static inline void
-++ieee80211_aes_gmac_key_free(struct crypto_aead *tfm)
-++{
-++}
-+ 
-+ #endif /* AES_GMAC_H */
-+--- a/net/mac80211/key.h
-++++ b/net/mac80211/key.h
-+@@ -84,7 +84,7 @@ struct ieee80211_key {
-+ 			 * Management frames.
-+ 			 */
-+ 			u8 rx_pn[IEEE80211_NUM_TIDS + 1][IEEE80211_CCMP_PN_LEN];
-+-			struct crypto_aead *tfm;
-++			struct crypto_cipher *tfm;
-+ 			u32 replays; /* dot11RSNAStatsCCMPReplays */
-+ 		} ccmp;
-+ 		struct {
-+--- a/net/mac80211/wpa.c
-++++ b/net/mac80211/wpa.c
-+@@ -304,7 +304,8 @@ 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,
-++				u16 data_len)
-+ {
-+ 	__le16 mask_fc;
-+ 	int a4_included, mgmt;
-+@@ -334,14 +335,8 @@ static void ccmp_special_blocks(struct s
-+ 	else
-+ 		qos_tid = 0;
-+ 
-+-	/* In CCM, the initial vectors (IV) used for CTR mode encryption and CBC
-+-	 * mode authentication are not allowed to collide, yet both are derived
-+-	 * from this vector b_0. We only set L := 1 here to indicate that the
-+-	 * data size can be represented in (L+1) bytes. The CCM layer will take
-+-	 * care of storing the data length in the top (L+1) bytes and setting
-+-	 * and clearing the other bits as is required to derive the two IVs.
-+-	 */
-+-	b_0[0] = 0x1;
-++	/* First block, b_0 */
-++	b_0[0] = 0x59; /* flags: Adata: 1, M: 011, L: 001 */
-+ 
-+ 	/* Nonce: Nonce Flags | A2 | PN
-+ 	 * Nonce Flags: Priority (b0..b3) | Management (b4) | Reserved (b5..b7)
-+@@ -349,6 +344,8 @@ static void ccmp_special_blocks(struct s
-+ 	b_0[1] = qos_tid | (mgmt << 4);
-+ 	memcpy(&b_0[2], hdr->addr2, ETH_ALEN);
-+ 	memcpy(&b_0[8], pn, IEEE80211_CCMP_PN_LEN);
-++	/* l(m) */
-++	put_unaligned_be16(data_len, &b_0[14]);
-+ 
-+ 	/* AAD (extra authenticate-only data) / masked 802.11 header
-+ 	 * FC | A1 | A2 | A3 | SC | [A4] | [QC] */
-+@@ -460,7 +457,7 @@ static int ccmp_encrypt_skb(struct ieee8
-+ 		return 0;
-+ 
-+ 	pos += IEEE80211_CCMP_HDR_LEN;
-+-	ccmp_special_blocks(skb, pn, b_0, aad);
-++	ccmp_special_blocks(skb, pn, b_0, aad, len);
-+ 	ieee80211_aes_ccm_encrypt(key->u.ccmp.tfm, b_0, aad, pos, len,
-+ 				  skb_put(skb, mic_len), mic_len);
-+ 
-+@@ -531,7 +528,7 @@ ieee80211_crypto_ccmp_decrypt(struct iee
-+ 			u8 aad[2 * AES_BLOCK_SIZE];
-+ 			u8 b_0[AES_BLOCK_SIZE];
-+ 			/* hardware didn't decrypt/verify MIC */
-+-			ccmp_special_blocks(skb, pn, b_0, aad);
-++			ccmp_special_blocks(skb, pn, b_0, aad, data_len);
-+ 
-+ 			if (ieee80211_aes_ccm_decrypt(
-+ 				    key->u.ccmp.tfm, b_0, aad,
-diff --git a/package/kernel/mac80211/patches/100-revert-cryptoapi-ports.patch b/package/kernel/mac80211/patches/100-revert-cryptoapi-ports.patch
-deleted file mode 100644
-index ceca952..0000000
---- a/package/kernel/mac80211/patches/100-revert-cryptoapi-ports.patch
-+++ /dev/null
-@@ -1,2055 +0,0 @@
--This patch reverts the following commits from wireless-testing:
--
--8ade538bf39b1ee53418528fdacd36b8e65621b9
--56c52da2d554f081e8fce58ecbcf6a40c605b95b
--2b2ba0db1c820d04d5143452d70012cd44d7b578
--00b9cfa3ff38401bd70c34b250ca13e5ea347b4a
--4f031fa9f188b2b0641ac20087d9e16bcfb4e49d
--6e1ee5d2e9e411892b5d84e3ea93e3fc88ac786c
--30ef7ef9672d92ab2cac37f60a31955c118321e7
--f359d3fe832e49eeec2232b2af5a9e3aee6b4862 (only the changes in aes_cmac.{c,h})
--7ec7c4a9a686c608315739ab6a2b0527a240883c
-----
--
----- a/include/linux/ieee80211.h
--+++ b/include/linux/ieee80211.h
--@@ -1017,15 +1017,6 @@ struct ieee80211_mmie {
-- 	u8 mic[8];
-- } __packed;
-- 
---/* Management MIC information element (IEEE 802.11w) for GMAC and CMAC-256 */
---struct ieee80211_mmie_16 {
---	u8 element_id;
---	u8 length;
---	__le16 key_id;
---	u8 sequence_number[6];
---	u8 mic[16];
---} __packed;
---
-- struct ieee80211_vendor_ie {
-- 	u8 element_id;
-- 	u8 len;
----- a/include/net/mac80211.h
--+++ b/include/net/mac80211.h
--@@ -1306,8 +1306,8 @@ struct ieee80211_vif *wdev_to_ieee80211_
--  * @IEEE80211_KEY_FLAG_PAIRWISE: Set by mac80211, this flag indicates
--  *	that the key is pairwise rather then a shared key.
--  * @IEEE80211_KEY_FLAG_SW_MGMT_TX: This flag should be set by the driver for a
--- *	CCMP/GCMP key if it requires CCMP/GCMP encryption of management frames
--- *	(MFP) to be done in software.
--+ *	CCMP key if it requires CCMP encryption of management frames (MFP) to
--+ *	be done in software.
--  * @IEEE80211_KEY_FLAG_PUT_IV_SPACE: This flag should be set by the driver
--  *	if space should be prepared for the IV, but the IV
--  *	itself should not be generated. Do not set together with
--@@ -1322,7 +1322,7 @@ struct ieee80211_vif *wdev_to_ieee80211_
--  *	RX, if your crypto engine can't deal with TX you can also set the
--  *	%IEEE80211_KEY_FLAG_SW_MGMT_TX flag to encrypt such frames in SW.
--  * @IEEE80211_KEY_FLAG_GENERATE_IV_MGMT: This flag should be set by the
--- *	driver for a CCMP/GCMP key to indicate that is requires IV generation
--+ *	driver for a CCMP key to indicate that is requires IV generation
--  *	only for managment frames (MFP).
--  * @IEEE80211_KEY_FLAG_RESERVE_TAILROOM: This flag should be set by the
--  *	driver for a key to indicate that sufficient tailroom must always
--@@ -4112,10 +4112,6 @@ void ieee80211_aes_cmac_calculate_k1_k2(
--  *	reverse order than in packet)
--  * @aes_cmac: PN data, most significant byte first (big endian,
--  *	reverse order than in packet)
--- * @aes_gmac: PN data, most significant byte first (big endian,
--- *	reverse order than in packet)
--- * @gcmp: PN data, most significant byte first (big endian,
--- *	reverse order than in packet)
--  */
-- struct ieee80211_key_seq {
-- 	union {
--@@ -4129,12 +4125,6 @@ struct ieee80211_key_seq {
-- 		struct {
-- 			u8 pn[6];
-- 		} aes_cmac;
---		struct {
---			u8 pn[6];
---		} aes_gmac;
---		struct {
---			u8 pn[6];
---		} gcmp;
-- 	};
-- };
-- 
--@@ -4159,7 +4149,7 @@ void ieee80211_get_key_tx_seq(struct iee
--  * ieee80211_get_key_rx_seq - get key RX sequence counter
--  *
--  * @keyconf: the parameter passed with the set key
--- * @tid: The TID, or -1 for the management frame value (CCMP/GCMP only);
--+ * @tid: The TID, or -1 for the management frame value (CCMP only);
--  *	the value on TID 0 is also used for non-QoS frames. For
--  *	CMAC, only TID 0 is valid.
--  * @seq: buffer to receive the sequence data
--@@ -4195,7 +4185,7 @@ void ieee80211_set_key_tx_seq(struct iee
--  * ieee80211_set_key_rx_seq - set key RX sequence counter
--  *
--  * @keyconf: the parameter passed with the set key
--- * @tid: The TID, or -1 for the management frame value (CCMP/GCMP only);
--+ * @tid: The TID, or -1 for the management frame value (CCMP only);
--  *	the value on TID 0 is also used for non-QoS frames. For
--  *	CMAC, only TID 0 is valid.
--  * @seq: new sequence data
----- a/net/mac80211/Kconfig
--+++ b/net/mac80211/Kconfig
--@@ -5,8 +5,6 @@ config MAC80211
-- 	depends on CRYPTO
-- 	depends on CRYPTO_ARC4
-- 	depends on CRYPTO_AES
---	select BPAUTO_CRYPTO_CCM
---	depends on CRYPTO_GCM
-- 	depends on CRC32
-- 	select BPAUTO_AVERAGE
-- 	---help---
----- a/net/mac80211/Makefile
--+++ b/net/mac80211/Makefile
--@@ -15,9 +15,7 @@ mac80211-y := \
-- 	michael.o \
-- 	tkip.o \
-- 	aes_ccm.o \
---	aes_gcm.o \
-- 	aes_cmac.o \
---	aes_gmac.o \
-- 	cfg.o \
-- 	ethtool.o \
-- 	rx.o \
----- a/net/mac80211/aes_ccm.c
--+++ b/net/mac80211/aes_ccm.c
--@@ -2,8 +2,6 @@
--  * Copyright 2003-2004, Instant802 Networks, Inc.
--  * Copyright 2005-2006, Devicescape Software, Inc.
--  *
--- * Rewrite: Copyright (C) 2013 Linaro Ltd <ard.biesheuvel@linaro.org>
--- *
--  * 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,82 +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,
---			       size_t mic_len)
--+static void aes_ccm_prepare(struct crypto_cipher *tfm, u8 *scratch, u8 *a)
--+{
--+	int i;
--+	u8 *b_0, *aad, *b, *s_0;
--+
--+	b_0 = scratch + 3 * AES_BLOCK_SIZE;
--+	aad = scratch + 4 * AES_BLOCK_SIZE;
--+	b = scratch;
--+	s_0 = scratch + AES_BLOCK_SIZE;
--+
--+	crypto_cipher_encrypt_one(tfm, b, b_0);
--+
--+	/* Extra Authenticate-only data (always two AES blocks) */
--+	for (i = 0; i < AES_BLOCK_SIZE; i++)
--+		aad[i] ^= b[i];
--+	crypto_cipher_encrypt_one(tfm, b, aad);
--+
--+	aad += AES_BLOCK_SIZE;
--+
--+	for (i = 0; i < AES_BLOCK_SIZE; i++)
--+		aad[i] ^= b[i];
--+	crypto_cipher_encrypt_one(tfm, a, aad);
--+
--+	/* Mask out bits from auth-only-b_0 */
--+	b_0[0] &= 0x07;
--+
--+	/* S_0 is used to encrypt T (= MIC) */
--+	b_0[14] = 0;
--+	b_0[15] = 0;
--+	crypto_cipher_encrypt_one(tfm, s_0, b_0);
--+}
--+
--+
--+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];
--+	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_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, mic_len);
---
---	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;
--+	b_0 = scratch + 3 * AES_BLOCK_SIZE;
--+
--+	num_blocks = DIV_ROUND_UP(data_len, AES_BLOCK_SIZE);
--+	last_len = data_len % AES_BLOCK_SIZE;
--+	aes_ccm_prepare(tfm, scratch, b);
--+
--+	/* Process payload blocks */
--+	pos = data;
--+	cpos = cdata;
--+	for (j = 1; j <= num_blocks; j++) {
--+		int blen = (j == num_blocks && last_len) ?
--+			last_len : AES_BLOCK_SIZE;
--+
--+		/* Authentication followed by encryption */
--+		for (i = 0; i < blen; i++)
--+			b[i] ^= pos[i];
--+		crypto_cipher_encrypt_one(tfm, b, b);
--+
--+		b_0[14] = (j >> 8) & 0xff;
--+		b_0[15] = j & 0xff;
--+		crypto_cipher_encrypt_one(tfm, e, b_0);
--+		for (i = 0; i < blen; i++)
--+			*cpos++ = *pos++ ^ e[i];
--+	}
-- 
---	crypto_aead_encrypt(aead_req);
--+	for (i = 0; i < IEEE80211_CCMP_MIC_LEN; i++)
--+		mic[i] = b[i] ^ s_0[i];
-- }
-- 
---int ieee80211_aes_ccm_decrypt(struct crypto_aead *tfm, u8 *b_0, u8 *aad,
---			      u8 *data, size_t data_len, u8 *mic,
---			      size_t mic_len)
--+
--+int ieee80211_aes_ccm_decrypt(struct crypto_cipher *tfm, u8 *scratch,
--+			      u8 *cdata, size_t data_len, u8 *mic, u8 *data)
-- {
---	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;
---
---	if (data_len == 0)
---		return -EINVAL;
---
---	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, 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 + mic_len, b_0);
--+	int i, j, last_len, num_blocks;
--+	u8 *pos, *cpos, *b, *s_0, *a, *b_0;
--+
--+	b = scratch;
--+	s_0 = scratch + AES_BLOCK_SIZE;
--+	a = scratch + 2 * AES_BLOCK_SIZE;
--+	b_0 = scratch + 3 * AES_BLOCK_SIZE;
--+
--+	num_blocks = DIV_ROUND_UP(data_len, AES_BLOCK_SIZE);
--+	last_len = data_len % AES_BLOCK_SIZE;
--+	aes_ccm_prepare(tfm, scratch, a);
--+
--+	/* Process payload blocks */
--+	cpos = cdata;
--+	pos = data;
--+	for (j = 1; j <= num_blocks; j++) {
--+		int blen = (j == num_blocks && last_len) ?
--+			last_len : AES_BLOCK_SIZE;
--+
--+		/* Decryption followed by authentication */
--+		b_0[14] = (j >> 8) & 0xff;
--+		b_0[15] = j & 0xff;
--+		crypto_cipher_encrypt_one(tfm, b, b_0);
--+		for (i = 0; i < blen; i++) {
--+			*pos = *cpos++ ^ b[i];
--+			a[i] ^= *pos++;
--+		}
--+		crypto_cipher_encrypt_one(tfm, a, a);
--+	}
--+
--+	for (i = 0; i < IEEE80211_CCMP_MIC_LEN; i++) {
--+		if ((mic[i] ^ s_0[i]) != a[i])
--+			return -1;
--+	}
-- 
---	return crypto_aead_decrypt(aead_req);
--+	return 0;
-- }
-- 
---struct crypto_aead *ieee80211_aes_key_setup_encrypt(const u8 key[],
---						    size_t key_len,
---						    size_t mic_len)
--+
--+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, key_len);
---	if (!err)
---		err = crypto_aead_setauthsize(tfm, 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)
-- {
---	crypto_free_aead(tfm);
--+	crypto_free_cipher(tfm);
-- }
----- a/net/mac80211/aes_ccm.h
--+++ b/net/mac80211/aes_ccm.h
--@@ -12,15 +12,13 @@
-- 
-- #include <linux/crypto.h>
-- 
---struct crypto_aead *ieee80211_aes_key_setup_encrypt(const u8 key[],
---						    size_t key_len,
---						    size_t mic_len);
---void ieee80211_aes_ccm_encrypt(struct crypto_aead *tfm, u8 *b_0, u8 *aad,
---			       u8 *data, size_t data_len, u8 *mic,
---			       size_t mic_len);
---int ieee80211_aes_ccm_decrypt(struct crypto_aead *tfm, u8 *b_0, u8 *aad,
---			      u8 *data, size_t data_len, u8 *mic,
---			      size_t mic_len);
---void ieee80211_aes_key_free(struct crypto_aead *tfm);
--+struct crypto_cipher *ieee80211_aes_key_setup_encrypt(const u8 key[]);
--+void ieee80211_aes_ccm_encrypt(struct crypto_cipher *tfm, u8 *scratch,
--+			       u8 *data, size_t data_len,
--+			       u8 *cdata, u8 *mic);
--+int ieee80211_aes_ccm_decrypt(struct crypto_cipher *tfm, u8 *scratch,
--+			      u8 *cdata, size_t data_len,
--+			      u8 *mic, u8 *data);
--+void ieee80211_aes_key_free(struct crypto_cipher *tfm);
-- 
-- #endif /* AES_CCM_H */
----- a/net/mac80211/aes_cmac.c
--+++ b/net/mac80211/aes_cmac.c
--@@ -18,8 +18,8 @@
-- #include "key.h"
-- #include "aes_cmac.h"
-- 
--+#define AES_CMAC_KEY_LEN 16
-- #define CMAC_TLEN 8 /* CMAC TLen = 64 bits (8 octets) */
---#define CMAC_TLEN_256 16 /* CMAC TLen = 128 bits (16 octets) */
-- #define AAD_LEN 20
-- 
-- 
--@@ -35,9 +35,9 @@ static void gf_mulx(u8 *pad)
-- 		pad[AES_BLOCK_SIZE - 1] ^= 0x87;
-- }
-- 
---static void aes_cmac_vector(struct crypto_cipher *tfm, size_t num_elem,
---			    const u8 *addr[], const size_t *len, u8 *mac,
---			    size_t mac_len)
--+
--+static void aes_128_cmac_vector(struct crypto_cipher *tfm, size_t num_elem,
--+				const u8 *addr[], const size_t *len, u8 *mac)
-- {
-- 	u8 cbc[AES_BLOCK_SIZE], pad[AES_BLOCK_SIZE];
-- 	const u8 *pos, *end;
--@@ -88,7 +88,7 @@ static void aes_cmac_vector(struct crypt
-- 	for (i = 0; i < AES_BLOCK_SIZE; i++)
-- 		pad[i] ^= cbc[i];
-- 	crypto_cipher_encrypt_one(tfm, pad, pad);
---	memcpy(mac, pad, mac_len);
--+	memcpy(mac, pad, CMAC_TLEN);
-- }
-- 
-- 
--@@ -107,35 +107,17 @@ void ieee80211_aes_cmac(struct crypto_ci
-- 	addr[2] = zero;
-- 	len[2] = CMAC_TLEN;
-- 
---	aes_cmac_vector(tfm, 3, addr, len, mic, CMAC_TLEN);
--+	aes_128_cmac_vector(tfm, 3, addr, len, mic);
-- }
-- 
---void ieee80211_aes_cmac_256(struct crypto_cipher *tfm, const u8 *aad,
---			    const u8 *data, size_t data_len, u8 *mic)
---{
---	const u8 *addr[3];
---	size_t len[3];
---	u8 zero[CMAC_TLEN_256];
---
---	memset(zero, 0, CMAC_TLEN_256);
---	addr[0] = aad;
---	len[0] = AAD_LEN;
---	addr[1] = data;
---	len[1] = data_len - CMAC_TLEN_256;
---	addr[2] = zero;
---	len[2] = CMAC_TLEN_256;
---
---	aes_cmac_vector(tfm, 3, addr, len, mic, CMAC_TLEN_256);
---}
-- 
---struct crypto_cipher *ieee80211_aes_cmac_key_setup(const u8 key[],
---						   size_t key_len)
--+struct crypto_cipher * ieee80211_aes_cmac_key_setup(const u8 key[])
-- {
-- 	struct crypto_cipher *tfm;
-- 
-- 	tfm = crypto_alloc_cipher("aes", 0, CRYPTO_ALG_ASYNC);
-- 	if (!IS_ERR(tfm))
---		crypto_cipher_setkey(tfm, key, key_len);
--+		crypto_cipher_setkey(tfm, key, AES_CMAC_KEY_LEN);
-- 
-- 	return tfm;
-- }
----- a/net/mac80211/aes_cmac.h
--+++ b/net/mac80211/aes_cmac.h
--@@ -11,12 +11,9 @@
-- 
-- #include <linux/crypto.h>
-- 
---struct crypto_cipher *ieee80211_aes_cmac_key_setup(const u8 key[],
---						   size_t key_len);
--+struct crypto_cipher * ieee80211_aes_cmac_key_setup(const u8 key[]);
-- void ieee80211_aes_cmac(struct crypto_cipher *tfm, const u8 *aad,
-- 			const u8 *data, size_t data_len, u8 *mic);
---void ieee80211_aes_cmac_256(struct crypto_cipher *tfm, const u8 *aad,
---			    const u8 *data, size_t data_len, u8 *mic);
-- void ieee80211_aes_cmac_key_free(struct crypto_cipher *tfm);
-- 
-- #endif /* AES_CMAC_H */
----- a/net/mac80211/aes_gcm.c
--+++ /dev/null
--@@ -1,95 +0,0 @@
---/*
--- * Copyright 2014-2015, Qualcomm Atheros, Inc.
--- *
--- * 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.
--- */
---
---#include <linux/kernel.h>
---#include <linux/types.h>
---#include <linux/crypto.h>
---#include <linux/err.h>
---#include <crypto/aes.h>
---
---#include <net/mac80211.h>
---#include "key.h"
---#include "aes_gcm.h"
---
---void ieee80211_aes_gcm_encrypt(struct crypto_aead *tfm, u8 *j_0, u8 *aad,
---			       u8 *data, size_t data_len, u8 *mic)
---{
---	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_GCMP_MIC_LEN);
---
---	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, j_0);
---
---	crypto_aead_encrypt(aead_req);
---}
---
---int ieee80211_aes_gcm_decrypt(struct crypto_aead *tfm, u8 *j_0, u8 *aad,
---			      u8 *data, size_t data_len, u8 *mic)
---{
---	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;
---
---	if (data_len == 0)
---		return -EINVAL;
---
---	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_GCMP_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_GCMP_MIC_LEN, j_0);
---
---	return crypto_aead_decrypt(aead_req);
---}
---
---struct crypto_aead *ieee80211_aes_gcm_key_setup_encrypt(const u8 key[],
---							size_t key_len)
---{
---	struct crypto_aead *tfm;
---	int err;
---
---	tfm = crypto_alloc_aead("gcm(aes)", 0, CRYPTO_ALG_ASYNC);
---	if (IS_ERR(tfm))
---		return tfm;
---
---	err = crypto_aead_setkey(tfm, key, key_len);
---	if (!err)
---		err = crypto_aead_setauthsize(tfm, IEEE80211_GCMP_MIC_LEN);
---	if (!err)
---		return tfm;
---
---	crypto_free_aead(tfm);
---	return ERR_PTR(err);
---}
---
---void ieee80211_aes_gcm_key_free(struct crypto_aead *tfm)
---{
---	crypto_free_aead(tfm);
---}
----- a/net/mac80211/aes_gcm.h
--+++ /dev/null
--@@ -1,22 +0,0 @@
---/*
--- * Copyright 2014-2015, Qualcomm Atheros, Inc.
--- *
--- * This program is free software; you can redistribute it and/or modify
--- * it under the terms of the GNU General Public License version 2 as
--- * published by the Free Software Foundation.
--- */
---
---#ifndef AES_GCM_H
---#define AES_GCM_H
---
---#include <linux/crypto.h>
---
---void ieee80211_aes_gcm_encrypt(struct crypto_aead *tfm, u8 *j_0, u8 *aad,
---			       u8 *data, size_t data_len, u8 *mic);
---int ieee80211_aes_gcm_decrypt(struct crypto_aead *tfm, u8 *j_0, u8 *aad,
---			      u8 *data, size_t data_len, u8 *mic);
---struct crypto_aead *ieee80211_aes_gcm_key_setup_encrypt(const u8 key[],
---							size_t key_len);
---void ieee80211_aes_gcm_key_free(struct crypto_aead *tfm);
---
---#endif /* AES_GCM_H */
----- a/net/mac80211/aes_gmac.c
--+++ /dev/null
--@@ -1,84 +0,0 @@
---/*
--- * AES-GMAC for IEEE 802.11 BIP-GMAC-128 and BIP-GMAC-256
--- * Copyright 2015, Qualcomm Atheros, Inc.
--- *
--- * 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.
--- */
---
---#include <linux/kernel.h>
---#include <linux/types.h>
---#include <linux/crypto.h>
---#include <linux/err.h>
---#include <crypto/aes.h>
---
---#include <net/mac80211.h>
---#include "key.h"
---#include "aes_gmac.h"
---
---#define GMAC_MIC_LEN 16
---#define GMAC_NONCE_LEN 12
---#define AAD_LEN 20
---
---int ieee80211_aes_gmac(struct crypto_aead *tfm, const u8 *aad, u8 *nonce,
---		       const u8 *data, size_t data_len, u8 *mic)
---{
---	struct scatterlist sg[3], ct[1];
---	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;
---	u8 zero[GMAC_MIC_LEN], iv[AES_BLOCK_SIZE];
---
---	if (data_len < GMAC_MIC_LEN)
---		return -EINVAL;
---
---	memset(aead_req, 0, sizeof(aead_req_data));
---
---	memset(zero, 0, GMAC_MIC_LEN);
---	sg_init_table(sg, 3);
---	sg_set_buf(&sg[0], aad, AAD_LEN);
---	sg_set_buf(&sg[1], data, data_len - GMAC_MIC_LEN);
---	sg_set_buf(&sg[2], zero, GMAC_MIC_LEN);
---
---	memcpy(iv, nonce, GMAC_NONCE_LEN);
---	memset(iv + GMAC_NONCE_LEN, 0, sizeof(iv) - GMAC_NONCE_LEN);
---	iv[AES_BLOCK_SIZE - 1] = 0x01;
---
---	sg_init_table(ct, 1);
---	sg_set_buf(&ct[0], mic, GMAC_MIC_LEN);
---
---	aead_request_set_tfm(aead_req, tfm);
---	aead_request_set_assoc(aead_req, sg, AAD_LEN + data_len);
---	aead_request_set_crypt(aead_req, NULL, ct, 0, iv);
---
---	crypto_aead_encrypt(aead_req);
---
---	return 0;
---}
---
---struct crypto_aead *ieee80211_aes_gmac_key_setup(const u8 key[],
---						 size_t key_len)
---{
---	struct crypto_aead *tfm;
---	int err;
---
---	tfm = crypto_alloc_aead("gcm(aes)", 0, CRYPTO_ALG_ASYNC);
---	if (IS_ERR(tfm))
---		return tfm;
---
---	err = crypto_aead_setkey(tfm, key, key_len);
---	if (!err)
---		return tfm;
---	if (!err)
---		err = crypto_aead_setauthsize(tfm, GMAC_MIC_LEN);
---
---	crypto_free_aead(tfm);
---	return ERR_PTR(err);
---}
---
---void ieee80211_aes_gmac_key_free(struct crypto_aead *tfm)
---{
---	crypto_free_aead(tfm);
---}
----- a/net/mac80211/aes_gmac.h
--+++ /dev/null
--@@ -1,20 +0,0 @@
---/*
--- * Copyright 2015, Qualcomm Atheros, Inc.
--- *
--- * This program is free software; you can redistribute it and/or modify
--- * it under the terms of the GNU General Public License version 2 as
--- * published by the Free Software Foundation.
--- */
---
---#ifndef AES_GMAC_H
---#define AES_GMAC_H
---
---#include <linux/crypto.h>
---
---struct crypto_aead *ieee80211_aes_gmac_key_setup(const u8 key[],
---						 size_t key_len);
---int ieee80211_aes_gmac(struct crypto_aead *tfm, const u8 *aad, u8 *nonce,
---		       const u8 *data, size_t data_len, u8 *mic);
---void ieee80211_aes_gmac_key_free(struct crypto_aead *tfm);
---
---#endif /* AES_GMAC_H */
----- a/net/mac80211/cfg.c
--+++ b/net/mac80211/cfg.c
--@@ -162,13 +162,8 @@ static int ieee80211_add_key(struct wiph
-- 			return -EINVAL;
-- 		break;
-- 	case WLAN_CIPHER_SUITE_CCMP:
---	case WLAN_CIPHER_SUITE_CCMP_256:
-- 	case WLAN_CIPHER_SUITE_AES_CMAC:
---	case WLAN_CIPHER_SUITE_BIP_CMAC_256:
---	case WLAN_CIPHER_SUITE_BIP_GMAC_128:
---	case WLAN_CIPHER_SUITE_BIP_GMAC_256:
-- 	case WLAN_CIPHER_SUITE_GCMP:
---	case WLAN_CIPHER_SUITE_GCMP_256:
-- 		break;
-- 	default:
-- 		cs = ieee80211_cs_get(local, params->cipher, sdata->vif.type);
--@@ -353,7 +348,6 @@ static int ieee80211_get_key(struct wiph
-- 		params.seq_len = 6;
-- 		break;
-- 	case WLAN_CIPHER_SUITE_CCMP:
---	case WLAN_CIPHER_SUITE_CCMP_256:
-- 		pn64 = atomic64_read(&key->u.ccmp.tx_pn);
-- 		seq[0] = pn64;
-- 		seq[1] = pn64 >> 8;
--@@ -365,35 +359,10 @@ static int ieee80211_get_key(struct wiph
-- 		params.seq_len = 6;
-- 		break;
-- 	case WLAN_CIPHER_SUITE_AES_CMAC:
---	case WLAN_CIPHER_SUITE_BIP_CMAC_256:
-- 		pn64 = atomic64_read(&key->u.aes_cmac.tx_pn);
-- 		seq[0] = pn64;
-- 		seq[1] = pn64 >> 8;
-- 		seq[2] = pn64 >> 16;
---		seq[3] = pn64 >> 24;
---		seq[4] = pn64 >> 32;
---		seq[5] = pn64 >> 40;
---		params.seq = seq;
---		params.seq_len = 6;
---		break;
---	case WLAN_CIPHER_SUITE_BIP_GMAC_128:
---	case WLAN_CIPHER_SUITE_BIP_GMAC_256:
---		pn64 = atomic64_read(&key->u.aes_gmac.tx_pn);
---		seq[0] = pn64;
---		seq[1] = pn64 >> 8;
---		seq[2] = pn64 >> 16;
---		seq[3] = pn64 >> 24;
---		seq[4] = pn64 >> 32;
---		seq[5] = pn64 >> 40;
---		params.seq = seq;
---		params.seq_len = 6;
---		break;
---	case WLAN_CIPHER_SUITE_GCMP:
---	case WLAN_CIPHER_SUITE_GCMP_256:
---		pn64 = atomic64_read(&key->u.gcmp.tx_pn);
---		seq[0] = pn64;
---		seq[1] = pn64 >> 8;
---		seq[2] = pn64 >> 16;
-- 		seq[3] = pn64 >> 24;
-- 		seq[4] = pn64 >> 32;
-- 		seq[5] = pn64 >> 40;
----- a/net/mac80211/debugfs_key.c
--+++ b/net/mac80211/debugfs_key.c
--@@ -94,33 +94,17 @@ static ssize_t key_tx_spec_read(struct f
-- 				key->u.tkip.tx.iv16);
-- 		break;
-- 	case WLAN_CIPHER_SUITE_CCMP:
---	case WLAN_CIPHER_SUITE_CCMP_256:
-- 		pn = atomic64_read(&key->u.ccmp.tx_pn);
-- 		len = scnprintf(buf, sizeof(buf), "%02x%02x%02x%02x%02x%02x\n",
-- 				(u8)(pn >> 40), (u8)(pn >> 32), (u8)(pn >> 24),
-- 				(u8)(pn >> 16), (u8)(pn >> 8), (u8)pn);
-- 		break;
-- 	case WLAN_CIPHER_SUITE_AES_CMAC:
---	case WLAN_CIPHER_SUITE_BIP_CMAC_256:
-- 		pn = atomic64_read(&key->u.aes_cmac.tx_pn);
-- 		len = scnprintf(buf, sizeof(buf), "%02x%02x%02x%02x%02x%02x\n",
-- 				(u8)(pn >> 40), (u8)(pn >> 32), (u8)(pn >> 24),
-- 				(u8)(pn >> 16), (u8)(pn >> 8), (u8)pn);
-- 		break;
---	case WLAN_CIPHER_SUITE_BIP_GMAC_128:
---	case WLAN_CIPHER_SUITE_BIP_GMAC_256:
---		pn = atomic64_read(&key->u.aes_gmac.tx_pn);
---		len = scnprintf(buf, sizeof(buf), "%02x%02x%02x%02x%02x%02x\n",
---				(u8)(pn >> 40), (u8)(pn >> 32), (u8)(pn >> 24),
---				(u8)(pn >> 16), (u8)(pn >> 8), (u8)pn);
---		break;
---	case WLAN_CIPHER_SUITE_GCMP:
---	case WLAN_CIPHER_SUITE_GCMP_256:
---		pn = atomic64_read(&key->u.gcmp.tx_pn);
---		len = scnprintf(buf, sizeof(buf), "%02x%02x%02x%02x%02x%02x\n",
---				(u8)(pn >> 40), (u8)(pn >> 32), (u8)(pn >> 24),
---				(u8)(pn >> 16), (u8)(pn >> 8), (u8)pn);
---		break;
-- 	default:
-- 		return 0;
-- 	}
--@@ -150,7 +134,6 @@ static ssize_t key_rx_spec_read(struct f
-- 		len = p - buf;
-- 		break;
-- 	case WLAN_CIPHER_SUITE_CCMP:
---	case WLAN_CIPHER_SUITE_CCMP_256:
-- 		for (i = 0; i < IEEE80211_NUM_TIDS + 1; i++) {
-- 			rpn = key->u.ccmp.rx_pn[i];
-- 			p += scnprintf(p, sizeof(buf)+buf-p,
--@@ -161,7 +144,6 @@ static ssize_t key_rx_spec_read(struct f
-- 		len = p - buf;
-- 		break;
-- 	case WLAN_CIPHER_SUITE_AES_CMAC:
---	case WLAN_CIPHER_SUITE_BIP_CMAC_256:
-- 		rpn = key->u.aes_cmac.rx_pn;
-- 		p += scnprintf(p, sizeof(buf)+buf-p,
-- 			       "%02x%02x%02x%02x%02x%02x\n",
--@@ -169,26 +151,6 @@ static ssize_t key_rx_spec_read(struct f
-- 			       rpn[3], rpn[4], rpn[5]);
-- 		len = p - buf;
-- 		break;
---	case WLAN_CIPHER_SUITE_BIP_GMAC_128:
---	case WLAN_CIPHER_SUITE_BIP_GMAC_256:
---		rpn = key->u.aes_gmac.rx_pn;
---		p += scnprintf(p, sizeof(buf)+buf-p,
---			       "%02x%02x%02x%02x%02x%02x\n",
---			       rpn[0], rpn[1], rpn[2],
---			       rpn[3], rpn[4], rpn[5]);
---		len = p - buf;
---		break;
---	case WLAN_CIPHER_SUITE_GCMP:
---	case WLAN_CIPHER_SUITE_GCMP_256:
---		for (i = 0; i < IEEE80211_NUM_TIDS + 1; i++) {
---			rpn = key->u.gcmp.rx_pn[i];
---			p += scnprintf(p, sizeof(buf)+buf-p,
---				       "%02x%02x%02x%02x%02x%02x\n",
---				       rpn[0], rpn[1], rpn[2],
---				       rpn[3], rpn[4], rpn[5]);
---		}
---		len = p - buf;
---		break;
-- 	default:
-- 		return 0;
-- 	}
--@@ -205,23 +167,12 @@ static ssize_t key_replays_read(struct f
-- 
-- 	switch (key->conf.cipher) {
-- 	case WLAN_CIPHER_SUITE_CCMP:
---	case WLAN_CIPHER_SUITE_CCMP_256:
-- 		len = scnprintf(buf, sizeof(buf), "%u\n", key->u.ccmp.replays);
-- 		break;
-- 	case WLAN_CIPHER_SUITE_AES_CMAC:
---	case WLAN_CIPHER_SUITE_BIP_CMAC_256:
-- 		len = scnprintf(buf, sizeof(buf), "%u\n",
-- 				key->u.aes_cmac.replays);
-- 		break;
---	case WLAN_CIPHER_SUITE_BIP_GMAC_128:
---	case WLAN_CIPHER_SUITE_BIP_GMAC_256:
---		len = scnprintf(buf, sizeof(buf), "%u\n",
---				key->u.aes_gmac.replays);
---		break;
---	case WLAN_CIPHER_SUITE_GCMP:
---	case WLAN_CIPHER_SUITE_GCMP_256:
---		len = scnprintf(buf, sizeof(buf), "%u\n", key->u.gcmp.replays);
---		break;
-- 	default:
-- 		return 0;
-- 	}
--@@ -238,15 +189,9 @@ static ssize_t key_icverrors_read(struct
-- 
-- 	switch (key->conf.cipher) {
-- 	case WLAN_CIPHER_SUITE_AES_CMAC:
---	case WLAN_CIPHER_SUITE_BIP_CMAC_256:
-- 		len = scnprintf(buf, sizeof(buf), "%u\n",
-- 				key->u.aes_cmac.icverrors);
-- 		break;
---	case WLAN_CIPHER_SUITE_BIP_GMAC_128:
---	case WLAN_CIPHER_SUITE_BIP_GMAC_256:
---		len = scnprintf(buf, sizeof(buf), "%u\n",
---				key->u.aes_gmac.icverrors);
---		break;
-- 	default:
-- 		return 0;
-- 	}
----- a/net/mac80211/key.c
--+++ b/net/mac80211/key.c
--@@ -24,8 +24,6 @@
-- #include "debugfs_key.h"
-- #include "aes_ccm.h"
-- #include "aes_cmac.h"
---#include "aes_gmac.h"
---#include "aes_gcm.h"
-- 
-- 
-- /**
--@@ -164,13 +162,7 @@ static int ieee80211_key_enable_hw_accel
-- 	case WLAN_CIPHER_SUITE_WEP104:
-- 	case WLAN_CIPHER_SUITE_TKIP:
-- 	case WLAN_CIPHER_SUITE_CCMP:
---	case WLAN_CIPHER_SUITE_CCMP_256:
-- 	case WLAN_CIPHER_SUITE_AES_CMAC:
---	case WLAN_CIPHER_SUITE_BIP_CMAC_256:
---	case WLAN_CIPHER_SUITE_BIP_GMAC_128:
---	case WLAN_CIPHER_SUITE_BIP_GMAC_256:
---	case WLAN_CIPHER_SUITE_GCMP:
---	case WLAN_CIPHER_SUITE_GCMP_256:
-- 		/* all of these we can do in software - if driver can */
-- 		if (ret == 1)
-- 			return 0;
--@@ -394,26 +386,7 @@ ieee80211_key_alloc(u32 cipher, int idx,
-- 		 * Initialize AES key state here as an optimization so that
-- 		 * it does not need to be initialized for every packet.
-- 		 */
---		key->u.ccmp.tfm = ieee80211_aes_key_setup_encrypt(
---			key_data, key_len, IEEE80211_CCMP_MIC_LEN);
---		if (IS_ERR(key->u.ccmp.tfm)) {
---			err = PTR_ERR(key->u.ccmp.tfm);
---			kfree(key);
---			return ERR_PTR(err);
---		}
---		break;
---	case WLAN_CIPHER_SUITE_CCMP_256:
---		key->conf.iv_len = IEEE80211_CCMP_256_HDR_LEN;
---		key->conf.icv_len = IEEE80211_CCMP_256_MIC_LEN;
---		for (i = 0; seq && i < IEEE80211_NUM_TIDS + 1; i++)
---			for (j = 0; j < IEEE80211_CCMP_256_PN_LEN; j++)
---				key->u.ccmp.rx_pn[i][j] =
---					seq[IEEE80211_CCMP_256_PN_LEN - j - 1];
---		/* Initialize AES key state here as an optimization so that
---		 * it does not need to be initialized for every packet.
---		 */
---		key->u.ccmp.tfm = ieee80211_aes_key_setup_encrypt(
---			key_data, key_len, IEEE80211_CCMP_256_MIC_LEN);
--+		key->u.ccmp.tfm = ieee80211_aes_key_setup_encrypt(key_data);
-- 		if (IS_ERR(key->u.ccmp.tfm)) {
-- 			err = PTR_ERR(key->u.ccmp.tfm);
-- 			kfree(key);
--@@ -421,12 +394,8 @@ ieee80211_key_alloc(u32 cipher, int idx,
-- 		}
-- 		break;
-- 	case WLAN_CIPHER_SUITE_AES_CMAC:
---	case WLAN_CIPHER_SUITE_BIP_CMAC_256:
-- 		key->conf.iv_len = 0;
---		if (cipher == WLAN_CIPHER_SUITE_AES_CMAC)
---			key->conf.icv_len = sizeof(struct ieee80211_mmie);
---		else
---			key->conf.icv_len = sizeof(struct ieee80211_mmie_16);
--+		key->conf.icv_len = sizeof(struct ieee80211_mmie);
-- 		if (seq)
-- 			for (j = 0; j < IEEE80211_CMAC_PN_LEN; j++)
-- 				key->u.aes_cmac.rx_pn[j] =
--@@ -436,51 +405,13 @@ ieee80211_key_alloc(u32 cipher, int idx,
-- 		 * it does not need to be initialized for every packet.
-- 		 */
-- 		key->u.aes_cmac.tfm =
---			ieee80211_aes_cmac_key_setup(key_data, key_len);
--+			ieee80211_aes_cmac_key_setup(key_data);
-- 		if (IS_ERR(key->u.aes_cmac.tfm)) {
-- 			err = PTR_ERR(key->u.aes_cmac.tfm);
-- 			kfree(key);
-- 			return ERR_PTR(err);
-- 		}
-- 		break;
---	case WLAN_CIPHER_SUITE_BIP_GMAC_128:
---	case WLAN_CIPHER_SUITE_BIP_GMAC_256:
---		key->conf.iv_len = 0;
---		key->conf.icv_len = sizeof(struct ieee80211_mmie_16);
---		if (seq)
---			for (j = 0; j < IEEE80211_GMAC_PN_LEN; j++)
---				key->u.aes_gmac.rx_pn[j] =
---					seq[IEEE80211_GMAC_PN_LEN - j - 1];
---		/* Initialize AES key state here as an optimization so that
---		 * it does not need to be initialized for every packet.
---		 */
---		key->u.aes_gmac.tfm =
---			ieee80211_aes_gmac_key_setup(key_data, key_len);
---		if (IS_ERR(key->u.aes_gmac.tfm)) {
---			err = PTR_ERR(key->u.aes_gmac.tfm);
---			kfree(key);
---			return ERR_PTR(err);
---		}
---		break;
---	case WLAN_CIPHER_SUITE_GCMP:
---	case WLAN_CIPHER_SUITE_GCMP_256:
---		key->conf.iv_len = IEEE80211_GCMP_HDR_LEN;
---		key->conf.icv_len = IEEE80211_GCMP_MIC_LEN;
---		for (i = 0; seq && i < IEEE80211_NUM_TIDS + 1; i++)
---			for (j = 0; j < IEEE80211_GCMP_PN_LEN; j++)
---				key->u.gcmp.rx_pn[i][j] =
---					seq[IEEE80211_GCMP_PN_LEN - j - 1];
---		/* Initialize AES key state here as an optimization so that
---		 * it does not need to be initialized for every packet.
---		 */
---		key->u.gcmp.tfm = ieee80211_aes_gcm_key_setup_encrypt(key_data,
---								      key_len);
---		if (IS_ERR(key->u.gcmp.tfm)) {
---			err = PTR_ERR(key->u.gcmp.tfm);
---			kfree(key);
---			return ERR_PTR(err);
---		}
---		break;
-- 	default:
-- 		if (cs) {
-- 			size_t len = (seq_len > MAX_PN_LEN) ?
--@@ -502,24 +433,10 @@ ieee80211_key_alloc(u32 cipher, int idx,
-- 
-- static void ieee80211_key_free_common(struct ieee80211_key *key)
-- {
---	switch (key->conf.cipher) {
---	case WLAN_CIPHER_SUITE_CCMP:
---	case WLAN_CIPHER_SUITE_CCMP_256:
--+	if (key->conf.cipher == WLAN_CIPHER_SUITE_CCMP)
-- 		ieee80211_aes_key_free(key->u.ccmp.tfm);
---		break;
---	case WLAN_CIPHER_SUITE_AES_CMAC:
---	case WLAN_CIPHER_SUITE_BIP_CMAC_256:
--+	if (key->conf.cipher == WLAN_CIPHER_SUITE_AES_CMAC)
-- 		ieee80211_aes_cmac_key_free(key->u.aes_cmac.tfm);
---		break;
---	case WLAN_CIPHER_SUITE_BIP_GMAC_128:
---	case WLAN_CIPHER_SUITE_BIP_GMAC_256:
---		ieee80211_aes_gmac_key_free(key->u.aes_gmac.tfm);
---		break;
---	case WLAN_CIPHER_SUITE_GCMP:
---	case WLAN_CIPHER_SUITE_GCMP_256:
---		ieee80211_aes_gcm_key_free(key->u.gcmp.tfm);
---		break;
---	}
-- 	kzfree(key);
-- }
-- 
--@@ -826,7 +743,6 @@ void ieee80211_get_key_tx_seq(struct iee
-- 		seq->tkip.iv16 = key->u.tkip.tx.iv16;
-- 		break;
-- 	case WLAN_CIPHER_SUITE_CCMP:
---	case WLAN_CIPHER_SUITE_CCMP_256:
-- 		pn64 = atomic64_read(&key->u.ccmp.tx_pn);
-- 		seq->ccmp.pn[5] = pn64;
-- 		seq->ccmp.pn[4] = pn64 >> 8;
--@@ -836,7 +752,6 @@ void ieee80211_get_key_tx_seq(struct iee
-- 		seq->ccmp.pn[0] = pn64 >> 40;
-- 		break;
-- 	case WLAN_CIPHER_SUITE_AES_CMAC:
---	case WLAN_CIPHER_SUITE_BIP_CMAC_256:
-- 		pn64 = atomic64_read(&key->u.aes_cmac.tx_pn);
-- 		seq->ccmp.pn[5] = pn64;
-- 		seq->ccmp.pn[4] = pn64 >> 8;
--@@ -845,26 +760,6 @@ void ieee80211_get_key_tx_seq(struct iee
-- 		seq->ccmp.pn[1] = pn64 >> 32;
-- 		seq->ccmp.pn[0] = pn64 >> 40;
-- 		break;
---	case WLAN_CIPHER_SUITE_BIP_GMAC_128:
---	case WLAN_CIPHER_SUITE_BIP_GMAC_256:
---		pn64 = atomic64_read(&key->u.aes_gmac.tx_pn);
---		seq->ccmp.pn[5] = pn64;
---		seq->ccmp.pn[4] = pn64 >> 8;
---		seq->ccmp.pn[3] = pn64 >> 16;
---		seq->ccmp.pn[2] = pn64 >> 24;
---		seq->ccmp.pn[1] = pn64 >> 32;
---		seq->ccmp.pn[0] = pn64 >> 40;
---		break;
---	case WLAN_CIPHER_SUITE_GCMP:
---	case WLAN_CIPHER_SUITE_GCMP_256:
---		pn64 = atomic64_read(&key->u.gcmp.tx_pn);
---		seq->gcmp.pn[5] = pn64;
---		seq->gcmp.pn[4] = pn64 >> 8;
---		seq->gcmp.pn[3] = pn64 >> 16;
---		seq->gcmp.pn[2] = pn64 >> 24;
---		seq->gcmp.pn[1] = pn64 >> 32;
---		seq->gcmp.pn[0] = pn64 >> 40;
---		break;
-- 	default:
-- 		WARN_ON(1);
-- 	}
--@@ -887,7 +782,6 @@ void ieee80211_get_key_rx_seq(struct iee
-- 		seq->tkip.iv16 = key->u.tkip.rx[tid].iv16;
-- 		break;
-- 	case WLAN_CIPHER_SUITE_CCMP:
---	case WLAN_CIPHER_SUITE_CCMP_256:
-- 		if (WARN_ON(tid < -1 || tid >= IEEE80211_NUM_TIDS))
-- 			return;
-- 		if (tid < 0)
--@@ -897,29 +791,11 @@ void ieee80211_get_key_rx_seq(struct iee
-- 		memcpy(seq->ccmp.pn, pn, IEEE80211_CCMP_PN_LEN);
-- 		break;
-- 	case WLAN_CIPHER_SUITE_AES_CMAC:
---	case WLAN_CIPHER_SUITE_BIP_CMAC_256:
-- 		if (WARN_ON(tid != 0))
-- 			return;
-- 		pn = key->u.aes_cmac.rx_pn;
-- 		memcpy(seq->aes_cmac.pn, pn, IEEE80211_CMAC_PN_LEN);
-- 		break;
---	case WLAN_CIPHER_SUITE_BIP_GMAC_128:
---	case WLAN_CIPHER_SUITE_BIP_GMAC_256:
---		if (WARN_ON(tid != 0))
---			return;
---		pn = key->u.aes_gmac.rx_pn;
---		memcpy(seq->aes_gmac.pn, pn, IEEE80211_GMAC_PN_LEN);
---		break;
---	case WLAN_CIPHER_SUITE_GCMP:
---	case WLAN_CIPHER_SUITE_GCMP_256:
---		if (WARN_ON(tid < -1 || tid >= IEEE80211_NUM_TIDS))
---			return;
---		if (tid < 0)
---			pn = key->u.gcmp.rx_pn[IEEE80211_NUM_TIDS];
---		else
---			pn = key->u.gcmp.rx_pn[tid];
---		memcpy(seq->gcmp.pn, pn, IEEE80211_GCMP_PN_LEN);
---		break;
-- 	}
-- }
-- EXPORT_SYMBOL(ieee80211_get_key_rx_seq);
--@@ -938,7 +814,6 @@ void ieee80211_set_key_tx_seq(struct iee
-- 		key->u.tkip.tx.iv16 = seq->tkip.iv16;
-- 		break;
-- 	case WLAN_CIPHER_SUITE_CCMP:
---	case WLAN_CIPHER_SUITE_CCMP_256:
-- 		pn64 = (u64)seq->ccmp.pn[5] |
-- 		       ((u64)seq->ccmp.pn[4] << 8) |
-- 		       ((u64)seq->ccmp.pn[3] << 16) |
--@@ -948,7 +823,6 @@ void ieee80211_set_key_tx_seq(struct iee
-- 		atomic64_set(&key->u.ccmp.tx_pn, pn64);
-- 		break;
-- 	case WLAN_CIPHER_SUITE_AES_CMAC:
---	case WLAN_CIPHER_SUITE_BIP_CMAC_256:
-- 		pn64 = (u64)seq->aes_cmac.pn[5] |
-- 		       ((u64)seq->aes_cmac.pn[4] << 8) |
-- 		       ((u64)seq->aes_cmac.pn[3] << 16) |
--@@ -957,26 +831,6 @@ void ieee80211_set_key_tx_seq(struct iee
-- 		       ((u64)seq->aes_cmac.pn[0] << 40);
-- 		atomic64_set(&key->u.aes_cmac.tx_pn, pn64);
-- 		break;
---	case WLAN_CIPHER_SUITE_BIP_GMAC_128:
---	case WLAN_CIPHER_SUITE_BIP_GMAC_256:
---		pn64 = (u64)seq->aes_gmac.pn[5] |
---		       ((u64)seq->aes_gmac.pn[4] << 8) |
---		       ((u64)seq->aes_gmac.pn[3] << 16) |
---		       ((u64)seq->aes_gmac.pn[2] << 24) |
---		       ((u64)seq->aes_gmac.pn[1] << 32) |
---		       ((u64)seq->aes_gmac.pn[0] << 40);
---		atomic64_set(&key->u.aes_gmac.tx_pn, pn64);
---		break;
---	case WLAN_CIPHER_SUITE_GCMP:
---	case WLAN_CIPHER_SUITE_GCMP_256:
---		pn64 = (u64)seq->gcmp.pn[5] |
---		       ((u64)seq->gcmp.pn[4] << 8) |
---		       ((u64)seq->gcmp.pn[3] << 16) |
---		       ((u64)seq->gcmp.pn[2] << 24) |
---		       ((u64)seq->gcmp.pn[1] << 32) |
---		       ((u64)seq->gcmp.pn[0] << 40);
---		atomic64_set(&key->u.gcmp.tx_pn, pn64);
---		break;
-- 	default:
-- 		WARN_ON(1);
-- 		break;
--@@ -1000,7 +854,6 @@ void ieee80211_set_key_rx_seq(struct iee
-- 		key->u.tkip.rx[tid].iv16 = seq->tkip.iv16;
-- 		break;
-- 	case WLAN_CIPHER_SUITE_CCMP:
---	case WLAN_CIPHER_SUITE_CCMP_256:
-- 		if (WARN_ON(tid < -1 || tid >= IEEE80211_NUM_TIDS))
-- 			return;
-- 		if (tid < 0)
--@@ -1010,29 +863,11 @@ void ieee80211_set_key_rx_seq(struct iee
-- 		memcpy(pn, seq->ccmp.pn, IEEE80211_CCMP_PN_LEN);
-- 		break;
-- 	case WLAN_CIPHER_SUITE_AES_CMAC:
---	case WLAN_CIPHER_SUITE_BIP_CMAC_256:
-- 		if (WARN_ON(tid != 0))
-- 			return;
-- 		pn = key->u.aes_cmac.rx_pn;
-- 		memcpy(pn, seq->aes_cmac.pn, IEEE80211_CMAC_PN_LEN);
-- 		break;
---	case WLAN_CIPHER_SUITE_BIP_GMAC_128:
---	case WLAN_CIPHER_SUITE_BIP_GMAC_256:
---		if (WARN_ON(tid != 0))
---			return;
---		pn = key->u.aes_gmac.rx_pn;
---		memcpy(pn, seq->aes_gmac.pn, IEEE80211_GMAC_PN_LEN);
---		break;
---	case WLAN_CIPHER_SUITE_GCMP:
---	case WLAN_CIPHER_SUITE_GCMP_256:
---		if (WARN_ON(tid < -1 || tid >= IEEE80211_NUM_TIDS))
---			return;
---		if (tid < 0)
---			pn = key->u.gcmp.rx_pn[IEEE80211_NUM_TIDS];
---		else
---			pn = key->u.gcmp.rx_pn[tid];
---		memcpy(pn, seq->gcmp.pn, IEEE80211_GCMP_PN_LEN);
---		break;
-- 	default:
-- 		WARN_ON(1);
-- 		break;
----- a/net/mac80211/key.h
--+++ b/net/mac80211/key.h
--@@ -84,7 +84,7 @@ struct ieee80211_key {
-- 			 * Management frames.
-- 			 */
-- 			u8 rx_pn[IEEE80211_NUM_TIDS + 1][IEEE80211_CCMP_PN_LEN];
---			struct crypto_aead *tfm;
--+			struct crypto_cipher *tfm;
-- 			u32 replays; /* dot11RSNAStatsCCMPReplays */
-- 		} ccmp;
-- 		struct {
--@@ -95,24 +95,6 @@ struct ieee80211_key {
-- 			u32 icverrors; /* dot11RSNAStatsCMACICVErrors */
-- 		} aes_cmac;
-- 		struct {
---			atomic64_t tx_pn;
---			u8 rx_pn[IEEE80211_GMAC_PN_LEN];
---			struct crypto_aead *tfm;
---			u32 replays; /* dot11RSNAStatsCMACReplays */
---			u32 icverrors; /* dot11RSNAStatsCMACICVErrors */
---		} aes_gmac;
---		struct {
---			atomic64_t tx_pn;
---			/* Last received packet number. The first
---			 * IEEE80211_NUM_TIDS counters are used with Data
---			 * frames and the last counter is used with Robust
---			 * Management frames.
---			 */
---			u8 rx_pn[IEEE80211_NUM_TIDS + 1][IEEE80211_GCMP_PN_LEN];
---			struct crypto_aead *tfm;
---			u32 replays; /* dot11RSNAStatsGCMPReplays */
---		} gcmp;
---		struct {
-- 			/* generic cipher scheme */
-- 			u8 rx_pn[IEEE80211_NUM_TIDS + 1][MAX_PN_LEN];
-- 		} gen;
----- a/net/mac80211/main.c
--+++ b/net/mac80211/main.c
--@@ -666,15 +666,9 @@ static int ieee80211_init_cipher_suites(
-- 		WLAN_CIPHER_SUITE_WEP104,
-- 		WLAN_CIPHER_SUITE_TKIP,
-- 		WLAN_CIPHER_SUITE_CCMP,
---		WLAN_CIPHER_SUITE_CCMP_256,
---		WLAN_CIPHER_SUITE_GCMP,
---		WLAN_CIPHER_SUITE_GCMP_256,
-- 
-- 		/* keep last -- depends on hw flags! */
---		WLAN_CIPHER_SUITE_AES_CMAC,
---		WLAN_CIPHER_SUITE_BIP_CMAC_256,
---		WLAN_CIPHER_SUITE_BIP_GMAC_128,
---		WLAN_CIPHER_SUITE_BIP_GMAC_256,
--+		WLAN_CIPHER_SUITE_AES_CMAC
-- 	};
-- 
-- 	if (local->hw.flags & IEEE80211_HW_SW_CRYPTO_CONTROL ||
--@@ -713,7 +707,7 @@ static int ieee80211_init_cipher_suites(
-- 		local->hw.wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);
-- 
-- 		if (!have_mfp)
---			local->hw.wiphy->n_cipher_suites -= 4;
--+			local->hw.wiphy->n_cipher_suites--;
-- 
-- 		if (!have_wep) {
-- 			local->hw.wiphy->cipher_suites += 2;
--@@ -730,42 +724,32 @@ static int ieee80211_init_cipher_suites(
-- 		/* Driver specifies cipher schemes only (but not cipher suites
-- 		 * including the schemes)
-- 		 *
---		 * We start counting ciphers defined by schemes, TKIP, CCMP,
---		 * CCMP-256, GCMP, and GCMP-256
--+		 * We start counting ciphers defined by schemes, TKIP and CCMP
-- 		 */
---		n_suites = local->hw.n_cipher_schemes + 5;
--+		n_suites = local->hw.n_cipher_schemes + 2;
-- 
-- 		/* check if we have WEP40 and WEP104 */
-- 		if (have_wep)
-- 			n_suites += 2;
-- 
---		/* check if we have AES_CMAC, BIP-CMAC-256, BIP-GMAC-128,
---		 * BIP-GMAC-256
---		 */
--+		/* check if we have AES_CMAC */
-- 		if (have_mfp)
---			n_suites += 4;
--+			n_suites++;
-- 
-- 		suites = kmalloc(sizeof(u32) * n_suites, GFP_KERNEL);
-- 		if (!suites)
-- 			return -ENOMEM;
-- 
-- 		suites[w++] = WLAN_CIPHER_SUITE_CCMP;
---		suites[w++] = WLAN_CIPHER_SUITE_CCMP_256;
-- 		suites[w++] = WLAN_CIPHER_SUITE_TKIP;
---		suites[w++] = WLAN_CIPHER_SUITE_GCMP;
---		suites[w++] = WLAN_CIPHER_SUITE_GCMP_256;
-- 
-- 		if (have_wep) {
-- 			suites[w++] = WLAN_CIPHER_SUITE_WEP40;
-- 			suites[w++] = WLAN_CIPHER_SUITE_WEP104;
-- 		}
-- 
---		if (have_mfp) {
--+		if (have_mfp)
-- 			suites[w++] = WLAN_CIPHER_SUITE_AES_CMAC;
---			suites[w++] = WLAN_CIPHER_SUITE_BIP_CMAC_256;
---			suites[w++] = WLAN_CIPHER_SUITE_BIP_GMAC_128;
---			suites[w++] = WLAN_CIPHER_SUITE_BIP_GMAC_256;
---		}
-- 
-- 		for (r = 0; r < local->hw.n_cipher_schemes; r++)
-- 			suites[w++] = cs[r].cipher;
----- a/net/mac80211/rx.c
--+++ b/net/mac80211/rx.c
--@@ -647,7 +647,6 @@ static int ieee80211_get_mmie_keyidx(str
-- {
-- 	struct ieee80211_mgmt *hdr = (struct ieee80211_mgmt *) skb->data;
-- 	struct ieee80211_mmie *mmie;
---	struct ieee80211_mmie_16 *mmie16;
-- 
-- 	if (skb->len < 24 + sizeof(*mmie) || !is_multicast_ether_addr(hdr->da))
-- 		return -1;
--@@ -657,18 +656,11 @@ static int ieee80211_get_mmie_keyidx(str
-- 
-- 	mmie = (struct ieee80211_mmie *)
-- 		(skb->data + skb->len - sizeof(*mmie));
---	if (mmie->element_id == WLAN_EID_MMIE &&
---	    mmie->length == sizeof(*mmie) - 2)
---		return le16_to_cpu(mmie->key_id);
---
---	mmie16 = (struct ieee80211_mmie_16 *)
---		(skb->data + skb->len - sizeof(*mmie16));
---	if (skb->len >= 24 + sizeof(*mmie16) &&
---	    mmie16->element_id == WLAN_EID_MMIE &&
---	    mmie16->length == sizeof(*mmie16) - 2)
---		return le16_to_cpu(mmie16->key_id);
--+	if (mmie->element_id != WLAN_EID_MMIE ||
--+	    mmie->length != sizeof(*mmie) - 2)
--+		return -1;
-- 
---	return -1;
--+	return le16_to_cpu(mmie->key_id);
-- }
-- 
-- static int iwl80211_get_cs_keyid(const struct ieee80211_cipher_scheme *cs,
--@@ -1658,27 +1650,11 @@ ieee80211_rx_h_decrypt(struct ieee80211_
-- 		result = ieee80211_crypto_tkip_decrypt(rx);
-- 		break;
-- 	case WLAN_CIPHER_SUITE_CCMP:
---		result = ieee80211_crypto_ccmp_decrypt(
---			rx, IEEE80211_CCMP_MIC_LEN);
---		break;
---	case WLAN_CIPHER_SUITE_CCMP_256:
---		result = ieee80211_crypto_ccmp_decrypt(
---			rx, IEEE80211_CCMP_256_MIC_LEN);
--+		result = ieee80211_crypto_ccmp_decrypt(rx);
-- 		break;
-- 	case WLAN_CIPHER_SUITE_AES_CMAC:
-- 		result = ieee80211_crypto_aes_cmac_decrypt(rx);
-- 		break;
---	case WLAN_CIPHER_SUITE_BIP_CMAC_256:
---		result = ieee80211_crypto_aes_cmac_256_decrypt(rx);
---		break;
---	case WLAN_CIPHER_SUITE_BIP_GMAC_128:
---	case WLAN_CIPHER_SUITE_BIP_GMAC_256:
---		result = ieee80211_crypto_aes_gmac_decrypt(rx);
---		break;
---	case WLAN_CIPHER_SUITE_GCMP:
---	case WLAN_CIPHER_SUITE_GCMP_256:
---		result = ieee80211_crypto_gcmp_decrypt(rx);
---		break;
-- 	default:
-- 		result = ieee80211_crypto_hw_decrypt(rx);
-- 	}
--@@ -1805,9 +1781,7 @@ ieee80211_rx_h_defragment(struct ieee802
-- 		/* This is the first fragment of a new frame. */
-- 		entry = ieee80211_reassemble_add(rx->sdata, frag, seq,
-- 						 rx->seqno_idx, &(rx->skb));
---		if (rx->key &&
---		    (rx->key->conf.cipher == WLAN_CIPHER_SUITE_CCMP ||
---		     rx->key->conf.cipher == WLAN_CIPHER_SUITE_CCMP_256) &&
--+		if (rx->key && rx->key->conf.cipher == WLAN_CIPHER_SUITE_CCMP &&
-- 		    ieee80211_has_protected(fc)) {
-- 			int queue = rx->security_idx;
-- 			/* Store CCMP PN so that we can verify that the next
--@@ -1836,9 +1810,7 @@ ieee80211_rx_h_defragment(struct ieee802
-- 		int i;
-- 		u8 pn[IEEE80211_CCMP_PN_LEN], *rpn;
-- 		int queue;
---		if (!rx->key ||
---		    (rx->key->conf.cipher != WLAN_CIPHER_SUITE_CCMP &&
---		     rx->key->conf.cipher != WLAN_CIPHER_SUITE_CCMP_256))
--+		if (!rx->key || rx->key->conf.cipher != WLAN_CIPHER_SUITE_CCMP)
-- 			return RX_DROP_UNUSABLE;
-- 		memcpy(pn, entry->last_pn, IEEE80211_CCMP_PN_LEN);
-- 		for (i = IEEE80211_CCMP_PN_LEN - 1; i >= 0; i--) {
----- a/net/mac80211/tx.c
--+++ b/net/mac80211/tx.c
--@@ -626,9 +626,6 @@ ieee80211_tx_h_select_key(struct ieee802
-- 				tx->key = NULL;
-- 			break;
-- 		case WLAN_CIPHER_SUITE_CCMP:
---		case WLAN_CIPHER_SUITE_CCMP_256:
---		case WLAN_CIPHER_SUITE_GCMP:
---		case WLAN_CIPHER_SUITE_GCMP_256:
-- 			if (!ieee80211_is_data_present(hdr->frame_control) &&
-- 			    !ieee80211_use_mfp(hdr->frame_control, tx->sta,
-- 					       tx->skb))
--@@ -639,9 +636,6 @@ ieee80211_tx_h_select_key(struct ieee802
-- 					ieee80211_is_mgmt(hdr->frame_control);
-- 			break;
-- 		case WLAN_CIPHER_SUITE_AES_CMAC:
---		case WLAN_CIPHER_SUITE_BIP_CMAC_256:
---		case WLAN_CIPHER_SUITE_BIP_GMAC_128:
---		case WLAN_CIPHER_SUITE_BIP_GMAC_256:
-- 			if (!ieee80211_is_mgmt(hdr->frame_control))
-- 				tx->key = NULL;
-- 			break;
--@@ -1017,21 +1011,9 @@ ieee80211_tx_h_encrypt(struct ieee80211_
-- 	case WLAN_CIPHER_SUITE_TKIP:
-- 		return ieee80211_crypto_tkip_encrypt(tx);
-- 	case WLAN_CIPHER_SUITE_CCMP:
---		return ieee80211_crypto_ccmp_encrypt(
---			tx, IEEE80211_CCMP_MIC_LEN);
---	case WLAN_CIPHER_SUITE_CCMP_256:
---		return ieee80211_crypto_ccmp_encrypt(
---			tx, IEEE80211_CCMP_256_MIC_LEN);
--+		return ieee80211_crypto_ccmp_encrypt(tx);
-- 	case WLAN_CIPHER_SUITE_AES_CMAC:
-- 		return ieee80211_crypto_aes_cmac_encrypt(tx);
---	case WLAN_CIPHER_SUITE_BIP_CMAC_256:
---		return ieee80211_crypto_aes_cmac_256_encrypt(tx);
---	case WLAN_CIPHER_SUITE_BIP_GMAC_128:
---	case WLAN_CIPHER_SUITE_BIP_GMAC_256:
---		return ieee80211_crypto_aes_gmac_encrypt(tx);
---	case WLAN_CIPHER_SUITE_GCMP:
---	case WLAN_CIPHER_SUITE_GCMP_256:
---		return ieee80211_crypto_gcmp_encrypt(tx);
-- 	default:
-- 		return ieee80211_crypto_hw_encrypt(tx);
-- 	}
----- a/net/mac80211/wpa.c
--+++ b/net/mac80211/wpa.c
--@@ -22,8 +22,6 @@
-- #include "tkip.h"
-- #include "aes_ccm.h"
-- #include "aes_cmac.h"
---#include "aes_gmac.h"
---#include "aes_gcm.h"
-- #include "wpa.h"
-- 
-- ieee80211_tx_result
--@@ -304,15 +302,22 @@ ieee80211_crypto_tkip_decrypt(struct iee
-- }
-- 
-- 
---static void ccmp_special_blocks(struct sk_buff *skb, u8 *pn, u8 *b_0, u8 *aad)
--+static void ccmp_special_blocks(struct sk_buff *skb, u8 *pn, u8 *scratch,
--+				int encrypted)
-- {
-- 	__le16 mask_fc;
-- 	int a4_included, mgmt;
-- 	u8 qos_tid;
---	u16 len_a;
--+	u8 *b_0, *aad;
--+	u16 data_len, len_a;
-- 	unsigned int hdrlen;
-- 	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
-- 
--+	memset(scratch, 0, 6 * AES_BLOCK_SIZE);
--+
--+	b_0 = scratch + 3 * AES_BLOCK_SIZE;
--+	aad = scratch + 4 * AES_BLOCK_SIZE;
--+
-- 	/*
-- 	 * Mask FC: zero subtype b4 b5 b6 (if not mgmt)
-- 	 * Retry, PwrMgt, MoreData; set Protected
--@@ -334,21 +339,20 @@ static void ccmp_special_blocks(struct s
-- 	else
-- 		qos_tid = 0;
-- 
---	/* In CCM, the initial vectors (IV) used for CTR mode encryption and CBC
---	 * mode authentication are not allowed to collide, yet both are derived
---	 * from this vector b_0. We only set L := 1 here to indicate that the
---	 * data size can be represented in (L+1) bytes. The CCM layer will take
---	 * care of storing the data length in the top (L+1) bytes and setting
---	 * and clearing the other bits as is required to derive the two IVs.
---	 */
---	b_0[0] = 0x1;
--+	data_len = skb->len - hdrlen - IEEE80211_CCMP_HDR_LEN;
--+	if (encrypted)
--+		data_len -= IEEE80211_CCMP_MIC_LEN;
-- 
--+	/* First block, b_0 */
--+	b_0[0] = 0x59; /* flags: Adata: 1, M: 011, L: 001 */
-- 	/* Nonce: Nonce Flags | A2 | PN
-- 	 * Nonce Flags: Priority (b0..b3) | Management (b4) | Reserved (b5..b7)
-- 	 */
-- 	b_0[1] = qos_tid | (mgmt << 4);
-- 	memcpy(&b_0[2], hdr->addr2, ETH_ALEN);
-- 	memcpy(&b_0[8], pn, IEEE80211_CCMP_PN_LEN);
--+	/* l(m) */
--+	put_unaligned_be16(data_len, &b_0[14]);
-- 
-- 	/* AAD (extra authenticate-only data) / masked 802.11 header
-- 	 * FC | A1 | A2 | A3 | SC | [A4] | [QC] */
--@@ -395,8 +399,7 @@ static inline void ccmp_hdr2pn(u8 *pn, u
-- }
-- 
-- 
---static int ccmp_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb,
---			    unsigned int mic_len)
--+static int ccmp_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb)
-- {
-- 	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
-- 	struct ieee80211_key *key = tx->key;
--@@ -405,8 +408,7 @@ static int ccmp_encrypt_skb(struct ieee8
-- 	u8 *pos;
-- 	u8 pn[6];
-- 	u64 pn64;
---	u8 aad[2 * AES_BLOCK_SIZE];
---	u8 b_0[AES_BLOCK_SIZE];
--+	u8 scratch[6 * AES_BLOCK_SIZE];
-- 
-- 	if (info->control.hw_key &&
-- 	    !(info->control.hw_key->flags & IEEE80211_KEY_FLAG_GENERATE_IV) &&
--@@ -427,7 +429,7 @@ static int ccmp_encrypt_skb(struct ieee8
-- 	if (info->control.hw_key)
-- 		tail = 0;
-- 	else
---		tail = mic_len;
--+		tail = IEEE80211_CCMP_MIC_LEN;
-- 
-- 	if (WARN_ON(skb_tailroom(skb) < tail ||
-- 		    skb_headroom(skb) < IEEE80211_CCMP_HDR_LEN))
--@@ -460,24 +462,23 @@ static int ccmp_encrypt_skb(struct ieee8
-- 		return 0;
-- 
-- 	pos += IEEE80211_CCMP_HDR_LEN;
---	ccmp_special_blocks(skb, pn, b_0, aad);
---	ieee80211_aes_ccm_encrypt(key->u.ccmp.tfm, b_0, aad, pos, len,
---				  skb_put(skb, mic_len), mic_len);
--+	ccmp_special_blocks(skb, pn, scratch, 0);
--+	ieee80211_aes_ccm_encrypt(key->u.ccmp.tfm, scratch, pos, len,
--+				  pos, skb_put(skb, IEEE80211_CCMP_MIC_LEN));
-- 
-- 	return 0;
-- }
-- 
-- 
-- ieee80211_tx_result
---ieee80211_crypto_ccmp_encrypt(struct ieee80211_tx_data *tx,
---			      unsigned int mic_len)
--+ieee80211_crypto_ccmp_encrypt(struct ieee80211_tx_data *tx)
-- {
-- 	struct sk_buff *skb;
-- 
-- 	ieee80211_tx_set_protected(tx);
-- 
-- 	skb_queue_walk(&tx->skbs, skb) {
---		if (ccmp_encrypt_skb(tx, skb, mic_len) < 0)
--+		if (ccmp_encrypt_skb(tx, skb) < 0)
-- 			return TX_DROP;
-- 	}
-- 
--@@ -486,8 +487,7 @@ ieee80211_crypto_ccmp_encrypt(struct iee
-- 
-- 
-- ieee80211_rx_result
---ieee80211_crypto_ccmp_decrypt(struct ieee80211_rx_data *rx,
---			      unsigned int mic_len)
--+ieee80211_crypto_ccmp_decrypt(struct ieee80211_rx_data *rx)
-- {
-- 	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data;
-- 	int hdrlen;
--@@ -504,7 +504,8 @@ ieee80211_crypto_ccmp_decrypt(struct iee
-- 	    !ieee80211_is_robust_mgmt_frame(skb))
-- 		return RX_CONTINUE;
-- 
---	data_len = skb->len - hdrlen - IEEE80211_CCMP_HDR_LEN - mic_len;
--+	data_len = skb->len - hdrlen - IEEE80211_CCMP_HDR_LEN -
--+		   IEEE80211_CCMP_MIC_LEN;
-- 	if (!rx->sta || data_len < 0)
-- 		return RX_DROP_UNUSABLE;
-- 
--@@ -526,23 +527,23 @@ ieee80211_crypto_ccmp_decrypt(struct iee
-- 	}
-- 
-- 	if (!(status->flag & RX_FLAG_DECRYPTED)) {
---		u8 aad[2 * AES_BLOCK_SIZE];
---		u8 b_0[AES_BLOCK_SIZE];
--+		u8 scratch[6 * AES_BLOCK_SIZE];
-- 		/* hardware didn't decrypt/verify MIC */
---		ccmp_special_blocks(skb, pn, b_0, aad);
--+		ccmp_special_blocks(skb, pn, scratch, 1);
-- 
-- 		if (ieee80211_aes_ccm_decrypt(
---			    key->u.ccmp.tfm, b_0, aad,
--+			    key->u.ccmp.tfm, scratch,
-- 			    skb->data + hdrlen + IEEE80211_CCMP_HDR_LEN,
-- 			    data_len,
---			    skb->data + skb->len - mic_len, mic_len))
--+			    skb->data + skb->len - IEEE80211_CCMP_MIC_LEN,
--+			    skb->data + hdrlen + IEEE80211_CCMP_HDR_LEN))
-- 			return RX_DROP_UNUSABLE;
-- 	}
-- 
-- 	memcpy(key->u.ccmp.rx_pn[queue], pn, IEEE80211_CCMP_PN_LEN);
-- 
-- 	/* Remove CCMP header and MIC */
---	if (pskb_trim(skb, skb->len - mic_len))
--+	if (pskb_trim(skb, skb->len - IEEE80211_CCMP_MIC_LEN))
-- 		return RX_DROP_UNUSABLE;
-- 	memmove(skb->data + IEEE80211_CCMP_HDR_LEN, skb->data, hdrlen);
-- 	skb_pull(skb, IEEE80211_CCMP_HDR_LEN);
--@@ -550,229 +551,6 @@ ieee80211_crypto_ccmp_decrypt(struct iee
-- 	return RX_CONTINUE;
-- }
-- 
---static void gcmp_special_blocks(struct sk_buff *skb, u8 *pn, u8 *j_0, u8 *aad)
---{
---	__le16 mask_fc;
---	u8 qos_tid;
---	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
---
---	memcpy(j_0, hdr->addr2, ETH_ALEN);
---	memcpy(&j_0[ETH_ALEN], pn, IEEE80211_GCMP_PN_LEN);
---	j_0[13] = 0;
---	j_0[14] = 0;
---	j_0[AES_BLOCK_SIZE - 1] = 0x01;
---
---	/* AAD (extra authenticate-only data) / masked 802.11 header
---	 * FC | A1 | A2 | A3 | SC | [A4] | [QC]
---	 */
---	put_unaligned_be16(ieee80211_hdrlen(hdr->frame_control) - 2, &aad[0]);
---	/* Mask FC: zero subtype b4 b5 b6 (if not mgmt)
---	 * Retry, PwrMgt, MoreData; set Protected
---	 */
---	mask_fc = hdr->frame_control;
---	mask_fc &= ~cpu_to_le16(IEEE80211_FCTL_RETRY |
---				IEEE80211_FCTL_PM | IEEE80211_FCTL_MOREDATA);
---	if (!ieee80211_is_mgmt(hdr->frame_control))
---		mask_fc &= ~cpu_to_le16(0x0070);
---	mask_fc |= cpu_to_le16(IEEE80211_FCTL_PROTECTED);
---
---	put_unaligned(mask_fc, (__le16 *)&aad[2]);
---	memcpy(&aad[4], &hdr->addr1, 3 * ETH_ALEN);
---
---	/* Mask Seq#, leave Frag# */
---	aad[22] = *((u8 *)&hdr->seq_ctrl) & 0x0f;
---	aad[23] = 0;
---
---	if (ieee80211_is_data_qos(hdr->frame_control))
---		qos_tid = *ieee80211_get_qos_ctl(hdr) &
---			IEEE80211_QOS_CTL_TID_MASK;
---	else
---		qos_tid = 0;
---
---	if (ieee80211_has_a4(hdr->frame_control)) {
---		memcpy(&aad[24], hdr->addr4, ETH_ALEN);
---		aad[30] = qos_tid;
---		aad[31] = 0;
---	} else {
---		memset(&aad[24], 0, ETH_ALEN + IEEE80211_QOS_CTL_LEN);
---		aad[24] = qos_tid;
---	}
---}
---
---static inline void gcmp_pn2hdr(u8 *hdr, const u8 *pn, int key_id)
---{
---	hdr[0] = pn[5];
---	hdr[1] = pn[4];
---	hdr[2] = 0;
---	hdr[3] = 0x20 | (key_id << 6);
---	hdr[4] = pn[3];
---	hdr[5] = pn[2];
---	hdr[6] = pn[1];
---	hdr[7] = pn[0];
---}
---
---static inline void gcmp_hdr2pn(u8 *pn, const u8 *hdr)
---{
---	pn[0] = hdr[7];
---	pn[1] = hdr[6];
---	pn[2] = hdr[5];
---	pn[3] = hdr[4];
---	pn[4] = hdr[1];
---	pn[5] = hdr[0];
---}
---
---static int gcmp_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb)
---{
---	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
---	struct ieee80211_key *key = tx->key;
---	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
---	int hdrlen, len, tail;
---	u8 *pos;
---	u8 pn[6];
---	u64 pn64;
---	u8 aad[2 * AES_BLOCK_SIZE];
---	u8 j_0[AES_BLOCK_SIZE];
---
---	if (info->control.hw_key &&
---	    !(info->control.hw_key->flags & IEEE80211_KEY_FLAG_GENERATE_IV) &&
---	    !(info->control.hw_key->flags & IEEE80211_KEY_FLAG_PUT_IV_SPACE) &&
---	    !((info->control.hw_key->flags &
---	       IEEE80211_KEY_FLAG_GENERATE_IV_MGMT) &&
---	      ieee80211_is_mgmt(hdr->frame_control))) {
---		/* hwaccel has no need for preallocated room for GCMP
---		 * header or MIC fields
---		 */
---		return 0;
---	}
---
---	hdrlen = ieee80211_hdrlen(hdr->frame_control);
---	len = skb->len - hdrlen;
---
---	if (info->control.hw_key)
---		tail = 0;
---	else
---		tail = IEEE80211_GCMP_MIC_LEN;
---
---	if (WARN_ON(skb_tailroom(skb) < tail ||
---		    skb_headroom(skb) < IEEE80211_GCMP_HDR_LEN))
---		return -1;
---
---	pos = skb_push(skb, IEEE80211_GCMP_HDR_LEN);
---	memmove(pos, pos + IEEE80211_GCMP_HDR_LEN, hdrlen);
---	skb_set_network_header(skb, skb_network_offset(skb) +
---				    IEEE80211_GCMP_HDR_LEN);
---
---	/* the HW only needs room for the IV, but not the actual IV */
---	if (info->control.hw_key &&
---	    (info->control.hw_key->flags & IEEE80211_KEY_FLAG_PUT_IV_SPACE))
---		return 0;
---
---	hdr = (struct ieee80211_hdr *)pos;
---	pos += hdrlen;
---
---	pn64 = atomic64_inc_return(&key->u.gcmp.tx_pn);
---
---	pn[5] = pn64;
---	pn[4] = pn64 >> 8;
---	pn[3] = pn64 >> 16;
---	pn[2] = pn64 >> 24;
---	pn[1] = pn64 >> 32;
---	pn[0] = pn64 >> 40;
---
---	gcmp_pn2hdr(pos, pn, key->conf.keyidx);
---
---	/* hwaccel - with software GCMP header */
---	if (info->control.hw_key)
---		return 0;
---
---	pos += IEEE80211_GCMP_HDR_LEN;
---	gcmp_special_blocks(skb, pn, j_0, aad);
---	ieee80211_aes_gcm_encrypt(key->u.gcmp.tfm, j_0, aad, pos, len,
---				  skb_put(skb, IEEE80211_GCMP_MIC_LEN));
---
---	return 0;
---}
---
---ieee80211_tx_result
---ieee80211_crypto_gcmp_encrypt(struct ieee80211_tx_data *tx)
---{
---	struct sk_buff *skb;
---
---	ieee80211_tx_set_protected(tx);
---
---	skb_queue_walk(&tx->skbs, skb) {
---		if (gcmp_encrypt_skb(tx, skb) < 0)
---			return TX_DROP;
---	}
---
---	return TX_CONTINUE;
---}
---
---ieee80211_rx_result
---ieee80211_crypto_gcmp_decrypt(struct ieee80211_rx_data *rx)
---{
---	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data;
---	int hdrlen;
---	struct ieee80211_key *key = rx->key;
---	struct sk_buff *skb = rx->skb;
---	struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
---	u8 pn[IEEE80211_GCMP_PN_LEN];
---	int data_len;
---	int queue;
---
---	hdrlen = ieee80211_hdrlen(hdr->frame_control);
---
---	if (!ieee80211_is_data(hdr->frame_control) &&
---	    !ieee80211_is_robust_mgmt_frame(skb))
---		return RX_CONTINUE;
---
---	data_len = skb->len - hdrlen - IEEE80211_GCMP_HDR_LEN -
---		   IEEE80211_GCMP_MIC_LEN;
---	if (!rx->sta || data_len < 0)
---		return RX_DROP_UNUSABLE;
---
---	if (status->flag & RX_FLAG_DECRYPTED) {
---		if (!pskb_may_pull(rx->skb, hdrlen + IEEE80211_GCMP_HDR_LEN))
---			return RX_DROP_UNUSABLE;
---	} else {
---		if (skb_linearize(rx->skb))
---			return RX_DROP_UNUSABLE;
---	}
---
---	gcmp_hdr2pn(pn, skb->data + hdrlen);
---
---	queue = rx->security_idx;
---
---	if (memcmp(pn, key->u.gcmp.rx_pn[queue], IEEE80211_GCMP_PN_LEN) <= 0) {
---		key->u.gcmp.replays++;
---		return RX_DROP_UNUSABLE;
---	}
---
---	if (!(status->flag & RX_FLAG_DECRYPTED)) {
---		u8 aad[2 * AES_BLOCK_SIZE];
---		u8 j_0[AES_BLOCK_SIZE];
---		/* hardware didn't decrypt/verify MIC */
---		gcmp_special_blocks(skb, pn, j_0, aad);
---
---		if (ieee80211_aes_gcm_decrypt(
---			    key->u.gcmp.tfm, j_0, aad,
---			    skb->data + hdrlen + IEEE80211_GCMP_HDR_LEN,
---			    data_len,
---			    skb->data + skb->len - IEEE80211_GCMP_MIC_LEN))
---			return RX_DROP_UNUSABLE;
---	}
---
---	memcpy(key->u.gcmp.rx_pn[queue], pn, IEEE80211_GCMP_PN_LEN);
---
---	/* Remove GCMP header and MIC */
---	if (pskb_trim(skb, skb->len - IEEE80211_GCMP_MIC_LEN))
---		return RX_DROP_UNUSABLE;
---	memmove(skb->data + IEEE80211_GCMP_HDR_LEN, skb->data, hdrlen);
---	skb_pull(skb, IEEE80211_GCMP_HDR_LEN);
---
---	return RX_CONTINUE;
---}
---
-- static ieee80211_tx_result
-- ieee80211_crypto_cs_encrypt(struct ieee80211_tx_data *tx,
-- 			    struct sk_buff *skb)
--@@ -956,48 +734,6 @@ ieee80211_crypto_aes_cmac_encrypt(struct
-- 	return TX_CONTINUE;
-- }
-- 
---ieee80211_tx_result
---ieee80211_crypto_aes_cmac_256_encrypt(struct ieee80211_tx_data *tx)
---{
---	struct sk_buff *skb;
---	struct ieee80211_tx_info *info;
---	struct ieee80211_key *key = tx->key;
---	struct ieee80211_mmie_16 *mmie;
---	u8 aad[20];
---	u64 pn64;
---
---	if (WARN_ON(skb_queue_len(&tx->skbs) != 1))
---		return TX_DROP;
---
---	skb = skb_peek(&tx->skbs);
---
---	info = IEEE80211_SKB_CB(skb);
---
---	if (info->control.hw_key)
---		return TX_CONTINUE;
---
---	if (WARN_ON(skb_tailroom(skb) < sizeof(*mmie)))
---		return TX_DROP;
---
---	mmie = (struct ieee80211_mmie_16 *)skb_put(skb, sizeof(*mmie));
---	mmie->element_id = WLAN_EID_MMIE;
---	mmie->length = sizeof(*mmie) - 2;
---	mmie->key_id = cpu_to_le16(key->conf.keyidx);
---
---	/* PN = PN + 1 */
---	pn64 = atomic64_inc_return(&key->u.aes_cmac.tx_pn);
---
---	bip_ipn_set64(mmie->sequence_number, pn64);
---
---	bip_aad(skb, aad);
---
---	/* MIC = AES-256-CMAC(IGTK, AAD || Management Frame Body || MMIE, 128)
---	 */
---	ieee80211_aes_cmac_256(key->u.aes_cmac.tfm, aad,
---			       skb->data + 24, skb->len - 24, mmie->mic);
---
---	return TX_CONTINUE;
---}
-- 
-- ieee80211_rx_result
-- ieee80211_crypto_aes_cmac_decrypt(struct ieee80211_rx_data *rx)
--@@ -1045,160 +781,6 @@ ieee80211_crypto_aes_cmac_decrypt(struct
-- 
-- 	/* Remove MMIE */
-- 	skb_trim(skb, skb->len - sizeof(*mmie));
---
---	return RX_CONTINUE;
---}
---
---ieee80211_rx_result
---ieee80211_crypto_aes_cmac_256_decrypt(struct ieee80211_rx_data *rx)
---{
---	struct sk_buff *skb = rx->skb;
---	struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
---	struct ieee80211_key *key = rx->key;
---	struct ieee80211_mmie_16 *mmie;
---	u8 aad[20], mic[16], ipn[6];
---	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
---
---	if (!ieee80211_is_mgmt(hdr->frame_control))
---		return RX_CONTINUE;
---
---	/* management frames are already linear */
---
---	if (skb->len < 24 + sizeof(*mmie))
---		return RX_DROP_UNUSABLE;
---
---	mmie = (struct ieee80211_mmie_16 *)
---		(skb->data + skb->len - sizeof(*mmie));
---	if (mmie->element_id != WLAN_EID_MMIE ||
---	    mmie->length != sizeof(*mmie) - 2)
---		return RX_DROP_UNUSABLE; /* Invalid MMIE */
---
---	bip_ipn_swap(ipn, mmie->sequence_number);
---
---	if (memcmp(ipn, key->u.aes_cmac.rx_pn, 6) <= 0) {
---		key->u.aes_cmac.replays++;
---		return RX_DROP_UNUSABLE;
---	}
---
---	if (!(status->flag & RX_FLAG_DECRYPTED)) {
---		/* hardware didn't decrypt/verify MIC */
---		bip_aad(skb, aad);
---		ieee80211_aes_cmac_256(key->u.aes_cmac.tfm, aad,
---				       skb->data + 24, skb->len - 24, mic);
---		if (memcmp(mic, mmie->mic, sizeof(mmie->mic)) != 0) {
---			key->u.aes_cmac.icverrors++;
---			return RX_DROP_UNUSABLE;
---		}
---	}
---
---	memcpy(key->u.aes_cmac.rx_pn, ipn, 6);
---
---	/* Remove MMIE */
---	skb_trim(skb, skb->len - sizeof(*mmie));
---
---	return RX_CONTINUE;
---}
---
---ieee80211_tx_result
---ieee80211_crypto_aes_gmac_encrypt(struct ieee80211_tx_data *tx)
---{
---	struct sk_buff *skb;
---	struct ieee80211_tx_info *info;
---	struct ieee80211_key *key = tx->key;
---	struct ieee80211_mmie_16 *mmie;
---	struct ieee80211_hdr *hdr;
---	u8 aad[20];
---	u64 pn64;
---	u8 nonce[12];
---
---	if (WARN_ON(skb_queue_len(&tx->skbs) != 1))
---		return TX_DROP;
---
---	skb = skb_peek(&tx->skbs);
---
---	info = IEEE80211_SKB_CB(skb);
---
---	if (info->control.hw_key)
---		return TX_CONTINUE;
---
---	if (WARN_ON(skb_tailroom(skb) < sizeof(*mmie)))
---		return TX_DROP;
---
---	mmie = (struct ieee80211_mmie_16 *)skb_put(skb, sizeof(*mmie));
---	mmie->element_id = WLAN_EID_MMIE;
---	mmie->length = sizeof(*mmie) - 2;
---	mmie->key_id = cpu_to_le16(key->conf.keyidx);
---
---	/* PN = PN + 1 */
---	pn64 = atomic64_inc_return(&key->u.aes_gmac.tx_pn);
---
---	bip_ipn_set64(mmie->sequence_number, pn64);
---
---	bip_aad(skb, aad);
---
---	hdr = (struct ieee80211_hdr *)skb->data;
---	memcpy(nonce, hdr->addr2, ETH_ALEN);
---	bip_ipn_swap(nonce + ETH_ALEN, mmie->sequence_number);
---
---	/* MIC = AES-GMAC(IGTK, AAD || Management Frame Body || MMIE, 128) */
---	if (ieee80211_aes_gmac(key->u.aes_gmac.tfm, aad, nonce,
---			       skb->data + 24, skb->len - 24, mmie->mic) < 0)
---		return TX_DROP;
---
---	return TX_CONTINUE;
---}
---
---ieee80211_rx_result
---ieee80211_crypto_aes_gmac_decrypt(struct ieee80211_rx_data *rx)
---{
---	struct sk_buff *skb = rx->skb;
---	struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
---	struct ieee80211_key *key = rx->key;
---	struct ieee80211_mmie_16 *mmie;
---	u8 aad[20], mic[16], ipn[6], nonce[12];
---	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
---
---	if (!ieee80211_is_mgmt(hdr->frame_control))
---		return RX_CONTINUE;
---
---	/* management frames are already linear */
---
---	if (skb->len < 24 + sizeof(*mmie))
---		return RX_DROP_UNUSABLE;
---
---	mmie = (struct ieee80211_mmie_16 *)
---		(skb->data + skb->len - sizeof(*mmie));
---	if (mmie->element_id != WLAN_EID_MMIE ||
---	    mmie->length != sizeof(*mmie) - 2)
---		return RX_DROP_UNUSABLE; /* Invalid MMIE */
---
---	bip_ipn_swap(ipn, mmie->sequence_number);
---
---	if (memcmp(ipn, key->u.aes_gmac.rx_pn, 6) <= 0) {
---		key->u.aes_gmac.replays++;
---		return RX_DROP_UNUSABLE;
---	}
---
---	if (!(status->flag & RX_FLAG_DECRYPTED)) {
---		/* hardware didn't decrypt/verify MIC */
---		bip_aad(skb, aad);
---
---		memcpy(nonce, hdr->addr2, ETH_ALEN);
---		memcpy(nonce + ETH_ALEN, ipn, 6);
---
---		if (ieee80211_aes_gmac(key->u.aes_gmac.tfm, aad, nonce,
---				       skb->data + 24, skb->len - 24,
---				       mic) < 0 ||
---		    memcmp(mic, mmie->mic, sizeof(mmie->mic)) != 0) {
---			key->u.aes_gmac.icverrors++;
---			return RX_DROP_UNUSABLE;
---		}
---	}
---
---	memcpy(key->u.aes_gmac.rx_pn, ipn, 6);
---
---	/* Remove MMIE */
---	skb_trim(skb, skb->len - sizeof(*mmie));
-- 
-- 	return RX_CONTINUE;
-- }
----- a/net/mac80211/wpa.h
--+++ b/net/mac80211/wpa.h
--@@ -24,32 +24,17 @@ ieee80211_rx_result
-- ieee80211_crypto_tkip_decrypt(struct ieee80211_rx_data *rx);
-- 
-- ieee80211_tx_result
---ieee80211_crypto_ccmp_encrypt(struct ieee80211_tx_data *tx,
---			      unsigned int mic_len);
--+ieee80211_crypto_ccmp_encrypt(struct ieee80211_tx_data *tx);
-- ieee80211_rx_result
---ieee80211_crypto_ccmp_decrypt(struct ieee80211_rx_data *rx,
---			      unsigned int mic_len);
--+ieee80211_crypto_ccmp_decrypt(struct ieee80211_rx_data *rx);
-- 
-- ieee80211_tx_result
-- ieee80211_crypto_aes_cmac_encrypt(struct ieee80211_tx_data *tx);
---ieee80211_tx_result
---ieee80211_crypto_aes_cmac_256_encrypt(struct ieee80211_tx_data *tx);
-- ieee80211_rx_result
-- ieee80211_crypto_aes_cmac_decrypt(struct ieee80211_rx_data *rx);
---ieee80211_rx_result
---ieee80211_crypto_aes_cmac_256_decrypt(struct ieee80211_rx_data *rx);
---ieee80211_tx_result
---ieee80211_crypto_aes_gmac_encrypt(struct ieee80211_tx_data *tx);
---ieee80211_rx_result
---ieee80211_crypto_aes_gmac_decrypt(struct ieee80211_rx_data *rx);
-- ieee80211_tx_result
-- ieee80211_crypto_hw_encrypt(struct ieee80211_tx_data *tx);
-- ieee80211_rx_result
-- ieee80211_crypto_hw_decrypt(struct ieee80211_rx_data *rx);
-- 
---ieee80211_tx_result
---ieee80211_crypto_gcmp_encrypt(struct ieee80211_tx_data *tx);
---ieee80211_rx_result
---ieee80211_crypto_gcmp_decrypt(struct ieee80211_rx_data *rx);
---
-- #endif /* WPA_H */
-diff --git a/package/kernel/mac80211/patches/110-mac80211_keep_keys_on_stop_ap.patch b/package/kernel/mac80211/patches/110-mac80211_keep_keys_on_stop_ap.patch
-index 41a3c4f..cff6d89 100644
---- a/package/kernel/mac80211/patches/110-mac80211_keep_keys_on_stop_ap.patch
-+++ b/package/kernel/mac80211/patches/110-mac80211_keep_keys_on_stop_ap.patch
-@@ -2,7 +2,7 @@ Used for AP+STA support in OpenWrt - preserve AP mode keys across STA reconnects
- 
- --- a/net/mac80211/cfg.c
- +++ b/net/mac80211/cfg.c
--@@ -856,7 +856,6 @@ static int ieee80211_stop_ap(struct wiph
-+@@ -886,7 +886,6 @@ static int ieee80211_stop_ap(struct wiph
-  	sdata->u.ap.driver_smps_mode = IEEE80211_SMPS_OFF;
-  
-  	__sta_info_flush(sdata, true);
-diff --git a/package/kernel/mac80211/patches/150-disable_addr_notifier.patch b/package/kernel/mac80211/patches/150-disable_addr_notifier.patch
-index de79bd2..5fc9454 100644
---- a/package/kernel/mac80211/patches/150-disable_addr_notifier.patch
-+++ b/package/kernel/mac80211/patches/150-disable_addr_notifier.patch
-@@ -18,7 +18,7 @@
-  static int ieee80211_ifa6_changed(struct notifier_block *nb,
-  				  unsigned long data, void *arg)
-  {
--@@ -1057,14 +1057,14 @@ int ieee80211_register_hw(struct ieee802
-+@@ -1086,14 +1086,14 @@ int ieee80211_register_hw(struct ieee802
-  	if (result)
-  		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)
--@@ -1073,13 +1073,13 @@ int ieee80211_register_hw(struct ieee802
-+@@ -1102,13 +1102,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);
--@@ -1124,10 +1124,10 @@ void ieee80211_unregister_hw(struct ieee
-+@@ -1141,10 +1141,10 @@ void ieee80211_unregister_hw(struct ieee
-  
-  	pm_qos_remove_notifier(PM_QOS_NETWORK_LATENCY,
-  			       &local->network_latency_notifier);
-diff --git a/package/kernel/mac80211/patches/210-ap_scan.patch b/package/kernel/mac80211/patches/210-ap_scan.patch
-index 47dcec3..29f05c4 100644
---- a/package/kernel/mac80211/patches/210-ap_scan.patch
-+++ b/package/kernel/mac80211/patches/210-ap_scan.patch
-@@ -1,6 +1,6 @@
- --- a/net/mac80211/cfg.c
- +++ b/net/mac80211/cfg.c
--@@ -1963,7 +1963,7 @@ static int ieee80211_scan(struct wiphy *
-+@@ -2008,7 +2008,7 @@ static int ieee80211_scan(struct wiphy *
-  		 * the  frames sent while scanning on other channel will be
-  		 * lost)
-  		 */
-diff --git a/package/kernel/mac80211/patches/300-ath9k-force-rx_clear-when-disabling-rx.patch b/package/kernel/mac80211/patches/300-ath9k-force-rx_clear-when-disabling-rx.patch
-new file mode 100644
-index 0000000..bddb15a
---- /dev/null
-+++ b/package/kernel/mac80211/patches/300-ath9k-force-rx_clear-when-disabling-rx.patch
-@@ -0,0 +1,31 @@
-+From: Felix Fietkau <nbd@openwrt.org>
-+Date: Sun, 7 Jun 2015 13:53:35 +0200
-+Subject: [PATCH] ath9k: force rx_clear when disabling rx
-+
-+This makes stopping Rx more reliable and should reduce the frequency of
-+Rx related DMA stop warnings
-+
-+Cc: stable@vger.kernel.org
-+Signed-off-by: Felix Fietkau <nbd@openwrt.org>
-+---
-+
-+--- a/drivers/net/wireless/ath/ath9k/mac.c
-++++ b/drivers/net/wireless/ath/ath9k/mac.c
-+@@ -677,13 +677,15 @@ void ath9k_hw_startpcureceive(struct ath
-+ 
-+ 	ath9k_ani_reset(ah, is_scanning);
-+ 
-+-	REG_CLR_BIT(ah, AR_DIAG_SW, (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT));
-++	REG_CLR_BIT(ah, AR_DIAG_SW,
-++		    AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT | AR_DIAG_FORCE_RX_CLEAR);
-+ }
-+ EXPORT_SYMBOL(ath9k_hw_startpcureceive);
-+ 
-+ void ath9k_hw_abortpcurecv(struct ath_hw *ah)
-+ {
-+-	REG_SET_BIT(ah, AR_DIAG_SW, AR_DIAG_RX_ABORT | AR_DIAG_RX_DIS);
-++	REG_SET_BIT(ah, AR_DIAG_SW,
-++		    AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT | AR_DIAG_FORCE_RX_CLEAR);
-+ 
-+ 	ath9k_hw_disable_mib_counters(ah);
-+ }
-diff --git a/package/kernel/mac80211/patches/300-mac80211-add-an-intermediate-software-queue-implemen.patch b/package/kernel/mac80211/patches/300-mac80211-add-an-intermediate-software-queue-implemen.patch
-deleted file mode 100644
-index 237121b..0000000
---- a/package/kernel/mac80211/patches/300-mac80211-add-an-intermediate-software-queue-implemen.patch
-+++ /dev/null
-@@ -1,882 +0,0 @@
--From: Felix Fietkau <nbd@openwrt.org>
--Date: Tue, 18 Nov 2014 23:58:51 +0100
--Subject: [PATCH] mac80211: add an intermediate software queue implementation
--
--This allows drivers to request per-vif and per-sta-tid queues from which
--they can pull frames. This makes it easier to keep the hardware queues
--short, and to improve fairness between clients and vifs.
--
--The task of scheduling packet transmission is left up to the driver -
--queueing is controlled by mac80211. Drivers can only dequeue packets by
--calling ieee80211_tx_dequeue. This makes it possible to add active queue
--management later without changing drivers using this code.
--
--This can also be used as a starting point to implement A-MSDU
--aggregation in a way that does not add artificially induced latency.
--
--Signed-off-by: Felix Fietkau <nbd@openwrt.org>
-----
--
----- a/include/net/mac80211.h
--+++ b/include/net/mac80211.h
--@@ -84,6 +84,39 @@
--  *
--  */
-- 
--+/**
--+ * DOC: mac80211 software tx queueing
--+ *
--+ * mac80211 provides an optional intermediate queueing implementation designed
--+ * to allow the driver to keep hardware queues short and provide some fairness
--+ * between different stations/interfaces.
--+ * In this model, the driver pulls data frames from the mac80211 queue instead
--+ * of letting mac80211 push them via drv_tx().
--+ * Other frames (e.g. control or management) are still pushed using drv_tx().
--+ *
--+ * Drivers indicate that they use this model by implementing the .wake_tx_queue
--+ * driver operation.
--+ *
--+ * Intermediate queues (struct ieee80211_txq) are kept per-sta per-tid, with a
--+ * single per-vif queue for multicast data frames.
--+ *
--+ * The driver is expected to initialize its private per-queue data for stations
--+ * and interfaces in the .add_interface and .sta_add ops.
--+ *
--+ * The driver can't access the queue directly. To dequeue a frame, it calls
--+ * ieee80211_tx_dequeue(). Whenever mac80211 adds a new frame to a queue, it
--+ * calls the .wake_tx_queue driver op.
--+ *
--+ * For AP powersave TIM handling, the driver only needs to indicate if it has
--+ * buffered packets in the driver specific data structures by calling
--+ * ieee80211_sta_set_buffered(). For frames buffered in the ieee80211_txq
--+ * struct, mac80211 sets the appropriate TIM PVB bits and calls
--+ * .release_buffered_frames().
--+ * In that callback the driver is therefore expected to release its own
--+ * buffered frames and afterwards also frames from the ieee80211_txq (obtained
--+ * via the usual ieee80211_tx_dequeue).
--+ */
--+
-- struct device;
-- 
-- /**
--@@ -1246,6 +1279,7 @@ enum ieee80211_vif_flags {
--  *	monitor interface (if that is requested.)
--  * @drv_priv: data area for driver use, will always be aligned to
--  *	sizeof(void *).
--+ * @txq: the multicast data TX queue (if driver uses the TXQ abstraction)
--  */
-- struct ieee80211_vif {
-- 	enum nl80211_iftype type;
--@@ -1257,6 +1291,8 @@ struct ieee80211_vif {
-- 	u8 cab_queue;
-- 	u8 hw_queue[IEEE80211_NUM_ACS];
-- 
--+	struct ieee80211_txq *txq;
--+
-- 	struct ieee80211_chanctx_conf __rcu *chanctx_conf;
-- 
-- 	u32 driver_flags;
--@@ -1501,6 +1537,7 @@ struct ieee80211_sta_rates {
--  * @tdls_initiator: indicates the STA is an initiator of the TDLS link. Only
--  *	valid if the STA is a TDLS peer in the first place.
--  * @mfp: indicates whether the STA uses management frame protection or not.
--+ * @txq: per-TID data TX queues (if driver uses the TXQ abstraction)
--  */
-- struct ieee80211_sta {
-- 	u32 supp_rates[IEEE80211_NUM_BANDS];
--@@ -1519,6 +1556,8 @@ struct ieee80211_sta {
-- 	bool tdls_initiator;
-- 	bool mfp;
-- 
--+	struct ieee80211_txq *txq[IEEE80211_NUM_TIDS];
--+
-- 	/* must be last */
-- 	u8 drv_priv[0] __aligned(sizeof(void *));
-- };
--@@ -1547,6 +1586,27 @@ struct ieee80211_tx_control {
-- };
-- 
-- /**
--+ * struct ieee80211_txq - Software intermediate tx queue
--+ *
--+ * @vif: &struct ieee80211_vif pointer from the add_interface callback.
--+ * @sta: station table entry, %NULL for per-vif queue
--+ * @tid: the TID for this queue (unused for per-vif queue)
--+ * @ac: the AC for this queue
--+ *
--+ * The driver can obtain packets from this queue by calling
--+ * ieee80211_tx_dequeue().
--+ */
--+struct ieee80211_txq {
--+	struct ieee80211_vif *vif;
--+	struct ieee80211_sta *sta;
--+	u8 tid;
--+	u8 ac;
--+
--+	/* must be last */
--+	u8 drv_priv[0] __aligned(sizeof(void *));
--+};
--+
--+/**
--  * enum ieee80211_hw_flags - hardware flags
--  *
--  * These flags are used to indicate hardware capabilities to
--@@ -1770,6 +1830,8 @@ enum ieee80211_hw_flags {
--  *	within &struct ieee80211_sta.
--  * @chanctx_data_size: size (in bytes) of the drv_priv data area
--  *	within &struct ieee80211_chanctx_conf.
--+ * @txq_data_size: size (in bytes) of the drv_priv data area
--+ *	within @struct ieee80211_txq.
--  *
--  * @max_rates: maximum number of alternate rate retry stages the hw
--  *	can handle.
--@@ -1818,6 +1880,9 @@ enum ieee80211_hw_flags {
--  * @n_cipher_schemes: a size of an array of cipher schemes definitions.
--  * @cipher_schemes: a pointer to an array of cipher scheme definitions
--  *	supported by HW.
--+ *
--+ * @txq_ac_max_pending: maximum number of frames per AC pending in all txq
--+ *	entries for a vif.
--  */
-- struct ieee80211_hw {
-- 	struct ieee80211_conf conf;
--@@ -1830,6 +1895,7 @@ struct ieee80211_hw {
-- 	int vif_data_size;
-- 	int sta_data_size;
-- 	int chanctx_data_size;
--+	int txq_data_size;
-- 	u16 queues;
-- 	u16 max_listen_interval;
-- 	s8 max_signal;
--@@ -1846,6 +1912,7 @@ struct ieee80211_hw {
-- 	u8 uapsd_max_sp_len;
-- 	u8 n_cipher_schemes;
-- 	const struct ieee80211_cipher_scheme *cipher_schemes;
--+	int txq_ac_max_pending;
-- };
-- 
-- /**
--@@ -3007,6 +3074,8 @@ enum ieee80211_reconfig_type {
--  *	response template is provided, together with the location of the
--  *	switch-timing IE within the template. The skb can only be used within
--  *	the function call.
--+ *
--+ * @wake_tx_queue: Called when new packets have been added to the queue.
--  */
-- struct ieee80211_ops {
-- 	void (*tx)(struct ieee80211_hw *hw,
--@@ -3238,6 +3307,9 @@ struct ieee80211_ops {
-- 	void (*tdls_recv_channel_switch)(struct ieee80211_hw *hw,
-- 					 struct ieee80211_vif *vif,
-- 					 struct ieee80211_tdls_ch_sw_params *params);
--+
--+	void (*wake_tx_queue)(struct ieee80211_hw *hw,
--+			      struct ieee80211_txq *txq);
-- };
-- 
-- /**
--@@ -5249,4 +5321,15 @@ void ieee80211_unreserve_tid(struct ieee
--  */
-- size_t ieee80211_ie_split(const u8 *ies, size_t ielen,
-- 			  const u8 *ids, int n_ids, size_t offset);
--+
--+/**
--+ * ieee80211_tx_dequeue - dequeue a packet from a software tx queue
--+ *
--+ * @hw: pointer as obtained from ieee80211_alloc_hw()
--+ * @txq: pointer obtained from station or virtual interface
--+ *
--+ * Returns the skb if successful, %NULL if no frame was available.
--+ */
--+struct sk_buff *ieee80211_tx_dequeue(struct ieee80211_hw *hw,
--+				     struct ieee80211_txq *txq);
-- #endif /* MAC80211_H */
----- a/net/mac80211/driver-ops.h
--+++ b/net/mac80211/driver-ops.h
--@@ -1367,4 +1367,16 @@ drv_tdls_recv_channel_switch(struct ieee
-- 	trace_drv_return_void(local);
-- }
-- 
--+static inline void drv_wake_tx_queue(struct ieee80211_local *local,
--+				     struct txq_info *txq)
--+{
--+	struct ieee80211_sub_if_data *sdata = vif_to_sdata(txq->txq.vif);
--+
--+	if (!check_sdata_in_driver(sdata))
--+		return;
--+
--+	trace_drv_wake_tx_queue(local, sdata, txq);
--+	local->ops->wake_tx_queue(&local->hw, &txq->txq);
--+}
--+
-- #endif /* __MAC80211_DRIVER_OPS */
----- a/net/mac80211/ieee80211_i.h
--+++ b/net/mac80211/ieee80211_i.h
--@@ -809,6 +809,19 @@ struct mac80211_qos_map {
-- 	struct rcu_head rcu_head;
-- };
-- 
--+enum txq_info_flags {
--+	IEEE80211_TXQ_STOP,
--+	IEEE80211_TXQ_AMPDU,
--+};
--+
--+struct txq_info {
--+	struct sk_buff_head queue;
--+	unsigned long flags;
--+
--+	/* keep last! */
--+	struct ieee80211_txq txq;
--+};
--+
-- struct ieee80211_sub_if_data {
-- 	struct list_head list;
-- 
--@@ -853,6 +866,7 @@ struct ieee80211_sub_if_data {
-- 	bool control_port_no_encrypt;
-- 	int encrypt_headroom;
-- 
--+	atomic_t txqs_len[IEEE80211_NUM_ACS];
-- 	struct ieee80211_tx_queue_params tx_conf[IEEE80211_NUM_ACS];
-- 	struct mac80211_qos_map __rcu *qos_map;
-- 
--@@ -1453,6 +1467,10 @@ static inline struct ieee80211_local *hw
-- 	return container_of(hw, struct ieee80211_local, hw);
-- }
-- 
--+static inline struct txq_info *to_txq_info(struct ieee80211_txq *txq)
--+{
--+	return container_of(txq, struct txq_info, txq);
--+}
-- 
-- static inline int ieee80211_bssid_match(const u8 *raddr, const u8 *addr)
-- {
--@@ -1905,6 +1923,9 @@ static inline bool ieee80211_can_run_wor
-- 	return true;
-- }
-- 
--+void ieee80211_init_tx_queue(struct ieee80211_sub_if_data *sdata,
--+			     struct sta_info *sta,
--+			     struct txq_info *txq, int tid);
-- void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata,
-- 			 u16 transaction, u16 auth_alg, u16 status,
-- 			 const u8 *extra, size_t extra_len, const u8 *bssid,
----- a/net/mac80211/iface.c
--+++ b/net/mac80211/iface.c
--@@ -969,6 +969,13 @@ static void ieee80211_do_stop(struct iee
-- 	}
-- 	spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
-- 
--+	if (sdata->vif.txq) {
--+		struct txq_info *txqi = to_txq_info(sdata->vif.txq);
--+
--+		ieee80211_purge_tx_queue(&local->hw, &txqi->queue);
--+		atomic_set(&sdata->txqs_len[txqi->txq.ac], 0);
--+	}
--+
-- 	if (local->open_count == 0)
-- 		ieee80211_clear_tx_pending(local);
-- 
--@@ -1674,6 +1681,7 @@ int ieee80211_if_add(struct ieee80211_lo
-- {
-- 	struct net_device *ndev = NULL;
-- 	struct ieee80211_sub_if_data *sdata = NULL;
--+	struct txq_info *txqi;
-- 	int ret, i;
-- 	int txqs = 1;
-- 
--@@ -1693,10 +1701,18 @@ int ieee80211_if_add(struct ieee80211_lo
-- 		ieee80211_assign_perm_addr(local, wdev->address, type);
-- 		memcpy(sdata->vif.addr, wdev->address, ETH_ALEN);
-- 	} else {
--+		int size = ALIGN(sizeof(*sdata) + local->hw.vif_data_size,
--+				 sizeof(void *));
--+		int txq_size = 0;
--+
--+		if (local->ops->wake_tx_queue)
--+			txq_size += sizeof(struct txq_info) +
--+				    local->hw.txq_data_size;
--+
-- 		if (local->hw.queues >= IEEE80211_NUM_ACS)
-- 			txqs = IEEE80211_NUM_ACS;
-- 
---		ndev = alloc_netdev_mqs(sizeof(*sdata) + local->hw.vif_data_size,
--+		ndev = alloc_netdev_mqs(size + txq_size,
-- 					name, NET_NAME_UNKNOWN,
-- 					ieee80211_if_setup, txqs, 1);
-- 		if (!ndev)
--@@ -1731,6 +1747,11 @@ int ieee80211_if_add(struct ieee80211_lo
-- 		memcpy(sdata->vif.addr, ndev->dev_addr, ETH_ALEN);
-- 		memcpy(sdata->name, ndev->name, IFNAMSIZ);
-- 
--+		if (txq_size) {
--+			txqi = netdev_priv(ndev) + size;
--+			ieee80211_init_tx_queue(sdata, NULL, txqi, 0);
--+		}
--+
-- 		sdata->dev = ndev;
-- 	}
-- 
----- a/net/mac80211/main.c
--+++ b/net/mac80211/main.c
--@@ -1019,6 +1019,9 @@ int ieee80211_register_hw(struct ieee802
-- 
-- 	local->dynamic_ps_forced_timeout = -1;
-- 
--+	if (!local->hw.txq_ac_max_pending)
--+		local->hw.txq_ac_max_pending = 64;
--+
-- 	result = ieee80211_wep_init(local);
-- 	if (result < 0)
-- 		wiphy_debug(local->hw.wiphy, "Failed to initialize wep: %d\n",
----- a/net/mac80211/sta_info.c
--+++ b/net/mac80211/sta_info.c
--@@ -118,6 +118,16 @@ static void __cleanup_single_sta(struct
-- 		atomic_dec(&ps->num_sta_ps);
-- 	}
-- 
--+	if (sta->sta.txq[0]) {
--+		for (i = 0; i < ARRAY_SIZE(sta->sta.txq); i++) {
--+			struct txq_info *txqi = to_txq_info(sta->sta.txq[i]);
--+			int n = skb_queue_len(&txqi->queue);
--+
--+			ieee80211_purge_tx_queue(&local->hw, &txqi->queue);
--+			atomic_sub(n, &sdata->txqs_len[txqi->txq.ac]);
--+		}
--+	}
--+
-- 	for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) {
-- 		local->total_ps_buffered -= skb_queue_len(&sta->ps_tx_buf[ac]);
-- 		ieee80211_purge_tx_queue(&local->hw, &sta->ps_tx_buf[ac]);
--@@ -234,6 +244,8 @@ void sta_info_free(struct ieee80211_loca
-- 
-- 	sta_dbg(sta->sdata, "Destroyed STA %pM\n", sta->sta.addr);
-- 
--+	if (sta->sta.txq[0])
--+		kfree(to_txq_info(sta->sta.txq[0]));
-- 	kfree(rcu_dereference_raw(sta->sta.rates));
-- 	kfree(sta);
-- }
--@@ -285,11 +297,12 @@ struct sta_info *sta_info_alloc(struct i
-- 				const u8 *addr, gfp_t gfp)
-- {
-- 	struct ieee80211_local *local = sdata->local;
--+	struct ieee80211_hw *hw = &local->hw;
-- 	struct sta_info *sta;
-- 	struct timespec uptime;
-- 	int i;
-- 
---	sta = kzalloc(sizeof(*sta) + local->hw.sta_data_size, gfp);
--+	sta = kzalloc(sizeof(*sta) + hw->sta_data_size, gfp);
-- 	if (!sta)
-- 		return NULL;
-- 
--@@ -321,11 +334,25 @@ struct sta_info *sta_info_alloc(struct i
-- 	for (i = 0; i < ARRAY_SIZE(sta->chain_signal_avg); i++)
-- 		ewma_init(&sta->chain_signal_avg[i], 1024, 8);
-- 
---	if (sta_prepare_rate_control(local, sta, gfp)) {
---		kfree(sta);
---		return NULL;
--+	if (local->ops->wake_tx_queue) {
--+		void *txq_data;
--+		int size = sizeof(struct txq_info) +
--+			   ALIGN(hw->txq_data_size, sizeof(void *));
--+
--+		txq_data = kcalloc(ARRAY_SIZE(sta->sta.txq), size, gfp);
--+		if (!txq_data)
--+			goto free;
--+
--+		for (i = 0; i < ARRAY_SIZE(sta->sta.txq); i++) {
--+			struct txq_info *txq = txq_data + i * size;
--+
--+			ieee80211_init_tx_queue(sdata, sta, txq, i);
--+		}
-- 	}
-- 
--+	if (sta_prepare_rate_control(local, sta, gfp))
--+		goto free_txq;
--+
-- 	for (i = 0; i < IEEE80211_NUM_TIDS; i++) {
-- 		/*
-- 		 * timer_to_tid must be initialized with identity mapping
--@@ -346,7 +373,7 @@ struct sta_info *sta_info_alloc(struct i
-- 	if (sdata->vif.type == NL80211_IFTYPE_AP ||
-- 	    sdata->vif.type == NL80211_IFTYPE_AP_VLAN) {
-- 		struct ieee80211_supported_band *sband =
---			local->hw.wiphy->bands[ieee80211_get_sdata_band(sdata)];
--+			hw->wiphy->bands[ieee80211_get_sdata_band(sdata)];
-- 		u8 smps = (sband->ht_cap.cap & IEEE80211_HT_CAP_SM_PS) >>
-- 				IEEE80211_HT_CAP_SM_PS_SHIFT;
-- 		/*
--@@ -371,6 +398,13 @@ struct sta_info *sta_info_alloc(struct i
-- 	sta_dbg(sdata, "Allocated STA %pM\n", sta->sta.addr);
-- 
-- 	return sta;
--+
--+free_txq:
--+	if (sta->sta.txq[0])
--+		kfree(to_txq_info(sta->sta.txq[0]));
--+free:
--+	kfree(sta);
--+	return NULL;
-- }
-- 
-- static int sta_info_insert_check(struct sta_info *sta)
--@@ -640,6 +674,8 @@ static void __sta_info_recalc_tim(struct
-- 
-- 		indicate_tim |=
-- 			sta->driver_buffered_tids & tids;
--+		indicate_tim |=
--+			sta->txq_buffered_tids & tids;
-- 	}
-- 
--  done:
--@@ -1071,7 +1107,7 @@ void ieee80211_sta_ps_deliver_wakeup(str
-- 	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;
--+	int filtered = 0, buffered = 0, ac, i;
-- 	unsigned long flags;
-- 	struct ps_data *ps;
-- 
--@@ -1090,10 +1126,22 @@ void ieee80211_sta_ps_deliver_wakeup(str
-- 
-- 	BUILD_BUG_ON(BITS_TO_LONGS(IEEE80211_NUM_TIDS) > 1);
-- 	sta->driver_buffered_tids = 0;
--+	sta->txq_buffered_tids = 0;
-- 
-- 	if (!(local->hw.flags & IEEE80211_HW_AP_LINK_PS))
-- 		drv_sta_notify(local, sdata, STA_NOTIFY_AWAKE, &sta->sta);
-- 
--+	if (sta->sta.txq[0]) {
--+		for (i = 0; i < ARRAY_SIZE(sta->sta.txq); i++) {
--+			struct txq_info *txqi = to_txq_info(sta->sta.txq[i]);
--+
--+			if (!skb_queue_len(&txqi->queue))
--+				continue;
--+
--+			drv_wake_tx_queue(local, txqi);
--+		}
--+	}
--+
-- 	skb_queue_head_init(&pending);
-- 
-- 	/* sync with ieee80211_tx_h_unicast_ps_buf */
--@@ -1275,8 +1323,10 @@ ieee80211_sta_ps_deliver_response(struct
-- 		/* if we already have frames from software, then we can't also
-- 		 * release from hardware queues
-- 		 */
---		if (skb_queue_empty(&frames))
--+		if (skb_queue_empty(&frames)) {
-- 			driver_release_tids |= sta->driver_buffered_tids & tids;
--+			driver_release_tids |= sta->txq_buffered_tids & tids;
--+		}
-- 
-- 		if (driver_release_tids) {
-- 			/* If the driver has data on more than one TID then
--@@ -1447,6 +1497,9 @@ ieee80211_sta_ps_deliver_response(struct
-- 
-- 		sta_info_recalc_tim(sta);
-- 	} else {
--+		unsigned long tids = sta->txq_buffered_tids & driver_release_tids;
--+		int tid;
--+
-- 		/*
-- 		 * We need to release a frame that is buffered somewhere in the
-- 		 * driver ... it'll have to handle that.
--@@ -1466,8 +1519,22 @@ ieee80211_sta_ps_deliver_response(struct
-- 		 * that the TID(s) became empty before returning here from the
-- 		 * release function.
-- 		 * Either way, however, when the driver tells us that the TID(s)
---		 * became empty we'll do the TIM recalculation.
--+		 * became empty or we find that a txq became empty, we'll do the
--+		 * TIM recalculation.
-- 		 */
--+
--+		if (!sta->sta.txq[0])
--+			return;
--+
--+		for (tid = 0; tid < ARRAY_SIZE(sta->sta.txq); tid++) {
--+			struct txq_info *txqi = to_txq_info(sta->sta.txq[tid]);
--+
--+			if (!(tids & BIT(tid)) || skb_queue_len(&txqi->queue))
--+				continue;
--+
--+			sta_info_recalc_tim(sta);
--+			break;
--+		}
-- 	}
-- }
-- 
----- a/net/mac80211/sta_info.h
--+++ b/net/mac80211/sta_info.h
--@@ -274,6 +274,7 @@ struct sta_ampdu_mlme {
--  *	entered power saving state, these are also delivered to
--  *	the station when it leaves powersave or polls for frames
--  * @driver_buffered_tids: bitmap of TIDs the driver has data buffered on
--+ * @txq_buffered_tids: bitmap of TIDs that mac80211 has txq data buffered on
--  * @rx_packets: Number of MSDUs received from this STA
--  * @rx_bytes: Number of bytes received from this STA
--  * @last_rx: time (in jiffies) when last frame was received from this STA
--@@ -368,6 +369,7 @@ struct sta_info {
-- 	struct sk_buff_head ps_tx_buf[IEEE80211_NUM_ACS];
-- 	struct sk_buff_head tx_filtered[IEEE80211_NUM_ACS];
-- 	unsigned long driver_buffered_tids;
--+	unsigned long txq_buffered_tids;
-- 
-- 	/* Updated from RX path only, no locking requirements */
-- 	unsigned long rx_packets;
----- a/net/mac80211/trace.h
--+++ b/net/mac80211/trace.h
--@@ -2312,6 +2312,37 @@ TRACE_EVENT(drv_tdls_recv_channel_switch
-- 	)
-- );
-- 
--+TRACE_EVENT(drv_wake_tx_queue,
--+	TP_PROTO(struct ieee80211_local *local,
--+		 struct ieee80211_sub_if_data *sdata,
--+		 struct txq_info *txq),
--+
--+	TP_ARGS(local, sdata, txq),
--+
--+	TP_STRUCT__entry(
--+		LOCAL_ENTRY
--+		VIF_ENTRY
--+		STA_ENTRY
--+		__field(u8, ac)
--+		__field(u8, tid)
--+	),
--+
--+	TP_fast_assign(
--+		struct ieee80211_sta *sta = txq->txq.sta;
--+
--+		LOCAL_ASSIGN;
--+		VIF_ASSIGN;
--+		STA_ASSIGN;
--+		__entry->ac = txq->txq.ac;
--+		__entry->tid = txq->txq.tid;
--+	),
--+
--+	TP_printk(
--+		LOCAL_PR_FMT  VIF_PR_FMT  STA_PR_FMT " ac:%d tid:%d",
--+		LOCAL_PR_ARG, VIF_PR_ARG, STA_PR_ARG, __entry->ac, __entry->tid
--+	)
--+);
--+
-- #ifdef CPTCFG_MAC80211_MESSAGE_TRACING
-- #undef TRACE_SYSTEM
-- #define TRACE_SYSTEM mac80211_msg
----- a/net/mac80211/tx.c
--+++ b/net/mac80211/tx.c
--@@ -776,12 +776,22 @@ ieee80211_tx_h_rate_ctrl(struct ieee8021
-- 	return TX_CONTINUE;
-- }
-- 
--+static __le16 ieee80211_tx_next_seq(struct sta_info *sta, int tid)
--+{
--+	u16 *seq = &sta->tid_seq[tid];
--+	__le16 ret = cpu_to_le16(*seq);
--+
--+	/* Increase the sequence number. */
--+	*seq = (*seq + 0x10) & IEEE80211_SCTL_SEQ;
--+
--+	return ret;
--+}
--+
-- static ieee80211_tx_result debug_noinline
-- ieee80211_tx_h_sequence(struct ieee80211_tx_data *tx)
-- {
-- 	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb);
-- 	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)tx->skb->data;
---	u16 *seq;
-- 	u8 *qc;
-- 	int tid;
-- 
--@@ -832,13 +842,10 @@ ieee80211_tx_h_sequence(struct ieee80211
-- 
-- 	qc = ieee80211_get_qos_ctl(hdr);
-- 	tid = *qc & IEEE80211_QOS_CTL_TID_MASK;
---	seq = &tx->sta->tid_seq[tid];
-- 	tx->sta->tx_msdu[tid]++;
-- 
---	hdr->seq_ctrl = cpu_to_le16(*seq);
---
---	/* Increase the sequence number. */
---	*seq = (*seq + 0x10) & IEEE80211_SCTL_SEQ;
--+	if (!tx->sta->sta.txq[0])
--+		hdr->seq_ctrl = ieee80211_tx_next_seq(tx->sta, tid);
-- 
-- 	return TX_CONTINUE;
-- }
--@@ -1067,7 +1074,7 @@ static bool ieee80211_tx_prep_agg(struct
-- 		 * nothing -- this aggregation session is being started
-- 		 * but that might still fail with the driver
-- 		 */
---	} else {
--+	} else if (!tx->sta->sta.txq[tid]) {
-- 		spin_lock(&tx->sta->lock);
-- 		/*
-- 		 * Need to re-check now, because we may get here
--@@ -1201,13 +1208,102 @@ ieee80211_tx_prepare(struct ieee80211_su
-- 	return TX_CONTINUE;
-- }
-- 
--+static void ieee80211_drv_tx(struct ieee80211_local *local,
--+			     struct ieee80211_vif *vif,
--+			     struct ieee80211_sta *pubsta,
--+			     struct sk_buff *skb)
--+{
--+	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
--+	struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
--+	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
--+	struct ieee80211_tx_control control = {
--+		.sta = pubsta,
--+	};
--+	struct ieee80211_txq *txq = NULL;
--+	struct txq_info *txqi;
--+	u8 ac;
--+
--+	if (info->control.flags & IEEE80211_TX_CTRL_PS_RESPONSE)
--+		goto tx_normal;
--+
--+	if (!ieee80211_is_data(hdr->frame_control))
--+		goto tx_normal;
--+
--+	if (pubsta) {
--+		u8 tid = skb->priority & IEEE80211_QOS_CTL_TID_MASK;
--+
--+		txq = pubsta->txq[tid];
--+	} else if (vif) {
--+		txq = vif->txq;
--+	}
--+
--+	if (!txq)
--+		goto tx_normal;
--+
--+	ac = txq->ac;
--+	txqi = to_txq_info(txq);
--+	atomic_inc(&sdata->txqs_len[ac]);
--+	if (atomic_read(&sdata->txqs_len[ac]) >= local->hw.txq_ac_max_pending)
--+		netif_stop_subqueue(sdata->dev, ac);
--+
--+	skb_queue_tail(&txqi->queue, skb);
--+	drv_wake_tx_queue(local, txqi);
--+
--+	return;
--+
--+tx_normal:
--+	drv_tx(local, &control, skb);
--+}
--+
--+struct sk_buff *ieee80211_tx_dequeue(struct ieee80211_hw *hw,
--+				     struct ieee80211_txq *txq)
--+{
--+	struct ieee80211_local *local = hw_to_local(hw);
--+	struct ieee80211_sub_if_data *sdata = vif_to_sdata(txq->vif);
--+	struct txq_info *txqi = container_of(txq, struct txq_info, txq);
--+	struct ieee80211_hdr *hdr;
--+	struct sk_buff *skb = NULL;
--+	u8 ac = txq->ac;
--+
--+	spin_lock_bh(&txqi->queue.lock);
--+
--+	if (test_bit(IEEE80211_TXQ_STOP, &txqi->flags))
--+		goto out;
--+
--+	skb = __skb_dequeue(&txqi->queue);
--+	if (!skb)
--+		goto out;
--+
--+	atomic_dec(&sdata->txqs_len[ac]);
--+	if (__netif_subqueue_stopped(sdata->dev, ac))
--+		ieee80211_propagate_queue_wake(local, sdata->vif.hw_queue[ac]);
--+
--+	hdr = (struct ieee80211_hdr *)skb->data;
--+	if (txq->sta && ieee80211_is_data_qos(hdr->frame_control)) {
--+		struct sta_info *sta = container_of(txq->sta, struct sta_info,
--+						    sta);
--+		struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
--+
--+		hdr->seq_ctrl = ieee80211_tx_next_seq(sta, txq->tid);
--+		if (test_bit(IEEE80211_TXQ_AMPDU, &txqi->flags))
--+			info->flags |= IEEE80211_TX_CTL_AMPDU;
--+		else
--+			info->flags &= ~IEEE80211_TX_CTL_AMPDU;
--+	}
--+
--+out:
--+	spin_unlock_bh(&txqi->queue.lock);
--+
--+	return skb;
--+}
--+EXPORT_SYMBOL(ieee80211_tx_dequeue);
--+
-- static bool ieee80211_tx_frags(struct ieee80211_local *local,
-- 			       struct ieee80211_vif *vif,
-- 			       struct ieee80211_sta *sta,
-- 			       struct sk_buff_head *skbs,
-- 			       bool txpending)
-- {
---	struct ieee80211_tx_control control;
-- 	struct sk_buff *skb, *tmp;
-- 	unsigned long flags;
-- 
--@@ -1265,10 +1361,9 @@ static bool ieee80211_tx_frags(struct ie
-- 		spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
-- 
-- 		info->control.vif = vif;
---		control.sta = sta;
-- 
-- 		__skb_unlink(skb, skbs);
---		drv_tx(local, &control, skb);
--+		ieee80211_drv_tx(local, vif, sta, skb);
-- 	}
-- 
-- 	return true;
----- a/net/mac80211/util.c
--+++ b/net/mac80211/util.c
--@@ -308,6 +308,11 @@ void ieee80211_propagate_queue_wake(stru
-- 		for (ac = 0; ac < n_acs; ac++) {
-- 			int ac_queue = sdata->vif.hw_queue[ac];
-- 
--+			if (local->ops->wake_tx_queue &&
--+			    (atomic_read(&sdata->txqs_len[ac]) >
--+			     local->hw.txq_ac_max_pending))
--+				continue;
--+
-- 			if (ac_queue == queue ||
-- 			    (sdata->vif.cab_queue == queue &&
-- 			     local->queue_stop_reasons[ac_queue] == 0 &&
--@@ -3307,3 +3312,20 @@ u8 *ieee80211_add_wmm_info_ie(u8 *buf, u
-- 
-- 	return buf;
-- }
--+
--+void ieee80211_init_tx_queue(struct ieee80211_sub_if_data *sdata,
--+			     struct sta_info *sta,
--+			     struct txq_info *txqi, int tid)
--+{
--+	skb_queue_head_init(&txqi->queue);
--+	txqi->txq.vif = &sdata->vif;
--+
--+	if (sta) {
--+		txqi->txq.sta = &sta->sta;
--+		sta->sta.txq[tid] = &txqi->txq;
--+		txqi->txq.ac = ieee802_1d_to_ac[tid & 7];
--+	} else {
--+		sdata->vif.txq = &txqi->txq;
--+		txqi->txq.ac = IEEE80211_AC_BE;
--+	}
--+}
----- a/net/mac80211/rx.c
--+++ b/net/mac80211/rx.c
--@@ -1176,6 +1176,7 @@ static void sta_ps_start(struct sta_info
-- 	struct ieee80211_sub_if_data *sdata = sta->sdata;
-- 	struct ieee80211_local *local = sdata->local;
-- 	struct ps_data *ps;
--+	int tid;
-- 
-- 	if (sta->sdata->vif.type == NL80211_IFTYPE_AP ||
-- 	    sta->sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
--@@ -1189,6 +1190,18 @@ static void sta_ps_start(struct sta_info
-- 		drv_sta_notify(local, sdata, STA_NOTIFY_SLEEP, &sta->sta);
-- 	ps_dbg(sdata, "STA %pM aid %d enters power save mode\n",
-- 	       sta->sta.addr, sta->sta.aid);
--+
--+	if (!sta->sta.txq[0])
--+		return;
--+
--+	for (tid = 0; tid < ARRAY_SIZE(sta->sta.txq); tid++) {
--+		struct txq_info *txqi = to_txq_info(sta->sta.txq[tid]);
--+
--+		if (!skb_queue_len(&txqi->queue))
--+			set_bit(tid, &sta->txq_buffered_tids);
--+		else
--+			clear_bit(tid, &sta->txq_buffered_tids);
--+	}
-- }
-- 
-- static void sta_ps_end(struct sta_info *sta)
----- a/net/mac80211/agg-tx.c
--+++ b/net/mac80211/agg-tx.c
--@@ -188,6 +188,43 @@ ieee80211_wake_queue_agg(struct ieee8021
-- 	__release(agg_queue);
-- }
-- 
--+static void
--+ieee80211_agg_stop_txq(struct sta_info *sta, int tid)
--+{
--+	struct ieee80211_txq *txq = sta->sta.txq[tid];
--+	struct txq_info *txqi;
--+
--+	if (!txq)
--+		return;
--+
--+	txqi = to_txq_info(txq);
--+
--+	/* Lock here to protect against further seqno updates on dequeue */
--+	spin_lock_bh(&txqi->queue.lock);
--+	set_bit(IEEE80211_TXQ_STOP, &txqi->flags);
--+	spin_unlock_bh(&txqi->queue.lock);
--+}
--+
--+static void
--+ieee80211_agg_start_txq(struct sta_info *sta, int tid, bool enable)
--+{
--+	struct ieee80211_txq *txq = sta->sta.txq[tid];
--+	struct txq_info *txqi;
--+
--+	if (!txq)
--+		return;
--+
--+	txqi = to_txq_info(txq);
--+
--+	if (enable)
--+		set_bit(IEEE80211_TXQ_AMPDU, &txqi->flags);
--+	else
--+		clear_bit(IEEE80211_TXQ_AMPDU, &txqi->flags);
--+
--+	clear_bit(IEEE80211_TXQ_STOP, &txqi->flags);
--+	drv_wake_tx_queue(sta->sdata->local, txqi);
--+}
--+
-- /*
--  * splice packets from the STA's pending to the local pending,
--  * requires a call to ieee80211_agg_splice_finish later
--@@ -247,6 +284,7 @@ static void ieee80211_remove_tid_tx(stru
-- 	ieee80211_assign_tid_tx(sta, tid, NULL);
-- 
-- 	ieee80211_agg_splice_finish(sta->sdata, tid);
--+	ieee80211_agg_start_txq(sta, tid, false);
-- 
-- 	kfree_rcu(tid_tx, rcu_head);
-- }
--@@ -418,6 +456,8 @@ void ieee80211_tx_ba_session_handle_star
-- 	 */
-- 	clear_bit(HT_AGG_STATE_WANT_START, &tid_tx->state);
-- 
--+	ieee80211_agg_stop_txq(sta, tid);
--+
-- 	/*
-- 	 * Make sure no packets are being processed. This ensures that
-- 	 * we have a valid starting sequence number and that in-flight
--@@ -440,6 +480,8 @@ void ieee80211_tx_ba_session_handle_star
-- 		ieee80211_agg_splice_finish(sdata, tid);
-- 		spin_unlock_bh(&sta->lock);
-- 
--+		ieee80211_agg_start_txq(sta, tid, false);
--+
-- 		kfree_rcu(tid_tx, rcu_head);
-- 		return;
-- 	}
--@@ -666,6 +708,8 @@ static void ieee80211_agg_tx_operational
-- 	ieee80211_agg_splice_finish(sta->sdata, tid);
-- 
-- 	spin_unlock_bh(&sta->lock);
--+
--+	ieee80211_agg_start_txq(sta, tid, true);
-- }
-- 
-- void ieee80211_start_tx_ba_cb(struct ieee80211_vif *vif, u8 *ra, u16 tid)
-diff --git a/package/kernel/mac80211/patches/301-ath9k-limit-retries-for-powersave-response-frames.patch b/package/kernel/mac80211/patches/301-ath9k-limit-retries-for-powersave-response-frames.patch
-new file mode 100644
-index 0000000..4faac0d
---- /dev/null
-+++ b/package/kernel/mac80211/patches/301-ath9k-limit-retries-for-powersave-response-frames.patch
-@@ -0,0 +1,121 @@
-+From: Felix Fietkau <nbd@openwrt.org>
-+Date: Thu, 2 Jul 2015 15:20:56 +0200
-+Subject: [PATCH] ath9k: limit retries for powersave response frames
-+
-+In some cases, the channel might be busy enough that an ath9k AP's
-+response to PS-Poll frames might be too slow and the station has already
-+gone to sleep. To avoid wasting too much airtime on this, limit the
-+number of retries on such frames and ensure that no sample rate gets
-+used.
-+
-+Signed-off-by: Felix Fietkau <nbd@openwrt.org>
-+---
-+
-+--- a/drivers/net/wireless/ath/ath9k/xmit.c
-++++ b/drivers/net/wireless/ath/ath9k/xmit.c
-+@@ -147,10 +147,25 @@ static void ath_send_bar(struct ath_atx_
-+ }
-+ 
-+ static void ath_set_rates(struct ieee80211_vif *vif, struct ieee80211_sta *sta,
-+-			  struct ath_buf *bf)
-++			  struct ath_buf *bf, bool ps)
-+ {
-++	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(bf->bf_mpdu);
-++
-++	if (ps) {
-++		/* Clear the first rate to avoid using a sample rate for PS frames */
-++		info->control.rates[0].idx = -1;
-++		info->control.rates[0].count = 0;
-++	}
-++
-+ 	ieee80211_get_tx_rates(vif, sta, bf->bf_mpdu, bf->rates,
-+ 			       ARRAY_SIZE(bf->rates));
-++	if (!ps)
-++		return;
-++
-++	if (bf->rates[0].count > 2)
-++		bf->rates[0].count = 2;
-++
-++	bf->rates[1].idx = -1;
-+ }
-+ 
-+ static void ath_txq_skb_done(struct ath_softc *sc, struct ath_txq *txq,
-+@@ -1430,7 +1445,7 @@ ath_tx_form_burst(struct ath_softc *sc,
-+ 		if (tx_info->flags & IEEE80211_TX_CTL_AMPDU)
-+ 			break;
-+ 
-+-		ath_set_rates(tid->an->vif, tid->an->sta, bf);
-++		ath_set_rates(tid->an->vif, tid->an->sta, bf, false);
-+ 	} while (1);
-+ }
-+ 
-+@@ -1461,7 +1476,7 @@ static bool ath_tx_sched_aggr(struct ath
-+ 		return false;
-+ 	}
-+ 
-+-	ath_set_rates(tid->an->vif, tid->an->sta, bf);
-++	ath_set_rates(tid->an->vif, tid->an->sta, bf, false);
-+ 	if (aggr)
-+ 		last = ath_tx_form_aggr(sc, txq, tid, &bf_q, bf,
-+ 					tid_q, &aggr_len);
-+@@ -1653,7 +1668,7 @@ void ath9k_release_buffered_frames(struc
-+ 
-+ 			__skb_unlink(bf->bf_mpdu, tid_q);
-+ 			list_add_tail(&bf->list, &bf_q);
-+-			ath_set_rates(tid->an->vif, tid->an->sta, bf);
-++			ath_set_rates(tid->an->vif, tid->an->sta, bf, true);
-+ 			if (bf_isampdu(bf)) {
-+ 				ath_tx_addto_baw(sc, tid, bf);
-+ 				bf->bf_state.bf_type &= ~BUF_AGGR;
-+@@ -2318,7 +2333,7 @@ int ath_tx_start(struct ieee80211_hw *hw
-+ 	struct ath_txq *txq = txctl->txq;
-+ 	struct ath_atx_tid *tid = NULL;
-+ 	struct ath_buf *bf;
-+-	bool queue, skip_uapsd = false, ps_resp;
-++	bool queue, ps_resp;
-+ 	int q, ret;
-+ 
-+ 	if (vif)
-+@@ -2365,13 +2380,13 @@ int ath_tx_start(struct ieee80211_hw *hw
-+ 		if (!txctl->an)
-+ 			txctl->an = &avp->mcast_node;
-+ 		queue = true;
-+-		skip_uapsd = true;
-++		ps_resp = false;
-+ 	}
-+ 
-+ 	if (txctl->an && queue)
-+ 		tid = ath_get_skb_tid(sc, txctl->an, skb);
-+ 
-+-	if (!skip_uapsd && ps_resp) {
-++	if (ps_resp) {
-+ 		ath_txq_unlock(sc, txq);
-+ 		txq = sc->tx.uapsdq;
-+ 		ath_txq_lock(sc, txq);
-+@@ -2409,7 +2424,7 @@ int ath_tx_start(struct ieee80211_hw *hw
-+ 	if (txctl->paprd)
-+ 		bf->bf_state.bfs_paprd_timestamp = jiffies;
-+ 
-+-	ath_set_rates(vif, sta, bf);
-++	ath_set_rates(vif, sta, bf, ps_resp);
-+ 	ath_tx_send_normal(sc, txq, tid, skb);
-+ 
-+ out:
-+@@ -2448,7 +2463,7 @@ void ath_tx_cabq(struct ieee80211_hw *hw
-+ 			break;
-+ 
-+ 		bf->bf_lastbf = bf;
-+-		ath_set_rates(vif, NULL, bf);
-++		ath_set_rates(vif, NULL, bf, false);
-+ 		ath_buf_set_rate(sc, bf, &info, fi->framelen, false);
-+ 		duration += info.rates[0].PktDuration;
-+ 		if (bf_tail)
-+@@ -2968,7 +2983,7 @@ int ath9k_tx99_send(struct ath_softc *sc
-+ 		return -EINVAL;
-+ 	}
-+ 
-+-	ath_set_rates(sc->tx99_vif, NULL, bf);
-++	ath_set_rates(sc->tx99_vif, NULL, bf, false);
-+ 
-+ 	ath9k_hw_set_desc_link(sc->sc_ah, bf->bf_desc, bf->bf_daddr);
-+ 	ath9k_hw_tx99_start(sc->sc_ah, txctl->txq->axq_qnum);
-diff --git a/package/kernel/mac80211/patches/301-mac80211-lock-rate-control.patch b/package/kernel/mac80211/patches/301-mac80211-lock-rate-control.patch
-deleted file mode 100644
-index 465d943..0000000
---- a/package/kernel/mac80211/patches/301-mac80211-lock-rate-control.patch
-+++ /dev/null
-@@ -1,125 +0,0 @@
--From: Johannes Berg <johannes.berg@intel.com>
--Date: Wed, 11 Mar 2015 09:14:15 +0100
--Subject: [PATCH] mac80211: lock rate control
--
--Both minstrel (reported by Sven Eckelmann) and the iwlwifi rate
--control aren't properly taking concurrency into account. It's
--likely that the same is true for other rate control algorithms.
--
--In the case of minstrel this manifests itself in crashes when an
--update and other data access are run concurrently, for example
--when the stations change bandwidth or similar. In iwlwifi, this
--can cause firmware crashes.
--
--Since fixing all rate control algorithms will be very difficult,
--just provide locking for invocations. This protects the internal
--data structures the algorithms maintain.
--
--I've manipulated hostapd to test this, by having it change its
--advertised bandwidth roughly ever 150ms. At the same time, I'm
--running a flood ping between the client and the AP, which causes
--this race of update vs. get_rate/status to easily happen on the
--client. With this change, the system survives this test.
--
--Reported-by: Sven Eckelmann <sven@open-mesh.com>
--Signed-off-by: Johannes Berg <johannes.berg@intel.com>
-----
--
----- a/net/mac80211/rate.c
--+++ b/net/mac80211/rate.c
--@@ -683,7 +683,13 @@ void rate_control_get_rate(struct ieee80
-- 	if (sdata->local->hw.flags & IEEE80211_HW_HAS_RATE_CONTROL)
-- 		return;
-- 
---	ref->ops->get_rate(ref->priv, ista, priv_sta, txrc);
--+	if (ista) {
--+		spin_lock_bh(&sta->rate_ctrl_lock);
--+		ref->ops->get_rate(ref->priv, ista, priv_sta, txrc);
--+		spin_unlock_bh(&sta->rate_ctrl_lock);
--+	} else {
--+		ref->ops->get_rate(ref->priv, NULL, NULL, txrc);
--+	}
-- 
-- 	if (sdata->local->hw.flags & IEEE80211_HW_SUPPORTS_RC_TABLE)
-- 		return;
----- a/net/mac80211/rate.h
--+++ b/net/mac80211/rate.h
--@@ -42,10 +42,12 @@ static inline void rate_control_tx_statu
-- 	if (!ref || !test_sta_flag(sta, WLAN_STA_RATE_CONTROL))
-- 		return;
-- 
--+	spin_lock_bh(&sta->rate_ctrl_lock);
-- 	if (ref->ops->tx_status)
-- 		ref->ops->tx_status(ref->priv, sband, ista, priv_sta, skb);
-- 	else
-- 		ref->ops->tx_status_noskb(ref->priv, sband, ista, priv_sta, info);
--+	spin_unlock_bh(&sta->rate_ctrl_lock);
-- }
-- 
-- static inline void
--@@ -64,7 +66,9 @@ rate_control_tx_status_noskb(struct ieee
-- 	if (WARN_ON_ONCE(!ref->ops->tx_status_noskb))
-- 		return;
-- 
--+	spin_lock_bh(&sta->rate_ctrl_lock);
-- 	ref->ops->tx_status_noskb(ref->priv, sband, ista, priv_sta, info);
--+	spin_unlock_bh(&sta->rate_ctrl_lock);
-- }
-- 
-- static inline void rate_control_rate_init(struct sta_info *sta)
--@@ -91,8 +95,10 @@ static inline void rate_control_rate_ini
-- 
-- 	sband = local->hw.wiphy->bands[chanctx_conf->def.chan->band];
-- 
--+	spin_lock_bh(&sta->rate_ctrl_lock);
-- 	ref->ops->rate_init(ref->priv, sband, &chanctx_conf->def, ista,
-- 			    priv_sta);
--+	spin_unlock_bh(&sta->rate_ctrl_lock);
-- 	rcu_read_unlock();
-- 	set_sta_flag(sta, WLAN_STA_RATE_CONTROL);
-- }
--@@ -115,18 +121,20 @@ static inline void rate_control_rate_upd
-- 			return;
-- 		}
-- 
--+		spin_lock_bh(&sta->rate_ctrl_lock);
-- 		ref->ops->rate_update(ref->priv, sband, &chanctx_conf->def,
-- 				      ista, priv_sta, changed);
--+		spin_unlock_bh(&sta->rate_ctrl_lock);
-- 		rcu_read_unlock();
-- 	}
-- 	drv_sta_rc_update(local, sta->sdata, &sta->sta, changed);
-- }
-- 
-- static inline void *rate_control_alloc_sta(struct rate_control_ref *ref,
---					   struct ieee80211_sta *sta,
---					   gfp_t gfp)
--+					   struct sta_info *sta, gfp_t gfp)
-- {
---	return ref->ops->alloc_sta(ref->priv, sta, gfp);
--+	spin_lock_init(&sta->rate_ctrl_lock);
--+	return ref->ops->alloc_sta(ref->priv, &sta->sta, gfp);
-- }
-- 
-- static inline void rate_control_free_sta(struct sta_info *sta)
----- a/net/mac80211/sta_info.c
--+++ b/net/mac80211/sta_info.c
--@@ -286,7 +286,7 @@ static int sta_prepare_rate_control(stru
-- 
-- 	sta->rate_ctrl = local->rate_ctrl;
-- 	sta->rate_ctrl_priv = rate_control_alloc_sta(sta->rate_ctrl,
---						     &sta->sta, gfp);
--+						     sta, gfp);
-- 	if (!sta->rate_ctrl_priv)
-- 		return -ENOMEM;
-- 
----- a/net/mac80211/sta_info.h
--+++ b/net/mac80211/sta_info.h
--@@ -349,6 +349,7 @@ struct sta_info {
-- 	u8 ptk_idx;
-- 	struct rate_control_ref *rate_ctrl;
-- 	void *rate_ctrl_priv;
--+	spinlock_t rate_ctrl_lock;
-- 	spinlock_t lock;
-- 
-- 	struct work_struct drv_deliver_wk;
-diff --git a/package/kernel/mac80211/patches/302-ath10k-Delay-device-access-after-cold-reset.patch b/package/kernel/mac80211/patches/302-ath10k-Delay-device-access-after-cold-reset.patch
-new file mode 100644
-index 0000000..820aa9a
---- /dev/null
-+++ b/package/kernel/mac80211/patches/302-ath10k-Delay-device-access-after-cold-reset.patch
-@@ -0,0 +1,56 @@
-+From: Vasanthakumar Thiagarajan <vthiagar@qti.qualcomm.com>
-+Date: Fri, 3 Jul 2015 11:45:42 +0530
-+Subject: [PATCH] ath10k: Delay device access after cold reset
-+
-+It is observed that during cold reset pcie access right
-+after a write operation to SOC_GLOBAL_RESET_ADDRESS causes
-+Data Bus Error and system hard lockup. The reason
-+for bus error is that pcie needs some time to get
-+back to stable state for any transaction during cold reset. Add
-+delay of 20 msecs after write of SOC_GLOBAL_RESET_ADDRESS
-+to fix this issue.
-+
-+Signed-off-by: Vasanthakumar Thiagarajan <vthiagar@qti.qualcomm.com>
-+---
-+
-+--- a/drivers/net/wireless/ath/ath10k/pci.c
-++++ b/drivers/net/wireless/ath/ath10k/pci.c
-+@@ -2761,7 +2761,6 @@ static int ath10k_pci_wait_for_target_in
-+ 
-+ static int ath10k_pci_cold_reset(struct ath10k *ar)
-+ {
-+-	int i;
-+ 	u32 val;
-+ 
-+ 	ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot cold reset\n");
-+@@ -2777,23 +2776,18 @@ static int ath10k_pci_cold_reset(struct
-+ 	val |= 1;
-+ 	ath10k_pci_reg_write32(ar, SOC_GLOBAL_RESET_ADDRESS, val);
-+ 
-+-	for (i = 0; i < ATH_PCI_RESET_WAIT_MAX; i++) {
-+-		if (ath10k_pci_reg_read32(ar, RTC_STATE_ADDRESS) &
-+-					  RTC_STATE_COLD_RESET_MASK)
-+-			break;
-+-		msleep(1);
-+-	}
-++	/* After writing into SOC_GLOBAL_RESET to put device into
-++	 * reset and pulling out of reset pcie may not be stable
-++	 * for any immediate pcie register access and cause bus error,
-++	 * add delay before any pcie access request to fix this issue.
-++	 */
-++	msleep(20);
-+ 
-+ 	/* Pull Target, including PCIe, out of RESET. */
-+ 	val &= ~1;
-+ 	ath10k_pci_reg_write32(ar, SOC_GLOBAL_RESET_ADDRESS, val);
-+ 
-+-	for (i = 0; i < ATH_PCI_RESET_WAIT_MAX; i++) {
-+-		if (!(ath10k_pci_reg_read32(ar, RTC_STATE_ADDRESS) &
-+-					    RTC_STATE_COLD_RESET_MASK))
-+-			break;
-+-		msleep(1);
-+-	}
-++	msleep(20);
-+ 
-+ 	ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot cold reset complete\n");
-+ 
-diff --git a/package/kernel/mac80211/patches/302-ath9k-restart-only-triggering-DFS-detector-line.patch b/package/kernel/mac80211/patches/302-ath9k-restart-only-triggering-DFS-detector-line.patch
-deleted file mode 100644
-index e54e16e..0000000
---- a/package/kernel/mac80211/patches/302-ath9k-restart-only-triggering-DFS-detector-line.patch
-+++ /dev/null
-@@ -1,21 +0,0 @@
--From: Zefir Kurtisi <zefir.kurtisi@neratec.com>
--Date: Tue, 10 Mar 2015 17:49:29 +0100
--Subject: [PATCH] ath9k: restart only triggering DFS detector line
--
--To support HT40 DFS mode, a triggering detector must
--reset only itself but not other detector lines.
--
--Signed-off-by: Zefir Kurtisi <zefir.kurtisi@neratec.com>
-----
--
----- a/drivers/net/wireless/ath/dfs_pattern_detector.c
--+++ b/drivers/net/wireless/ath/dfs_pattern_detector.c
--@@ -289,7 +289,7 @@ dpd_add_pulse(struct dfs_pattern_detecto
-- 				"count=%d, count_false=%d\n",
-- 				event->freq, pd->rs->type_id,
-- 				ps->pri, ps->count, ps->count_falses);
---			channel_detector_reset(dpd, cd);
--+			pd->reset(pd, dpd->last_pulse_ts);
-- 			return true;
-- 		}
-- 	}
-diff --git a/package/kernel/mac80211/patches/303-ath9k-add-DFS-support-for-extension-channel.patch b/package/kernel/mac80211/patches/303-ath9k-add-DFS-support-for-extension-channel.patch
-deleted file mode 100644
-index ed268ea..0000000
---- a/package/kernel/mac80211/patches/303-ath9k-add-DFS-support-for-extension-channel.patch
-+++ /dev/null
-@@ -1,76 +0,0 @@
--From: Zefir Kurtisi <zefir.kurtisi@neratec.com>
--Date: Tue, 10 Mar 2015 17:49:30 +0100
--Subject: [PATCH] ath9k: add DFS support for extension channel
--
--In HT40 modes, pulse events on primary and extension
--channel are processed individually. If valid, a pulse
--event will be fed into the detector
--* for primary frequency, or
--* for extension frequency (+/-20MHz based on HT40-mode)
--* or both
--
--With that, a 40MHz radar will result in two individual
--radar events.
--
--Signed-off-by: Zefir Kurtisi <zefir.kurtisi@neratec.com>
-----
--
----- a/drivers/net/wireless/ath/ath9k/dfs.c
--+++ b/drivers/net/wireless/ath/ath9k/dfs.c
--@@ -126,8 +126,19 @@ ath9k_postprocess_radar_event(struct ath
-- 	DFS_STAT_INC(sc, pulses_detected);
-- 	return true;
-- }
---#undef PRI_CH_RADAR_FOUND
---#undef EXT_CH_RADAR_FOUND
--+
--+static void
--+ath9k_dfs_process_radar_pulse(struct ath_softc *sc, struct pulse_event *pe)
--+{
--+	struct dfs_pattern_detector *pd = sc->dfs_detector;
--+	DFS_STAT_INC(sc, pulses_processed);
--+	if (pd == NULL)
--+		return;
--+	if (!pd->add_pulse(pd, pe))
--+		return;
--+	DFS_STAT_INC(sc, radar_detected);
--+	ieee80211_radar_detected(sc->hw);
--+}
-- 
-- /*
--  * DFS: check PHY-error for radar pulse and feed the detector
--@@ -176,18 +187,21 @@ void ath9k_dfs_process_phyerr(struct ath
-- 	ard.pulse_length_pri = vdata_end[-3];
-- 	pe.freq = ah->curchan->channel;
-- 	pe.ts = mactime;
---	if (ath9k_postprocess_radar_event(sc, &ard, &pe)) {
---		struct dfs_pattern_detector *pd = sc->dfs_detector;
---		ath_dbg(common, DFS,
---			"ath9k_dfs_process_phyerr: channel=%d, ts=%llu, "
---			"width=%d, rssi=%d, delta_ts=%llu\n",
---			pe.freq, pe.ts, pe.width, pe.rssi,
---			pe.ts - sc->dfs_prev_pulse_ts);
---		sc->dfs_prev_pulse_ts = pe.ts;
---		DFS_STAT_INC(sc, pulses_processed);
---		if (pd != NULL && pd->add_pulse(pd, &pe)) {
---			DFS_STAT_INC(sc, radar_detected);
---			ieee80211_radar_detected(sc->hw);
---		}
--+	if (!ath9k_postprocess_radar_event(sc, &ard, &pe))
--+		return;
--+
--+	ath_dbg(common, DFS,
--+		"ath9k_dfs_process_phyerr: type=%d, freq=%d, ts=%llu, "
--+		"width=%d, rssi=%d, delta_ts=%llu\n",
--+		ard.pulse_bw_info, pe.freq, pe.ts, pe.width, pe.rssi,
--+		pe.ts - sc->dfs_prev_pulse_ts);
--+	sc->dfs_prev_pulse_ts = pe.ts;
--+	if (ard.pulse_bw_info & PRI_CH_RADAR_FOUND)
--+		ath9k_dfs_process_radar_pulse(sc, &pe);
--+	if (ard.pulse_bw_info & EXT_CH_RADAR_FOUND) {
--+		pe.freq += IS_CHAN_HT40PLUS(ah->curchan) ? 20 : -20;
--+		ath9k_dfs_process_radar_pulse(sc, &pe);
-- 	}
-- }
--+#undef PRI_CH_RADAR_FOUND
--+#undef EXT_CH_RADAR_FOUND
-diff --git a/package/kernel/mac80211/patches/303-ath9k-add-fast-xmit-support.patch b/package/kernel/mac80211/patches/303-ath9k-add-fast-xmit-support.patch
-new file mode 100644
-index 0000000..139015c
---- /dev/null
-+++ b/package/kernel/mac80211/patches/303-ath9k-add-fast-xmit-support.patch
-@@ -0,0 +1,17 @@
-+From: Felix Fietkau <nbd@openwrt.org>
-+Date: Mon, 11 May 2015 18:35:20 +0200
-+Subject: [PATCH] ath9k: add fast-xmit support
-+
-+Signed-off-by: Felix Fietkau <nbd@openwrt.org>
-+---
-+
-+--- a/drivers/net/wireless/ath/ath9k/init.c
-++++ b/drivers/net/wireless/ath/ath9k/init.c
-+@@ -826,6 +826,7 @@ static void ath9k_set_hw_capab(struct at
-+ 	ieee80211_hw_set(hw, SIGNAL_DBM);
-+ 	ieee80211_hw_set(hw, RX_INCLUDES_FCS);
-+ 	ieee80211_hw_set(hw, HOST_BROADCAST_PS_BUFFERING);
-++	ieee80211_hw_set(hw, SUPPORT_FAST_XMIT);
-+ 
-+ 	if (ath9k_ps_enable)
-+ 		ieee80211_hw_set(hw, SUPPORTS_PS);
-diff --git a/package/kernel/mac80211/patches/304-ath9k-allow-40MHz-radar-detection-width.patch b/package/kernel/mac80211/patches/304-ath9k-allow-40MHz-radar-detection-width.patch
-deleted file mode 100644
-index e1eab64..0000000
---- a/package/kernel/mac80211/patches/304-ath9k-allow-40MHz-radar-detection-width.patch
-+++ /dev/null
-@@ -1,19 +0,0 @@
--From: Zefir Kurtisi <zefir.kurtisi@neratec.com>
--Date: Tue, 10 Mar 2015 17:49:31 +0100
--Subject: [PATCH] ath9k: allow 40MHz radar detection width
--
--Signed-off-by: Zefir Kurtisi <zefir.kurtisi@neratec.com>
-----
--
----- a/drivers/net/wireless/ath/ath9k/init.c
--+++ b/drivers/net/wireless/ath/ath9k/init.c
--@@ -763,7 +763,8 @@ static const struct ieee80211_iface_comb
-- 		.num_different_channels = 1,
-- 		.beacon_int_infra_match = true,
-- 		.radar_detect_widths =	BIT(NL80211_CHAN_WIDTH_20_NOHT) |
---					BIT(NL80211_CHAN_WIDTH_20),
--+					BIT(NL80211_CHAN_WIDTH_20) |
--+					BIT(NL80211_CHAN_WIDTH_40),
-- 	}
-- #endif
-- };
-diff --git a/package/kernel/mac80211/patches/304-ath9k-remove-struct-ath_atx_ac.patch b/package/kernel/mac80211/patches/304-ath9k-remove-struct-ath_atx_ac.patch
-new file mode 100644
-index 0000000..9f04276
---- /dev/null
-+++ b/package/kernel/mac80211/patches/304-ath9k-remove-struct-ath_atx_ac.patch
-@@ -0,0 +1,385 @@
-+From: Felix Fietkau <nbd@openwrt.org>
-+Date: Sat, 4 Apr 2015 18:39:06 +0200
-+Subject: [PATCH] ath9k: remove struct ath_atx_ac
-+
-+struct ath_atx_ac contains a list of active TIDs belonging to one WMM AC.
-+This patch changes the code to track active station TIDs in the txq directly.
-+
-+Signed-off-by: Felix Fietkau <nbd@openwrt.org>
-+---
-+
-+--- a/drivers/net/wireless/ath/ath9k/ath9k.h
-++++ b/drivers/net/wireless/ath/ath9k/ath9k.h
-+@@ -173,14 +173,6 @@ struct ath_txq {
-+ 	struct sk_buff_head complete_q;
-+ };
-+ 
-+-struct ath_atx_ac {
-+-	struct ath_txq *txq;
-+-	struct list_head list;
-+-	struct list_head tid_q;
-+-	bool clear_ps_filter;
-+-	bool sched;
-+-};
-+-
-+ struct ath_frame_info {
-+ 	struct ath_buf *bf;
-+ 	u16 framelen;
-+@@ -243,7 +235,7 @@ struct ath_atx_tid {
-+ 	struct sk_buff_head buf_q;
-+ 	struct sk_buff_head retry_q;
-+ 	struct ath_node *an;
-+-	struct ath_atx_ac *ac;
-++	struct ath_txq *txq;
-+ 	unsigned long tx_buf[BITS_TO_LONGS(ATH_TID_MAX_BUFS)];
-+ 	u16 seq_start;
-+ 	u16 seq_next;
-+@@ -255,6 +247,7 @@ struct ath_atx_tid {
-+ 	s8 bar_index;
-+ 	bool sched;
-+ 	bool active;
-++	bool clear_ps_filter;
-+ };
-+ 
-+ struct ath_node {
-+@@ -262,7 +255,6 @@ struct ath_node {
-+ 	struct ieee80211_sta *sta; /* station struct we're part of */
-+ 	struct ieee80211_vif *vif; /* interface with which we're associated */
-+ 	struct ath_atx_tid tid[IEEE80211_NUM_TIDS];
-+-	struct ath_atx_ac ac[IEEE80211_NUM_ACS];
-+ 
-+ 	u16 maxampdu;
-+ 	u8 mpdudensity;
-+--- a/drivers/net/wireless/ath/ath9k/xmit.c
-++++ b/drivers/net/wireless/ath/ath9k/xmit.c
-+@@ -106,7 +106,6 @@ void ath_txq_unlock_complete(struct ath_
-+ static void ath_tx_queue_tid(struct ath_softc *sc, struct ath_txq *txq,
-+ 			     struct ath_atx_tid *tid)
-+ {
-+-	struct ath_atx_ac *ac = tid->ac;
-+ 	struct list_head *list;
-+ 	struct ath_vif *avp = (struct ath_vif *) tid->an->vif->drv_priv;
-+ 	struct ath_chanctx *ctx = avp->chanctx;
-+@@ -118,15 +117,8 @@ static void ath_tx_queue_tid(struct ath_
-+ 		return;
-+ 
-+ 	tid->sched = true;
-+-	list_add_tail(&tid->list, &ac->tid_q);
-+-
-+-	if (ac->sched)
-+-		return;
-+-
-+-	ac->sched = true;
-+-
-+ 	list = &ctx->acq[TID_TO_WME_AC(tid->tidno)];
-+-	list_add_tail(&ac->list, list);
-++	list_add_tail(&tid->list, list);
-+ }
-+ 
-+ static struct ath_frame_info *get_frame_info(struct sk_buff *skb)
-+@@ -223,7 +215,7 @@ static struct sk_buff *ath_tid_dequeue(s
-+ static void
-+ ath_tx_tid_change_state(struct ath_softc *sc, struct ath_atx_tid *tid)
-+ {
-+-	struct ath_txq *txq = tid->ac->txq;
-++	struct ath_txq *txq = tid->txq;
-+ 	struct ieee80211_tx_info *tx_info;
-+ 	struct sk_buff *skb, *tskb;
-+ 	struct ath_buf *bf;
-+@@ -252,7 +244,7 @@ ath_tx_tid_change_state(struct ath_softc
-+ 
-+ static void ath_tx_flush_tid(struct ath_softc *sc, struct ath_atx_tid *tid)
-+ {
-+-	struct ath_txq *txq = tid->ac->txq;
-++	struct ath_txq *txq = tid->txq;
-+ 	struct sk_buff *skb;
-+ 	struct ath_buf *bf;
-+ 	struct list_head bf_head;
-+@@ -659,7 +651,7 @@ static void ath_tx_complete_aggr(struct
-+ 			ath_tx_queue_tid(sc, txq, tid);
-+ 
-+ 			if (ts->ts_status & (ATH9K_TXERR_FILT | ATH9K_TXERR_XRETRY))
-+-				tid->ac->clear_ps_filter = true;
-++				tid->clear_ps_filter = true;
-+ 		}
-+ 	}
-+ 
-+@@ -749,7 +741,7 @@ static u32 ath_lookup_rate(struct ath_so
-+ 	struct ieee80211_tx_rate *rates;
-+ 	u32 max_4ms_framelen, frmlen;
-+ 	u16 aggr_limit, bt_aggr_limit, legacy = 0;
-+-	int q = tid->ac->txq->mac80211_qnum;
-++	int q = tid->txq->mac80211_qnum;
-+ 	int i;
-+ 
-+ 	skb = bf->bf_mpdu;
-+@@ -1486,8 +1478,8 @@ static bool ath_tx_sched_aggr(struct ath
-+ 	if (list_empty(&bf_q))
-+ 		return false;
-+ 
-+-	if (tid->ac->clear_ps_filter || tid->an->no_ps_filter) {
-+-		tid->ac->clear_ps_filter = false;
-++	if (tid->clear_ps_filter || tid->an->no_ps_filter) {
-++		tid->clear_ps_filter = false;
-+ 		tx_info->flags |= IEEE80211_TX_CTL_CLEAR_PS_FILT;
-+ 	}
-+ 
-+@@ -1506,7 +1498,7 @@ int ath_tx_aggr_start(struct ath_softc *
-+ 
-+ 	an = (struct ath_node *)sta->drv_priv;
-+ 	txtid = ATH_AN_2_TID(an, tid);
-+-	txq = txtid->ac->txq;
-++	txq = txtid->txq;
-+ 
-+ 	ath_txq_lock(sc, txq);
-+ 
-+@@ -1540,7 +1532,7 @@ void ath_tx_aggr_stop(struct ath_softc *
-+ {
-+ 	struct ath_node *an = (struct ath_node *)sta->drv_priv;
-+ 	struct ath_atx_tid *txtid = ATH_AN_2_TID(an, tid);
-+-	struct ath_txq *txq = txtid->ac->txq;
-++	struct ath_txq *txq = txtid->txq;
-+ 
-+ 	ath_txq_lock(sc, txq);
-+ 	txtid->active = false;
-+@@ -1553,7 +1545,6 @@ void ath_tx_aggr_sleep(struct ieee80211_
-+ 		       struct ath_node *an)
-+ {
-+ 	struct ath_atx_tid *tid;
-+-	struct ath_atx_ac *ac;
-+ 	struct ath_txq *txq;
-+ 	bool buffered;
-+ 	int tidno;
-+@@ -1561,8 +1552,7 @@ void ath_tx_aggr_sleep(struct ieee80211_
-+ 	for (tidno = 0, tid = &an->tid[tidno];
-+ 	     tidno < IEEE80211_NUM_TIDS; tidno++, tid++) {
-+ 
-+-		ac = tid->ac;
-+-		txq = ac->txq;
-++		txq = tid->txq;
-+ 
-+ 		ath_txq_lock(sc, txq);
-+ 
-+@@ -1576,11 +1566,6 @@ void ath_tx_aggr_sleep(struct ieee80211_
-+ 		tid->sched = false;
-+ 		list_del(&tid->list);
-+ 
-+-		if (ac->sched) {
-+-			ac->sched = false;
-+-			list_del(&ac->list);
-+-		}
-+-
-+ 		ath_txq_unlock(sc, txq);
-+ 
-+ 		ieee80211_sta_set_buffered(sta, tidno, buffered);
-+@@ -1590,18 +1575,16 @@ void ath_tx_aggr_sleep(struct ieee80211_
-+ void ath_tx_aggr_wakeup(struct ath_softc *sc, struct ath_node *an)
-+ {
-+ 	struct ath_atx_tid *tid;
-+-	struct ath_atx_ac *ac;
-+ 	struct ath_txq *txq;
-+ 	int tidno;
-+ 
-+ 	for (tidno = 0, tid = &an->tid[tidno];
-+ 	     tidno < IEEE80211_NUM_TIDS; tidno++, tid++) {
-+ 
-+-		ac = tid->ac;
-+-		txq = ac->txq;
-++		txq = tid->txq;
-+ 
-+ 		ath_txq_lock(sc, txq);
-+-		ac->clear_ps_filter = true;
-++		tid->clear_ps_filter = true;
-+ 
-+ 		if (ath_tid_has_buffered(tid)) {
-+ 			ath_tx_queue_tid(sc, txq, tid);
-+@@ -1621,7 +1604,7 @@ void ath_tx_aggr_resume(struct ath_softc
-+ 
-+ 	an = (struct ath_node *)sta->drv_priv;
-+ 	tid = ATH_AN_2_TID(an, tidno);
-+-	txq = tid->ac->txq;
-++	txq = tid->txq;
-+ 
-+ 	ath_txq_lock(sc, txq);
-+ 
-+@@ -1660,7 +1643,7 @@ void ath9k_release_buffered_frames(struc
-+ 
-+ 		tid = ATH_AN_2_TID(an, i);
-+ 
-+-		ath_txq_lock(sc, tid->ac->txq);
-++		ath_txq_lock(sc, tid->txq);
-+ 		while (nframes > 0) {
-+ 			bf = ath_tx_get_tid_subframe(sc, sc->tx.uapsdq, tid, &tid_q);
-+ 			if (!bf)
-+@@ -1684,7 +1667,7 @@ void ath9k_release_buffered_frames(struc
-+ 			if (an->sta && !ath_tid_has_buffered(tid))
-+ 				ieee80211_sta_set_buffered(an->sta, i, false);
-+ 		}
-+-		ath_txq_unlock_complete(sc, tid->ac->txq);
-++		ath_txq_unlock_complete(sc, tid->txq);
-+ 	}
-+ 
-+ 	if (list_empty(&bf_q))
-+@@ -1933,9 +1916,8 @@ void ath_tx_cleanupq(struct ath_softc *s
-+ void ath_txq_schedule(struct ath_softc *sc, struct ath_txq *txq)
-+ {
-+ 	struct ath_common *common = ath9k_hw_common(sc->sc_ah);
-+-	struct ath_atx_ac *ac, *last_ac;
-+ 	struct ath_atx_tid *tid, *last_tid;
-+-	struct list_head *ac_list;
-++	struct list_head *tid_list;
-+ 	bool sent = false;
-+ 
-+ 	if (txq->mac80211_qnum < 0)
-+@@ -1945,63 +1927,46 @@ void ath_txq_schedule(struct ath_softc *
-+ 		return;
-+ 
-+ 	spin_lock_bh(&sc->chan_lock);
-+-	ac_list = &sc->cur_chan->acq[txq->mac80211_qnum];
-++	tid_list = &sc->cur_chan->acq[txq->mac80211_qnum];
-+ 
-+-	if (list_empty(ac_list)) {
-++	if (list_empty(tid_list)) {
-+ 		spin_unlock_bh(&sc->chan_lock);
-+ 		return;
-+ 	}
-+ 
-+ 	rcu_read_lock();
-+ 
-+-	last_ac = list_entry(ac_list->prev, struct ath_atx_ac, list);
-+-	while (!list_empty(ac_list)) {
-++	last_tid = list_entry(tid_list->prev, struct ath_atx_tid, list);
-++	while (!list_empty(tid_list)) {
-+ 		bool stop = false;
-+ 
-+ 		if (sc->cur_chan->stopped)
-+ 			break;
-+ 
-+-		ac = list_first_entry(ac_list, struct ath_atx_ac, list);
-+-		last_tid = list_entry(ac->tid_q.prev, struct ath_atx_tid, list);
-+-		list_del(&ac->list);
-+-		ac->sched = false;
-+-
-+-		while (!list_empty(&ac->tid_q)) {
-+-
-+-			tid = list_first_entry(&ac->tid_q, struct ath_atx_tid,
-+-					       list);
-+-			list_del(&tid->list);
-+-			tid->sched = false;
-+-
-+-			if (ath_tx_sched_aggr(sc, txq, tid, &stop))
-+-				sent = true;
-+-
-+-			/*
-+-			 * add tid to round-robin queue if more frames
-+-			 * are pending for the tid
-+-			 */
-+-			if (ath_tid_has_buffered(tid))
-+-				ath_tx_queue_tid(sc, txq, tid);
-++		tid = list_first_entry(tid_list, struct ath_atx_tid, list);
-++		list_del(&tid->list);
-++		tid->sched = false;
-+ 
-+-			if (stop || tid == last_tid)
-+-				break;
-+-		}
-++		if (ath_tx_sched_aggr(sc, txq, tid, &stop))
-++			sent = true;
-+ 
-+-		if (!list_empty(&ac->tid_q) && !ac->sched) {
-+-			ac->sched = true;
-+-			list_add_tail(&ac->list, ac_list);
-+-		}
-++		/*
-++		 * add tid to round-robin queue if more frames
-++		 * are pending for the tid
-++		 */
-++		if (ath_tid_has_buffered(tid))
-++			ath_tx_queue_tid(sc, txq, tid);
-+ 
-+ 		if (stop)
-+ 			break;
-+ 
-+-		if (ac == last_ac) {
-++		if (tid == last_tid) {
-+ 			if (!sent)
-+ 				break;
-+ 
-+ 			sent = false;
-+-			last_ac = list_entry(ac_list->prev,
-+-					     struct ath_atx_ac, list);
-++			last_tid = list_entry(tid_list->prev,
-++					      struct ath_atx_tid, list);
-+ 		}
-+ 	}
-+ 
-+@@ -2391,10 +2356,10 @@ int ath_tx_start(struct ieee80211_hw *hw
-+ 		txq = sc->tx.uapsdq;
-+ 		ath_txq_lock(sc, txq);
-+ 	} else if (txctl->an && queue) {
-+-		WARN_ON(tid->ac->txq != txctl->txq);
-++		WARN_ON(tid->txq != txctl->txq);
-+ 
-+ 		if (info->flags & IEEE80211_TX_CTL_CLEAR_PS_FILT)
-+-			tid->ac->clear_ps_filter = true;
-++			tid->clear_ps_filter = true;
-+ 
-+ 		/*
-+ 		 * Add this frame to software queue for scheduling later
-+@@ -2888,7 +2853,6 @@ int ath_tx_init(struct ath_softc *sc, in
-+ void ath_tx_node_init(struct ath_softc *sc, struct ath_node *an)
-+ {
-+ 	struct ath_atx_tid *tid;
-+-	struct ath_atx_ac *ac;
-+ 	int tidno, acno;
-+ 
-+ 	for (tidno = 0, tid = &an->tid[tidno];
-+@@ -2901,24 +2865,16 @@ void ath_tx_node_init(struct ath_softc *
-+ 		tid->baw_head  = tid->baw_tail = 0;
-+ 		tid->sched     = false;
-+ 		tid->active	   = false;
-++		tid->clear_ps_filter = true;
-+ 		__skb_queue_head_init(&tid->buf_q);
-+ 		__skb_queue_head_init(&tid->retry_q);
-+ 		acno = TID_TO_WME_AC(tidno);
-+-		tid->ac = &an->ac[acno];
-+-	}
-+-
-+-	for (acno = 0, ac = &an->ac[acno];
-+-	     acno < IEEE80211_NUM_ACS; acno++, ac++) {
-+-		ac->sched    = false;
-+-		ac->clear_ps_filter = true;
-+-		ac->txq = sc->tx.txq_map[acno];
-+-		INIT_LIST_HEAD(&ac->tid_q);
-++		tid->txq = sc->tx.txq_map[acno];
-+ 	}
-+ }
-+ 
-+ void ath_tx_node_cleanup(struct ath_softc *sc, struct ath_node *an)
-+ {
-+-	struct ath_atx_ac *ac;
-+ 	struct ath_atx_tid *tid;
-+ 	struct ath_txq *txq;
-+ 	int tidno;
-+@@ -2926,8 +2882,7 @@ void ath_tx_node_cleanup(struct ath_soft
-+ 	for (tidno = 0, tid = &an->tid[tidno];
-+ 	     tidno < IEEE80211_NUM_TIDS; tidno++, tid++) {
-+ 
-+-		ac = tid->ac;
-+-		txq = ac->txq;
-++		txq = tid->txq;
-+ 
-+ 		ath_txq_lock(sc, txq);
-+ 
-+@@ -2936,11 +2891,6 @@ void ath_tx_node_cleanup(struct ath_soft
-+ 			tid->sched = false;
-+ 		}
-+ 
-+-		if (ac->sched) {
-+-			list_del(&ac->list);
-+-			tid->ac->sched = false;
-+-		}
-+-
-+ 		ath_tid_drain(sc, txq, tid);
-+ 		tid->active = false;
-+ 
-diff --git a/package/kernel/mac80211/patches/305-ath5k-channel-change-fix.patch b/package/kernel/mac80211/patches/305-ath5k-channel-change-fix.patch
-deleted file mode 100644
-index 4cfa53f..0000000
---- a/package/kernel/mac80211/patches/305-ath5k-channel-change-fix.patch
-+++ /dev/null
-@@ -1,137 +0,0 @@
--From: Sergey Ryazanov <ryazanov.s.a@gmail.com>
--Date: Wed, 4 Mar 2015 05:12:10 +0300
--Subject: [PATCH] ath5k: channel change fix
--
--ath5k updates the channel pointer and after that it stops the Rx logic
--and apply channel to HW. In case of channel switch, such sequence
--creates a small window when a frame, which is received on the old
--channel is considered as a frame received on the new one.
--
--The most notable consequence of this situation occurs during the switch
--from 2 GHz band (CCK+OFDM) to the 5GHz band (OFDM-only). Frame received
--with CCK rate, e.g. beacon received at the 1mbps, causes the following
--warning:
--
--  WARNING: at ath5k/base.c:589 ath5k_tasklet_rx+0x318/0x6ec [ath5k]()
--  invalid hw_rix: 1a
--  [..]
--  Call Trace:
--  [<802656a8>] show_stack+0x48/0x70
--  [<802dd92c>] warn_slowpath_common+0x88/0xbc
--  [<802dd98c>] warn_slowpath_fmt+0x2c/0x38
--  [<81b51be8>] ath5k_tasklet_rx+0x318/0x6ec [ath5k]
--  [<8028ac64>] tasklet_action+0x8c/0xf0
--  [<80075804>] __do_softirq+0x180/0x32c
--  [<80196ce8>] irq_exit+0x54/0x70
--  [<80041848>] ret_from_irq+0x0/0x4
--  [<80182fdc>] ioread32+0x4/0xc
--  [<81b4c42c>] ath5k_hw_set_sleep_clock+0x2ec/0x474 [ath5k]
--  [<81b4cf28>] ath5k_hw_reset+0x50/0xeb8 [ath5k]
--  [<81b50900>] ath5k_reset+0xd4/0x310 [ath5k]
--  [<81b557e8>] ath5k_config+0x4c/0x104 [ath5k]
--  [<80d01770>] ieee80211_hw_config+0x2f4/0x35c [mac80211]
--  [<80d09aa8>] ieee80211_scan_work+0x2e4/0x414 [mac80211]
--  [<8022c3f4>] process_one_work+0x28c/0x400
--  [<802df8f8>] worker_thread+0x258/0x3c0
--  [<801b5710>] kthread+0xe0/0xec
--  [<800418a8>] ret_from_kernel_thread+0x14/0x1c
--
--The easiest way to reproduce this warning is to run scan with dualband
--NIC in noisy environments, when the channel 11 runs multiple APs. In my
--tests if the APs num >= 12, the warning appears in the first few
--seconds of scanning.
--
--In order to fix this, the Rx disable code moved to a higher level and
--placed before the channel pointer update. This is also makes the code a
--bit more symmetrical, since we disable and enable the Rx in the same
--function.
--
--In fact, at the pointer update time new frames should not appear,
--because interrupt generation at this point should already be disabled.
--The next patch should address this issue.
--
--CC: Jiri Slaby <jirislaby@gmail.com>
--CC: Nick Kossifidis <mickflemm@gmail.com>
--CC: Luis R. Rodriguez <mcgrof@do-not-panic.com>
--Reported-by: Christophe Prevotaux <cprevotaux@nltinc.com>
--Tested-by: Christophe Prevotaux <cprevotaux@nltinc.com>
--Tested-by: Eric Bree <ebree@nltinc.com>
--Signed-off-by: Sergey Ryazanov <ryazanov.s.a@gmail.com>
-----
--
----- a/drivers/net/wireless/ath/ath5k/base.c
--+++ b/drivers/net/wireless/ath/ath5k/base.c
--@@ -2858,7 +2858,7 @@ ath5k_reset(struct ath5k_hw *ah, struct
-- {
-- 	struct ath_common *common = ath5k_hw_common(ah);
-- 	int ret, ani_mode;
---	bool fast;
--+	bool fast = chan && modparam_fastchanswitch ? 1 : 0;
-- 
-- 	ATH5K_DBG(ah, ATH5K_DEBUG_RESET, "resetting\n");
-- 
--@@ -2876,11 +2876,29 @@ ath5k_reset(struct ath5k_hw *ah, struct
-- 	 * so we should also free any remaining
-- 	 * tx buffers */
-- 	ath5k_drain_tx_buffs(ah);
--+
--+	/* Stop PCU */
--+	ath5k_hw_stop_rx_pcu(ah);
--+
--+	/* Stop DMA
--+	 *
--+	 * Note: If DMA didn't stop continue
--+	 * since only a reset will fix it.
--+	 */
--+	ret = ath5k_hw_dma_stop(ah);
--+
--+	/* RF Bus grant won't work if we have pending
--+	 * frames
--+	 */
--+	if (ret && fast) {
--+		ATH5K_DBG(ah, ATH5K_DEBUG_RESET,
--+			  "DMA didn't stop, falling back to normal reset\n");
--+		fast = false;
--+	}
--+
-- 	if (chan)
-- 		ah->curchan = chan;
-- 
---	fast = ((chan != NULL) && modparam_fastchanswitch) ? 1 : 0;
---
-- 	ret = ath5k_hw_reset(ah, ah->opmode, ah->curchan, fast, skip_pcu);
-- 	if (ret) {
-- 		ATH5K_ERR(ah, "can't reset hardware (%d)\n", ret);
----- a/drivers/net/wireless/ath/ath5k/reset.c
--+++ b/drivers/net/wireless/ath/ath5k/reset.c
--@@ -1169,30 +1169,6 @@ ath5k_hw_reset(struct ath5k_hw *ah, enum
-- 	if (ah->ah_version == AR5K_AR5212)
-- 		ath5k_hw_set_sleep_clock(ah, false);
-- 
---	/*
---	 * Stop PCU
---	 */
---	ath5k_hw_stop_rx_pcu(ah);
---
---	/*
---	 * Stop DMA
---	 *
---	 * Note: If DMA didn't stop continue
---	 * since only a reset will fix it.
---	 */
---	ret = ath5k_hw_dma_stop(ah);
---
---	/* RF Bus grant won't work if we have pending
---	 * frames */
---	if (ret && fast) {
---		ATH5K_DBG(ah, ATH5K_DEBUG_RESET,
---			"DMA didn't stop, falling back to normal reset\n");
---		fast = false;
---		/* Non fatal, just continue with
---		 * normal reset */
---		ret = 0;
---	}
---
-- 	mode = channel->hw_value;
-- 	switch (mode) {
-- 	case AR5K_MODE_11A:
-diff --git a/package/kernel/mac80211/patches/305-ath9k-remove-the-sched-field-in-struct-ath_atx_tid.patch b/package/kernel/mac80211/patches/305-ath9k-remove-the-sched-field-in-struct-ath_atx_tid.patch
-new file mode 100644
-index 0000000..ec860dc
---- /dev/null
-+++ b/package/kernel/mac80211/patches/305-ath9k-remove-the-sched-field-in-struct-ath_atx_tid.patch
-@@ -0,0 +1,90 @@
-+From: Felix Fietkau <nbd@openwrt.org>
-+Date: Sat, 4 Apr 2015 18:42:33 +0200
-+Subject: [PATCH] ath9k: remove the sched field in struct ath_atx_tid
-+
-+Use list_empty(&tid->list) instead
-+
-+Signed-off-by: Felix Fietkau <nbd@openwrt.org>
-+---
-+
-+--- a/drivers/net/wireless/ath/ath9k/ath9k.h
-++++ b/drivers/net/wireless/ath/ath9k/ath9k.h
-+@@ -245,7 +245,6 @@ struct ath_atx_tid {
-+ 	int baw_tail;   /* next unused tx buffer slot */
-+ 
-+ 	s8 bar_index;
-+-	bool sched;
-+ 	bool active;
-+ 	bool clear_ps_filter;
-+ };
-+--- a/drivers/net/wireless/ath/ath9k/xmit.c
-++++ b/drivers/net/wireless/ath/ath9k/xmit.c
-+@@ -113,12 +113,9 @@ static void ath_tx_queue_tid(struct ath_
-+ 	if (!ctx)
-+ 		return;
-+ 
-+-	if (tid->sched)
-+-		return;
-+-
-+-	tid->sched = true;
-+ 	list = &ctx->acq[TID_TO_WME_AC(tid->tidno)];
-+-	list_add_tail(&tid->list, list);
-++	if (list_empty(&tid->list))
-++		list_add_tail(&tid->list, list);
-+ }
-+ 
-+ static struct ath_frame_info *get_frame_info(struct sk_buff *skb)
-+@@ -1556,15 +1553,14 @@ void ath_tx_aggr_sleep(struct ieee80211_
-+ 
-+ 		ath_txq_lock(sc, txq);
-+ 
-+-		if (!tid->sched) {
-++		if (list_empty(&tid->list)) {
-+ 			ath_txq_unlock(sc, txq);
-+ 			continue;
-+ 		}
-+ 
-+ 		buffered = ath_tid_has_buffered(tid);
-+ 
-+-		tid->sched = false;
-+-		list_del(&tid->list);
-++		list_del_init(&tid->list);
-+ 
-+ 		ath_txq_unlock(sc, txq);
-+ 
-+@@ -1944,8 +1940,7 @@ void ath_txq_schedule(struct ath_softc *
-+ 			break;
-+ 
-+ 		tid = list_first_entry(tid_list, struct ath_atx_tid, list);
-+-		list_del(&tid->list);
-+-		tid->sched = false;
-++		list_del_init(&tid->list);
-+ 
-+ 		if (ath_tx_sched_aggr(sc, txq, tid, &stop))
-+ 			sent = true;
-+@@ -2863,11 +2858,11 @@ void ath_tx_node_init(struct ath_softc *
-+ 		tid->seq_start = tid->seq_next = 0;
-+ 		tid->baw_size  = WME_MAX_BA;
-+ 		tid->baw_head  = tid->baw_tail = 0;
-+-		tid->sched     = false;
-+ 		tid->active	   = false;
-+ 		tid->clear_ps_filter = true;
-+ 		__skb_queue_head_init(&tid->buf_q);
-+ 		__skb_queue_head_init(&tid->retry_q);
-++		INIT_LIST_HEAD(&tid->list);
-+ 		acno = TID_TO_WME_AC(tidno);
-+ 		tid->txq = sc->tx.txq_map[acno];
-+ 	}
-+@@ -2886,10 +2881,8 @@ void ath_tx_node_cleanup(struct ath_soft
-+ 
-+ 		ath_txq_lock(sc, txq);
-+ 
-+-		if (tid->sched) {
-+-			list_del(&tid->list);
-+-			tid->sched = false;
-+-		}
-++		if (!list_empty(&tid->list))
-++			list_del_init(&tid->list);
-+ 
-+ 		ath_tid_drain(sc, txq, tid);
-+ 		tid->active = false;
-diff --git a/package/kernel/mac80211/patches/306-ath5k-fix-reset-race.patch b/package/kernel/mac80211/patches/306-ath5k-fix-reset-race.patch
-deleted file mode 100644
-index 85a1904..0000000
---- a/package/kernel/mac80211/patches/306-ath5k-fix-reset-race.patch
-+++ /dev/null
-@@ -1,96 +0,0 @@
--From: Sergey Ryazanov <ryazanov.s.a@gmail.com>
--Date: Wed, 4 Mar 2015 05:12:11 +0300
--Subject: [PATCH] ath5k: fix reset race
--
--To prepare for reset ath5k should finish all asynchronous tasks. At
--first, it disables the interrupt generation, then it waits for the
--interrupt handler and tasklets completion, and then proceeds to the HW
--configuration update. But it does not consider that the interrupt
--handler or tasklet re-enables the interrupt generation. And we fall in a
--situation when ath5k assumes that interrupts are disabled, but it is
--not.
--
--This can lead to different consequences, such as reception of the frame,
--when we do not expect it. Under certain circumstances, this can lead to
--the following warning:
--
--  WARNING: at ath5k/base.c:589 ath5k_tasklet_rx+0x318/0x6ec [ath5k]()
--  invalid hw_rix: 1a
--  [..]
--  Call Trace:
--  [<802656a8>] show_stack+0x48/0x70
--  [<802dd92c>] warn_slowpath_common+0x88/0xbc
--  [<802dd98c>] warn_slowpath_fmt+0x2c/0x38
--  [<81b51be8>] ath5k_tasklet_rx+0x318/0x6ec [ath5k]
--  [<8028ac64>] tasklet_action+0x8c/0xf0
--  [<80075804>] __do_softirq+0x180/0x32c
--  [<80196ce8>] irq_exit+0x54/0x70
--  [<80041848>] ret_from_irq+0x0/0x4
--  [<80182fdc>] ioread32+0x4/0xc
--  [<81b4c42c>] ath5k_hw_set_sleep_clock+0x2ec/0x474 [ath5k]
--  [<81b4cf28>] ath5k_hw_reset+0x50/0xeb8 [ath5k]
--  [<81b50900>] ath5k_reset+0xd4/0x310 [ath5k]
--  [<81b557e8>] ath5k_config+0x4c/0x104 [ath5k]
--  [<80d01770>] ieee80211_hw_config+0x2f4/0x35c [mac80211]
--  [<80d09aa8>] ieee80211_scan_work+0x2e4/0x414 [mac80211]
--  [<8022c3f4>] process_one_work+0x28c/0x400
--  [<802df8f8>] worker_thread+0x258/0x3c0
--  [<801b5710>] kthread+0xe0/0xec
--  [<800418a8>] ret_from_kernel_thread+0x14/0x1c
--
--Fix this issue by adding a new status flag, which forbids to re-enable
--the interrupt generation until the HW configuration is completed.
--
--Note: previous patch, which reorders the Rx disable code helps to avoid
--the above warning, but not fixes the root cause of unexpected frame
--receiving.
--
--CC: Jiri Slaby <jirislaby@gmail.com>
--CC: Nick Kossifidis <mickflemm@gmail.com>
--CC: Luis R. Rodriguez <mcgrof@do-not-panic.com>
--Reported-by: Christophe Prevotaux <cprevotaux@nltinc.com>
--Tested-by: Christophe Prevotaux <cprevotaux@nltinc.com>
--Tested-by: Eric Bree <ebree@nltinc.com>
--Signed-off-by: Sergey Ryazanov <ryazanov.s.a@gmail.com>
-----
--
----- a/drivers/net/wireless/ath/ath5k/ath5k.h
--+++ b/drivers/net/wireless/ath/ath5k/ath5k.h
--@@ -1283,6 +1283,7 @@ struct ath5k_hw {
-- #define ATH_STAT_PROMISC	1
-- #define ATH_STAT_LEDSOFT	2		/* enable LED gpio status */
-- #define ATH_STAT_STARTED	3		/* opened & irqs enabled */
--+#define ATH_STAT_RESET		4		/* hw reset */
-- 
-- 	unsigned int		filter_flags;	/* HW flags, AR5K_RX_FILTER_* */
-- 	unsigned int		fif_filter_flags; /* Current FIF_* filter flags */
----- a/drivers/net/wireless/ath/ath5k/base.c
--+++ b/drivers/net/wireless/ath/ath5k/base.c
--@@ -1523,6 +1523,9 @@ ath5k_set_current_imask(struct ath5k_hw
-- 	enum ath5k_int imask;
-- 	unsigned long flags;
-- 
--+	if (test_bit(ATH_STAT_RESET, ah->status))
--+		return;
--+
-- 	spin_lock_irqsave(&ah->irqlock, flags);
-- 	imask = ah->imask;
-- 	if (ah->rx_pending)
--@@ -2862,6 +2865,8 @@ ath5k_reset(struct ath5k_hw *ah, struct
-- 
-- 	ATH5K_DBG(ah, ATH5K_DEBUG_RESET, "resetting\n");
-- 
--+	__set_bit(ATH_STAT_RESET, ah->status);
--+
-- 	ath5k_hw_set_imr(ah, 0);
-- 	synchronize_irq(ah->irq);
-- 	ath5k_stop_tasklets(ah);
--@@ -2952,6 +2957,8 @@ ath5k_reset(struct ath5k_hw *ah, struct
-- 	 */
-- /*	ath5k_chan_change(ah, c); */
-- 
--+	__clear_bit(ATH_STAT_RESET, ah->status);
--+
-- 	ath5k_beacon_config(ah);
-- 	/* intrs are enabled by ath5k_beacon_config */
-- 
-diff --git a/package/kernel/mac80211/patches/306-mac80211-Deinline-rate_control_rate_init-rate_contro.patch b/package/kernel/mac80211/patches/306-mac80211-Deinline-rate_control_rate_init-rate_contro.patch
-new file mode 100644
-index 0000000..928c93b
---- /dev/null
-+++ b/package/kernel/mac80211/patches/306-mac80211-Deinline-rate_control_rate_init-rate_contro.patch
-@@ -0,0 +1,161 @@
-+From: Denys Vlasenko <dvlasenk@redhat.com>
-+Date: Wed, 15 Jul 2015 14:56:06 +0200
-+Subject: [PATCH] mac80211: Deinline rate_control_rate_init,
-+ rate_control_rate_update
-+
-+With this .config: http://busybox.net/~vda/kernel_config,
-+after deinlining these functions have sizes and callsite counts
-+as follows:
-+
-+rate_control_rate_init: 554 bytes, 8 calls
-+rate_control_rate_update: 1596 bytes, 5 calls
-+
-+Total size reduction: about 11 kbytes.
-+
-+Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
-+CC: John Linville <linville@tuxdriver.com>
-+CC: Michal Kazior <michal.kazior@tieto.com>
-+CC: Johannes Berg <johannes.berg@intel.com>
-+Cc: linux-wireless@vger.kernel.org
-+Cc: netdev@vger.kernel.org
-+CC: linux-kernel@vger.kernel.org
-+---
-+
-+--- a/net/mac80211/rate.c
-++++ b/net/mac80211/rate.c
-+@@ -29,6 +29,65 @@ module_param(ieee80211_default_rc_algo,
-+ MODULE_PARM_DESC(ieee80211_default_rc_algo,
-+ 		 "Default rate control algorithm for mac80211 to use");
-+ 
-++void rate_control_rate_init(struct sta_info *sta)
-++{
-++	struct ieee80211_local *local = sta->sdata->local;
-++	struct rate_control_ref *ref = sta->rate_ctrl;
-++	struct ieee80211_sta *ista = &sta->sta;
-++	void *priv_sta = sta->rate_ctrl_priv;
-++	struct ieee80211_supported_band *sband;
-++	struct ieee80211_chanctx_conf *chanctx_conf;
-++
-++	ieee80211_sta_set_rx_nss(sta);
-++
-++	if (!ref)
-++		return;
-++
-++	rcu_read_lock();
-++
-++	chanctx_conf = rcu_dereference(sta->sdata->vif.chanctx_conf);
-++	if (WARN_ON(!chanctx_conf)) {
-++		rcu_read_unlock();
-++		return;
-++	}
-++
-++	sband = local->hw.wiphy->bands[chanctx_conf->def.chan->band];
-++
-++	spin_lock_bh(&sta->rate_ctrl_lock);
-++	ref->ops->rate_init(ref->priv, sband, &chanctx_conf->def, ista,
-++			    priv_sta);
-++	spin_unlock_bh(&sta->rate_ctrl_lock);
-++	rcu_read_unlock();
-++	set_sta_flag(sta, WLAN_STA_RATE_CONTROL);
-++}
-++
-++void rate_control_rate_update(struct ieee80211_local *local,
-++				    struct ieee80211_supported_band *sband,
-++				    struct sta_info *sta, u32 changed)
-++{
-++	struct rate_control_ref *ref = local->rate_ctrl;
-++	struct ieee80211_sta *ista = &sta->sta;
-++	void *priv_sta = sta->rate_ctrl_priv;
-++	struct ieee80211_chanctx_conf *chanctx_conf;
-++
-++	if (ref && ref->ops->rate_update) {
-++		rcu_read_lock();
-++
-++		chanctx_conf = rcu_dereference(sta->sdata->vif.chanctx_conf);
-++		if (WARN_ON(!chanctx_conf)) {
-++			rcu_read_unlock();
-++			return;
-++		}
-++
-++		spin_lock_bh(&sta->rate_ctrl_lock);
-++		ref->ops->rate_update(ref->priv, sband, &chanctx_conf->def,
-++				      ista, priv_sta, changed);
-++		spin_unlock_bh(&sta->rate_ctrl_lock);
-++		rcu_read_unlock();
-++	}
-++	drv_sta_rc_update(local, sta->sdata, &sta->sta, changed);
-++}
-++
-+ int ieee80211_rate_control_register(const struct rate_control_ops *ops)
-+ {
-+ 	struct rate_control_alg *alg;
-+--- a/net/mac80211/rate.h
-++++ b/net/mac80211/rate.h
-+@@ -71,64 +71,10 @@ rate_control_tx_status_noskb(struct ieee
-+ 	spin_unlock_bh(&sta->rate_ctrl_lock);
-+ }
-+ 
-+-static inline void rate_control_rate_init(struct sta_info *sta)
-+-{
-+-	struct ieee80211_local *local = sta->sdata->local;
-+-	struct rate_control_ref *ref = sta->rate_ctrl;
-+-	struct ieee80211_sta *ista = &sta->sta;
-+-	void *priv_sta = sta->rate_ctrl_priv;
-+-	struct ieee80211_supported_band *sband;
-+-	struct ieee80211_chanctx_conf *chanctx_conf;
-+-
-+-	ieee80211_sta_set_rx_nss(sta);
-+-
-+-	if (!ref)
-+-		return;
-+-
-+-	rcu_read_lock();
-+-
-+-	chanctx_conf = rcu_dereference(sta->sdata->vif.chanctx_conf);
-+-	if (WARN_ON(!chanctx_conf)) {
-+-		rcu_read_unlock();
-+-		return;
-+-	}
-+-
-+-	sband = local->hw.wiphy->bands[chanctx_conf->def.chan->band];
-+-
-+-	spin_lock_bh(&sta->rate_ctrl_lock);
-+-	ref->ops->rate_init(ref->priv, sband, &chanctx_conf->def, ista,
-+-			    priv_sta);
-+-	spin_unlock_bh(&sta->rate_ctrl_lock);
-+-	rcu_read_unlock();
-+-	set_sta_flag(sta, WLAN_STA_RATE_CONTROL);
-+-}
-+-
-+-static inline void rate_control_rate_update(struct ieee80211_local *local,
-++void rate_control_rate_init(struct sta_info *sta);
-++void rate_control_rate_update(struct ieee80211_local *local,
-+ 				    struct ieee80211_supported_band *sband,
-+-				    struct sta_info *sta, u32 changed)
-+-{
-+-	struct rate_control_ref *ref = local->rate_ctrl;
-+-	struct ieee80211_sta *ista = &sta->sta;
-+-	void *priv_sta = sta->rate_ctrl_priv;
-+-	struct ieee80211_chanctx_conf *chanctx_conf;
-+-
-+-	if (ref && ref->ops->rate_update) {
-+-		rcu_read_lock();
-+-
-+-		chanctx_conf = rcu_dereference(sta->sdata->vif.chanctx_conf);
-+-		if (WARN_ON(!chanctx_conf)) {
-+-			rcu_read_unlock();
-+-			return;
-+-		}
-+-
-+-		spin_lock_bh(&sta->rate_ctrl_lock);
-+-		ref->ops->rate_update(ref->priv, sband, &chanctx_conf->def,
-+-				      ista, priv_sta, changed);
-+-		spin_unlock_bh(&sta->rate_ctrl_lock);
-+-		rcu_read_unlock();
-+-	}
-+-	drv_sta_rc_update(local, sta->sdata, &sta->sta, changed);
-+-}
-++				    struct sta_info *sta, u32 changed);
-+ 
-+ static inline void *rate_control_alloc_sta(struct rate_control_ref *ref,
-+ 					   struct sta_info *sta, gfp_t gfp)
-diff --git a/package/kernel/mac80211/patches/307-ath9k-fix-tracking-of-enabled-AP-beacons.patch b/package/kernel/mac80211/patches/307-ath9k-fix-tracking-of-enabled-AP-beacons.patch
-deleted file mode 100644
-index ab9771e..0000000
---- a/package/kernel/mac80211/patches/307-ath9k-fix-tracking-of-enabled-AP-beacons.patch
-+++ /dev/null
-@@ -1,76 +0,0 @@
--From: Felix Fietkau <nbd@openwrt.org>
--Date: Thu, 12 Mar 2015 17:10:50 +0100
--Subject: [PATCH] ath9k: fix tracking of enabled AP beacons
--
--sc->nbcnvifs tracks assigned beacon slots, not enabled beacons.
--Therefore, it cannot be used to decide if cur_conf->enable_beacon (bool)
--should be updated, or if beacons have been enabled already.
--With the current code (depending on the order of calls), beacons often
--do not get enabled in an AP+STA setup.
--To fix tracking of enabled beacons, convert cur_conf->enable_beacon to a
--bitmask of enabled beacon slots.
--
--Cc: stable@vger.kernel.org
--Signed-off-by: Felix Fietkau <nbd@openwrt.org>
-----
--
----- a/drivers/net/wireless/ath/ath9k/beacon.c
--+++ b/drivers/net/wireless/ath/ath9k/beacon.c
--@@ -219,12 +219,15 @@ void ath9k_beacon_remove_slot(struct ath
-- 	struct ath_common *common = ath9k_hw_common(sc->sc_ah);
-- 	struct ath_vif *avp = (void *)vif->drv_priv;
-- 	struct ath_buf *bf = avp->av_bcbuf;
--+	struct ath_beacon_config *cur_conf = &sc->cur_chan->beacon;
-- 
-- 	ath_dbg(common, CONFIG, "Removing interface at beacon slot: %d\n",
-- 		avp->av_bslot);
-- 
-- 	tasklet_disable(&sc->bcon_tasklet);
-- 
--+	cur_conf->enable_beacon &= ~BIT(avp->av_bslot);
--+
-- 	if (bf && bf->bf_mpdu) {
-- 		struct sk_buff *skb = bf->bf_mpdu;
-- 		dma_unmap_single(sc->dev, bf->bf_buf_addr,
--@@ -521,8 +524,7 @@ static bool ath9k_allow_beacon_config(st
-- 	}
-- 
-- 	if (sc->sc_ah->opmode == NL80211_IFTYPE_AP) {
---		if ((vif->type != NL80211_IFTYPE_AP) ||
---		    (sc->nbcnvifs > 1)) {
--+		if (vif->type != NL80211_IFTYPE_AP) {
-- 			ath_dbg(common, CONFIG,
-- 				"An AP interface is already present !\n");
-- 			return false;
--@@ -616,12 +618,14 @@ void ath9k_beacon_config(struct ath_soft
-- 	 * enabling/disabling SWBA.
-- 	 */
-- 	if (changed & BSS_CHANGED_BEACON_ENABLED) {
---		if (!bss_conf->enable_beacon &&
---		    (sc->nbcnvifs <= 1)) {
---			cur_conf->enable_beacon = false;
---		} else if (bss_conf->enable_beacon) {
---			cur_conf->enable_beacon = true;
---			ath9k_cache_beacon_config(sc, ctx, bss_conf);
--+		bool enabled = cur_conf->enable_beacon;
--+
--+		if (!bss_conf->enable_beacon) {
--+			cur_conf->enable_beacon &= ~BIT(avp->av_bslot);
--+		} else {
--+			cur_conf->enable_beacon |= BIT(avp->av_bslot);
--+			if (!enabled)
--+				ath9k_cache_beacon_config(sc, ctx, bss_conf);
-- 		}
-- 	}
-- 
----- a/drivers/net/wireless/ath/ath9k/common.h
--+++ b/drivers/net/wireless/ath/ath9k/common.h
--@@ -54,7 +54,7 @@ struct ath_beacon_config {
-- 	u16 dtim_period;
-- 	u16 bmiss_timeout;
-- 	u8 dtim_count;
---	bool enable_beacon;
--+	u8 enable_beacon;
-- 	bool ibss_creator;
-- 	u32 nexttbtt;
-- 	u32 intval;
-diff --git a/package/kernel/mac80211/patches/307-mac80211-Deinline-drv_sta_state.patch b/package/kernel/mac80211/patches/307-mac80211-Deinline-drv_sta_state.patch
-new file mode 100644
-index 0000000..474c409
---- /dev/null
-+++ b/package/kernel/mac80211/patches/307-mac80211-Deinline-drv_sta_state.patch
-@@ -0,0 +1,116 @@
-+From: Denys Vlasenko <dvlasenk@redhat.com>
-+Date: Wed, 15 Jul 2015 14:56:05 +0200
-+Subject: [PATCH] mac80211: Deinline drv_sta_state
-+
-+With this .config: http://busybox.net/~vda/kernel_config,
-+after deinlining the function size is 3132 bytes and there are
-+7 callsites.
-+
-+Total size reduction: about 20 kbytes.
-+
-+Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
-+CC: John Linville <linville@tuxdriver.com>
-+CC: Michal Kazior <michal.kazior@tieto.com>
-+Cc: Johannes Berg <johannes.berg@intel.com>
-+Cc: linux-wireless@vger.kernel.org
-+Cc: netdev@vger.kernel.org
-+CC: linux-kernel@vger.kernel.org
-+---
-+ create mode 100644 net/mac80211/driver-ops.c
-+
-+--- a/net/mac80211/Makefile
-++++ b/net/mac80211/Makefile
-+@@ -3,6 +3,7 @@ obj-$(CPTCFG_MAC80211) += mac80211.o
-+ # mac80211 objects
-+ mac80211-y := \
-+ 	main.o status.o \
-++	driver-ops.o \
-+ 	sta_info.o \
-+ 	wep.o \
-+ 	wpa.o \
-+--- /dev/null
-++++ b/net/mac80211/driver-ops.c
-+@@ -0,0 +1,41 @@
-++/*
-++ * 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.
-++ */
-++#include <net/mac80211.h>
-++#include "ieee80211_i.h"
-++#include "trace.h"
-++#include "driver-ops.h"
-++
-++__must_check
-++int drv_sta_state(struct ieee80211_local *local,
-++		  struct ieee80211_sub_if_data *sdata,
-++		  struct sta_info *sta,
-++		  enum ieee80211_sta_state old_state,
-++		  enum ieee80211_sta_state new_state)
-++{
-++	int ret = 0;
-++
-++	might_sleep();
-++
-++	sdata = get_bss_sdata(sdata);
-++	if (!check_sdata_in_driver(sdata))
-++		return -EIO;
-++
-++	trace_drv_sta_state(local, sdata, &sta->sta, old_state, new_state);
-++	if (local->ops->sta_state) {
-++		ret = local->ops->sta_state(&local->hw, &sdata->vif, &sta->sta,
-++					    old_state, new_state);
-++	} else if (old_state == IEEE80211_STA_AUTH &&
-++		   new_state == IEEE80211_STA_ASSOC) {
-++		ret = drv_sta_add(local, sdata, &sta->sta);
-++		if (ret == 0)
-++			sta->uploaded = true;
-++	} else if (old_state == IEEE80211_STA_ASSOC &&
-++		   new_state == IEEE80211_STA_AUTH) {
-++		drv_sta_remove(local, sdata, &sta->sta);
-++	}
-++	trace_drv_return_int(local, ret);
-++	return ret;
-++}
-+--- a/net/mac80211/driver-ops.h
-++++ b/net/mac80211/driver-ops.h
-+@@ -573,37 +573,12 @@ static inline void drv_sta_pre_rcu_remov
-+ 	trace_drv_return_void(local);
-+ }
-+ 
-+-static inline __must_check
-++__must_check
-+ int drv_sta_state(struct ieee80211_local *local,
-+ 		  struct ieee80211_sub_if_data *sdata,
-+ 		  struct sta_info *sta,
-+ 		  enum ieee80211_sta_state old_state,
-+-		  enum ieee80211_sta_state new_state)
-+-{
-+-	int ret = 0;
-+-
-+-	might_sleep();
-+-
-+-	sdata = get_bss_sdata(sdata);
-+-	if (!check_sdata_in_driver(sdata))
-+-		return -EIO;
-+-
-+-	trace_drv_sta_state(local, sdata, &sta->sta, old_state, new_state);
-+-	if (local->ops->sta_state) {
-+-		ret = local->ops->sta_state(&local->hw, &sdata->vif, &sta->sta,
-+-					    old_state, new_state);
-+-	} else if (old_state == IEEE80211_STA_AUTH &&
-+-		   new_state == IEEE80211_STA_ASSOC) {
-+-		ret = drv_sta_add(local, sdata, &sta->sta);
-+-		if (ret == 0)
-+-			sta->uploaded = true;
-+-	} else if (old_state == IEEE80211_STA_ASSOC &&
-+-		   new_state == IEEE80211_STA_AUTH) {
-+-		drv_sta_remove(local, sdata, &sta->sta);
-+-	}
-+-	trace_drv_return_int(local, ret);
-+-	return ret;
-+-}
-++		  enum ieee80211_sta_state new_state);
-+ 
-+ static inline void drv_sta_rc_update(struct ieee80211_local *local,
-+ 				     struct ieee80211_sub_if_data *sdata,
-diff --git a/package/kernel/mac80211/patches/308-ath9k-Fix-NF-CCA-limits-for-AR9287-and-AR9227.patch b/package/kernel/mac80211/patches/308-ath9k-Fix-NF-CCA-limits-for-AR9287-and-AR9227.patch
-new file mode 100644
-index 0000000..1a3a9d4
---- /dev/null
-+++ b/package/kernel/mac80211/patches/308-ath9k-Fix-NF-CCA-limits-for-AR9287-and-AR9227.patch
-@@ -0,0 +1,30 @@
-+From: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
-+Date: Wed, 22 Jul 2015 10:42:43 +0200
-+Subject: [PATCH] ath9k: Fix NF CCA limits for AR9287 and AR9227
-+
-+The FreeBSD driver [0] uses the same 2G values as for the AR9280 chips.
-+Using the same values in ath9k results in much better throughput for me.
-+
-+Before this patch I had a huge amount of packet loss (sometimes up to
-+40%) and the max transfer speed was somewhere around 5Mbit/s. With this
-+patch applied I have zero packet loss and ten times the throughput.
-+My device uses a AR9227 which is the PCI variant of the AR9287.
-+
-+[0] http://bxr.su/FreeBSD/sys/dev/ath/ath_hal/ar9002/ar9287.h
-+
-+Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
-+---
-+
-+--- a/drivers/net/wireless/ath/ath9k/ar9002_phy.h
-++++ b/drivers/net/wireless/ath/ath9k/ar9002_phy.h
-+@@ -610,8 +610,8 @@
-+ #define AR_PHY_CCA_MIN_GOOD_VAL_9271_2GHZ      -127
-+ #define AR_PHY_CCA_MAX_GOOD_VAL_9271_2GHZ      -116
-+ 
-+-#define AR_PHY_CCA_NOM_VAL_9287_2GHZ           -120
-++#define AR_PHY_CCA_NOM_VAL_9287_2GHZ           -112
-+ #define AR_PHY_CCA_MIN_GOOD_VAL_9287_2GHZ    -127
-+-#define AR_PHY_CCA_MAX_GOOD_VAL_9287_2GHZ    -110
-++#define AR_PHY_CCA_MAX_GOOD_VAL_9287_2GHZ    -97
-+ 
-+ #endif
-diff --git a/package/kernel/mac80211/patches/308-mac80211-minstrel_ht-fix-rounding-issue-in-MCS-durat.patch b/package/kernel/mac80211/patches/308-mac80211-minstrel_ht-fix-rounding-issue-in-MCS-durat.patch
-deleted file mode 100644
-index d132636..0000000
---- a/package/kernel/mac80211/patches/308-mac80211-minstrel_ht-fix-rounding-issue-in-MCS-durat.patch
-+++ /dev/null
-@@ -1,43 +0,0 @@
--From: Felix Fietkau <nbd@openwrt.org>
--Date: Fri, 13 Mar 2015 10:49:40 +0100
--Subject: [PATCH] mac80211: minstrel_ht: fix rounding issue in MCS duration
-- calculation
--
--On very high MCS bitrates, the calculated duration of rates that are
--next to each other can be very imprecise, due to the small packet size
--used as reference (1200 bytes).
--This is most visible in VHT80 nss=2 MCS8/9, for which minstrel shows the
--same throughput when the probability is also the same. This leads to a
--bad rate selection for such rates.
--
--Fix this issue by introducing an average A-MPDU size factor into the
--calculation.
--
--Signed-off-by: Felix Fietkau <nbd@openwrt.org>
-----
--
----- a/net/mac80211/rc80211_minstrel_ht.c
--+++ b/net/mac80211/rc80211_minstrel_ht.c
--@@ -17,10 +17,11 @@
-- #include "rc80211_minstrel.h"
-- #include "rc80211_minstrel_ht.h"
-- 
--+#define AVG_AMPDU_SIZE	16
-- #define AVG_PKT_SIZE	1200
-- 
-- /* Number of bits for an average sized packet */
---#define MCS_NBITS (AVG_PKT_SIZE << 3)
--+#define MCS_NBITS ((AVG_PKT_SIZE * AVG_AMPDU_SIZE) << 3)
-- 
-- /* Number of symbols for a packet with (bps) bits per symbol */
-- #define MCS_NSYMS(bps) DIV_ROUND_UP(MCS_NBITS, (bps))
--@@ -33,7 +34,8 @@
-- 	)
-- 
-- /* Transmit duration for the raw data part of an average sized packet */
---#define MCS_DURATION(streams, sgi, bps) MCS_SYMBOL_TIME(sgi, MCS_NSYMS((streams) * (bps)))
--+#define MCS_DURATION(streams, sgi, bps) \
--+	(MCS_SYMBOL_TIME(sgi, MCS_NSYMS((streams) * (bps))) / AVG_AMPDU_SIZE)
-- 
-- #define BW_20			0
-- #define BW_40			1
-diff --git a/package/kernel/mac80211/patches/309-ath9k-disable-TPC-support-again-for-now.patch b/package/kernel/mac80211/patches/309-ath9k-disable-TPC-support-again-for-now.patch
-deleted file mode 100644
-index 945fbce..0000000
---- a/package/kernel/mac80211/patches/309-ath9k-disable-TPC-support-again-for-now.patch
-+++ /dev/null
-@@ -1,22 +0,0 @@
--From: Felix Fietkau <nbd@openwrt.org>
--Date: Sun, 15 Mar 2015 08:02:37 +0100
--Subject: [PATCH] ath9k: disable TPC support again (for now)
--
--TPC support has been observed to cause some tx power fluctuations on
--some devices with at least AR934x and AR938x chips.
--Disable it for now until the bugs have been found and fixed
--
--Signed-off-by: Felix Fietkau <nbd@openwrt.org>
-----
--
----- a/drivers/net/wireless/ath/ath9k/hw.c
--+++ b/drivers/net/wireless/ath/ath9k/hw.c
--@@ -424,7 +424,7 @@ static void ath9k_hw_init_defaults(struc
-- 	ah->power_mode = ATH9K_PM_UNDEFINED;
-- 	ah->htc_reset_init = true;
-- 
---	ah->tpc_enabled = true;
--+	ah->tpc_enabled = false;
-- 
-- 	ah->ani_function = ATH9K_ANI_ALL;
-- 	if (!AR_SREV_9300_20_OR_LATER(ah))
-diff --git a/package/kernel/mac80211/patches/309-mac80211-make-local-tx_headroom-a-multiple-of-4.patch b/package/kernel/mac80211/patches/309-mac80211-make-local-tx_headroom-a-multiple-of-4.patch
-new file mode 100644
-index 0000000..e8e9617
---- /dev/null
-+++ b/package/kernel/mac80211/patches/309-mac80211-make-local-tx_headroom-a-multiple-of-4.patch
-@@ -0,0 +1,20 @@
-+From: Felix Fietkau <nbd@openwrt.org>
-+Date: Thu, 30 Jul 2015 14:12:25 +0200
-+Subject: [PATCH] mac80211: make local->tx_headroom a multiple of 4
-+
-+This ensures that mac80211 generated management frames and beacons are
-+aligned before being passed to the driver
-+
-+Signed-off-by: Felix Fietkau <nbd@openwrt.org>
-+---
-+
-+--- a/net/mac80211/main.c
-++++ b/net/mac80211/main.c
-+@@ -1031,6 +1031,7 @@ int ieee80211_register_hw(struct ieee802
-+ 	 */
-+ 	local->tx_headroom = max_t(unsigned int , local->hw.extra_tx_headroom,
-+ 				   IEEE80211_TX_STATUS_HEADROOM);
-++	local->tx_headroom = ALIGN(local->tx_headroom, 4);
-+ 
-+ 	debugfs_hw_add(local);
-+ 
-diff --git a/package/kernel/mac80211/patches/310-mac80211-don-t-look-up-stations-for-multicast-addres.patch b/package/kernel/mac80211/patches/310-mac80211-don-t-look-up-stations-for-multicast-addres.patch
-deleted file mode 100644
-index bd3050e..0000000
---- a/package/kernel/mac80211/patches/310-mac80211-don-t-look-up-stations-for-multicast-addres.patch
-+++ /dev/null
-@@ -1,21 +0,0 @@
--From: Johannes Berg <johannes.berg@intel.com>
--Date: Tue, 24 Feb 2015 00:28:18 +0100
--Subject: [PATCH] mac80211: don't look up stations for multicast addresses
--
--Since multicast addresses don't exist as stations, don't attempt
--to look them up in the hashtable on TX.
--
--Signed-off-by: Johannes Berg <johannes.berg@intel.com>
-----
--
----- a/net/mac80211/tx.c
--+++ b/net/mac80211/tx.c
--@@ -1161,7 +1161,7 @@ ieee80211_tx_prepare(struct ieee80211_su
-- 		   tx->sdata->control_port_protocol == tx->skb->protocol) {
-- 		tx->sta = sta_info_get_bss(sdata, hdr->addr1);
-- 	}
---	if (!tx->sta)
--+	if (!tx->sta && !is_multicast_ether_addr(hdr->addr1))
-- 		tx->sta = sta_info_get(sdata, hdr->addr1);
-- 
-- 	if (tx->sta && ieee80211_is_data_qos(hdr->frame_control) &&
-diff --git a/package/kernel/mac80211/patches/310-mac80211-fix-invalid-read-in-minstrel_sort_best_tp_r.patch b/package/kernel/mac80211/patches/310-mac80211-fix-invalid-read-in-minstrel_sort_best_tp_r.patch
-new file mode 100644
-index 0000000..51a315c
---- /dev/null
-+++ b/package/kernel/mac80211/patches/310-mac80211-fix-invalid-read-in-minstrel_sort_best_tp_r.patch
-@@ -0,0 +1,34 @@
-+From: Adrien Schildknecht <adrien+dev@schischi.me>
-+Date: Tue, 28 Jul 2015 10:30:16 +0200
-+Subject: [PATCH] mac80211: fix invalid read in minstrel_sort_best_tp_rates()
-+
-+At the last iteration of the loop, j may equal zero and thus
-+tp_list[j - 1] causes an invalid read.
-+Changed the logic of the loop so that j - 1 is always >= 0.
-+
-+Signed-off-by: Adrien Schildknecht <adrien+dev@schischi.me>
-+---
-+
-+--- a/net/mac80211/rc80211_minstrel.c
-++++ b/net/mac80211/rc80211_minstrel.c
-+@@ -92,14 +92,15 @@ int minstrel_get_tp_avg(struct minstrel_
-+ static inline void
-+ minstrel_sort_best_tp_rates(struct minstrel_sta_info *mi, int i, u8 *tp_list)
-+ {
-+-	int j = MAX_THR_RATES;
-+-	struct minstrel_rate_stats *tmp_mrs = &mi->r[j - 1].stats;
-++	int j;
-++	struct minstrel_rate_stats *tmp_mrs;
-+ 	struct minstrel_rate_stats *cur_mrs = &mi->r[i].stats;
-+ 
-+-	while (j > 0 && (minstrel_get_tp_avg(&mi->r[i], cur_mrs->prob_ewma) >
-+-	       minstrel_get_tp_avg(&mi->r[tp_list[j - 1]], tmp_mrs->prob_ewma))) {
-+-		j--;
-++	for (j = MAX_THR_RATES; j > 0; --j) {
-+ 		tmp_mrs = &mi->r[tp_list[j - 1]].stats;
-++		if (minstrel_get_tp_avg(&mi->r[i], cur_mrs->prob_ewma) <=
-++		    minstrel_get_tp_avg(&mi->r[tp_list[j - 1]], tmp_mrs->prob_ewma))
-++			break;
-+ 	}
-+ 
-+ 	if (j < MAX_THR_RATES - 1)
-diff --git a/package/kernel/mac80211/patches/311-brcmfmac-dhd_sdio.c-use-existing-atomic_or-primitive.patch b/package/kernel/mac80211/patches/311-brcmfmac-dhd_sdio.c-use-existing-atomic_or-primitive.patch
-new file mode 100644
-index 0000000..e44f121
---- /dev/null
-+++ b/package/kernel/mac80211/patches/311-brcmfmac-dhd_sdio.c-use-existing-atomic_or-primitive.patch
-@@ -0,0 +1,45 @@
-+From: Vineet Gupta <Vineet.Gupta1@synopsys.com>
-+Date: Thu, 9 Jul 2015 13:43:18 +0530
-+Subject: [PATCH] brcmfmac: dhd_sdio.c: use existing atomic_or primitive
-+
-+There's already a generic implementation so use that instead.
-+
-+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
-+---
-+
-+--- a/drivers/net/wireless/brcm80211/brcmfmac/sdio.c
-++++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio.c
-+@@ -2564,15 +2564,6 @@ static inline void brcmf_sdio_clrintr(st
-+ 	}
-+ }
-+ 
-+-static void atomic_orr(int val, atomic_t *v)
-+-{
-+-	int old_val;
-+-
-+-	old_val = atomic_read(v);
-+-	while (atomic_cmpxchg(v, old_val, val | old_val) != old_val)
-+-		old_val = atomic_read(v);
-+-}
-+-
-+ static int brcmf_sdio_intr_rstatus(struct brcmf_sdio *bus)
-+ {
-+ 	struct brcmf_core *buscore;
-+@@ -2595,7 +2586,7 @@ static int brcmf_sdio_intr_rstatus(struc
-+ 	if (val) {
-+ 		brcmf_sdiod_regwl(bus->sdiodev, addr, val, &ret);
-+ 		bus->sdcnt.f1regdata++;
-+-		atomic_orr(val, &bus->intstatus);
-++		atomic_or(val, &bus->intstatus);
-+ 	}
-+ 
-+ 	return ret;
-+@@ -2712,7 +2703,7 @@ static void brcmf_sdio_dpc(struct brcmf_
-+ 
-+ 	/* Keep still-pending events for next scheduling */
-+ 	if (intstatus)
-+-		atomic_orr(intstatus, &bus->intstatus);
-++		atomic_or(intstatus, &bus->intstatus);
-+ 
-+ 	brcmf_sdio_clrintr(bus);
-+ 
-diff --git a/package/kernel/mac80211/patches/311-mac80211-remove-drop_unencrypted-code.patch b/package/kernel/mac80211/patches/311-mac80211-remove-drop_unencrypted-code.patch
-deleted file mode 100644
-index b2475b9..0000000
---- a/package/kernel/mac80211/patches/311-mac80211-remove-drop_unencrypted-code.patch
-+++ /dev/null
-@@ -1,130 +0,0 @@
--From: Johannes Berg <johannes.berg@intel.com>
--Date: Fri, 20 Mar 2015 11:41:58 +0100
--Subject: [PATCH] mac80211: remove drop_unencrypted code
--
--This mechanism was historic, and only ever used by IBSS, which
--also doesn't need to have it as it properly manages station's
--802.1X PAE state (or, with WEP, always has a key.)
--
--Remove the mechanism to clean up the code.
--
--Signed-off-by: Johannes Berg <johannes.berg@intel.com>
-----
--
----- a/net/mac80211/debugfs.c
--+++ b/net/mac80211/debugfs.c
--@@ -274,8 +274,6 @@ void debugfs_hw_add(struct ieee80211_loc
-- #ifdef CPTCFG_MAC80211_DEBUG_COUNTERS
-- 	DEBUGFS_STATS_ADD(tx_handlers_drop, local->tx_handlers_drop);
-- 	DEBUGFS_STATS_ADD(tx_handlers_queued, local->tx_handlers_queued);
---	DEBUGFS_STATS_ADD(tx_handlers_drop_unencrypted,
---		local->tx_handlers_drop_unencrypted);
-- 	DEBUGFS_STATS_ADD(tx_handlers_drop_fragment,
-- 		local->tx_handlers_drop_fragment);
-- 	DEBUGFS_STATS_ADD(tx_handlers_drop_wep,
----- a/net/mac80211/debugfs_netdev.c
--+++ b/net/mac80211/debugfs_netdev.c
--@@ -177,7 +177,6 @@ static ssize_t ieee80211_if_write_##name
-- 	IEEE80211_IF_FILE_R(name)
-- 
-- /* common attributes */
---IEEE80211_IF_FILE(drop_unencrypted, drop_unencrypted, DEC);
-- IEEE80211_IF_FILE(rc_rateidx_mask_2ghz, rc_rateidx_mask[IEEE80211_BAND_2GHZ],
-- 		  HEX);
-- IEEE80211_IF_FILE(rc_rateidx_mask_5ghz, rc_rateidx_mask[IEEE80211_BAND_5GHZ],
--@@ -562,7 +561,6 @@ IEEE80211_IF_FILE(dot11MeshAwakeWindowDu
-- 
-- static void add_common_files(struct ieee80211_sub_if_data *sdata)
-- {
---	DEBUGFS_ADD(drop_unencrypted);
-- 	DEBUGFS_ADD(rc_rateidx_mask_2ghz);
-- 	DEBUGFS_ADD(rc_rateidx_mask_5ghz);
-- 	DEBUGFS_ADD(rc_rateidx_mcs_mask_2ghz);
----- a/net/mac80211/ibss.c
--+++ b/net/mac80211/ibss.c
--@@ -249,8 +249,6 @@ static void __ieee80211_sta_join_ibss(st
-- 	if (presp)
-- 		kfree_rcu(presp, rcu_head);
-- 
---	sdata->drop_unencrypted = capability & WLAN_CAPABILITY_PRIVACY ? 1 : 0;
---
-- 	/* make a copy of the chandef, it could be modified below. */
-- 	chandef = *req_chandef;
-- 	chan = chandef.chan;
--@@ -1289,8 +1287,6 @@ static void ieee80211_sta_create_ibss(st
-- 
-- 	if (ifibss->privacy)
-- 		capability |= WLAN_CAPABILITY_PRIVACY;
---	else
---		sdata->drop_unencrypted = 0;
-- 
-- 	__ieee80211_sta_join_ibss(sdata, bssid, sdata->vif.bss_conf.beacon_int,
-- 				  &ifibss->chandef, ifibss->basic_rates,
----- a/net/mac80211/ieee80211_i.h
--+++ b/net/mac80211/ieee80211_i.h
--@@ -842,8 +842,6 @@ struct ieee80211_sub_if_data {
-- 
-- 	unsigned long state;
-- 
---	int drop_unencrypted;
---
-- 	char name[IFNAMSIZ];
-- 
-- 	/* Fragment table for host-based reassembly */
--@@ -1289,7 +1287,6 @@ struct ieee80211_local {
-- 	/* TX/RX handler statistics */
-- 	unsigned int tx_handlers_drop;
-- 	unsigned int tx_handlers_queued;
---	unsigned int tx_handlers_drop_unencrypted;
-- 	unsigned int tx_handlers_drop_fragment;
-- 	unsigned int tx_handlers_drop_wep;
-- 	unsigned int tx_handlers_drop_not_assoc;
----- a/net/mac80211/iface.c
--+++ b/net/mac80211/iface.c
--@@ -1535,7 +1535,6 @@ int ieee80211_if_change_type(struct ieee
-- 	}
-- 
-- 	/* reset some values that shouldn't be kept across type changes */
---	sdata->drop_unencrypted = 0;
-- 	if (type == NL80211_IFTYPE_STATION)
-- 		sdata->u.mgd.use_4addr = false;
-- 
----- a/net/mac80211/rx.c
--+++ b/net/mac80211/rx.c
--@@ -1897,8 +1897,7 @@ static int ieee80211_drop_unencrypted(st
-- 	/* Drop unencrypted frames if key is set. */
-- 	if (unlikely(!ieee80211_has_protected(fc) &&
-- 		     !ieee80211_is_nullfunc(fc) &&
---		     ieee80211_is_data(fc) &&
---		     (rx->key || rx->sdata->drop_unencrypted)))
--+		     ieee80211_is_data(fc) && rx->key))
-- 		return -EACCES;
-- 
-- 	return 0;
----- a/net/mac80211/tx.c
--+++ b/net/mac80211/tx.c
--@@ -594,23 +594,8 @@ ieee80211_tx_h_select_key(struct ieee802
-- 	else if (!is_multicast_ether_addr(hdr->addr1) &&
-- 		 (key = rcu_dereference(tx->sdata->default_unicast_key)))
-- 		tx->key = key;
---	else if (info->flags & IEEE80211_TX_CTL_INJECTED)
--+	else
-- 		tx->key = NULL;
---	else if (!tx->sdata->drop_unencrypted)
---		tx->key = NULL;
---	else if (tx->skb->protocol == tx->sdata->control_port_protocol)
---		tx->key = NULL;
---	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(tx->skb))
---		tx->key = NULL;
---	else {
---		I802_DEBUG_INC(tx->local->tx_handlers_drop_unencrypted);
---		return TX_DROP;
---	}
-- 
-- 	if (tx->key) {
-- 		bool skip_hw = false;
-diff --git a/package/kernel/mac80211/patches/312-brcmfmac-check-all-combinations-when-setting-wiphy-s.patch b/package/kernel/mac80211/patches/312-brcmfmac-check-all-combinations-when-setting-wiphy-s.patch
-new file mode 100644
-index 0000000..bb27115
---- /dev/null
-+++ b/package/kernel/mac80211/patches/312-brcmfmac-check-all-combinations-when-setting-wiphy-s.patch
-@@ -0,0 +1,46 @@
-+From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <zajec5@gmail.com>
-+Date: Thu, 20 Aug 2015 00:16:42 +0200
-+Subject: [PATCH] brcmfmac: check all combinations when setting wiphy's
-+ addresses
-+MIME-Version: 1.0
-+Content-Type: text/plain; charset=UTF-8
-+Content-Transfer-Encoding: 8bit
-+
-+Broadcom is working on better reflection of interface combinations. With
-+upcoming patches we may have 1st combination supporting less interfaces
-+than others.
-+To don't run out of addresses check all combinations to find the one
-+with the greatest max_interfaces value.
-+
-+Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
-+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
-+---
-+
-+--- a/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c
-++++ b/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c
-+@@ -5786,7 +5786,9 @@ static void brcmf_wiphy_wowl_params(stru
-+ static int brcmf_setup_wiphy(struct wiphy *wiphy, struct brcmf_if *ifp)
-+ {
-+ 	struct brcmf_pub *drvr = ifp->drvr;
-++	const struct ieee80211_iface_combination *combo;
-+ 	struct ieee80211_supported_band *band;
-++	u16 max_interfaces = 0;
-+ 	__le32 bandlist[3];
-+ 	u32 n_bands;
-+ 	int err, i;
-+@@ -5799,8 +5801,13 @@ static int brcmf_setup_wiphy(struct wiph
-+ 	if (err)
-+ 		return err;
-+ 
-+-	for (i = 0; i < wiphy->iface_combinations->max_interfaces &&
-+-	     i < ARRAY_SIZE(drvr->addresses); i++) {
-++	for (i = 0, combo = wiphy->iface_combinations;
-++	     i < wiphy->n_iface_combinations; i++, combo++) {
-++		max_interfaces = max(max_interfaces, combo->max_interfaces);
-++	}
-++
-++	for (i = 0; i < max_interfaces && i < ARRAY_SIZE(drvr->addresses);
-++	     i++) {
-+ 		u8 *addr = drvr->addresses[i].addr;
-+ 
-+ 		memcpy(addr, drvr->mac, ETH_ALEN);
-diff --git a/package/kernel/mac80211/patches/312-mac80211-don-t-look-up-destination-station-twice.patch b/package/kernel/mac80211/patches/312-mac80211-don-t-look-up-destination-station-twice.patch
-deleted file mode 100644
-index 02a7fab..0000000
---- a/package/kernel/mac80211/patches/312-mac80211-don-t-look-up-destination-station-twice.patch
-+++ /dev/null
-@@ -1,71 +0,0 @@
--From: Johannes Berg <johannes.berg@intel.com>
--Date: Fri, 20 Mar 2015 16:24:21 +0100
--Subject: [PATCH] mac80211: don't look up destination station twice
--
--There's no need to look up the destination station twice while
--building the 802.11 header for a given frame if the frame will
--actually be transmitted to the station we initially looked up.
--
--This happens for 4-addr VLAN interfaces and TDLS connections, which
--both directly send the frame to the station they looked up, though
--in the case of TDLS some station conditions need to be checked.
--
--To avoid that, add a variable indicating that we've looked up the
--station that the frame is going to be transmitted to, and avoid the
--lookup/flag checking if it already has been done.
--
--In the TDLS case, also move the authorized/wme_sta flag assignment
--to the correct place, i.e. only when that station is really used.
--Before this change, the new lookup should always have succeeded so
--that the potentially erroneous data would be overwritten.
--
--Signed-off-by: Johannes Berg <johannes.berg@intel.com>
-----
--
----- a/net/mac80211/tx.c
--+++ b/net/mac80211/tx.c
--@@ -1894,6 +1894,7 @@ static struct sk_buff *ieee80211_build_h
-- 	bool wme_sta = false, authorized = false, tdls_auth = false;
-- 	bool tdls_peer = false, tdls_setup_frame = false;
-- 	bool multicast;
--+	bool have_station = false;
-- 	u16 info_id = 0;
-- 	struct ieee80211_chanctx_conf *chanctx_conf;
-- 	struct ieee80211_sub_if_data *ap_sdata;
--@@ -1918,6 +1919,7 @@ static struct sk_buff *ieee80211_build_h
-- 			hdrlen = 30;
-- 			authorized = test_sta_flag(sta, WLAN_STA_AUTHORIZED);
-- 			wme_sta = sta->sta.wme;
--+			have_station = true;
-- 		}
-- 		ap_sdata = container_of(sdata->bss, struct ieee80211_sub_if_data,
-- 					u.ap);
--@@ -2034,9 +2036,6 @@ static struct sk_buff *ieee80211_build_h
-- 		if (sdata->wdev.wiphy->flags & WIPHY_FLAG_SUPPORTS_TDLS) {
-- 			sta = sta_info_get(sdata, skb->data);
-- 			if (sta) {
---				authorized = test_sta_flag(sta,
---							WLAN_STA_AUTHORIZED);
---				wme_sta = sta->sta.wme;
-- 				tdls_peer = test_sta_flag(sta,
-- 							  WLAN_STA_TDLS_PEER);
-- 				tdls_auth = test_sta_flag(sta,
--@@ -2068,6 +2067,9 @@ static struct sk_buff *ieee80211_build_h
-- 			memcpy(hdr.addr2, skb->data + ETH_ALEN, ETH_ALEN);
-- 			memcpy(hdr.addr3, sdata->u.mgd.bssid, ETH_ALEN);
-- 			hdrlen = 24;
--+			have_station = true;
--+			authorized = test_sta_flag(sta, WLAN_STA_AUTHORIZED);
--+			wme_sta = sta->sta.wme;
-- 		}  else if (sdata->u.mgd.use_4addr &&
-- 			    cpu_to_be16(ethertype) != sdata->control_port_protocol) {
-- 			fc |= cpu_to_le16(IEEE80211_FCTL_FROMDS |
--@@ -2130,7 +2132,7 @@ static struct sk_buff *ieee80211_build_h
-- 	 * in AP mode)
-- 	 */
-- 	multicast = is_multicast_ether_addr(hdr.addr1);
---	if (!multicast) {
--+	if (!multicast && !have_station) {
-- 		sta = sta_info_get(sdata, hdr.addr1);
-- 		if (sta) {
-- 			authorized = test_sta_flag(sta, WLAN_STA_AUTHORIZED);
-diff --git a/package/kernel/mac80211/patches/313-brcmfmac-correct-interface-combination-info.patch b/package/kernel/mac80211/patches/313-brcmfmac-correct-interface-combination-info.patch
-new file mode 100644
-index 0000000..baee295
---- /dev/null
-+++ b/package/kernel/mac80211/patches/313-brcmfmac-correct-interface-combination-info.patch
-@@ -0,0 +1,204 @@
-+From: Arend van Spriel <arend@broadcom.com>
-+Date: Thu, 20 Aug 2015 22:06:03 +0200
-+Subject: [PATCH] brcmfmac: correct interface combination info
-+
-+The interface combination provided by brcmfmac did not truly reflect
-+the combinations supported by driver and/or firmware.
-+
-+Reviewed-by: Hante Meuleman <meuleman@broadcom.com>
-+Reviewed-by: Franky (Zhenhui) Lin <frankyl@broadcom.com>
-+Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
-+Reviewed-by: Pontus Fuchs <pontusf@broadcom.com>
-+Signed-off-by: Arend van Spriel <arend@broadcom.com>
-+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
-+---
-+
-+--- a/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c
-++++ b/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c
-+@@ -5695,63 +5695,132 @@ brcmf_txrx_stypes[NUM_NL80211_IFTYPES] =
-+ 	}
-+ };
-+ 
-++/**
-++ * brcmf_setup_ifmodes() - determine interface modes and combinations.
-++ *
-++ * @wiphy: wiphy object.
-++ * @ifp: interface object needed for feat module api.
-++ *
-++ * The interface modes and combinations are determined dynamically here
-++ * based on firmware functionality.
-++ *
-++ * no p2p and no mbss:
-++ *
-++ *	#STA <= 1, #AP <= 1, channels = 1, 2 total
-++ *
-++ * no p2p and mbss:
-++ *
-++ *	#STA <= 1, #AP <= 1, channels = 1, 2 total
-++ *	#AP <= 4, matching BI, channels = 1, 4 total
-++ *
-++ * p2p, no mchan, and mbss:
-++ *
-++ *	#STA <= 1, #P2P-DEV <= 1, #{P2P-CL, P2P-GO} <= 1, channels = 1, 3 total
-++ *	#STA <= 1, #P2P-DEV <= 1, #AP <= 1, #P2P-CL <= 1, channels = 1, 4 total
-++ *	#AP <= 4, matching BI, channels = 1, 4 total
-++ *
-++ * p2p, mchan, and mbss:
-++ *
-++ *	#STA <= 1, #P2P-DEV <= 1, #{P2P-CL, P2P-GO} <= 1, channels = 2, 3 total
-++ *	#STA <= 1, #P2P-DEV <= 1, #AP <= 1, #P2P-CL <= 1, channels = 1, 4 total
-++ *	#AP <= 4, matching BI, channels = 1, 4 total
-++ */
-+ static int brcmf_setup_ifmodes(struct wiphy *wiphy, struct brcmf_if *ifp)
-+ {
-+ 	struct ieee80211_iface_combination *combo = NULL;
-+-	struct ieee80211_iface_limit *limits = NULL;
-+-	int i = 0, max_iface_cnt;
-++	struct ieee80211_iface_limit *c0_limits = NULL;
-++	struct ieee80211_iface_limit *p2p_limits = NULL;
-++	struct ieee80211_iface_limit *mbss_limits = NULL;
-++	bool mbss, p2p;
-++	int i, c, n_combos;
-+ 
-+-	combo = kzalloc(sizeof(*combo), GFP_KERNEL);
-++	mbss = brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MBSS);
-++	p2p = brcmf_feat_is_enabled(ifp, BRCMF_FEAT_P2P);
-++
-++	n_combos = 1 + !!p2p + !!mbss;
-++	combo = kcalloc(n_combos, sizeof(*combo), GFP_KERNEL);
-+ 	if (!combo)
-+ 		goto err;
-+ 
-+-	limits = kzalloc(sizeof(*limits) * 4, GFP_KERNEL);
-+-	if (!limits)
-++	c0_limits = kcalloc(p2p ? 3 : 2, sizeof(*c0_limits), GFP_KERNEL);
-++	if (!c0_limits)
-+ 		goto err;
-+ 
-++	if (p2p) {
-++		p2p_limits = kcalloc(4, sizeof(*p2p_limits), GFP_KERNEL);
-++		if (!p2p_limits)
-++			goto err;
-++	}
-++
-++	if (mbss) {
-++		mbss_limits = kcalloc(1, sizeof(*mbss_limits), GFP_KERNEL);
-++		if (!mbss_limits)
-++			goto err;
-++	}
-++
-+ 	wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
-+ 				 BIT(NL80211_IFTYPE_ADHOC) |
-+ 				 BIT(NL80211_IFTYPE_AP);
-+ 
-+-	if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MCHAN))
-+-		combo->num_different_channels = 2;
-+-	else
-+-		combo->num_different_channels = 1;
-+-
-+-	if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MBSS)) {
-+-		limits[i].max = 1;
-+-		limits[i++].types = BIT(NL80211_IFTYPE_STATION);
-+-		limits[i].max = 4;
-+-		limits[i++].types = BIT(NL80211_IFTYPE_AP);
-+-		max_iface_cnt = 5;
-+-	} else {
-+-		limits[i].max = 2;
-+-		limits[i++].types = BIT(NL80211_IFTYPE_STATION) |
-+-				    BIT(NL80211_IFTYPE_AP);
-+-		max_iface_cnt = 2;
-+-	}
-+-
-+-	if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_P2P)) {
-++	c = 0;
-++	i = 0;
-++	combo[c].num_different_channels = 1;
-++	c0_limits[i].max = 1;
-++	c0_limits[i++].types = BIT(NL80211_IFTYPE_STATION);
-++	if (p2p) {
-++		if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MCHAN))
-++			combo[c].num_different_channels = 2;
-+ 		wiphy->interface_modes |= BIT(NL80211_IFTYPE_P2P_CLIENT) |
-+ 					  BIT(NL80211_IFTYPE_P2P_GO) |
-+ 					  BIT(NL80211_IFTYPE_P2P_DEVICE);
-+-		limits[i].max = 1;
-+-		limits[i++].types = BIT(NL80211_IFTYPE_P2P_CLIENT) |
-+-				    BIT(NL80211_IFTYPE_P2P_GO);
-+-		limits[i].max = 1;
-+-		limits[i++].types = BIT(NL80211_IFTYPE_P2P_DEVICE);
-+-		max_iface_cnt += 2;
-+-	}
-+-	combo->max_interfaces = max_iface_cnt;
-+-	combo->limits = limits;
-+-	combo->n_limits = i;
-++		c0_limits[i].max = 1;
-++		c0_limits[i++].types = BIT(NL80211_IFTYPE_P2P_DEVICE);
-++		c0_limits[i].max = 1;
-++		c0_limits[i++].types = BIT(NL80211_IFTYPE_P2P_CLIENT) |
-++				       BIT(NL80211_IFTYPE_P2P_GO);
-++	} else {
-++		c0_limits[i].max = 1;
-++		c0_limits[i++].types = BIT(NL80211_IFTYPE_AP);
-++	}
-++	combo[c].max_interfaces = i;
-++	combo[c].n_limits = i;
-++	combo[c].limits = c0_limits;
-++
-++	if (p2p) {
-++		c++;
-++		i = 0;
-++		combo[c].num_different_channels = 1;
-++		p2p_limits[i].max = 1;
-++		p2p_limits[i++].types = BIT(NL80211_IFTYPE_STATION);
-++		p2p_limits[i].max = 1;
-++		p2p_limits[i++].types = BIT(NL80211_IFTYPE_AP);
-++		p2p_limits[i].max = 1;
-++		p2p_limits[i++].types = BIT(NL80211_IFTYPE_P2P_CLIENT);
-++		p2p_limits[i].max = 1;
-++		p2p_limits[i++].types = BIT(NL80211_IFTYPE_P2P_DEVICE);
-++		combo[c].max_interfaces = i;
-++		combo[c].n_limits = i;
-++		combo[c].limits = p2p_limits;
-++	}
-+ 
-++	if (mbss) {
-++		c++;
-++		combo[c].beacon_int_infra_match = true;
-++		combo[c].num_different_channels = 1;
-++		mbss_limits[0].max = 4;
-++		mbss_limits[0].types = BIT(NL80211_IFTYPE_AP);
-++		combo[c].max_interfaces = 4;
-++		combo[c].n_limits = 1;
-++		combo[c].limits = mbss_limits;
-++	}
-++	wiphy->n_iface_combinations = n_combos;
-+ 	wiphy->iface_combinations = combo;
-+-	wiphy->n_iface_combinations = 1;
-+ 	return 0;
-+ 
-+ err:
-+-	kfree(limits);
-++	kfree(c0_limits);
-++	kfree(p2p_limits);
-++	kfree(mbss_limits);
-+ 	kfree(combo);
-+ 	return -ENOMEM;
-+ }
-+@@ -6080,11 +6149,15 @@ static void brcmf_cfg80211_reg_notifier(
-+ 
-+ static void brcmf_free_wiphy(struct wiphy *wiphy)
-+ {
-++	int i;
-++
-+ 	if (!wiphy)
-+ 		return;
-+ 
-+-	if (wiphy->iface_combinations)
-+-		kfree(wiphy->iface_combinations->limits);
-++	if (wiphy->iface_combinations) {
-++		for (i = 0; i < wiphy->n_iface_combinations; i++)
-++			kfree(wiphy->iface_combinations[i].limits);
-++	}
-+ 	kfree(wiphy->iface_combinations);
-+ 	if (wiphy->bands[IEEE80211_BAND_2GHZ]) {
-+ 		kfree(wiphy->bands[IEEE80211_BAND_2GHZ]->channels);
-diff --git a/package/kernel/mac80211/patches/313-mac80211-drop-4-addr-VLAN-frames-earlier-if-not-conn.patch b/package/kernel/mac80211/patches/313-mac80211-drop-4-addr-VLAN-frames-earlier-if-not-conn.patch
-deleted file mode 100644
-index 4125351..0000000
---- a/package/kernel/mac80211/patches/313-mac80211-drop-4-addr-VLAN-frames-earlier-if-not-conn.patch
-+++ /dev/null
-@@ -1,27 +0,0 @@
--From: Johannes Berg <johannes.berg@intel.com>
--Date: Fri, 20 Mar 2015 16:24:22 +0100
--Subject: [PATCH] mac80211: drop 4-addr VLAN frames earlier if not
-- connected
--
--If there's no station on the 4-addr VLAN interface, then frames
--cannot be transmitted. Drop such frames earlier, before setting
--up all the information for them.
--
--We should keep the old check though since that code might be used
--for other internally-generated frames.
--
--Signed-off-by: Johannes Berg <johannes.berg@intel.com>
-----
--
----- a/net/mac80211/tx.c
--+++ b/net/mac80211/tx.c
--@@ -1920,6 +1920,9 @@ static struct sk_buff *ieee80211_build_h
-- 			authorized = test_sta_flag(sta, WLAN_STA_AUTHORIZED);
-- 			wme_sta = sta->sta.wme;
-- 			have_station = true;
--+		} else if (sdata->wdev.use_4addr) {
--+			ret = -ENOLINK;
--+			goto free;
-- 		}
-- 		ap_sdata = container_of(sdata->bss, struct ieee80211_sub_if_data,
-- 					u.ap);
-diff --git a/package/kernel/mac80211/patches/314-brcmfmac-add-debugfs-entry-for-msgbuf-statistics.patch b/package/kernel/mac80211/patches/314-brcmfmac-add-debugfs-entry-for-msgbuf-statistics.patch
-new file mode 100644
-index 0000000..9768ef2
---- /dev/null
-+++ b/package/kernel/mac80211/patches/314-brcmfmac-add-debugfs-entry-for-msgbuf-statistics.patch
-@@ -0,0 +1,87 @@
-+From: Franky Lin <frankyl@broadcom.com>
-+Date: Thu, 20 Aug 2015 22:06:04 +0200
-+Subject: [PATCH] brcmfmac: add debugfs entry for msgbuf statistics
-+
-+Expose ring buffer read/write pointers and other useful statistics
-+through debugfs.
-+
-+Reviewed-by: Arend Van Spriel <arend@broadcom.com>
-+Reviewed-by: Hante Meuleman <meuleman@broadcom.com>
-+Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
-+Signed-off-by: Franky Lin <frankyl@broadcom.com>
-+Signed-off-by: Arend van Spriel <arend@broadcom.com>
-+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
-+---
-+
-+--- a/drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c
-++++ b/drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c
-+@@ -1360,6 +1360,60 @@ void brcmf_msgbuf_delete_flowring(struct
-+ 	}
-+ }
-+ 
-++#ifdef DEBUG
-++static int brcmf_msgbuf_stats_read(struct seq_file *seq, void *data)
-++{
-++	struct brcmf_bus *bus_if = dev_get_drvdata(seq->private);
-++	struct brcmf_pub *drvr = bus_if->drvr;
-++	struct brcmf_msgbuf *msgbuf = (struct brcmf_msgbuf *)drvr->proto->pd;
-++	struct brcmf_commonring *commonring;
-++	u16 i;
-++	struct brcmf_flowring_ring *ring;
-++	struct brcmf_flowring_hash *hash;
-++
-++	commonring = msgbuf->commonrings[BRCMF_H2D_MSGRING_CONTROL_SUBMIT];
-++	seq_printf(seq, "h2d_ctl_submit: rp %4u, wp %4u, depth %4u\n",
-++		   commonring->r_ptr, commonring->w_ptr, commonring->depth);
-++	commonring = msgbuf->commonrings[BRCMF_H2D_MSGRING_RXPOST_SUBMIT];
-++	seq_printf(seq, "h2d_rx_submit:  rp %4u, wp %4u, depth %4u\n",
-++		   commonring->r_ptr, commonring->w_ptr, commonring->depth);
-++	commonring = msgbuf->commonrings[BRCMF_D2H_MSGRING_CONTROL_COMPLETE];
-++	seq_printf(seq, "d2h_ctl_cmplt:  rp %4u, wp %4u, depth %4u\n",
-++		   commonring->r_ptr, commonring->w_ptr, commonring->depth);
-++	commonring = msgbuf->commonrings[BRCMF_D2H_MSGRING_TX_COMPLETE];
-++	seq_printf(seq, "d2h_tx_cmplt:   rp %4u, wp %4u, depth %4u\n",
-++		   commonring->r_ptr, commonring->w_ptr, commonring->depth);
-++	commonring = msgbuf->commonrings[BRCMF_D2H_MSGRING_RX_COMPLETE];
-++	seq_printf(seq, "d2h_rx_cmplt:   rp %4u, wp %4u, depth %4u\n",
-++		   commonring->r_ptr, commonring->w_ptr, commonring->depth);
-++
-++	seq_printf(seq, "\nh2d_flowrings: depth %u\n",
-++		   BRCMF_H2D_TXFLOWRING_MAX_ITEM);
-++	seq_puts(seq, "Active flowrings:\n");
-++	hash = msgbuf->flow->hash;
-++	for (i = 0; i < msgbuf->flow->nrofrings; i++) {
-++		if (!msgbuf->flow->rings[i])
-++			continue;
-++		ring = msgbuf->flow->rings[i];
-++		if (ring->status != RING_OPEN)
-++			continue;
-++		commonring = msgbuf->flowrings[i];
-++		hash = &msgbuf->flow->hash[ring->hash_id];
-++		seq_printf(seq, "id %3u: rp %4u, wp %4u, qlen %4u, blocked %u\n"
-++				"        ifidx %u, fifo %u, da %pM\n",
-++				i, commonring->r_ptr, commonring->w_ptr,
-++				skb_queue_len(&ring->skblist), ring->blocked,
-++				hash->ifidx, hash->fifo, hash->mac);
-++	}
-++
-++	return 0;
-++}
-++#else
-++static int brcmf_msgbuf_stats_read(struct seq_file *seq, void *data)
-++{
-++	return 0;
-++}
-++#endif
-+ 
-+ int brcmf_proto_msgbuf_attach(struct brcmf_pub *drvr)
-+ {
-+@@ -1460,6 +1514,8 @@ int brcmf_proto_msgbuf_attach(struct brc
-+ 	spin_lock_init(&msgbuf->flowring_work_lock);
-+ 	INIT_LIST_HEAD(&msgbuf->work_queue);
-+ 
-++	brcmf_debugfs_add_entry(drvr, "msgbuf_stats", brcmf_msgbuf_stats_read);
-++
-+ 	return 0;
-+ 
-+ fail:
-diff --git a/package/kernel/mac80211/patches/314-mac80211-mesh-avoid-pointless-station-lookup.patch b/package/kernel/mac80211/patches/314-mac80211-mesh-avoid-pointless-station-lookup.patch
-deleted file mode 100644
-index 9105a64..0000000
---- a/package/kernel/mac80211/patches/314-mac80211-mesh-avoid-pointless-station-lookup.patch
-+++ /dev/null
-@@ -1,33 +0,0 @@
--From: Johannes Berg <johannes.berg@intel.com>
--Date: Fri, 20 Mar 2015 16:24:23 +0100
--Subject: [PATCH] mac80211: mesh: avoid pointless station lookup
--
--In ieee80211_build_hdr(), the station is looked up to build the
--header correctly (QoS field) and to check for authorization. For
--mesh, authorization isn't checked here, and QoS capability is
--mandatory, so the station lookup can be avoided.
--
--Signed-off-by: Johannes Berg <johannes.berg@intel.com>
-----
--
----- a/net/mac80211/tx.c
--+++ b/net/mac80211/tx.c
--@@ -2130,12 +2130,14 @@ static struct sk_buff *ieee80211_build_h
-- 	}
-- 
-- 	/*
---	 * There's no need to try to look up the destination
---	 * if it is a multicast address (which can only happen
---	 * in AP mode)
--+	 * There's no need to try to look up the destination station
--+	 * if it is a multicast address. In mesh, there's no need to
--+	 * look up the station at all as it always must be QoS capable
--+	 * and mesh mode checks authorization later.
-- 	 */
-- 	multicast = is_multicast_ether_addr(hdr.addr1);
---	if (!multicast && !have_station) {
--+	if (!multicast && !have_station &&
--+	    !ieee80211_vif_is_mesh(&sdata->vif)) {
-- 		sta = sta_info_get(sdata, hdr.addr1);
-- 		if (sta) {
-- 			authorized = test_sta_flag(sta, WLAN_STA_AUTHORIZED);
-diff --git a/package/kernel/mac80211/patches/315-brcmfmac-make-use-of-cfg80211_check_combinations.patch b/package/kernel/mac80211/patches/315-brcmfmac-make-use-of-cfg80211_check_combinations.patch
-new file mode 100644
-index 0000000..281f02b
---- /dev/null
-+++ b/package/kernel/mac80211/patches/315-brcmfmac-make-use-of-cfg80211_check_combinations.patch
-@@ -0,0 +1,83 @@
-+From: Arend van Spriel <arend@broadcom.com>
-+Date: Thu, 20 Aug 2015 22:06:05 +0200
-+Subject: [PATCH] brcmfmac: make use of cfg80211_check_combinations()
-+
-+Use cfg80211_check_combinations() so we can bail out early when an
-+interface add or change results in an invalid combination.
-+
-+Reviewed-by: Hante Meuleman <meuleman@broadcom.com>
-+Reviewed-by: Franky (Zhenhui) Lin <frankyl@broadcom.com>
-+Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
-+Signed-off-by: Arend van Spriel <arend@broadcom.com>
-+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
-+---
-+
-+--- a/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c
-++++ b/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c
-+@@ -469,6 +469,36 @@ brcmf_find_wpsie(const u8 *parse, u32 le
-+ 	return NULL;
-+ }
-+ 
-++static int brcmf_vif_change_validate(struct brcmf_cfg80211_info *cfg,
-++				     struct brcmf_cfg80211_vif *vif,
-++				     enum nl80211_iftype new_type)
-++{
-++	int iftype_num[NUM_NL80211_IFTYPES];
-++	struct brcmf_cfg80211_vif *pos;
-++
-++	memset(&iftype_num[0], 0, sizeof(iftype_num));
-++	list_for_each_entry(pos, &cfg->vif_list, list)
-++		if (pos == vif)
-++			iftype_num[new_type]++;
-++		else
-++			iftype_num[pos->wdev.iftype]++;
-++
-++	return cfg80211_check_combinations(cfg->wiphy, 1, 0, iftype_num);
-++}
-++
-++static int brcmf_vif_add_validate(struct brcmf_cfg80211_info *cfg,
-++				  enum nl80211_iftype new_type)
-++{
-++	int iftype_num[NUM_NL80211_IFTYPES];
-++	struct brcmf_cfg80211_vif *pos;
-++
-++	memset(&iftype_num[0], 0, sizeof(iftype_num));
-++	list_for_each_entry(pos, &cfg->vif_list, list)
-++		iftype_num[pos->wdev.iftype]++;
-++
-++	iftype_num[new_type]++;
-++	return cfg80211_check_combinations(cfg->wiphy, 1, 0, iftype_num);
-++}
-+ 
-+ static void convert_key_from_CPU(struct brcmf_wsec_key *key,
-+ 				 struct brcmf_wsec_key_le *key_le)
-+@@ -663,8 +693,14 @@ static struct wireless_dev *brcmf_cfg802
-+ 						     struct vif_params *params)
-+ {
-+ 	struct wireless_dev *wdev;
-++	int err;
-+ 
-+ 	brcmf_dbg(TRACE, "enter: %s type %d\n", name, type);
-++	err = brcmf_vif_add_validate(wiphy_to_cfg(wiphy), type);
-++	if (err) {
-++		brcmf_err("iface validation failed: err=%d\n", err);
-++		return ERR_PTR(err);
-++	}
-+ 	switch (type) {
-+ 	case NL80211_IFTYPE_ADHOC:
-+ 	case NL80211_IFTYPE_STATION:
-+@@ -823,8 +859,12 @@ brcmf_cfg80211_change_iface(struct wiphy
-+ 	s32 ap = 0;
-+ 	s32 err = 0;
-+ 
-+-	brcmf_dbg(TRACE, "Enter, ndev=%p, type=%d\n", ndev, type);
-+-
-++	brcmf_dbg(TRACE, "Enter, idx=%d, type=%d\n", ifp->bssidx, type);
-++	err = brcmf_vif_change_validate(wiphy_to_cfg(wiphy), vif, type);
-++	if (err) {
-++		brcmf_err("iface validation failed: err=%d\n", err);
-++		return err;
-++	}
-+ 	switch (type) {
-+ 	case NL80211_IFTYPE_MONITOR:
-+ 	case NL80211_IFTYPE_WDS:
-diff --git a/package/kernel/mac80211/patches/315-mac80211-avoid-duplicate-TX-path-station-lookup.patch b/package/kernel/mac80211/patches/315-mac80211-avoid-duplicate-TX-path-station-lookup.patch
-deleted file mode 100644
-index d143025..0000000
---- a/package/kernel/mac80211/patches/315-mac80211-avoid-duplicate-TX-path-station-lookup.patch
-+++ /dev/null
-@@ -1,267 +0,0 @@
--From: Johannes Berg <johannes.berg@intel.com>
--Date: Fri, 20 Mar 2015 14:18:27 +0100
--Subject: [PATCH] mac80211: avoid duplicate TX path station lookup
--
--Instead of looking up the destination station twice in the TX path
--(first to build the header, and then for control processing), save
--it when building the header and use it later in the TX path.
--
--To avoid having to look up the station in the many callers, allow
--those to pass %NULL which keeps the existing lookup.
--
--Signed-off-by: Johannes Berg <johannes.berg@intel.com>
-----
--
----- a/net/mac80211/cfg.c
--+++ b/net/mac80211/cfg.c
--@@ -3565,7 +3565,7 @@ static int ieee80211_probe_client(struct
-- 		nullfunc->qos_ctrl = cpu_to_le16(7);
-- 
-- 	local_bh_disable();
---	ieee80211_xmit(sdata, skb);
--+	ieee80211_xmit(sdata, sta, skb);
-- 	local_bh_enable();
-- 	rcu_read_unlock();
-- 
----- a/net/mac80211/ieee80211_i.h
--+++ b/net/mac80211/ieee80211_i.h
--@@ -1775,7 +1775,8 @@ void mac80211_ev_michael_mic_failure(str
-- 				     gfp_t gfp);
-- void ieee80211_set_wmm_default(struct ieee80211_sub_if_data *sdata,
-- 			       bool bss_notify);
---void ieee80211_xmit(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb);
--+void ieee80211_xmit(struct ieee80211_sub_if_data *sdata,
--+		    struct sta_info *sta, struct sk_buff *skb);
-- 
-- void __ieee80211_tx_skb_tid_band(struct ieee80211_sub_if_data *sdata,
-- 				 struct sk_buff *skb, int tid,
----- a/net/mac80211/sta_info.c
--+++ b/net/mac80211/sta_info.c
--@@ -1279,7 +1279,7 @@ static void ieee80211_send_null_response
-- 	}
-- 
-- 	info->band = chanctx_conf->def.chan->band;
---	ieee80211_xmit(sdata, skb);
--+	ieee80211_xmit(sdata, sta, skb);
-- 	rcu_read_unlock();
-- }
-- 
----- a/net/mac80211/tx.c
--+++ b/net/mac80211/tx.c
--@@ -1110,11 +1110,13 @@ static bool ieee80211_tx_prep_agg(struct
-- 
-- /*
--  * initialises @tx
--+ * pass %NULL for the station if unknown, a valid pointer if known
--+ * or an ERR_PTR() if the station is known not to exist
--  */
-- static ieee80211_tx_result
-- ieee80211_tx_prepare(struct ieee80211_sub_if_data *sdata,
-- 		     struct ieee80211_tx_data *tx,
---		     struct sk_buff *skb)
--+		     struct sta_info *sta, struct sk_buff *skb)
-- {
-- 	struct ieee80211_local *local = sdata->local;
-- 	struct ieee80211_hdr *hdr;
--@@ -1137,17 +1139,22 @@ ieee80211_tx_prepare(struct ieee80211_su
-- 
-- 	hdr = (struct ieee80211_hdr *) skb->data;
-- 
---	if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) {
---		tx->sta = rcu_dereference(sdata->u.vlan.sta);
---		if (!tx->sta && sdata->dev->ieee80211_ptr->use_4addr)
---			return TX_DROP;
---	} else if (info->flags & (IEEE80211_TX_CTL_INJECTED |
---				  IEEE80211_TX_INTFL_NL80211_FRAME_TX) ||
---		   tx->sdata->control_port_protocol == tx->skb->protocol) {
---		tx->sta = sta_info_get_bss(sdata, hdr->addr1);
--+	if (likely(sta)) {
--+		if (!IS_ERR(sta))
--+			tx->sta = sta;
--+	} else {
--+		if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) {
--+			tx->sta = rcu_dereference(sdata->u.vlan.sta);
--+			if (!tx->sta && sdata->wdev.use_4addr)
--+				return TX_DROP;
--+		} else if (info->flags & (IEEE80211_TX_INTFL_NL80211_FRAME_TX |
--+					  IEEE80211_TX_CTL_INJECTED) ||
--+			   tx->sdata->control_port_protocol == tx->skb->protocol) {
--+			tx->sta = sta_info_get_bss(sdata, hdr->addr1);
--+		}
--+		if (!tx->sta && !is_multicast_ether_addr(hdr->addr1))
--+			tx->sta = sta_info_get(sdata, hdr->addr1);
-- 	}
---	if (!tx->sta && !is_multicast_ether_addr(hdr->addr1))
---		tx->sta = sta_info_get(sdata, hdr->addr1);
-- 
-- 	if (tx->sta && ieee80211_is_data_qos(hdr->frame_control) &&
-- 	    !ieee80211_is_qos_nullfunc(hdr->frame_control) &&
--@@ -1485,7 +1492,7 @@ bool ieee80211_tx_prepare_skb(struct iee
-- 	struct ieee80211_tx_data tx;
-- 	struct sk_buff *skb2;
-- 
---	if (ieee80211_tx_prepare(sdata, &tx, skb) == TX_DROP)
--+	if (ieee80211_tx_prepare(sdata, &tx, NULL, skb) == TX_DROP)
-- 		return false;
-- 
-- 	info->band = band;
--@@ -1518,7 +1525,8 @@ EXPORT_SYMBOL(ieee80211_tx_prepare_skb);
--  * Returns false if the frame couldn't be transmitted but was queued instead.
--  */
-- static bool ieee80211_tx(struct ieee80211_sub_if_data *sdata,
---			 struct sk_buff *skb, bool txpending)
--+			 struct sta_info *sta, struct sk_buff *skb,
--+			 bool txpending)
-- {
-- 	struct ieee80211_local *local = sdata->local;
-- 	struct ieee80211_tx_data tx;
--@@ -1534,7 +1542,7 @@ static bool ieee80211_tx(struct ieee8021
-- 
-- 	/* initialises tx */
-- 	led_len = skb->len;
---	res_prepare = ieee80211_tx_prepare(sdata, &tx, skb);
--+	res_prepare = ieee80211_tx_prepare(sdata, &tx, sta, skb);
-- 
-- 	if (unlikely(res_prepare == TX_DROP)) {
-- 		ieee80211_free_txskb(&local->hw, skb);
--@@ -1590,7 +1598,8 @@ static int ieee80211_skb_resize(struct i
-- 	return 0;
-- }
-- 
---void ieee80211_xmit(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb)
--+void ieee80211_xmit(struct ieee80211_sub_if_data *sdata,
--+		    struct sta_info *sta, struct sk_buff *skb)
-- {
-- 	struct ieee80211_local *local = sdata->local;
-- 	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
--@@ -1625,7 +1634,7 @@ void ieee80211_xmit(struct ieee80211_sub
-- 	}
-- 
-- 	ieee80211_set_qos_hdr(sdata, skb);
---	ieee80211_tx(sdata, skb, false);
--+	ieee80211_tx(sdata, sta, skb, false);
-- }
-- 
-- static bool ieee80211_parse_tx_radiotap(struct sk_buff *skb)
--@@ -1846,7 +1855,7 @@ netdev_tx_t ieee80211_monitor_start_xmit
-- 		goto fail_rcu;
-- 
-- 	info->band = chandef->chan->band;
---	ieee80211_xmit(sdata, skb);
--+	ieee80211_xmit(sdata, NULL, skb);
-- 	rcu_read_unlock();
-- 
-- 	return NETDEV_TX_OK;
--@@ -1877,7 +1886,8 @@ fail:
--  * Returns: the (possibly reallocated) skb or an ERR_PTR() code
--  */
-- static struct sk_buff *ieee80211_build_hdr(struct ieee80211_sub_if_data *sdata,
---					   struct sk_buff *skb, u32 info_flags)
--+					   struct sk_buff *skb, u32 info_flags,
--+					   struct sta_info **sta_out)
-- {
-- 	struct ieee80211_local *local = sdata->local;
-- 	struct ieee80211_tx_info *info;
--@@ -1920,6 +1930,7 @@ static struct sk_buff *ieee80211_build_h
-- 			authorized = test_sta_flag(sta, WLAN_STA_AUTHORIZED);
-- 			wme_sta = sta->sta.wme;
-- 			have_station = true;
--+			*sta_out = sta;
-- 		} else if (sdata->wdev.use_4addr) {
-- 			ret = -ENOLINK;
-- 			goto free;
--@@ -2073,6 +2084,7 @@ static struct sk_buff *ieee80211_build_h
-- 			have_station = true;
-- 			authorized = test_sta_flag(sta, WLAN_STA_AUTHORIZED);
-- 			wme_sta = sta->sta.wme;
--+			*sta_out = sta;
-- 		}  else if (sdata->u.mgd.use_4addr &&
-- 			    cpu_to_be16(ethertype) != sdata->control_port_protocol) {
-- 			fc |= cpu_to_le16(IEEE80211_FCTL_FROMDS |
--@@ -2136,13 +2148,18 @@ static struct sk_buff *ieee80211_build_h
-- 	 * and mesh mode checks authorization later.
-- 	 */
-- 	multicast = is_multicast_ether_addr(hdr.addr1);
---	if (!multicast && !have_station &&
---	    !ieee80211_vif_is_mesh(&sdata->vif)) {
---		sta = sta_info_get(sdata, hdr.addr1);
--+	if (multicast) {
--+		*sta_out = ERR_PTR(-ENOENT);
--+	} else if (!have_station && !ieee80211_vif_is_mesh(&sdata->vif)) {
--+		if (sdata->control_port_protocol == skb->protocol)
--+			sta = sta_info_get_bss(sdata, hdr.addr1);
--+		else
--+			sta = sta_info_get(sdata, hdr.addr1);
-- 		if (sta) {
-- 			authorized = test_sta_flag(sta, WLAN_STA_AUTHORIZED);
-- 			wme_sta = sta->sta.wme;
-- 		}
--+		*sta_out = sta ?: ERR_PTR(-ENOENT);
-- 	}
-- 
-- 	/* For mesh, the use of the QoS header is mandatory */
--@@ -2320,6 +2337,7 @@ void __ieee80211_subif_start_xmit(struct
-- 				  u32 info_flags)
-- {
-- 	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
--+	struct sta_info *sta = NULL;
-- 
-- 	if (unlikely(skb->len < ETH_HLEN)) {
-- 		kfree_skb(skb);
--@@ -2328,7 +2346,7 @@ void __ieee80211_subif_start_xmit(struct
-- 
-- 	rcu_read_lock();
-- 
---	skb = ieee80211_build_hdr(sdata, skb, info_flags);
--+	skb = ieee80211_build_hdr(sdata, skb, info_flags, &sta);
-- 	if (IS_ERR(skb))
-- 		goto out;
-- 
--@@ -2336,7 +2354,7 @@ void __ieee80211_subif_start_xmit(struct
-- 	dev->stats.tx_bytes += skb->len;
-- 	dev->trans_start = jiffies;
-- 
---	ieee80211_xmit(sdata, skb);
--+	ieee80211_xmit(sdata, sta, skb);
--  out:
-- 	rcu_read_unlock();
-- }
--@@ -2364,10 +2382,11 @@ ieee80211_build_data_template(struct iee
-- 		.local = sdata->local,
-- 		.sdata = sdata,
-- 	};
--+	struct sta_info *sta_ignore;
-- 
-- 	rcu_read_lock();
-- 
---	skb = ieee80211_build_hdr(sdata, skb, info_flags);
--+	skb = ieee80211_build_hdr(sdata, skb, info_flags, &sta_ignore);
-- 	if (IS_ERR(skb))
-- 		goto out;
-- 
--@@ -2425,7 +2444,7 @@ static bool ieee80211_tx_pending_skb(str
-- 			return true;
-- 		}
-- 		info->band = chanctx_conf->def.chan->band;
---		result = ieee80211_tx(sdata, skb, true);
--+		result = ieee80211_tx(sdata, NULL, skb, true);
-- 	} else {
-- 		struct sk_buff_head skbs;
-- 
--@@ -3163,7 +3182,7 @@ ieee80211_get_buffered_bc(struct ieee802
-- 
-- 		if (sdata->vif.type == NL80211_IFTYPE_AP)
-- 			sdata = IEEE80211_DEV_TO_SUB_IF(skb->dev);
---		if (!ieee80211_tx_prepare(sdata, &tx, skb))
--+		if (!ieee80211_tx_prepare(sdata, &tx, NULL, skb))
-- 			break;
-- 		dev_kfree_skb_any(skb);
-- 	}
--@@ -3295,6 +3314,6 @@ void __ieee80211_tx_skb_tid_band(struct
-- 	 */
-- 	local_bh_disable();
-- 	IEEE80211_SKB_CB(skb)->band = band;
---	ieee80211_xmit(sdata, skb);
--+	ieee80211_xmit(sdata, NULL, skb);
-- 	local_bh_enable();
-- }
-diff --git a/package/kernel/mac80211/patches/316-brcmfmac-block-the-correct-flowring-when-backup-queu.patch b/package/kernel/mac80211/patches/316-brcmfmac-block-the-correct-flowring-when-backup-queu.patch
-new file mode 100644
-index 0000000..2d5f7b9
---- /dev/null
-+++ b/package/kernel/mac80211/patches/316-brcmfmac-block-the-correct-flowring-when-backup-queu.patch
-@@ -0,0 +1,48 @@
-+From: Franky Lin <frankyl@broadcom.com>
-+Date: Thu, 20 Aug 2015 22:06:06 +0200
-+Subject: [PATCH] brcmfmac: block the correct flowring when backup queue
-+ overflow
-+
-+brcmf_flowring_block blocks the last active flowring under the same
-+interface instead of the one provided by caller. This could lead to a
-+dead lock of netif stop if there are more than one flowring under the
-+interface and the traffic is high enough so brcmf_flowring_enqueue can
-+not unblock the ring right away.
-+
-+Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
-+Reviewed-by: Hante Meuleman <meuleman@broadcom.com>
-+Signed-off-by: Franky Lin <frankyl@broadcom.com>
-+Signed-off-by: Arend van Spriel <arend@broadcom.com>
-+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
-+---
-+
-+--- a/drivers/net/wireless/brcm80211/brcmfmac/flowring.c
-++++ b/drivers/net/wireless/brcm80211/brcmfmac/flowring.c
-+@@ -194,11 +194,15 @@ static void brcmf_flowring_block(struct
-+ 	spin_lock_irqsave(&flow->block_lock, flags);
-+ 
-+ 	ring = flow->rings[flowid];
-++	if (ring->blocked == blocked) {
-++		spin_unlock_irqrestore(&flow->block_lock, flags);
-++		return;
-++	}
-+ 	ifidx = brcmf_flowring_ifidx_get(flow, flowid);
-+ 
-+ 	currently_blocked = false;
-+ 	for (i = 0; i < flow->nrofrings; i++) {
-+-		if (flow->rings[i]) {
-++		if ((flow->rings[i]) && (i != flowid)) {
-+ 			ring = flow->rings[i];
-+ 			if ((ring->status == RING_OPEN) &&
-+ 			    (brcmf_flowring_ifidx_get(flow, i) == ifidx)) {
-+@@ -209,8 +213,8 @@ static void brcmf_flowring_block(struct
-+ 			}
-+ 		}
-+ 	}
-+-	ring->blocked = blocked;
-+-	if (currently_blocked == blocked) {
-++	flow->rings[flowid]->blocked = blocked;
-++	if (currently_blocked) {
-+ 		spin_unlock_irqrestore(&flow->block_lock, flags);
-+ 		return;
-+ 	}
-diff --git a/package/kernel/mac80211/patches/316-mac80211-reduce-log-spam-from-ieee80211_handle_pwr_c.patch b/package/kernel/mac80211/patches/316-mac80211-reduce-log-spam-from-ieee80211_handle_pwr_c.patch
-deleted file mode 100644
-index 77a82c2..0000000
---- a/package/kernel/mac80211/patches/316-mac80211-reduce-log-spam-from-ieee80211_handle_pwr_c.patch
-+++ /dev/null
-@@ -1,38 +0,0 @@
--From: John Linville <linville@tuxdriver.com>
--Date: Tue, 31 Mar 2015 10:49:14 -0400
--Subject: [PATCH] mac80211: reduce log spam from ieee80211_handle_pwr_constr
--
--This changes a couple of messages from sdata_info to sdata_dbg.
--This should reduce some log spam, as reported here:
--
--	https://bugzilla.redhat.com/show_bug.cgi?id=1206468
--
--Signed-off-by: John W. Linville <linville@tuxdriver.com>
--Signed-off-by: Johannes Berg <johannes.berg@intel.com>
-----
--
----- a/net/mac80211/mlme.c
--+++ b/net/mac80211/mlme.c
--@@ -1347,15 +1347,15 @@ static u32 ieee80211_handle_pwr_constr(s
-- 	 */
-- 	if (has_80211h_pwr &&
-- 	    (!has_cisco_pwr || pwr_level_80211h <= pwr_level_cisco)) {
---		sdata_info(sdata,
---			   "Limiting TX power to %d (%d - %d) dBm as advertised by %pM\n",
---			   pwr_level_80211h, chan_pwr, pwr_reduction_80211h,
---			   sdata->u.mgd.bssid);
--+		sdata_dbg(sdata,
--+			  "Limiting TX power to %d (%d - %d) dBm as advertised by %pM\n",
--+			  pwr_level_80211h, chan_pwr, pwr_reduction_80211h,
--+			  sdata->u.mgd.bssid);
-- 		new_ap_level = pwr_level_80211h;
-- 	} else {  /* has_cisco_pwr is always true here. */
---		sdata_info(sdata,
---			   "Limiting TX power to %d dBm as advertised by %pM\n",
---			   pwr_level_cisco, sdata->u.mgd.bssid);
--+		sdata_dbg(sdata,
--+			  "Limiting TX power to %d dBm as advertised by %pM\n",
--+			  pwr_level_cisco, sdata->u.mgd.bssid);
-- 		new_ap_level = pwr_level_cisco;
-- 	}
-- 
-diff --git a/package/kernel/mac80211/patches/317-brcmfmac-Fix-race-condition-in-msgbuf-ioctl-processi.patch b/package/kernel/mac80211/patches/317-brcmfmac-Fix-race-condition-in-msgbuf-ioctl-processi.patch
-deleted file mode 100644
-index e005fe7..0000000
---- a/package/kernel/mac80211/patches/317-brcmfmac-Fix-race-condition-in-msgbuf-ioctl-processi.patch
-+++ /dev/null
-@@ -1,35 +0,0 @@
--From: Hante Meuleman <meuleman@broadcom.com>
--Date: Fri, 6 Mar 2015 18:40:41 +0100
--Subject: [PATCH] brcmfmac: Fix race condition in msgbuf ioctl processing.
--
--Msgbuf is using a wait_event_timeout to wait for the response on
--an ioctl. The wakeup routine uses waitqueue_active to see if
--wait_event_timeout has been called. There is a chance that the
--response arrives before wait_event_timeout is called, this
--will result in situation that wait_event_timeout never gets
--woken again and assumed result will be a timeout. This patch
--removes that errornous situation by always setting the
--ctl_completed var before checking for queue active.
--
--Reviewed-by: Arend Van Spriel <arend@broadcom.com>
--Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
--Signed-off-by: Hante Meuleman <meuleman@broadcom.com>
--Signed-off-by: Arend van Spriel <arend@broadcom.com>
--Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
-----
--
----- a/drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c
--+++ b/drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c
--@@ -481,10 +481,9 @@ static int brcmf_msgbuf_ioctl_resp_wait(
-- 
-- static void brcmf_msgbuf_ioctl_resp_wake(struct brcmf_msgbuf *msgbuf)
-- {
---	if (waitqueue_active(&msgbuf->ioctl_resp_wait)) {
---		msgbuf->ctl_completed = true;
--+	msgbuf->ctl_completed = true;
--+	if (waitqueue_active(&msgbuf->ioctl_resp_wait))
-- 		wake_up(&msgbuf->ioctl_resp_wait);
---	}
-- }
-- 
-- 
-diff --git a/package/kernel/mac80211/patches/317-brcmfmac-bump-highest-event-number-for-4339-firmware.patch b/package/kernel/mac80211/patches/317-brcmfmac-bump-highest-event-number-for-4339-firmware.patch
-new file mode 100644
-index 0000000..7378401
---- /dev/null
-+++ b/package/kernel/mac80211/patches/317-brcmfmac-bump-highest-event-number-for-4339-firmware.patch
-@@ -0,0 +1,52 @@
-+From: Arend van Spriel <arend@broadcom.com>
-+Date: Thu, 20 Aug 2015 22:06:07 +0200
-+Subject: [PATCH] brcmfmac: bump highest event number for 4339 firmware
-+
-+The event mask length is determined by the highest event number
-+that is specified in the driver. When this length is shorter than
-+firmware expects setting event mask will fail and device becomes
-+pretty useless. This issue was reported with bcm4339 firmware that
-+was recently released.
-+
-+Reported-by: Pontus Fuchs <pontusf@broadcom.com>
-+Reviewed-by: Hante Meuleman <meuleman@broadcom.com>
-+Reviewed-by: Franky (Zhenhui) Lin <frankyl@broadcom.com>
-+Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
-+Reviewed-by: Pontus Fuchs <pontusf@broadcom.com>
-+Signed-off-by: Arend van Spriel <arend@broadcom.com>
-+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
-+---
-+
-+--- a/drivers/net/wireless/brcm80211/brcmfmac/fweh.h
-++++ b/drivers/net/wireless/brcm80211/brcmfmac/fweh.h
-+@@ -85,7 +85,6 @@ struct brcmf_event;
-+ 	BRCMF_ENUM_DEF(IF, 54) \
-+ 	BRCMF_ENUM_DEF(P2P_DISC_LISTEN_COMPLETE, 55) \
-+ 	BRCMF_ENUM_DEF(RSSI, 56) \
-+-	BRCMF_ENUM_DEF(PFN_SCAN_COMPLETE, 57) \
-+ 	BRCMF_ENUM_DEF(EXTLOG_MSG, 58) \
-+ 	BRCMF_ENUM_DEF(ACTION_FRAME, 59) \
-+ 	BRCMF_ENUM_DEF(ACTION_FRAME_COMPLETE, 60) \
-+@@ -103,8 +102,7 @@ struct brcmf_event;
-+ 	BRCMF_ENUM_DEF(FIFO_CREDIT_MAP, 74) \
-+ 	BRCMF_ENUM_DEF(ACTION_FRAME_RX, 75) \
-+ 	BRCMF_ENUM_DEF(TDLS_PEER_EVENT, 92) \
-+-	BRCMF_ENUM_DEF(BCMC_CREDIT_SUPPORT, 127) \
-+-	BRCMF_ENUM_DEF(PSTA_PRIMARY_INTF_IND, 128)
-++	BRCMF_ENUM_DEF(BCMC_CREDIT_SUPPORT, 127)
-+ 
-+ #define BRCMF_ENUM_DEF(id, val) \
-+ 	BRCMF_E_##id = (val),
-+@@ -112,7 +110,11 @@ struct brcmf_event;
-+ /* firmware event codes sent by the dongle */
-+ enum brcmf_fweh_event_code {
-+ 	BRCMF_FWEH_EVENT_ENUM_DEFLIST
-+-	BRCMF_E_LAST
-++	/* this determines event mask length which must match
-++	 * minimum length check in device firmware so it is
-++	 * hard-coded here.
-++	 */
-++	BRCMF_E_LAST = 139
-+ };
-+ #undef BRCMF_ENUM_DEF
-+ 
-diff --git a/package/kernel/mac80211/patches/318-brcmfmac-Update-msgbuf-commonring-size-for-improved-.patch b/package/kernel/mac80211/patches/318-brcmfmac-Update-msgbuf-commonring-size-for-improved-.patch
-deleted file mode 100644
-index c2cd1c5..0000000
---- a/package/kernel/mac80211/patches/318-brcmfmac-Update-msgbuf-commonring-size-for-improved-.patch
-+++ /dev/null
-@@ -1,30 +0,0 @@
--From: Hante Meuleman <meuleman@broadcom.com>
--Date: Wed, 18 Mar 2015 13:25:23 +0100
--Subject: [PATCH] brcmfmac: Update msgbuf commonring size for improved
-- throughput.
--
--Reviewed-by: Arend Van Spriel <arend@broadcom.com>
--Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
--Signed-off-by: Hante Meuleman <meuleman@broadcom.com>
--Signed-off-by: Arend van Spriel <arend@broadcom.com>
--Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
-----
--
----- a/drivers/net/wireless/brcm80211/brcmfmac/msgbuf.h
--+++ b/drivers/net/wireless/brcm80211/brcmfmac/msgbuf.h
--@@ -17,11 +17,11 @@
-- 
-- #ifdef CPTCFG_BRCMFMAC_PROTO_MSGBUF
-- 
---#define BRCMF_H2D_MSGRING_CONTROL_SUBMIT_MAX_ITEM	20
---#define BRCMF_H2D_MSGRING_RXPOST_SUBMIT_MAX_ITEM	256
---#define BRCMF_D2H_MSGRING_CONTROL_COMPLETE_MAX_ITEM	20
--+#define BRCMF_H2D_MSGRING_CONTROL_SUBMIT_MAX_ITEM	64
--+#define BRCMF_H2D_MSGRING_RXPOST_SUBMIT_MAX_ITEM	512
--+#define BRCMF_D2H_MSGRING_CONTROL_COMPLETE_MAX_ITEM	64
-- #define BRCMF_D2H_MSGRING_TX_COMPLETE_MAX_ITEM		1024
---#define BRCMF_D2H_MSGRING_RX_COMPLETE_MAX_ITEM		256
--+#define BRCMF_D2H_MSGRING_RX_COMPLETE_MAX_ITEM		512
-- #define BRCMF_H2D_TXFLOWRING_MAX_ITEM			512
-- 
-- #define BRCMF_H2D_MSGRING_CONTROL_SUBMIT_ITEMSIZE	40
-diff --git a/package/kernel/mac80211/patches/319-ath9k_htc-add-new-WMI_REG_RMW_CMDID-command.patch b/package/kernel/mac80211/patches/319-ath9k_htc-add-new-WMI_REG_RMW_CMDID-command.patch
-deleted file mode 100644
-index 6af69eb..0000000
---- a/package/kernel/mac80211/patches/319-ath9k_htc-add-new-WMI_REG_RMW_CMDID-command.patch
-+++ /dev/null
-@@ -1,307 +0,0 @@
--From: Oleksij Rempel <linux@rempel-privat.de>
--Date: Sun, 22 Mar 2015 19:29:46 +0100
--Subject: [PATCH] ath9k_htc: add new WMI_REG_RMW_CMDID command
--
--Since usb bus add extra delay on each request, a command
--with read + write requests is too expensive. We can dramtically
--reduce usb load by moving this command to firmware.
--
--In my tests, this patch will reduce channel scan time
--for about 5-10 seconds.
--
--Signed-off-by: Oleksij Rempel <linux@rempel-privat.de>
--Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
-----
--
----- a/drivers/net/wireless/ath/ath.h
--+++ b/drivers/net/wireless/ath/ath.h
--@@ -131,6 +131,9 @@ struct ath_ops {
-- 	void (*enable_write_buffer)(void *);
-- 	void (*write_flush) (void *);
-- 	u32 (*rmw)(void *, u32 reg_offset, u32 set, u32 clr);
--+	void (*enable_rmw_buffer)(void *);
--+	void (*rmw_flush) (void *);
--+
-- };
-- 
-- struct ath_common;
----- a/drivers/net/wireless/ath/ath9k/htc.h
--+++ b/drivers/net/wireless/ath/ath9k/htc.h
--@@ -444,6 +444,10 @@ static inline void ath9k_htc_stop_btcoex
-- #define OP_BT_SCAN                 BIT(4)
-- #define OP_TSF_RESET               BIT(6)
-- 
--+enum htc_op_flags {
--+	HTC_FWFLAG_NO_RMW,
--+};
--+
-- struct ath9k_htc_priv {
-- 	struct device *dev;
-- 	struct ieee80211_hw *hw;
--@@ -482,6 +486,7 @@ struct ath9k_htc_priv {
-- 	bool reconfig_beacon;
-- 	unsigned int rxfilter;
-- 	unsigned long op_flags;
--+	unsigned long fw_flags;
-- 
-- 	struct ath9k_hw_cal_data caldata;
-- 	struct ath_spec_scan_priv spec_priv;
----- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c
--+++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c
--@@ -376,17 +376,139 @@ static void ath9k_regwrite_flush(void *h
-- 	mutex_unlock(&priv->wmi->multi_write_mutex);
-- }
-- 
---static u32 ath9k_reg_rmw(void *hw_priv, u32 reg_offset, u32 set, u32 clr)
--+static void ath9k_reg_rmw_buffer(void *hw_priv,
--+				 u32 reg_offset, u32 set, u32 clr)
--+{
--+	struct ath_hw *ah = (struct ath_hw *) hw_priv;
--+	struct ath_common *common = ath9k_hw_common(ah);
--+	struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) common->priv;
--+	u32 rsp_status;
--+	int r;
--+
--+	mutex_lock(&priv->wmi->multi_rmw_mutex);
--+
--+	/* Store the register/value */
--+	priv->wmi->multi_rmw[priv->wmi->multi_rmw_idx].reg =
--+		cpu_to_be32(reg_offset);
--+	priv->wmi->multi_rmw[priv->wmi->multi_rmw_idx].set =
--+		cpu_to_be32(set);
--+	priv->wmi->multi_rmw[priv->wmi->multi_rmw_idx].clr =
--+		cpu_to_be32(clr);
--+
--+	priv->wmi->multi_rmw_idx++;
--+
--+	/* If the buffer is full, send it out. */
--+	if (priv->wmi->multi_rmw_idx == MAX_RMW_CMD_NUMBER) {
--+		r = ath9k_wmi_cmd(priv->wmi, WMI_REG_RMW_CMDID,
--+			  (u8 *) &priv->wmi->multi_rmw,
--+			  sizeof(struct register_write) * priv->wmi->multi_rmw_idx,
--+			  (u8 *) &rsp_status, sizeof(rsp_status),
--+			  100);
--+		if (unlikely(r)) {
--+			ath_dbg(common, WMI,
--+				"REGISTER RMW FAILED, multi len: %d\n",
--+				priv->wmi->multi_rmw_idx);
--+		}
--+		priv->wmi->multi_rmw_idx = 0;
--+	}
--+
--+	mutex_unlock(&priv->wmi->multi_rmw_mutex);
--+}
--+
--+static void ath9k_reg_rmw_flush(void *hw_priv)
-- {
---	u32 val;
--+	struct ath_hw *ah = (struct ath_hw *) hw_priv;
--+	struct ath_common *common = ath9k_hw_common(ah);
--+	struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) common->priv;
--+	u32 rsp_status;
--+	int r;
--+
--+	if (test_bit(HTC_FWFLAG_NO_RMW, &priv->fw_flags))
--+		return;
--+
--+	atomic_dec(&priv->wmi->m_rmw_cnt);
--+
--+	mutex_lock(&priv->wmi->multi_rmw_mutex);
--+
--+	if (priv->wmi->multi_rmw_idx) {
--+		r = ath9k_wmi_cmd(priv->wmi, WMI_REG_RMW_CMDID,
--+			  (u8 *) &priv->wmi->multi_rmw,
--+			  sizeof(struct register_rmw) * priv->wmi->multi_rmw_idx,
--+			  (u8 *) &rsp_status, sizeof(rsp_status),
--+			  100);
--+		if (unlikely(r)) {
--+			ath_dbg(common, WMI,
--+				"REGISTER RMW FAILED, multi len: %d\n",
--+				priv->wmi->multi_rmw_idx);
--+		}
--+		priv->wmi->multi_rmw_idx = 0;
--+	}
-- 
---	val = ath9k_regread(hw_priv, reg_offset);
---	val &= ~clr;
---	val |= set;
---	ath9k_regwrite(hw_priv, val, reg_offset);
--+	mutex_unlock(&priv->wmi->multi_rmw_mutex);
--+}
--+
--+static void ath9k_enable_rmw_buffer(void *hw_priv)
--+{
--+	struct ath_hw *ah = (struct ath_hw *) hw_priv;
--+	struct ath_common *common = ath9k_hw_common(ah);
--+	struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) common->priv;
--+
--+	if (test_bit(HTC_FWFLAG_NO_RMW, &priv->fw_flags))
--+		return;
--+
--+	atomic_inc(&priv->wmi->m_rmw_cnt);
--+}
--+
--+static u32 ath9k_reg_rmw_single(void *hw_priv,
--+				 u32 reg_offset, u32 set, u32 clr)
--+{
--+	struct ath_hw *ah = (struct ath_hw *) hw_priv;
--+	struct ath_common *common = ath9k_hw_common(ah);
--+	struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) common->priv;
--+	struct register_rmw buf, buf_ret;
--+	int ret;
--+	u32 val = 0;
--+
--+	buf.reg = cpu_to_be32(reg_offset);
--+	buf.set = cpu_to_be32(set);
--+	buf.clr = cpu_to_be32(clr);
--+
--+	ret = ath9k_wmi_cmd(priv->wmi, WMI_REG_RMW_CMDID,
--+			  (u8 *) &buf, sizeof(buf),
--+			  (u8 *) &buf_ret, sizeof(buf_ret),
--+			  100);
--+	if (unlikely(ret)) {
--+		ath_dbg(common, WMI, "REGISTER RMW FAILED:(0x%04x, %d)\n",
--+			reg_offset, ret);
--+	}
-- 	return val;
-- }
-- 
--+static u32 ath9k_reg_rmw(void *hw_priv, u32 reg_offset, u32 set, u32 clr)
--+{
--+	struct ath_hw *ah = (struct ath_hw *) hw_priv;
--+	struct ath_common *common = ath9k_hw_common(ah);
--+	struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) common->priv;
--+
--+	if (test_bit(HTC_FWFLAG_NO_RMW, &priv->fw_flags)) {
--+		u32 val;
--+
--+		val = REG_READ(ah, reg_offset);
--+		val &= ~clr;
--+		val |= set;
--+		REG_WRITE(ah, reg_offset, val);
--+
--+		return 0;
--+	}
--+
--+	if (atomic_read(&priv->wmi->m_rmw_cnt))
--+		ath9k_reg_rmw_buffer(hw_priv, reg_offset, set, clr);
--+	else
--+		ath9k_reg_rmw_single(hw_priv, reg_offset, set, clr);
--+
--+	return 0;
--+}
--+
-- static void ath_usb_read_cachesize(struct ath_common *common, int *csz)
-- {
-- 	*csz = L1_CACHE_BYTES >> 2;
--@@ -501,6 +623,8 @@ static int ath9k_init_priv(struct ath9k_
-- 	ah->reg_ops.write = ath9k_regwrite;
-- 	ah->reg_ops.enable_write_buffer = ath9k_enable_regwrite_buffer;
-- 	ah->reg_ops.write_flush = ath9k_regwrite_flush;
--+	ah->reg_ops.enable_rmw_buffer = ath9k_enable_rmw_buffer;
--+	ah->reg_ops.rmw_flush = ath9k_reg_rmw_flush;
-- 	ah->reg_ops.rmw = ath9k_reg_rmw;
-- 	priv->ah = ah;
-- 
--@@ -686,6 +810,12 @@ static int ath9k_init_firmware_version(s
-- 		return -EINVAL;
-- 	}
-- 
--+	if (priv->fw_version_major == 1 && priv->fw_version_minor < 4)
--+		set_bit(HTC_FWFLAG_NO_RMW, &priv->fw_flags);
--+
--+	dev_info(priv->dev, "FW RMW support: %s\n",
--+		test_bit(HTC_FWFLAG_NO_RMW, &priv->fw_flags) ? "Off" : "On");
--+
-- 	return 0;
-- }
-- 
----- a/drivers/net/wireless/ath/ath9k/hw.h
--+++ b/drivers/net/wireless/ath/ath9k/hw.h
--@@ -100,6 +100,18 @@
-- 			(_ah)->reg_ops.write_flush((_ah));	\
-- 	} while (0)
-- 
--+#define ENABLE_REG_RMW_BUFFER(_ah)					\
--+	do {								\
--+		if ((_ah)->reg_ops.enable_rmw_buffer)	\
--+			(_ah)->reg_ops.enable_rmw_buffer((_ah)); \
--+	} while (0)
--+
--+#define REG_RMW_BUFFER_FLUSH(_ah)					\
--+	do {								\
--+		if ((_ah)->reg_ops.rmw_flush)		\
--+			(_ah)->reg_ops.rmw_flush((_ah));	\
--+	} while (0)
--+
-- #define PR_EEP(_s, _val)						\
-- 	do {								\
-- 		len += scnprintf(buf + len, size - len, "%20s : %10d\n",\
----- a/drivers/net/wireless/ath/ath9k/wmi.c
--+++ b/drivers/net/wireless/ath/ath9k/wmi.c
--@@ -61,6 +61,8 @@ static const char *wmi_cmd_to_name(enum
-- 		return "WMI_REG_READ_CMDID";
-- 	case WMI_REG_WRITE_CMDID:
-- 		return "WMI_REG_WRITE_CMDID";
--+	case WMI_REG_RMW_CMDID:
--+		return "WMI_REG_RMW_CMDID";
-- 	case WMI_RC_STATE_CHANGE_CMDID:
-- 		return "WMI_RC_STATE_CHANGE_CMDID";
-- 	case WMI_RC_RATE_UPDATE_CMDID:
--@@ -101,6 +103,7 @@ struct wmi *ath9k_init_wmi(struct ath9k_
-- 	spin_lock_init(&wmi->event_lock);
-- 	mutex_init(&wmi->op_mutex);
-- 	mutex_init(&wmi->multi_write_mutex);
--+	mutex_init(&wmi->multi_rmw_mutex);
-- 	init_completion(&wmi->cmd_wait);
-- 	INIT_LIST_HEAD(&wmi->pending_tx_events);
-- 	tasklet_init(&wmi->wmi_event_tasklet, ath9k_wmi_event_tasklet,
----- a/drivers/net/wireless/ath/ath9k/wmi.h
--+++ b/drivers/net/wireless/ath/ath9k/wmi.h
--@@ -112,6 +112,7 @@ enum wmi_cmd_id {
-- 	WMI_TX_STATS_CMDID,
-- 	WMI_RX_STATS_CMDID,
-- 	WMI_BITRATE_MASK_CMDID,
--+	WMI_REG_RMW_CMDID,
-- };
-- 
-- enum wmi_event_id {
--@@ -125,12 +126,19 @@ enum wmi_event_id {
-- };
-- 
-- #define MAX_CMD_NUMBER 62
--+#define MAX_RMW_CMD_NUMBER 15
-- 
-- struct register_write {
-- 	__be32 reg;
-- 	__be32 val;
-- };
-- 
--+struct register_rmw {
--+	__be32 reg;
--+	__be32 set;
--+	__be32 clr;
--+} __packed;
--+
-- struct ath9k_htc_tx_event {
-- 	int count;
-- 	struct __wmi_event_txstatus txs;
--@@ -156,10 +164,18 @@ struct wmi {
-- 
-- 	spinlock_t wmi_lock;
-- 
--+	/* multi write section */
-- 	atomic_t mwrite_cnt;
-- 	struct register_write multi_write[MAX_CMD_NUMBER];
-- 	u32 multi_write_idx;
-- 	struct mutex multi_write_mutex;
--+
--+	/* multi rmw section */
--+	atomic_t m_rmw_cnt;
--+	struct register_rmw multi_rmw[MAX_RMW_CMD_NUMBER];
--+	u32 multi_rmw_idx;
--+	struct mutex multi_rmw_mutex;
--+
-- };
-- 
-- struct wmi *ath9k_init_wmi(struct ath9k_htc_priv *priv);
-diff --git a/package/kernel/mac80211/patches/319-brcmfmac-consolidate-ifp-lookup-in-driver-core.patch b/package/kernel/mac80211/patches/319-brcmfmac-consolidate-ifp-lookup-in-driver-core.patch
-new file mode 100644
-index 0000000..97444b3
---- /dev/null
-+++ b/package/kernel/mac80211/patches/319-brcmfmac-consolidate-ifp-lookup-in-driver-core.patch
-@@ -0,0 +1,138 @@
-+From: Arend van Spriel <arend@broadcom.com>
-+Date: Wed, 26 Aug 2015 22:14:53 +0200
-+Subject: [PATCH] brcmfmac: consolidate ifp lookup in driver core
-+
-+In rx path the firmware provide an interface index which is used to
-+map to a struct brcmf_if instance. However, this involves some trick
-+that is done in two places. This is changed by having driver core
-+providing brcmf_get_ifp() function.
-+
-+Reviewed-by: Hante Meuleman <meuleman@broadcom.com>
-+Reviewed-by: Franky (Zhenhui) Lin <frankyl@broadcom.com>
-+Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
-+Signed-off-by: Arend van Spriel <arend@broadcom.com>
-+---
-+
-+--- a/drivers/net/wireless/brcm80211/brcmfmac/bcdc.c
-++++ b/drivers/net/wireless/brcm80211/brcmfmac/bcdc.c
-+@@ -276,6 +276,7 @@ brcmf_proto_bcdc_hdrpull(struct brcmf_pu
-+ 			 struct sk_buff *pktbuf)
-+ {
-+ 	struct brcmf_proto_bcdc_header *h;
-++	struct brcmf_if *ifp;
-+ 
-+ 	brcmf_dbg(BCDC, "Enter\n");
-+ 
-+@@ -289,30 +290,21 @@ brcmf_proto_bcdc_hdrpull(struct brcmf_pu
-+ 	trace_brcmf_bcdchdr(pktbuf->data);
-+ 	h = (struct brcmf_proto_bcdc_header *)(pktbuf->data);
-+ 
-+-	*ifidx = BCDC_GET_IF_IDX(h);
-+-	if (*ifidx >= BRCMF_MAX_IFS) {
-+-		brcmf_err("rx data ifnum out of range (%d)\n", *ifidx);
-++	ifp = brcmf_get_ifp(drvr, BCDC_GET_IF_IDX(h));
-++	if (IS_ERR_OR_NULL(ifp)) {
-++		brcmf_dbg(INFO, "no matching ifp found\n");
-+ 		return -EBADE;
-+ 	}
-+-	/* The ifidx is the idx to map to matching netdev/ifp. When receiving
-+-	 * events this is easy because it contains the bssidx which maps
-+-	 * 1-on-1 to the netdev/ifp. But for data frames the ifidx is rcvd.
-+-	 * bssidx 1 is used for p2p0 and no data can be received or
-+-	 * transmitted on it. Therefor bssidx is ifidx + 1 if ifidx > 0
-+-	 */
-+-	if (*ifidx)
-+-		(*ifidx)++;
-+-
-+ 	if (((h->flags & BCDC_FLAG_VER_MASK) >> BCDC_FLAG_VER_SHIFT) !=
-+ 	    BCDC_PROTO_VER) {
-+ 		brcmf_err("%s: non-BCDC packet received, flags 0x%x\n",
-+-			  brcmf_ifname(drvr, *ifidx), h->flags);
-++			  brcmf_ifname(drvr, ifp->ifidx), h->flags);
-+ 		return -EBADE;
-+ 	}
-+ 
-+ 	if (h->flags & BCDC_FLAG_SUM_GOOD) {
-+ 		brcmf_dbg(BCDC, "%s: BDC rcv, good checksum, flags 0x%x\n",
-+-			  brcmf_ifname(drvr, *ifidx), h->flags);
-++			  brcmf_ifname(drvr, ifp->ifidx), h->flags);
-+ 		pktbuf->ip_summed = CHECKSUM_UNNECESSARY;
-+ 	}
-+ 
-+@@ -320,12 +312,15 @@ brcmf_proto_bcdc_hdrpull(struct brcmf_pu
-+ 
-+ 	skb_pull(pktbuf, BCDC_HEADER_LEN);
-+ 	if (do_fws)
-+-		brcmf_fws_hdrpull(drvr, *ifidx, h->data_offset << 2, pktbuf);
-++		brcmf_fws_hdrpull(drvr, ifp->ifidx, h->data_offset << 2,
-++				  pktbuf);
-+ 	else
-+ 		skb_pull(pktbuf, h->data_offset << 2);
-+ 
-+ 	if (pktbuf->len == 0)
-+ 		return -ENODATA;
-++
-++	*ifidx = ifp->ifidx;
-+ 	return 0;
-+ }
-+ 
-+--- a/drivers/net/wireless/brcm80211/brcmfmac/core.c
-++++ b/drivers/net/wireless/brcm80211/brcmfmac/core.c
-+@@ -83,6 +83,25 @@ char *brcmf_ifname(struct brcmf_pub *drv
-+ 	return "<if_none>";
-+ }
-+ 
-++struct brcmf_if *brcmf_get_ifp(struct brcmf_pub *drvr, int ifidx)
-++{
-++	if (ifidx < 0 || ifidx >= BRCMF_MAX_IFS) {
-++		brcmf_err("ifidx %d out of range\n", ifidx);
-++		return ERR_PTR(-ERANGE);
-++	}
-++
-++	/* The ifidx is the idx to map to matching netdev/ifp. When receiving
-++	 * events this is easy because it contains the bssidx which maps
-++	 * 1-on-1 to the netdev/ifp. But for data frames the ifidx is rcvd.
-++	 * bssidx 1 is used for p2p0 and no data can be received or
-++	 * transmitted on it. Therefor bssidx is ifidx + 1 if ifidx > 0
-++	 */
-++	if (ifidx)
-++		ifidx++;
-++
-++	return drvr->iflist[ifidx];
-++}
-++
-+ static void _brcmf_set_multicast_list(struct work_struct *work)
-+ {
-+ 	struct brcmf_if *ifp;
-+--- a/drivers/net/wireless/brcm80211/brcmfmac/core.h
-++++ b/drivers/net/wireless/brcm80211/brcmfmac/core.h
-+@@ -202,7 +202,7 @@ int brcmf_netdev_wait_pend8021x(struct b
-+ 
-+ /* Return pointer to interface name */
-+ char *brcmf_ifname(struct brcmf_pub *drvr, int idx);
-+-
-++struct brcmf_if *brcmf_get_ifp(struct brcmf_pub *drvr, int ifidx);
-+ int brcmf_net_attach(struct brcmf_if *ifp, bool rtnl_locked);
-+ struct brcmf_if *brcmf_add_if(struct brcmf_pub *drvr, s32 bssidx, s32 ifidx,
-+ 			      char *name, u8 *mac_addr);
-+--- a/drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c
-++++ b/drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c
-+@@ -1081,16 +1081,8 @@ brcmf_msgbuf_rx_skb(struct brcmf_msgbuf
-+ {
-+ 	struct brcmf_if *ifp;
-+ 
-+-	/* The ifidx is the idx to map to matching netdev/ifp. When receiving
-+-	 * events this is easy because it contains the bssidx which maps
-+-	 * 1-on-1 to the netdev/ifp. But for data frames the ifidx is rcvd.
-+-	 * bssidx 1 is used for p2p0 and no data can be received or
-+-	 * transmitted on it. Therefor bssidx is ifidx + 1 if ifidx > 0
-+-	 */
-+-	if (ifidx)
-+-		(ifidx)++;
-+-	ifp = msgbuf->drvr->iflist[ifidx];
-+-	if (!ifp || !ifp->ndev) {
-++	ifp = brcmf_get_ifp(msgbuf->drvr, ifidx);
-++	if (IS_ERR_OR_NULL(ifp) || !ifp->ndev) {
-+ 		brcmf_err("Received pkt for invalid ifidx %d\n", ifidx);
-+ 		brcmu_pkt_buf_free_skb(skb);
-+ 		return;
-diff --git a/package/kernel/mac80211/patches/320-ath9k-ar9271_hw_pa_cal-use-defs-instead-of-magin-num.patch b/package/kernel/mac80211/patches/320-ath9k-ar9271_hw_pa_cal-use-defs-instead-of-magin-num.patch
-deleted file mode 100644
-index c4dd1af..0000000
---- a/package/kernel/mac80211/patches/320-ath9k-ar9271_hw_pa_cal-use-defs-instead-of-magin-num.patch
-+++ /dev/null
-@@ -1,89 +0,0 @@
--From: Oleksij Rempel <linux@rempel-privat.de>
--Date: Sun, 22 Mar 2015 19:29:47 +0100
--Subject: [PATCH] ath9k: ar9271_hw_pa_cal - use defs instead of magin
-- numbers
--
--This function uses mixed styles for register names/numbers which
--is make harder reading and optimisation.
--
--Signed-off-by: Oleksij Rempel <linux@rempel-privat.de>
--Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
-----
--
----- a/drivers/net/wireless/ath/ath9k/ar9002_calib.c
--+++ b/drivers/net/wireless/ath/ath9k/ar9002_calib.c
--@@ -430,22 +430,22 @@ static void ar9271_hw_pa_cal(struct ath_
-- 	u32 regVal;
-- 	unsigned int i;
-- 	u32 regList[][2] = {
---		{ 0x786c, 0 },
---		{ 0x7854, 0 },
---		{ 0x7820, 0 },
---		{ 0x7824, 0 },
---		{ 0x7868, 0 },
---		{ 0x783c, 0 },
---		{ 0x7838, 0 } ,
---		{ 0x7828, 0 } ,
--+		{ AR9285_AN_TOP3, 0 },
--+		{ AR9285_AN_RXTXBB1, 0 },
--+		{ AR9285_AN_RF2G1, 0 },
--+		{ AR9285_AN_RF2G2, 0 },
--+		{ AR9285_AN_TOP2, 0 },
--+		{ AR9285_AN_RF2G8, 0 },
--+		{ AR9285_AN_RF2G7, 0 } ,
--+		{ AR9285_AN_RF2G3, 0 } ,
-- 	};
-- 
-- 	for (i = 0; i < ARRAY_SIZE(regList); i++)
-- 		regList[i][1] = REG_READ(ah, regList[i][0]);
-- 
---	regVal = REG_READ(ah, 0x7834);
--+	regVal = REG_READ(ah, AR9285_AN_RF2G6);
-- 	regVal &= (~(0x1));
---	REG_WRITE(ah, 0x7834, regVal);
--+	REG_WRITE(ah, AR9285_AN_RF2G6, regVal);
-- 	regVal = REG_READ(ah, 0x9808);
-- 	regVal |= (0x1 << 27);
-- 	REG_WRITE(ah, 0x9808, regVal);
--@@ -477,7 +477,7 @@ static void ar9271_hw_pa_cal(struct ath_
-- 	 * does not matter since we turn it off
-- 	 */
-- 	REG_RMW_FIELD(ah, AR9285_AN_RF2G7, AR9285_AN_RF2G7_PADRVGN2TAB0, 0);
---
--+	/* 7828, b0-11, ccom=fff */
-- 	REG_RMW_FIELD(ah, AR9285_AN_RF2G3, AR9271_AN_RF2G3_CCOMP, 0xfff);
-- 
-- 	/* Set:
--@@ -490,15 +490,16 @@ static void ar9271_hw_pa_cal(struct ath_
-- 
-- 	/* find off_6_1; */
-- 	for (i = 6; i > 0; i--) {
---		regVal = REG_READ(ah, 0x7834);
--+		regVal = REG_READ(ah, AR9285_AN_RF2G6);
-- 		regVal |= (1 << (20 + i));
---		REG_WRITE(ah, 0x7834, regVal);
--+		REG_WRITE(ah, AR9285_AN_RF2G6, regVal);
-- 		udelay(1);
-- 		/* regVal = REG_READ(ah, 0x7834); */
-- 		regVal &= (~(0x1 << (20 + i)));
---		regVal |= (MS(REG_READ(ah, 0x7840), AR9285_AN_RXTXBB1_SPARE9)
--+		regVal |= (MS(REG_READ(ah, AR9285_AN_RF2G9),
--+			      AR9285_AN_RXTXBB1_SPARE9)
-- 			    << (20 + i));
---		REG_WRITE(ah, 0x7834, regVal);
--+		REG_WRITE(ah, AR9285_AN_RF2G6, regVal);
-- 	}
-- 
-- 	regVal = (regVal >> 20) & 0x7f;
--@@ -517,9 +518,9 @@ static void ar9271_hw_pa_cal(struct ath_
-- 
-- 	ENABLE_REGWRITE_BUFFER(ah);
-- 
---	regVal = REG_READ(ah, 0x7834);
--+	regVal = REG_READ(ah, AR_AN_RF2G1_CH1);
-- 	regVal |= 0x1;
---	REG_WRITE(ah, 0x7834, regVal);
--+	REG_WRITE(ah, AR_AN_RF2G1_CH1, regVal);
-- 	regVal = REG_READ(ah, 0x9808);
-- 	regVal &= (~(0x1 << 27));
-- 	REG_WRITE(ah, 0x9808, regVal);
-diff --git a/package/kernel/mac80211/patches/320-brcmfmac-make-brcmf_proto_hdrpull-return-struct-brcm.patch b/package/kernel/mac80211/patches/320-brcmfmac-make-brcmf_proto_hdrpull-return-struct-brcm.patch
-new file mode 100644
-index 0000000..632714c
---- /dev/null
-+++ b/package/kernel/mac80211/patches/320-brcmfmac-make-brcmf_proto_hdrpull-return-struct-brcm.patch
-@@ -0,0 +1,222 @@
-+From: Arend van Spriel <arend@broadcom.com>
-+Date: Wed, 26 Aug 2015 22:14:54 +0200
-+Subject: [PATCH] brcmfmac: make brcmf_proto_hdrpull() return struct
-+ brcmf_if instance
-+
-+Avoid spreading the ifidx in the driver, but have it return the
-+struct brcmf_if instance.
-+
-+Reviewed-by: Hante Meuleman <meuleman@broadcom.com>
-+Reviewed-by: Franky (Zhenhui) Lin <frankyl@broadcom.com>
-+Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
-+Signed-off-by: Arend van Spriel <arend@broadcom.com>
-+---
-+
-+--- a/drivers/net/wireless/brcm80211/brcmfmac/bcdc.c
-++++ b/drivers/net/wireless/brcm80211/brcmfmac/bcdc.c
-+@@ -272,11 +272,11 @@ brcmf_proto_bcdc_hdrpush(struct brcmf_pu
-+ }
-+ 
-+ static int
-+-brcmf_proto_bcdc_hdrpull(struct brcmf_pub *drvr, bool do_fws, u8 *ifidx,
-+-			 struct sk_buff *pktbuf)
-++brcmf_proto_bcdc_hdrpull(struct brcmf_pub *drvr, bool do_fws,
-++			 struct sk_buff *pktbuf, struct brcmf_if **ifp)
-+ {
-+ 	struct brcmf_proto_bcdc_header *h;
-+-	struct brcmf_if *ifp;
-++	struct brcmf_if *tmp_if;
-+ 
-+ 	brcmf_dbg(BCDC, "Enter\n");
-+ 
-+@@ -290,21 +290,21 @@ brcmf_proto_bcdc_hdrpull(struct brcmf_pu
-+ 	trace_brcmf_bcdchdr(pktbuf->data);
-+ 	h = (struct brcmf_proto_bcdc_header *)(pktbuf->data);
-+ 
-+-	ifp = brcmf_get_ifp(drvr, BCDC_GET_IF_IDX(h));
-+-	if (IS_ERR_OR_NULL(ifp)) {
-++	tmp_if = brcmf_get_ifp(drvr, BCDC_GET_IF_IDX(h));
-++	if (!tmp_if) {
-+ 		brcmf_dbg(INFO, "no matching ifp found\n");
-+ 		return -EBADE;
-+ 	}
-+ 	if (((h->flags & BCDC_FLAG_VER_MASK) >> BCDC_FLAG_VER_SHIFT) !=
-+ 	    BCDC_PROTO_VER) {
-+ 		brcmf_err("%s: non-BCDC packet received, flags 0x%x\n",
-+-			  brcmf_ifname(drvr, ifp->ifidx), h->flags);
-++			  brcmf_ifname(drvr, tmp_if->ifidx), h->flags);
-+ 		return -EBADE;
-+ 	}
-+ 
-+ 	if (h->flags & BCDC_FLAG_SUM_GOOD) {
-+ 		brcmf_dbg(BCDC, "%s: BDC rcv, good checksum, flags 0x%x\n",
-+-			  brcmf_ifname(drvr, ifp->ifidx), h->flags);
-++			  brcmf_ifname(drvr, tmp_if->ifidx), h->flags);
-+ 		pktbuf->ip_summed = CHECKSUM_UNNECESSARY;
-+ 	}
-+ 
-+@@ -312,7 +312,7 @@ brcmf_proto_bcdc_hdrpull(struct brcmf_pu
-+ 
-+ 	skb_pull(pktbuf, BCDC_HEADER_LEN);
-+ 	if (do_fws)
-+-		brcmf_fws_hdrpull(drvr, ifp->ifidx, h->data_offset << 2,
-++		brcmf_fws_hdrpull(drvr, tmp_if->ifidx, h->data_offset << 2,
-+ 				  pktbuf);
-+ 	else
-+ 		skb_pull(pktbuf, h->data_offset << 2);
-+@@ -320,7 +320,7 @@ brcmf_proto_bcdc_hdrpull(struct brcmf_pu
-+ 	if (pktbuf->len == 0)
-+ 		return -ENODATA;
-+ 
-+-	*ifidx = ifp->ifidx;
-++	*ifp = tmp_if;
-+ 	return 0;
-+ }
-+ 
-+--- a/drivers/net/wireless/brcm80211/brcmfmac/core.c
-++++ b/drivers/net/wireless/brcm80211/brcmfmac/core.c
-+@@ -87,7 +87,7 @@ struct brcmf_if *brcmf_get_ifp(struct br
-+ {
-+ 	if (ifidx < 0 || ifidx >= BRCMF_MAX_IFS) {
-+ 		brcmf_err("ifidx %d out of range\n", ifidx);
-+-		return ERR_PTR(-ERANGE);
-++		return NULL;
-+ 	}
-+ 
-+ 	/* The ifidx is the idx to map to matching netdev/ifp. When receiving
-+@@ -539,17 +539,15 @@ void brcmf_rx_frame(struct device *dev,
-+ 	struct brcmf_bus *bus_if = dev_get_drvdata(dev);
-+ 	struct brcmf_pub *drvr = bus_if->drvr;
-+ 	struct brcmf_skb_reorder_data *rd;
-+-	u8 ifidx;
-+ 	int ret;
-+ 
-+ 	brcmf_dbg(DATA, "Enter: %s: rxp=%p\n", dev_name(dev), skb);
-+ 
-+ 	/* process and remove protocol-specific header */
-+-	ret = brcmf_proto_hdrpull(drvr, true, &ifidx, skb);
-+-	ifp = drvr->iflist[ifidx];
-++	ret = brcmf_proto_hdrpull(drvr, true, skb, &ifp);
-+ 
-+ 	if (ret || !ifp || !ifp->ndev) {
-+-		if ((ret != -ENODATA) && ifp)
-++		if (ret != -ENODATA && ifp)
-+ 			ifp->stats.rx_errors++;
-+ 		brcmu_pkt_buf_free_skb(skb);
-+ 		return;
-+@@ -592,17 +590,17 @@ void brcmf_txcomplete(struct device *dev
-+ {
-+ 	struct brcmf_bus *bus_if = dev_get_drvdata(dev);
-+ 	struct brcmf_pub *drvr = bus_if->drvr;
-+-	u8 ifidx;
-++	struct brcmf_if *ifp;
-+ 
-+ 	/* await txstatus signal for firmware if active */
-+ 	if (brcmf_fws_fc_active(drvr->fws)) {
-+ 		if (!success)
-+ 			brcmf_fws_bustxfail(drvr->fws, txp);
-+ 	} else {
-+-		if (brcmf_proto_hdrpull(drvr, false, &ifidx, txp))
-++		if (brcmf_proto_hdrpull(drvr, false, txp, &ifp))
-+ 			brcmu_pkt_buf_free_skb(txp);
-+ 		else
-+-			brcmf_txfinalize(drvr, txp, ifidx, success);
-++			brcmf_txfinalize(drvr, txp, ifp->ifidx, success);
-+ 	}
-+ }
-+ 
-+--- a/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c
-++++ b/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c
-+@@ -1448,7 +1448,7 @@ brcmf_fws_txs_process(struct brcmf_fws_i
-+ 	struct sk_buff *skb;
-+ 	struct brcmf_skbuff_cb *skcb;
-+ 	struct brcmf_fws_mac_descriptor *entry = NULL;
-+-	u8 ifidx;
-++	struct brcmf_if *ifp;
-+ 
-+ 	brcmf_dbg(DATA, "flags %d\n", flags);
-+ 
-+@@ -1497,15 +1497,16 @@ brcmf_fws_txs_process(struct brcmf_fws_i
-+ 	}
-+ 	brcmf_fws_macdesc_return_req_credit(skb);
-+ 
-+-	if (brcmf_proto_hdrpull(fws->drvr, false, &ifidx, skb)) {
-++	ret = brcmf_proto_hdrpull(fws->drvr, false, skb, &ifp);
-++	if (ret) {
-+ 		brcmu_pkt_buf_free_skb(skb);
-+ 		return -EINVAL;
-+ 	}
-+ 	if (!remove_from_hanger)
-+-		ret = brcmf_fws_txstatus_suppressed(fws, fifo, skb, ifidx,
-++		ret = brcmf_fws_txstatus_suppressed(fws, fifo, skb, ifp->ifidx,
-+ 						    genbit, seq);
-+ 	if (remove_from_hanger || ret)
-+-		brcmf_txfinalize(fws->drvr, skb, ifidx, true);
-++		brcmf_txfinalize(fws->drvr, skb, ifp->ifidx, true);
-+ 
-+ 	return 0;
-+ }
-+@@ -1848,7 +1849,7 @@ static int brcmf_fws_commit_skb(struct b
-+ 		entry->transit_count--;
-+ 		if (entry->suppressed)
-+ 			entry->suppr_transit_count--;
-+-		brcmf_proto_hdrpull(fws->drvr, false, &ifidx, skb);
-++		(void)brcmf_proto_hdrpull(fws->drvr, false, skb, NULL);
-+ 		goto rollback;
-+ 	}
-+ 
-+--- a/drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c
-++++ b/drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c
-+@@ -522,7 +522,7 @@ static int brcmf_msgbuf_set_dcmd(struct
-+ 
-+ 
-+ static int brcmf_msgbuf_hdrpull(struct brcmf_pub *drvr, bool do_fws,
-+-				u8 *ifidx, struct sk_buff *skb)
-++				struct sk_buff *skb, struct brcmf_if **ifp)
-+ {
-+ 	return -ENODEV;
-+ }
-+@@ -1082,7 +1082,7 @@ brcmf_msgbuf_rx_skb(struct brcmf_msgbuf
-+ 	struct brcmf_if *ifp;
-+ 
-+ 	ifp = brcmf_get_ifp(msgbuf->drvr, ifidx);
-+-	if (IS_ERR_OR_NULL(ifp) || !ifp->ndev) {
-++	if (!ifp || !ifp->ndev) {
-+ 		brcmf_err("Received pkt for invalid ifidx %d\n", ifidx);
-+ 		brcmu_pkt_buf_free_skb(skb);
-+ 		return;
-+--- a/drivers/net/wireless/brcm80211/brcmfmac/proto.h
-++++ b/drivers/net/wireless/brcm80211/brcmfmac/proto.h
-+@@ -24,8 +24,8 @@ enum proto_addr_mode {
-+ 
-+ 
-+ struct brcmf_proto {
-+-	int (*hdrpull)(struct brcmf_pub *drvr, bool do_fws, u8 *ifidx,
-+-		       struct sk_buff *skb);
-++	int (*hdrpull)(struct brcmf_pub *drvr, bool do_fws,
-++		       struct sk_buff *skb, struct brcmf_if **ifp);
-+ 	int (*query_dcmd)(struct brcmf_pub *drvr, int ifidx, uint cmd,
-+ 			  void *buf, uint len);
-+ 	int (*set_dcmd)(struct brcmf_pub *drvr, int ifidx, uint cmd, void *buf,
-+@@ -46,9 +46,19 @@ int brcmf_proto_attach(struct brcmf_pub
-+ void brcmf_proto_detach(struct brcmf_pub *drvr);
-+ 
-+ static inline int brcmf_proto_hdrpull(struct brcmf_pub *drvr, bool do_fws,
-+-				      u8 *ifidx, struct sk_buff *skb)
-++				      struct sk_buff *skb,
-++				      struct brcmf_if **ifp)
-+ {
-+-	return drvr->proto->hdrpull(drvr, do_fws, ifidx, skb);
-++	struct brcmf_if *tmp = NULL;
-++
-++	/* assure protocol is always called with
-++	 * non-null initialized pointer.
-++	 */
-++	if (ifp)
-++		*ifp = NULL;
-++	else
-++		ifp = &tmp;
-++	return drvr->proto->hdrpull(drvr, do_fws, skb, ifp);
-+ }
-+ static inline int brcmf_proto_query_dcmd(struct brcmf_pub *drvr, int ifidx,
-+ 					 uint cmd, void *buf, uint len)
-diff --git a/package/kernel/mac80211/patches/321-ath9k-ar9271_hw_pa_cal-use-proper-makroses.patch b/package/kernel/mac80211/patches/321-ath9k-ar9271_hw_pa_cal-use-proper-makroses.patch
-deleted file mode 100644
-index f05287d..0000000
---- a/package/kernel/mac80211/patches/321-ath9k-ar9271_hw_pa_cal-use-proper-makroses.patch
-+++ /dev/null
-@@ -1,79 +0,0 @@
--From: Oleksij Rempel <linux@rempel-privat.de>
--Date: Sun, 22 Mar 2015 19:29:48 +0100
--Subject: [PATCH] ath9k: ar9271_hw_pa_cal: use proper makroses.
--
--Signed-off-by: Oleksij Rempel <linux@rempel-privat.de>
--Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
-----
--
----- a/drivers/net/wireless/ath/ath9k/ar9002_calib.c
--+++ b/drivers/net/wireless/ath/ath9k/ar9002_calib.c
--@@ -443,33 +443,30 @@ static void ar9271_hw_pa_cal(struct ath_
-- 	for (i = 0; i < ARRAY_SIZE(regList); i++)
-- 		regList[i][1] = REG_READ(ah, regList[i][0]);
-- 
---	regVal = REG_READ(ah, AR9285_AN_RF2G6);
---	regVal &= (~(0x1));
---	REG_WRITE(ah, AR9285_AN_RF2G6, regVal);
---	regVal = REG_READ(ah, 0x9808);
---	regVal |= (0x1 << 27);
---	REG_WRITE(ah, 0x9808, regVal);
---
--+	/* 7834, b1=0 */
--+	REG_CLR_BIT(ah, AR9285_AN_RF2G6, 1 << 0);
--+	/* 9808, b27=1 */
--+	REG_SET_BIT(ah, 0x9808, 1 << 27);
-- 	/* 786c,b23,1, pwddac=1 */
---	REG_RMW_FIELD(ah, AR9285_AN_TOP3, AR9285_AN_TOP3_PWDDAC, 1);
--+	REG_SET_BIT(ah, AR9285_AN_TOP3, AR9285_AN_TOP3_PWDDAC);
-- 	/* 7854, b5,1, pdrxtxbb=1 */
---	REG_RMW_FIELD(ah, AR9285_AN_RXTXBB1, AR9285_AN_RXTXBB1_PDRXTXBB1, 1);
--+	REG_SET_BIT(ah, AR9285_AN_RXTXBB1, AR9285_AN_RXTXBB1_PDRXTXBB1);
-- 	/* 7854, b7,1, pdv2i=1 */
---	REG_RMW_FIELD(ah, AR9285_AN_RXTXBB1, AR9285_AN_RXTXBB1_PDV2I, 1);
--+	REG_SET_BIT(ah, AR9285_AN_RXTXBB1, AR9285_AN_RXTXBB1_PDV2I);
-- 	/* 7854, b8,1, pddacinterface=1 */
---	REG_RMW_FIELD(ah, AR9285_AN_RXTXBB1, AR9285_AN_RXTXBB1_PDDACIF, 1);
--+	REG_SET_BIT(ah, AR9285_AN_RXTXBB1, AR9285_AN_RXTXBB1_PDDACIF);
-- 	/* 7824,b12,0, offcal=0 */
---	REG_RMW_FIELD(ah, AR9285_AN_RF2G2, AR9285_AN_RF2G2_OFFCAL, 0);
--+	REG_CLR_BIT(ah, AR9285_AN_RF2G2, AR9285_AN_RF2G2_OFFCAL);
-- 	/* 7838, b1,0, pwddb=0 */
---	REG_RMW_FIELD(ah, AR9285_AN_RF2G7, AR9285_AN_RF2G7_PWDDB, 0);
--+	REG_CLR_BIT(ah, AR9285_AN_RF2G7, AR9285_AN_RF2G7_PWDDB);
-- 	/* 7820,b11,0, enpacal=0 */
---	REG_RMW_FIELD(ah, AR9285_AN_RF2G1, AR9285_AN_RF2G1_ENPACAL, 0);
--+	REG_CLR_BIT(ah, AR9285_AN_RF2G1, AR9285_AN_RF2G1_ENPACAL);
-- 	/* 7820,b25,1, pdpadrv1=0 */
---	REG_RMW_FIELD(ah, AR9285_AN_RF2G1, AR9285_AN_RF2G1_PDPADRV1, 0);
--+	REG_CLR_BIT(ah, AR9285_AN_RF2G1, AR9285_AN_RF2G1_PDPADRV1);
-- 	/* 7820,b24,0, pdpadrv2=0 */
---	REG_RMW_FIELD(ah, AR9285_AN_RF2G1, AR9285_AN_RF2G1_PDPADRV2, 0);
--+	REG_CLR_BIT(ah, AR9285_AN_RF2G1, AR9285_AN_RF2G1_PDPADRV2);
-- 	/* 7820,b23,0, pdpaout=0 */
---	REG_RMW_FIELD(ah, AR9285_AN_RF2G1, AR9285_AN_RF2G1_PDPAOUT, 0);
--+	REG_CLR_BIT(ah, AR9285_AN_RF2G1, AR9285_AN_RF2G1_PDPAOUT);
-- 	/* 783c,b14-16,7, padrvgn2tab_0=7 */
-- 	REG_RMW_FIELD(ah, AR9285_AN_RF2G8, AR9285_AN_RF2G8_PADRVGN2TAB0, 7);
-- 	/*
--@@ -516,15 +513,13 @@ static void ar9271_hw_pa_cal(struct ath_
-- 		ah->pacal_info.prev_offset = regVal;
-- 	}
-- 
---	ENABLE_REGWRITE_BUFFER(ah);
-- 
---	regVal = REG_READ(ah, AR_AN_RF2G1_CH1);
---	regVal |= 0x1;
---	REG_WRITE(ah, AR_AN_RF2G1_CH1, regVal);
---	regVal = REG_READ(ah, 0x9808);
---	regVal &= (~(0x1 << 27));
---	REG_WRITE(ah, 0x9808, regVal);
--+	/* 7834, b1=1 */
--+	REG_SET_BIT(ah, AR9285_AN_RF2G6, 1 << 0);
--+	/* 9808, b27=0 */
--+	REG_CLR_BIT(ah, 0x9808, 1 << 27);
-- 
--+	ENABLE_REGWRITE_BUFFER(ah);
-- 	for (i = 0; i < ARRAY_SIZE(regList); i++)
-- 		REG_WRITE(ah, regList[i][0], regList[i][1]);
-- 
-diff --git a/package/kernel/mac80211/patches/321-brcmfmac-change-parameters-for-brcmf_remove_interfac.patch b/package/kernel/mac80211/patches/321-brcmfmac-change-parameters-for-brcmf_remove_interfac.patch
-new file mode 100644
-index 0000000..3360cbc
---- /dev/null
-+++ b/package/kernel/mac80211/patches/321-brcmfmac-change-parameters-for-brcmf_remove_interfac.patch
-@@ -0,0 +1,87 @@
-+From: Arend van Spriel <arend@broadcom.com>
-+Date: Wed, 26 Aug 2015 22:14:55 +0200
-+Subject: [PATCH] brcmfmac: change parameters for
-+ brcmf_remove_interface()
-+
-+Just pass the interface to be removed, ie. the struct brcmf_if instance.
-+
-+Reviewed-by: Hante Meuleman <meuleman@broadcom.com>
-+Reviewed-by: Franky (Zhenhui) Lin <frankyl@broadcom.com>
-+Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
-+Signed-off-by: Arend van Spriel <arend@broadcom.com>
-+---
-+
-+--- a/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c
-++++ b/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c
-+@@ -4983,7 +4983,7 @@ brcmf_notify_connect_status_ap(struct br
-+ 		brcmf_dbg(CONN, "AP mode link down\n");
-+ 		complete(&cfg->vif_disabled);
-+ 		if (ifp->vif->mbss)
-+-			brcmf_remove_interface(ifp->drvr, ifp->bssidx);
-++			brcmf_remove_interface(ifp);
-+ 		return 0;
-+ 	}
-+ 
-+--- a/drivers/net/wireless/brcm80211/brcmfmac/core.c
-++++ b/drivers/net/wireless/brcm80211/brcmfmac/core.c
-+@@ -887,12 +887,13 @@ static void brcmf_del_if(struct brcmf_pu
-+ 	}
-+ }
-+ 
-+-void brcmf_remove_interface(struct brcmf_pub *drvr, u32 bssidx)
-++void brcmf_remove_interface(struct brcmf_if *ifp)
-+ {
-+-	if (drvr->iflist[bssidx]) {
-+-		brcmf_fws_del_interface(drvr->iflist[bssidx]);
-+-		brcmf_del_if(drvr, bssidx);
-+-	}
-++	if (!ifp || WARN_ON(ifp->drvr->iflist[ifp->bssidx] != ifp))
-++		return;
-++
-++	brcmf_fws_del_interface(ifp);
-++	brcmf_del_if(ifp->drvr, ifp->bssidx);
-+ }
-+ 
-+ int brcmf_get_next_free_bsscfgidx(struct brcmf_pub *drvr)
-+@@ -1122,7 +1123,7 @@ void brcmf_detach(struct device *dev)
-+ 
-+ 	/* make sure primary interface removed last */
-+ 	for (i = BRCMF_MAX_IFS-1; i > -1; i--)
-+-		brcmf_remove_interface(drvr, i);
-++		brcmf_remove_interface(drvr->iflist[i]);
-+ 
-+ 	brcmf_cfg80211_detach(drvr->config);
-+ 
-+--- a/drivers/net/wireless/brcm80211/brcmfmac/core.h
-++++ b/drivers/net/wireless/brcm80211/brcmfmac/core.h
-+@@ -206,7 +206,7 @@ struct brcmf_if *brcmf_get_ifp(struct br
-+ int brcmf_net_attach(struct brcmf_if *ifp, bool rtnl_locked);
-+ struct brcmf_if *brcmf_add_if(struct brcmf_pub *drvr, s32 bssidx, s32 ifidx,
-+ 			      char *name, u8 *mac_addr);
-+-void brcmf_remove_interface(struct brcmf_pub *drvr, u32 bssidx);
-++void brcmf_remove_interface(struct brcmf_if *ifp);
-+ int brcmf_get_next_free_bsscfgidx(struct brcmf_pub *drvr);
-+ void brcmf_txflowblock_if(struct brcmf_if *ifp,
-+ 			  enum brcmf_netif_stop_reason reason, bool state);
-+--- a/drivers/net/wireless/brcm80211/brcmfmac/fweh.c
-++++ b/drivers/net/wireless/brcm80211/brcmfmac/fweh.c
-+@@ -222,7 +222,7 @@ static void brcmf_fweh_handle_if_event(s
-+ 	err = brcmf_fweh_call_event_handler(ifp, emsg->event_code, emsg, data);
-+ 
-+ 	if (ifp && ifevent->action == BRCMF_E_IF_DEL)
-+-		brcmf_remove_interface(drvr, ifevent->bssidx);
-++		brcmf_remove_interface(ifp);
-+ }
-+ 
-+ /**
-+--- a/drivers/net/wireless/brcm80211/brcmfmac/p2p.c
-++++ b/drivers/net/wireless/brcm80211/brcmfmac/p2p.c
-+@@ -2140,7 +2140,7 @@ static void brcmf_p2p_delete_p2pdev(stru
-+ {
-+ 	cfg80211_unregister_wdev(&vif->wdev);
-+ 	p2p->bss_idx[P2PAPI_BSSCFG_DEVICE].vif = NULL;
-+-	brcmf_remove_interface(vif->ifp->drvr, vif->ifp->bssidx);
-++	brcmf_remove_interface(vif->ifp);
-+ 	brcmf_free_vif(vif);
-+ }
-+ 
-diff --git a/package/kernel/mac80211/patches/322-ath9k-ar9271_hw_pa_cal-use-RMW-buffer.patch b/package/kernel/mac80211/patches/322-ath9k-ar9271_hw_pa_cal-use-RMW-buffer.patch
-deleted file mode 100644
-index 7247369..0000000
---- a/package/kernel/mac80211/patches/322-ath9k-ar9271_hw_pa_cal-use-RMW-buffer.patch
-+++ /dev/null
-@@ -1,48 +0,0 @@
--From: Oleksij Rempel <linux@rempel-privat.de>
--Date: Sun, 22 Mar 2015 19:29:49 +0100
--Subject: [PATCH] ath9k: ar9271_hw_pa_cal: use RMW buffer
--
--Signed-off-by: Oleksij Rempel <linux@rempel-privat.de>
--Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
-----
--
----- a/drivers/net/wireless/ath/ath9k/ar9002_calib.c
--+++ b/drivers/net/wireless/ath/ath9k/ar9002_calib.c
--@@ -436,13 +436,14 @@ static void ar9271_hw_pa_cal(struct ath_
-- 		{ AR9285_AN_RF2G2, 0 },
-- 		{ AR9285_AN_TOP2, 0 },
-- 		{ AR9285_AN_RF2G8, 0 },
---		{ AR9285_AN_RF2G7, 0 } ,
---		{ AR9285_AN_RF2G3, 0 } ,
--+		{ AR9285_AN_RF2G7, 0 },
--+		{ AR9285_AN_RF2G3, 0 },
-- 	};
-- 
-- 	for (i = 0; i < ARRAY_SIZE(regList); i++)
-- 		regList[i][1] = REG_READ(ah, regList[i][0]);
-- 
--+	ENABLE_REG_RMW_BUFFER(ah);
-- 	/* 7834, b1=0 */
-- 	REG_CLR_BIT(ah, AR9285_AN_RF2G6, 1 << 0);
-- 	/* 9808, b27=1 */
--@@ -476,6 +477,7 @@ static void ar9271_hw_pa_cal(struct ath_
-- 	REG_RMW_FIELD(ah, AR9285_AN_RF2G7, AR9285_AN_RF2G7_PADRVGN2TAB0, 0);
-- 	/* 7828, b0-11, ccom=fff */
-- 	REG_RMW_FIELD(ah, AR9285_AN_RF2G3, AR9271_AN_RF2G3_CCOMP, 0xfff);
--+	REG_RMW_BUFFER_FLUSH(ah);
-- 
-- 	/* Set:
-- 	 * localmode=1,bmode=1,bmoderxtx=1,synthon=1,
--@@ -514,10 +516,12 @@ static void ar9271_hw_pa_cal(struct ath_
-- 	}
-- 
-- 
--+	ENABLE_REG_RMW_BUFFER(ah);
-- 	/* 7834, b1=1 */
-- 	REG_SET_BIT(ah, AR9285_AN_RF2G6, 1 << 0);
-- 	/* 9808, b27=0 */
-- 	REG_CLR_BIT(ah, 0x9808, 1 << 27);
--+	REG_RMW_BUFFER_FLUSH(ah);
-- 
-- 	ENABLE_REGWRITE_BUFFER(ah);
-- 	for (i = 0; i < ARRAY_SIZE(regList); i++)
-diff --git a/package/kernel/mac80211/patches/322-brcmfmac-only-call-brcmf_cfg80211_detach-when-attach.patch b/package/kernel/mac80211/patches/322-brcmfmac-only-call-brcmf_cfg80211_detach-when-attach.patch
-new file mode 100644
-index 0000000..2b61f4e
---- /dev/null
-+++ b/package/kernel/mac80211/patches/322-brcmfmac-only-call-brcmf_cfg80211_detach-when-attach.patch
-@@ -0,0 +1,92 @@
-+From: Arend van Spriel <arend@broadcom.com>
-+Date: Wed, 26 Aug 2015 22:14:56 +0200
-+Subject: [PATCH] brcmfmac: only call brcmf_cfg80211_detach() when attach
-+ was successful
-+
-+In brcmf_bus_start() the function brcmf_cfg80211_attach() is called which
-+may fail. If this happens we should not call brcmf_cfg80211_detach() in
-+the failure path as it will result in NULL pointer dereference:
-+
-+  brcmf_fweh_activate_events: Set event_msgs error (-5)
-+  brcmf_bus_start: failed: -5
-+  brcmf_sdio_firmware_callback: dongle is not responding
-+  BUG: unable to handle kernel NULL pointer dereference at 0000000000000068
-+  IP: [<ffffffff811e8f08>] kernfs_find_ns+0x18/0xd0
-+  PGD 0
-+  Oops: 0000 [#1] SMP
-+  Modules linked in: brcmfmac(O) brcmutil(O) cfg80211 auth_rpcgss
-+  CPU: 1 PID: 45 Comm: kworker/1:1 Tainted: G           O
-+  Hardware name: Dell Inc. Latitude E6410/07XJP9, BIOS A07 02/15/2011
-+  Workqueue: events request_firmware_work_func
-+  task: ffff880036c09ac0 ti: ffff880036dd4000 task.ti: ffff880036dd4000
-+  RIP: 0010:[<ffffffff811e8f08>]  [<ffffffff811e8f08>] kernfs_find_ns+0x18/0xd0
-+  RSP: 0018:ffff880036dd7a28  EFLAGS: 00010246
-+  RAX: ffff880036c09ac0 RBX: 0000000000000000 RCX: 000000007fffffff
-+  RDX: 0000000000000000 RSI: ffffffff816578b9 RDI: 0000000000000000
-+  RBP: ffff880036dd7a48 R08: 0000000000000000 R09: ffff880036c0b340
-+  R10: 00000000000002ec R11: ffff880036dd7b08 R12: ffffffff816578b9
-+  R13: 0000000000000000 R14: ffffffff816578b9 R15: ffff8800c6c87000
-+  FS:  0000000000000000(0000) GS:ffff88012bc40000(0000) knlGS:0000000000000000
-+  CS:  0010 DS: 0000 ES: 0000 CR0: 000000008005003b
-+  CR2: 0000000000000068 CR3: 0000000001a0b000 CR4: 00000000000006e0
-+  Stack:
-+   0000000000000000 ffffffff816578b9 0000000000000000 ffff8800c0d003c8
-+   ffff880036dd7a78 ffffffff811e8ff5 0000000ffffffff1 ffffffff81a9b060
-+   ffff8800c789f880 ffff8800c0d00000 ffff880036dd7a98 ffffffff811ebe0d
-+  Call Trace:
-+   [<ffffffff811e8ff5>] kernfs_find_and_get_ns+0x35/0x60
-+   [<ffffffff811ebe0d>] sysfs_unmerge_group+0x1d/0x60
-+   [<ffffffff81404ef2>] dpm_sysfs_remove+0x22/0x60
-+   [<ffffffff813f9db9>] device_del+0x49/0x240
-+   [<ffffffff815da768>] rfkill_unregister+0x58/0xc0
-+   [<ffffffffa06bd91b>] wiphy_unregister+0xab/0x2f0 [cfg80211]
-+   [<ffffffffa0742fe3>] brcmf_cfg80211_detach+0x23/0x50 [brcmfmac]
-+   [<ffffffffa074d986>] brcmf_detach+0x86/0xe0 [brcmfmac]
-+   [<ffffffffa0757de8>] brcmf_sdio_remove+0x48/0x120 [brcmfmac]
-+   [<ffffffffa0758ed9>] brcmf_sdiod_remove+0x29/0xd0 [brcmfmac]
-+   [<ffffffffa0759031>] brcmf_ops_sdio_remove+0xb1/0x110 [brcmfmac]
-+   [<ffffffffa001c267>] sdio_bus_remove+0x37/0x100 [mmc_core]
-+   [<ffffffff813fe026>] __device_release_driver+0x96/0x130
-+   [<ffffffff813fe0e3>] device_release_driver+0x23/0x30
-+   [<ffffffffa0754bc8>] brcmf_sdio_firmware_callback+0x2a8/0x5d0 [brcmfmac]
-+   [<ffffffffa074deaf>] brcmf_fw_request_nvram_done+0x15f/0x5e0 [brcmfmac]
-+   [<ffffffff8140142f>] ? devres_add+0x3f/0x50
-+   [<ffffffff810642b5>] ? usermodehelper_read_unlock+0x15/0x20
-+   [<ffffffff81400000>] ? platform_match+0x70/0xa0
-+   [<ffffffff8140f400>] request_firmware_work_func+0x30/0x60
-+   [<ffffffff8106828c>] process_one_work+0x14c/0x3d0
-+   [<ffffffff8106862a>] worker_thread+0x11a/0x450
-+   [<ffffffff81068510>] ? process_one_work+0x3d0/0x3d0
-+   [<ffffffff8106d692>] kthread+0xd2/0xf0
-+   [<ffffffff8106d5c0>] ? kthread_create_on_node+0x180/0x180
-+   [<ffffffff815ed35f>] ret_from_fork+0x3f/0x70
-+   [<ffffffff8106d5c0>] ? kthread_create_on_node+0x180/0x180
-+  Code: e9 40 fe ff ff 48 89 d8 eb 87 66 0f 1f 84 00 00 00 00 00 66 66 66 66
-+	90 55 48 89 e5 41 56 49 89 f6 41 55 49 89 d5 31 d2 41 54 53 <0f> b7
-+	47 68 48 8b 5f 48 66 c1 e8 05 83 e0 01 4d 85 ed 0f b6 c8
-+  RIP  [<ffffffff811e8f08>] kernfs_find_ns+0x18/0xd0
-+   RSP <ffff880036dd7a28>
-+  CR2: 0000000000000068
-+  ---[ end trace 87d6ec0d3fe46740 ]---
-+
-+Reported-by: Daniel (Deognyoun) Kim <dekim@broadcom.com>
-+Reviewed-by: Hante Meuleman <meuleman@broadcom.com>
-+Reviewed-by: Franky (Zhenhui) Lin <frankyl@broadcom.com>
-+Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
-+Signed-off-by: Arend van Spriel <arend@broadcom.com>
-+---
-+
-+--- a/drivers/net/wireless/brcm80211/brcmfmac/core.c
-++++ b/drivers/net/wireless/brcm80211/brcmfmac/core.c
-+@@ -1049,7 +1049,10 @@ int brcmf_bus_start(struct device *dev)
-+ fail:
-+ 	if (ret < 0) {
-+ 		brcmf_err("failed: %d\n", ret);
-+-		brcmf_cfg80211_detach(drvr->config);
-++		if (drvr->config) {
-++			brcmf_cfg80211_detach(drvr->config);
-++			drvr->config = NULL;
-++		}
-+ 		if (drvr->fws) {
-+ 			brcmf_fws_del_interface(ifp);
-+ 			brcmf_fws_deinit(drvr);
-diff --git a/package/kernel/mac80211/patches/323-ath9k-add-multi_read-to-be-compatible-with-ath9k_htc.patch b/package/kernel/mac80211/patches/323-ath9k-add-multi_read-to-be-compatible-with-ath9k_htc.patch
-deleted file mode 100644
-index 246bb9d..0000000
---- a/package/kernel/mac80211/patches/323-ath9k-add-multi_read-to-be-compatible-with-ath9k_htc.patch
-+++ /dev/null
-@@ -1,35 +0,0 @@
--From: Oleksij Rempel <linux@rempel-privat.de>
--Date: Sun, 22 Mar 2015 19:29:50 +0100
--Subject: [PATCH] ath9k: add multi_read to be compatible with ath9k_htc
--
--Signed-off-by: Oleksij Rempel <linux@rempel-privat.de>
--Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
-----
--
----- a/drivers/net/wireless/ath/ath9k/init.c
--+++ b/drivers/net/wireless/ath/ath9k/init.c
--@@ -141,6 +141,16 @@ static unsigned int ath9k_ioread32(void
-- 	return val;
-- }
-- 
--+static void ath9k_multi_ioread32(void *hw_priv, u32 *addr,
--+                                u32 *val, u16 count)
--+{
--+	int i;
--+
--+	for (i = 0; i < count; i++)
--+		val[i] = ath9k_ioread32(hw_priv, addr[i]);
--+}
--+
--+
-- static unsigned int __ath9k_reg_rmw(struct ath_softc *sc, u32 reg_offset,
-- 				    u32 set, u32 clr)
-- {
--@@ -530,6 +540,7 @@ static int ath9k_init_softc(u16 devid, s
-- 	ah->hw = sc->hw;
-- 	ah->hw_version.devid = devid;
-- 	ah->reg_ops.read = ath9k_ioread32;
--+	ah->reg_ops.multi_read = ath9k_multi_ioread32;
-- 	ah->reg_ops.write = ath9k_iowrite32;
-- 	ah->reg_ops.rmw = ath9k_reg_rmw;
-- 	pCap = &ah->caps;
-diff --git a/package/kernel/mac80211/patches/323-brcmfmac-correct-detection-of-p2pdev-interface-event.patch b/package/kernel/mac80211/patches/323-brcmfmac-correct-detection-of-p2pdev-interface-event.patch
-new file mode 100644
-index 0000000..868b0a8
---- /dev/null
-+++ b/package/kernel/mac80211/patches/323-brcmfmac-correct-detection-of-p2pdev-interface-event.patch
-@@ -0,0 +1,105 @@
-+From: Arend van Spriel <arend@broadcom.com>
-+Date: Wed, 26 Aug 2015 22:14:57 +0200
-+Subject: [PATCH] brcmfmac: correct detection of p2pdev interface event
-+
-+The p2pdev interface is setup in firmware resulting in a interface
-+event. This event has role and no-if flag. When role is p2p client
-+and no-if flag is set it indicates that this is the p2pdev interface.
-+This info is used in handling the event and adding interface in the
-+driver.
-+
-+Reviewed-by: Hante Meuleman <meuleman@broadcom.com>
-+Reviewed-by: Franky (Zhenhui) Lin <frankyl@broadcom.com>
-+Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
-+Signed-off-by: Arend van Spriel <arend@broadcom.com>
-+---
-+
-+--- a/drivers/net/wireless/brcm80211/brcmfmac/core.c
-++++ b/drivers/net/wireless/brcm80211/brcmfmac/core.c
-+@@ -795,7 +795,7 @@ fail:
-+ }
-+ 
-+ struct brcmf_if *brcmf_add_if(struct brcmf_pub *drvr, s32 bssidx, s32 ifidx,
-+-			      char *name, u8 *mac_addr)
-++			      bool is_p2pdev, char *name, u8 *mac_addr)
-+ {
-+ 	struct brcmf_if *ifp;
-+ 	struct net_device *ndev;
-+@@ -821,7 +821,7 @@ struct brcmf_if *brcmf_add_if(struct brc
-+ 		}
-+ 	}
-+ 
-+-	if (!brcmf_p2p_enable && bssidx == 1) {
-++	if (!brcmf_p2p_enable && is_p2pdev) {
-+ 		/* this is P2P_DEVICE interface */
-+ 		brcmf_dbg(INFO, "allocate non-netdev interface\n");
-+ 		ifp = kzalloc(sizeof(*ifp), GFP_KERNEL);
-+@@ -999,12 +999,12 @@ int brcmf_bus_start(struct device *dev)
-+ 	brcmf_dbg(TRACE, "\n");
-+ 
-+ 	/* add primary networking interface */
-+-	ifp = brcmf_add_if(drvr, 0, 0, "wlan%d", NULL);
-++	ifp = brcmf_add_if(drvr, 0, 0, false, "wlan%d", NULL);
-+ 	if (IS_ERR(ifp))
-+ 		return PTR_ERR(ifp);
-+ 
-+ 	if (brcmf_p2p_enable)
-+-		p2p_ifp = brcmf_add_if(drvr, 1, 0, "p2p%d", NULL);
-++		p2p_ifp = brcmf_add_if(drvr, 1, 0, false, "p2p%d", NULL);
-+ 	else
-+ 		p2p_ifp = NULL;
-+ 	if (IS_ERR(p2p_ifp))
-+--- a/drivers/net/wireless/brcm80211/brcmfmac/core.h
-++++ b/drivers/net/wireless/brcm80211/brcmfmac/core.h
-+@@ -205,7 +205,7 @@ char *brcmf_ifname(struct brcmf_pub *drv
-+ struct brcmf_if *brcmf_get_ifp(struct brcmf_pub *drvr, int ifidx);
-+ int brcmf_net_attach(struct brcmf_if *ifp, bool rtnl_locked);
-+ struct brcmf_if *brcmf_add_if(struct brcmf_pub *drvr, s32 bssidx, s32 ifidx,
-+-			      char *name, u8 *mac_addr);
-++			      bool is_p2pdev, char *name, u8 *mac_addr);
-+ void brcmf_remove_interface(struct brcmf_if *ifp);
-+ int brcmf_get_next_free_bsscfgidx(struct brcmf_pub *drvr);
-+ void brcmf_txflowblock_if(struct brcmf_if *ifp,
-+--- a/drivers/net/wireless/brcm80211/brcmfmac/fweh.c
-++++ b/drivers/net/wireless/brcm80211/brcmfmac/fweh.c
-+@@ -179,6 +179,7 @@ static void brcmf_fweh_handle_if_event(s
-+ {
-+ 	struct brcmf_if_event *ifevent = data;
-+ 	struct brcmf_if *ifp;
-++	bool is_p2pdev;
-+ 	int err = 0;
-+ 
-+ 	brcmf_dbg(EVENT, "action: %u idx: %u bsscfg: %u flags: %u role: %u\n",
-+@@ -186,18 +187,16 @@ static void brcmf_fweh_handle_if_event(s
-+ 		  ifevent->flags, ifevent->role);
-+ 
-+ 	/* The P2P Device interface event must not be ignored
-+-	 * contrary to what firmware tells us. The only way to
-+-	 * distinguish the P2P Device is by looking at the ifidx
-+-	 * and bssidx received.
-++	 * contrary to what firmware tells us.
-+ 	 */
-+-	if (!(ifevent->ifidx == 0 && ifevent->bssidx == 1) &&
-+-	    (ifevent->flags & BRCMF_E_IF_FLAG_NOIF)) {
-++	is_p2pdev = (ifevent->flags & BRCMF_E_IF_FLAG_NOIF) &&
-++		    ifevent->role == BRCMF_E_IF_ROLE_P2P_CLIENT;
-++	if (!is_p2pdev && (ifevent->flags & BRCMF_E_IF_FLAG_NOIF)) {
-+ 		brcmf_dbg(EVENT, "event can be ignored\n");
-+ 		return;
-+ 	}
-+ 	if (ifevent->ifidx >= BRCMF_MAX_IFS) {
-+-		brcmf_err("invalid interface index: %u\n",
-+-			  ifevent->ifidx);
-++		brcmf_err("invalid interface index: %u\n", ifevent->ifidx);
-+ 		return;
-+ 	}
-+ 
-+@@ -207,7 +206,7 @@ static void brcmf_fweh_handle_if_event(s
-+ 		brcmf_dbg(EVENT, "adding %s (%pM)\n", emsg->ifname,
-+ 			  emsg->addr);
-+ 		ifp = brcmf_add_if(drvr, ifevent->bssidx, ifevent->ifidx,
-+-				   emsg->ifname, emsg->addr);
-++				   is_p2pdev, emsg->ifname, emsg->addr);
-+ 		if (IS_ERR(ifp))
-+ 			return;
-+ 		brcmf_fws_add_interface(ifp);
-diff --git a/package/kernel/mac80211/patches/324-ath9k-add-new-function-ath9k_hw_read_array.patch b/package/kernel/mac80211/patches/324-ath9k-add-new-function-ath9k_hw_read_array.patch
-deleted file mode 100644
-index 2eda1c9..0000000
---- a/package/kernel/mac80211/patches/324-ath9k-add-new-function-ath9k_hw_read_array.patch
-+++ /dev/null
-@@ -1,69 +0,0 @@
--From: Oleksij Rempel <linux@rempel-privat.de>
--Date: Sun, 22 Mar 2015 19:29:51 +0100
--Subject: [PATCH] ath9k: add new function ath9k_hw_read_array
--
--REG_READ generate most overhead on usb bus. It send and read micro packages
--and reduce usb bandwidth. To reduce this overhead we should read in batches.
--
--Signed-off-by: Oleksij Rempel <linux@rempel-privat.de>
--Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
-----
--
----- a/drivers/net/wireless/ath/ath9k/hw.c
--+++ b/drivers/net/wireless/ath/ath9k/hw.c
--@@ -121,6 +121,36 @@ void ath9k_hw_write_array(struct ath_hw
-- 	REGWRITE_BUFFER_FLUSH(ah);
-- }
-- 
--+void ath9k_hw_read_array(struct ath_hw *ah, u32 array[][2], int size)
--+{
--+	u32 *tmp_reg_list, *tmp_data;
--+	int i;
--+
--+	tmp_reg_list = kmalloc(size * sizeof(u32), GFP_KERNEL);
--+	if (!tmp_reg_list) {
--+		dev_err(ah->dev, "%s: tmp_reg_list: alloc filed\n", __func__);
--+		return;
--+	}
--+
--+	tmp_data = kmalloc(size * sizeof(u32), GFP_KERNEL);
--+	if (!tmp_data) {
--+		dev_err(ah->dev, "%s tmp_data: alloc filed\n", __func__);
--+		goto error_tmp_data;
--+	}
--+
--+	for (i = 0; i < size; i++)
--+		tmp_reg_list[i] = array[i][0];
--+
--+	REG_READ_MULTI(ah, tmp_reg_list, tmp_data, size);
--+
--+	for (i = 0; i < size; i++)
--+		array[i][1] = tmp_data[i];
--+
--+	kfree(tmp_data);
--+error_tmp_data:
--+	kfree(tmp_reg_list);
--+}
--+
-- u32 ath9k_hw_reverse_bits(u32 val, u32 n)
-- {
-- 	u32 retval;
----- a/drivers/net/wireless/ath/ath9k/hw.h
--+++ b/drivers/net/wireless/ath/ath9k/hw.h
--@@ -138,6 +138,8 @@
-- 
-- #define REG_WRITE_ARRAY(iniarray, column, regWr) \
-- 	ath9k_hw_write_array(ah, iniarray, column, &(regWr))
--+#define REG_READ_ARRAY(ah, array, size) \
--+	ath9k_hw_read_array(ah, array, size)
-- 
-- #define AR_GPIO_OUTPUT_MUX_AS_OUTPUT             0
-- #define AR_GPIO_OUTPUT_MUX_AS_PCIE_ATTENTION_LED 1
--@@ -1020,6 +1022,7 @@ void ath9k_hw_synth_delay(struct ath_hw
-- bool ath9k_hw_wait(struct ath_hw *ah, u32 reg, u32 mask, u32 val, u32 timeout);
-- void ath9k_hw_write_array(struct ath_hw *ah, const struct ar5416IniArray *array,
-- 			  int column, unsigned int *writecnt);
--+void ath9k_hw_read_array(struct ath_hw *ah, u32 array[][2], int size);
-- u32 ath9k_hw_reverse_bits(u32 val, u32 n);
-- u16 ath9k_hw_computetxtime(struct ath_hw *ah,
-- 			   u8 phy, int kbps,
-diff --git a/package/kernel/mac80211/patches/324-brcmfmac-use-brcmf_get_ifp-to-map-ifidx-to-struct-br.patch b/package/kernel/mac80211/patches/324-brcmfmac-use-brcmf_get_ifp-to-map-ifidx-to-struct-br.patch
-new file mode 100644
-index 0000000..abd6681
---- /dev/null
-+++ b/package/kernel/mac80211/patches/324-brcmfmac-use-brcmf_get_ifp-to-map-ifidx-to-struct-br.patch
-@@ -0,0 +1,126 @@
-+From: Arend van Spriel <arend@broadcom.com>
-+Date: Wed, 26 Aug 2015 22:14:58 +0200
-+Subject: [PATCH] brcmfmac: use brcmf_get_ifp() to map ifidx to struct
-+ brcmf_if instance
-+
-+The knowledge on how to map the interface index to a struct brcmf_if
-+instance is in brcmf_get_ifp() so use that function when only the
-+interface index is known instead of accessing brcmf_pub::iflist
-+directly.
-+
-+Reviewed-by: Hante Meuleman <meuleman@broadcom.com>
-+Reviewed-by: Franky (Zhenhui) Lin <frankyl@broadcom.com>
-+Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
-+Signed-off-by: Arend van Spriel <arend@broadcom.com>
-+---
-+
-+--- a/drivers/net/wireless/brcm80211/brcmfmac/btcoex.c
-++++ b/drivers/net/wireless/brcm80211/brcmfmac/btcoex.c
-+@@ -149,7 +149,7 @@ static s32 brcmf_btcoex_params_read(stru
-+ static void brcmf_btcoex_boost_wifi(struct brcmf_btcoex_info *btci,
-+ 				    bool trump_sco)
-+ {
-+-	struct brcmf_if *ifp = btci->cfg->pub->iflist[0];
-++	struct brcmf_if *ifp = brcmf_get_ifp(btci->cfg->pub, 0);
-+ 
-+ 	if (trump_sco && !btci->saved_regs_part2) {
-+ 		/* this should reduce eSCO agressive
-+@@ -468,7 +468,7 @@ int brcmf_btcoex_set_mode(struct brcmf_c
-+ {
-+ 	struct brcmf_cfg80211_info *cfg = wiphy_priv(vif->wdev.wiphy);
-+ 	struct brcmf_btcoex_info *btci = cfg->btcoex;
-+-	struct brcmf_if *ifp = cfg->pub->iflist[0];
-++	struct brcmf_if *ifp = brcmf_get_ifp(cfg->pub, 0);
-+ 
-+ 	switch (mode) {
-+ 	case BRCMF_BTCOEX_DISABLED:
-+--- a/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c
-++++ b/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c
-+@@ -6213,7 +6213,7 @@ static void brcmf_free_wiphy(struct wiph
-+ struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct brcmf_pub *drvr,
-+ 						  struct device *busdev)
-+ {
-+-	struct net_device *ndev = drvr->iflist[0]->ndev;
-++	struct net_device *ndev = brcmf_get_ifp(drvr, 0)->ndev;
-+ 	struct brcmf_cfg80211_info *cfg;
-+ 	struct wiphy *wiphy;
-+ 	struct brcmf_cfg80211_vif *vif;
-+--- a/drivers/net/wireless/brcm80211/brcmfmac/feature.c
-++++ b/drivers/net/wireless/brcm80211/brcmfmac/feature.c
-+@@ -121,7 +121,7 @@ static void brcmf_feat_iovar_int_set(str
-+ 
-+ void brcmf_feat_attach(struct brcmf_pub *drvr)
-+ {
-+-	struct brcmf_if *ifp = drvr->iflist[0];
-++	struct brcmf_if *ifp = brcmf_get_ifp(drvr, 0);
-+ 
-+ 	brcmf_feat_iovar_int_get(ifp, BRCMF_FEAT_MCHAN, "mchan");
-+ 	brcmf_feat_iovar_int_get(ifp, BRCMF_FEAT_PNO, "pfn");
-+--- a/drivers/net/wireless/brcm80211/brcmfmac/flowring.c
-++++ b/drivers/net/wireless/brcm80211/brcmfmac/flowring.c
-+@@ -221,7 +221,7 @@ static void brcmf_flowring_block(struct
-+ 
-+ 	bus_if = dev_get_drvdata(flow->dev);
-+ 	drvr = bus_if->drvr;
-+-	ifp = drvr->iflist[ifidx];
-++	ifp = brcmf_get_ifp(drvr, ifidx);
-+ 	brcmf_txflowblock_if(ifp, BRCMF_NETIF_STOP_REASON_FLOW, blocked);
-+ 
-+ 	spin_unlock_irqrestore(&flow->block_lock, flags);
-+--- a/drivers/net/wireless/brcm80211/brcmfmac/fweh.c
-++++ b/drivers/net/wireless/brcm80211/brcmfmac/fweh.c
-+@@ -334,7 +334,7 @@ void brcmf_fweh_attach(struct brcmf_pub
-+ void brcmf_fweh_detach(struct brcmf_pub *drvr)
-+ {
-+ 	struct brcmf_fweh_info *fweh = &drvr->fweh;
-+-	struct brcmf_if *ifp = drvr->iflist[0];
-++	struct brcmf_if *ifp = brcmf_get_ifp(drvr, 0);
-+ 	s8 eventmask[BRCMF_EVENTING_MASK_LEN];
-+ 
-+ 	if (ifp) {
-+--- a/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c
-++++ b/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c
-+@@ -972,7 +972,7 @@ static void
-+ brcmf_fws_flow_control_check(struct brcmf_fws_info *fws, struct pktq *pq,
-+ 			     u8 if_id)
-+ {
-+-	struct brcmf_if *ifp = fws->drvr->iflist[!if_id ? 0 : if_id + 1];
-++	struct brcmf_if *ifp = brcmf_get_ifp(fws->drvr, if_id);
-+ 
-+ 	if (WARN_ON(!ifp))
-+ 		return;
-+@@ -2118,6 +2118,7 @@ static int brcmf_debugfs_fws_stats_read(
-+ int brcmf_fws_init(struct brcmf_pub *drvr)
-+ {
-+ 	struct brcmf_fws_info *fws;
-++	struct brcmf_if *ifp;
-+ 	u32 tlv = BRCMF_FWS_FLAGS_RSSI_SIGNALS;
-+ 	int rc;
-+ 	u32 mode;
-+@@ -2177,21 +2178,22 @@ int brcmf_fws_init(struct brcmf_pub *drv
-+ 	 * continue. Set mode back to none indicating not enabled.
-+ 	 */
-+ 	fws->fw_signals = true;
-+-	if (brcmf_fil_iovar_int_set(drvr->iflist[0], "tlv", tlv)) {
-++	ifp = brcmf_get_ifp(drvr, 0);
-++	if (brcmf_fil_iovar_int_set(ifp, "tlv", tlv)) {
-+ 		brcmf_err("failed to set bdcv2 tlv signaling\n");
-+ 		fws->fcmode = BRCMF_FWS_FCMODE_NONE;
-+ 		fws->fw_signals = false;
-+ 	}
-+ 
-+-	if (brcmf_fil_iovar_int_set(drvr->iflist[0], "ampdu_hostreorder", 1))
-++	if (brcmf_fil_iovar_int_set(ifp, "ampdu_hostreorder", 1))
-+ 		brcmf_dbg(INFO, "enabling AMPDU host-reorder failed\n");
-+ 
-+ 	/* Enable seq number reuse, if supported */
-+-	if (brcmf_fil_iovar_int_get(drvr->iflist[0], "wlfc_mode", &mode) == 0) {
-++	if (brcmf_fil_iovar_int_get(ifp, "wlfc_mode", &mode) == 0) {
-+ 		if (BRCMF_FWS_MODE_GET_REUSESEQ(mode)) {
-+ 			mode = 0;
-+ 			BRCMF_FWS_MODE_SET_REUSESEQ(mode, 1);
-+-			if (brcmf_fil_iovar_int_set(drvr->iflist[0],
-++			if (brcmf_fil_iovar_int_set(ifp,
-+ 						    "wlfc_mode", mode) == 0) {
-+ 				BRCMF_FWS_MODE_SET_REUSESEQ(fws->mode, 1);
-+ 			}
-diff --git a/package/kernel/mac80211/patches/325-ath9k-ar9271_hw_pa_cal-use-REG_READ_ARRAY.patch b/package/kernel/mac80211/patches/325-ath9k-ar9271_hw_pa_cal-use-REG_READ_ARRAY.patch
-deleted file mode 100644
-index 4e4888f..0000000
---- a/package/kernel/mac80211/patches/325-ath9k-ar9271_hw_pa_cal-use-REG_READ_ARRAY.patch
-+++ /dev/null
-@@ -1,24 +0,0 @@
--From: Oleksij Rempel <linux@rempel-privat.de>
--Date: Sun, 22 Mar 2015 19:29:52 +0100
--Subject: [PATCH] ath9k: ar9271_hw_pa_cal: use REG_READ_ARRAY
--
--insted of reading each register separatly
--and waste 4ms on each operation, we can
--use one shot read.
--
--Signed-off-by: Oleksij Rempel <linux@rempel-privat.de>
--Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
-----
--
----- a/drivers/net/wireless/ath/ath9k/ar9002_calib.c
--+++ b/drivers/net/wireless/ath/ath9k/ar9002_calib.c
--@@ -440,8 +440,7 @@ static void ar9271_hw_pa_cal(struct ath_
-- 		{ AR9285_AN_RF2G3, 0 },
-- 	};
-- 
---	for (i = 0; i < ARRAY_SIZE(regList); i++)
---		regList[i][1] = REG_READ(ah, regList[i][0]);
--+	REG_READ_ARRAY(ah, regList, ARRAY_SIZE(regList));
-- 
-- 	ENABLE_REG_RMW_BUFFER(ah);
-- 	/* 7834, b1=0 */
-diff --git a/package/kernel/mac80211/patches/325-brcmfmac-pass-struct-brcmf_if-instance-in-brcmf_txfi.patch b/package/kernel/mac80211/patches/325-brcmfmac-pass-struct-brcmf_if-instance-in-brcmf_txfi.patch
-new file mode 100644
-index 0000000..23a7b6f
---- /dev/null
-+++ b/package/kernel/mac80211/patches/325-brcmfmac-pass-struct-brcmf_if-instance-in-brcmf_txfi.patch
-@@ -0,0 +1,122 @@
-+From: Arend van Spriel <arend@broadcom.com>
-+Date: Wed, 26 Aug 2015 22:14:59 +0200
-+Subject: [PATCH] brcmfmac: pass struct brcmf_if instance in
-+ brcmf_txfinalize()
-+
-+Most call sites of brcmf_txfinalize already have struct brcmf_if
-+instance so pass that to brcmf_txfinalize() as the function
-+needs it anyway.
-+
-+Reviewed-by: Hante Meuleman <meuleman@broadcom.com>
-+Reviewed-by: Franky (Zhenhui) Lin <frankyl@broadcom.com>
-+Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
-+Signed-off-by: Arend van Spriel <arend@broadcom.com>
-+---
-+
-+--- a/drivers/net/wireless/brcm80211/brcmfmac/core.c
-++++ b/drivers/net/wireless/brcm80211/brcmfmac/core.c
-+@@ -560,17 +560,11 @@ void brcmf_rx_frame(struct device *dev,
-+ 		brcmf_netif_rx(ifp, skb);
-+ }
-+ 
-+-void brcmf_txfinalize(struct brcmf_pub *drvr, struct sk_buff *txp, u8 ifidx,
-+-		      bool success)
-++void brcmf_txfinalize(struct brcmf_if *ifp, struct sk_buff *txp, bool success)
-+ {
-+-	struct brcmf_if *ifp;
-+ 	struct ethhdr *eh;
-+ 	u16 type;
-+ 
-+-	ifp = drvr->iflist[ifidx];
-+-	if (!ifp)
-+-		goto done;
-+-
-+ 	eh = (struct ethhdr *)(txp->data);
-+ 	type = ntohs(eh->h_proto);
-+ 
-+@@ -582,7 +576,7 @@ void brcmf_txfinalize(struct brcmf_pub *
-+ 
-+ 	if (!success)
-+ 		ifp->stats.tx_errors++;
-+-done:
-++
-+ 	brcmu_pkt_buf_free_skb(txp);
-+ }
-+ 
-+@@ -600,7 +594,7 @@ void brcmf_txcomplete(struct device *dev
-+ 		if (brcmf_proto_hdrpull(drvr, false, txp, &ifp))
-+ 			brcmu_pkt_buf_free_skb(txp);
-+ 		else
-+-			brcmf_txfinalize(drvr, txp, ifp->ifidx, success);
-++			brcmf_txfinalize(ifp, txp, success);
-+ 	}
-+ }
-+ 
-+--- a/drivers/net/wireless/brcm80211/brcmfmac/core.h
-++++ b/drivers/net/wireless/brcm80211/brcmfmac/core.h
-+@@ -210,8 +210,7 @@ void brcmf_remove_interface(struct brcmf
-+ int brcmf_get_next_free_bsscfgidx(struct brcmf_pub *drvr);
-+ void brcmf_txflowblock_if(struct brcmf_if *ifp,
-+ 			  enum brcmf_netif_stop_reason reason, bool state);
-+-void brcmf_txfinalize(struct brcmf_pub *drvr, struct sk_buff *txp, u8 ifidx,
-+-		      bool success);
-++void brcmf_txfinalize(struct brcmf_if *ifp, struct sk_buff *txp, bool success);
-+ void brcmf_netif_rx(struct brcmf_if *ifp, struct sk_buff *skb);
-+ 
-+ /* Sets dongle media info (drv_version, mac address). */
-+--- a/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c
-++++ b/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c
-+@@ -1506,7 +1506,7 @@ brcmf_fws_txs_process(struct brcmf_fws_i
-+ 		ret = brcmf_fws_txstatus_suppressed(fws, fifo, skb, ifp->ifidx,
-+ 						    genbit, seq);
-+ 	if (remove_from_hanger || ret)
-+-		brcmf_txfinalize(fws->drvr, skb, ifp->ifidx, true);
-++		brcmf_txfinalize(ifp, skb, true);
-+ 
-+ 	return 0;
-+ }
-+@@ -1905,7 +1905,7 @@ int brcmf_fws_process_skb(struct brcmf_i
-+ 	if (fws->avoid_queueing) {
-+ 		rc = brcmf_proto_txdata(drvr, ifp->ifidx, 0, skb);
-+ 		if (rc < 0)
-+-			brcmf_txfinalize(drvr, skb, ifp->ifidx, false);
-++			brcmf_txfinalize(ifp, skb, false);
-+ 		return rc;
-+ 	}
-+ 
-+@@ -1929,7 +1929,7 @@ int brcmf_fws_process_skb(struct brcmf_i
-+ 		brcmf_fws_schedule_deq(fws);
-+ 	} else {
-+ 		brcmf_err("drop skb: no hanger slot\n");
-+-		brcmf_txfinalize(drvr, skb, ifp->ifidx, false);
-++		brcmf_txfinalize(ifp, skb, false);
-+ 		rc = -ENOMEM;
-+ 	}
-+ 	brcmf_fws_unlock(fws);
-+@@ -2009,8 +2009,9 @@ static void brcmf_fws_dequeue_worker(str
-+ 				ret = brcmf_proto_txdata(drvr, ifidx, 0, skb);
-+ 				brcmf_fws_lock(fws);
-+ 				if (ret < 0)
-+-					brcmf_txfinalize(drvr, skb, ifidx,
-+-							 false);
-++					brcmf_txfinalize(brcmf_get_ifp(drvr,
-++								       ifidx),
-++							 skb, false);
-+ 				if (fws->bus_flow_blocked)
-+ 					break;
-+ 			}
-+--- a/drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c
-++++ b/drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c
-+@@ -873,7 +873,11 @@ brcmf_msgbuf_process_txstatus(struct brc
-+ 	commonring = msgbuf->flowrings[flowid];
-+ 	atomic_dec(&commonring->outstanding_tx);
-+ 
-+-	brcmf_txfinalize(msgbuf->drvr, skb, tx_status->msg.ifidx, true);
-++	/* Hante: i believe this was a bug as tx_status->msg.ifidx was used
-++	 * in brcmf_txfinalize as index in drvr->iflist. Can you confirm/deny?
-++	 */
-++	brcmf_txfinalize(brcmf_get_ifp(msgbuf->drvr, tx_status->msg.ifidx),
-++			 skb, true);
-+ }
-+ 
-+ 
-diff --git a/package/kernel/mac80211/patches/326-ath9k-use-one-shot-read-in-ath9k_hw_update_mibstats.patch b/package/kernel/mac80211/patches/326-ath9k-use-one-shot-read-in-ath9k_hw_update_mibstats.patch
-deleted file mode 100644
-index a22cd1d..0000000
---- a/package/kernel/mac80211/patches/326-ath9k-use-one-shot-read-in-ath9k_hw_update_mibstats.patch
-+++ /dev/null
-@@ -1,39 +0,0 @@
--From: Oleksij Rempel <linux@rempel-privat.de>
--Date: Sun, 22 Mar 2015 19:29:53 +0100
--Subject: [PATCH] ath9k: use one shot read in ath9k_hw_update_mibstats
--
--this will reduce some overhead on usb bus.
--
--Signed-off-by: Oleksij Rempel <linux@rempel-privat.de>
--Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
-----
--
----- a/drivers/net/wireless/ath/ath9k/ani.c
--+++ b/drivers/net/wireless/ath/ath9k/ani.c
--@@ -107,11 +107,21 @@ static const struct ani_cck_level_entry
-- static void ath9k_hw_update_mibstats(struct ath_hw *ah,
-- 				     struct ath9k_mib_stats *stats)
-- {
---	stats->ackrcv_bad += REG_READ(ah, AR_ACK_FAIL);
---	stats->rts_bad += REG_READ(ah, AR_RTS_FAIL);
---	stats->fcs_bad += REG_READ(ah, AR_FCS_FAIL);
---	stats->rts_good += REG_READ(ah, AR_RTS_OK);
---	stats->beacons += REG_READ(ah, AR_BEACON_CNT);
--+	u32 addr[5] = {AR_RTS_OK, AR_RTS_FAIL, AR_ACK_FAIL,
--+		       AR_FCS_FAIL, AR_BEACON_CNT};
--+	u32 data[5];
--+
--+	REG_READ_MULTI(ah, &addr[0], &data[0], 5);
--+	/* AR_RTS_OK */
--+	stats->rts_good += data[0];
--+	/* AR_RTS_FAIL */
--+	stats->rts_bad += data[1];
--+	/* AR_ACK_FAIL */
--+	stats->ackrcv_bad += data[2];
--+	/* AR_FCS_FAIL */
--+	stats->fcs_bad += data[3];
--+	/* AR_BEACON_CNT */
--+	stats->beacons += data[4];
-- }
-- 
-- static void ath9k_ani_restart(struct ath_hw *ah)
-diff --git a/package/kernel/mac80211/patches/326-brcmfmac-add-mapping-for-interface-index-to-bsscfg-i.patch b/package/kernel/mac80211/patches/326-brcmfmac-add-mapping-for-interface-index-to-bsscfg-i.patch
-new file mode 100644
-index 0000000..8ddc0a6
---- /dev/null
-+++ b/package/kernel/mac80211/patches/326-brcmfmac-add-mapping-for-interface-index-to-bsscfg-i.patch
-@@ -0,0 +1,92 @@
-+From: Arend van Spriel <arend@broadcom.com>
-+Date: Wed, 26 Aug 2015 22:15:00 +0200
-+Subject: [PATCH] brcmfmac: add mapping for interface index to bsscfg
-+ index
-+
-+Because the P2P Device interface in firmware uses the same interface
-+index as the primary interface we use the bsscfg index as index in the
-+struct brcmf_pub::iflist. However, in the data path we get the interface
-+index and not the bsscfg index. So we need a mapping of interface index
-+to bsscfg index, which can be determined upon handle adding the interface.
-+
-+Reviewed-by: Hante Meuleman <meuleman@broadcom.com>
-+Reviewed-by: Franky (Zhenhui) Lin <frankyl@broadcom.com>
-+Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
-+Signed-off-by: Arend van Spriel <arend@broadcom.com>
-+---
-+
-+--- a/drivers/net/wireless/brcm80211/brcmfmac/core.c
-++++ b/drivers/net/wireless/brcm80211/brcmfmac/core.c
-+@@ -85,21 +85,20 @@ char *brcmf_ifname(struct brcmf_pub *drv
-+ 
-+ struct brcmf_if *brcmf_get_ifp(struct brcmf_pub *drvr, int ifidx)
-+ {
-++	struct brcmf_if *ifp;
-++	s32 bssidx;
-++
-+ 	if (ifidx < 0 || ifidx >= BRCMF_MAX_IFS) {
-+ 		brcmf_err("ifidx %d out of range\n", ifidx);
-+ 		return NULL;
-+ 	}
-+ 
-+-	/* The ifidx is the idx to map to matching netdev/ifp. When receiving
-+-	 * events this is easy because it contains the bssidx which maps
-+-	 * 1-on-1 to the netdev/ifp. But for data frames the ifidx is rcvd.
-+-	 * bssidx 1 is used for p2p0 and no data can be received or
-+-	 * transmitted on it. Therefor bssidx is ifidx + 1 if ifidx > 0
-+-	 */
-+-	if (ifidx)
-+-		ifidx++;
-++	ifp = NULL;
-++	bssidx = drvr->if2bss[ifidx];
-++	if (bssidx >= 0)
-++		ifp = drvr->iflist[bssidx];
-+ 
-+-	return drvr->iflist[ifidx];
-++	return ifp;
-+ }
-+ 
-+ static void _brcmf_set_multicast_list(struct work_struct *work)
-+@@ -831,6 +830,8 @@ struct brcmf_if *brcmf_add_if(struct brc
-+ 
-+ 		ifp = netdev_priv(ndev);
-+ 		ifp->ndev = ndev;
-++		/* store mapping ifidx to bssidx */
-++		drvr->if2bss[ifidx] = bssidx;
-+ 	}
-+ 
-+ 	ifp->drvr = drvr;
-+@@ -855,6 +856,7 @@ static void brcmf_del_if(struct brcmf_pu
-+ 	struct brcmf_if *ifp;
-+ 
-+ 	ifp = drvr->iflist[bssidx];
-++	drvr->if2bss[ifp->ifidx] = -1;
-+ 	drvr->iflist[bssidx] = NULL;
-+ 	if (!ifp) {
-+ 		brcmf_err("Null interface, idx=%d\n", bssidx);
-+@@ -862,6 +864,7 @@ static void brcmf_del_if(struct brcmf_pu
-+ 	}
-+ 	brcmf_dbg(TRACE, "Enter, idx=%d, ifidx=%d\n", bssidx, ifp->ifidx);
-+ 	if (ifp->ndev) {
-++		drvr->if2bss[ifp->ifidx] = -1;
-+ 		if (bssidx == 0) {
-+ 			if (ifp->ndev->netdev_ops == &brcmf_netdev_ops_pri) {
-+ 				rtnl_lock();
-+@@ -926,6 +929,7 @@ int brcmf_attach(struct device *dev)
-+ 	if (!drvr)
-+ 		return -ENOMEM;
-+ 
-++	memset(drvr->if2bss, 0xFF, sizeof(drvr->if2bss));
-+ 	mutex_init(&drvr->proto_block);
-+ 
-+ 	/* Link to bus module */
-+--- a/drivers/net/wireless/brcm80211/brcmfmac/core.h
-++++ b/drivers/net/wireless/brcm80211/brcmfmac/core.h
-+@@ -122,6 +122,7 @@ struct brcmf_pub {
-+ 	struct mac_address addresses[BRCMF_MAX_IFS];
-+ 
-+ 	struct brcmf_if *iflist[BRCMF_MAX_IFS];
-++	s32 if2bss[BRCMF_MAX_IFS];
-+ 
-+ 	struct mutex proto_block;
-+ 	unsigned char proto_buf[BRCMF_DCMD_MAXLEN];
-diff --git a/package/kernel/mac80211/patches/327-ath9k-ath9k_hw_loadnf-use-REG_RMW.patch b/package/kernel/mac80211/patches/327-ath9k-ath9k_hw_loadnf-use-REG_RMW.patch
-deleted file mode 100644
-index e5a362f..0000000
---- a/package/kernel/mac80211/patches/327-ath9k-ath9k_hw_loadnf-use-REG_RMW.patch
-+++ /dev/null
-@@ -1,71 +0,0 @@
--From: Oleksij Rempel <linux@rempel-privat.de>
--Date: Sun, 22 Mar 2015 19:29:54 +0100
--Subject: [PATCH] ath9k: ath9k_hw_loadnf: use REG_RMW
--
--Signed-off-by: Oleksij Rempel <linux@rempel-privat.de>
--Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
-----
--
----- a/drivers/net/wireless/ath/ath9k/calib.c
--+++ b/drivers/net/wireless/ath/ath9k/calib.c
--@@ -238,7 +238,6 @@ int ath9k_hw_loadnf(struct ath_hw *ah, s
-- {
-- 	struct ath9k_nfcal_hist *h = NULL;
-- 	unsigned i, j;
---	int32_t val;
-- 	u8 chainmask = (ah->rxchainmask << 3) | ah->rxchainmask;
-- 	struct ath_common *common = ath9k_hw_common(ah);
-- 	s16 default_nf = ath9k_hw_get_default_nf(ah, chan);
--@@ -246,6 +245,7 @@ int ath9k_hw_loadnf(struct ath_hw *ah, s
-- 	if (ah->caldata)
-- 		h = ah->caldata->nfCalHist;
-- 
--+	ENABLE_REG_RMW_BUFFER(ah);
-- 	for (i = 0; i < NUM_NF_READINGS; i++) {
-- 		if (chainmask & (1 << i)) {
-- 			s16 nfval;
--@@ -258,10 +258,8 @@ int ath9k_hw_loadnf(struct ath_hw *ah, s
-- 			else
-- 				nfval = default_nf;
-- 
---			val = REG_READ(ah, ah->nf_regs[i]);
---			val &= 0xFFFFFE00;
---			val |= (((u32) nfval << 1) & 0x1ff);
---			REG_WRITE(ah, ah->nf_regs[i], val);
--+			REG_RMW(ah, ah->nf_regs[i],
--+				(((u32) nfval << 1) & 0x1ff), 0x1ff);
-- 		}
-- 	}
-- 
--@@ -274,6 +272,7 @@ int ath9k_hw_loadnf(struct ath_hw *ah, s
-- 	REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL,
-- 		    AR_PHY_AGC_CONTROL_NO_UPDATE_NF);
-- 	REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NF);
--+	REG_RMW_BUFFER_FLUSH(ah);
-- 
-- 	/*
-- 	 * Wait for load to complete, should be fast, a few 10s of us.
--@@ -309,19 +308,17 @@ int ath9k_hw_loadnf(struct ath_hw *ah, s
-- 	 * by the median we just loaded.  This will be initial (and max) value
-- 	 * of next noise floor calibration the baseband does.
-- 	 */
---	ENABLE_REGWRITE_BUFFER(ah);
--+	ENABLE_REG_RMW_BUFFER(ah);
-- 	for (i = 0; i < NUM_NF_READINGS; i++) {
-- 		if (chainmask & (1 << i)) {
-- 			if ((i >= AR5416_MAX_CHAINS) && !IS_CHAN_HT40(chan))
-- 				continue;
-- 
---			val = REG_READ(ah, ah->nf_regs[i]);
---			val &= 0xFFFFFE00;
---			val |= (((u32) (-50) << 1) & 0x1ff);
---			REG_WRITE(ah, ah->nf_regs[i], val);
--+			REG_RMW(ah, ah->nf_regs[i],
--+					(((u32) (-50) << 1) & 0x1ff), 0x1ff);
-- 		}
-- 	}
---	REGWRITE_BUFFER_FLUSH(ah);
--+	REG_RMW_BUFFER_FLUSH(ah);
-- 
-- 	return 0;
-- }
-diff --git a/package/kernel/mac80211/patches/327-brcmfmac-add-dedicated-debug-level-for-firmware-cons.patch b/package/kernel/mac80211/patches/327-brcmfmac-add-dedicated-debug-level-for-firmware-cons.patch
-new file mode 100644
-index 0000000..a0a798b
---- /dev/null
-+++ b/package/kernel/mac80211/patches/327-brcmfmac-add-dedicated-debug-level-for-firmware-cons.patch
-@@ -0,0 +1,103 @@
-+From: Arend van Spriel <arend@broadcom.com>
-+Date: Wed, 26 Aug 2015 22:15:01 +0200
-+Subject: [PATCH] brcmfmac: add dedicated debug level for firmware
-+ console logging
-+
-+Both PCIe and SDIO devices have the possibility to log the firmware
-+console output in kernel log. For PCIe it is logged when PCIE debug
-+level is enabled. For SDIO it is logged when user specifies a non-zero
-+console interval through debugfs. This patch tries to make it a
-+bit more consistent. The firmware console output is only logged when
-+FWCON debug level is enabled.
-+
-+Reviewed-by: Hante Meuleman <meuleman@broadcom.com>
-+Reviewed-by: Franky (Zhenhui) Lin <frankyl@broadcom.com>
-+Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
-+Reviewed-by: Pontus Fuchs <pontusf@broadcom.com>
-+Signed-off-by: Arend van Spriel <arend@broadcom.com>
-+---
-+
-+--- a/drivers/net/wireless/brcm80211/brcmfmac/debug.h
-++++ b/drivers/net/wireless/brcm80211/brcmfmac/debug.h
-+@@ -37,6 +37,7 @@
-+ #define BRCMF_SDIO_VAL		0x00020000
-+ #define BRCMF_MSGBUF_VAL	0x00040000
-+ #define BRCMF_PCIE_VAL		0x00080000
-++#define BRCMF_FWCON_VAL		0x00100000
-+ 
-+ /* set default print format */
-+ #undef pr_fmt
-+@@ -78,6 +79,7 @@ do {								\
-+ #define BRCMF_GLOM_ON()		(brcmf_msg_level & BRCMF_GLOM_VAL)
-+ #define BRCMF_EVENT_ON()	(brcmf_msg_level & BRCMF_EVENT_VAL)
-+ #define BRCMF_FIL_ON()		(brcmf_msg_level & BRCMF_FIL_VAL)
-++#define BRCMF_FWCON_ON()	(brcmf_msg_level & BRCMF_FWCON_VAL)
-+ 
-+ #else /* defined(DEBUG) || defined(CPTCFG_BRCM_TRACING) */
-+ 
-+@@ -90,6 +92,7 @@ do {								\
-+ #define BRCMF_GLOM_ON()		0
-+ #define BRCMF_EVENT_ON()	0
-+ #define BRCMF_FIL_ON()		0
-++#define BRCMF_FWCON_ON()	0
-+ 
-+ #endif /* defined(DEBUG) || defined(CPTCFG_BRCM_TRACING) */
-+ 
-+--- a/drivers/net/wireless/brcm80211/brcmfmac/pcie.c
-++++ b/drivers/net/wireless/brcm80211/brcmfmac/pcie.c
-+@@ -644,7 +644,7 @@ static void brcmf_pcie_bus_console_init(
-+ 	addr = console->base_addr + BRCMF_CONSOLE_BUFSIZE_OFFSET;
-+ 	console->bufsize = brcmf_pcie_read_tcm32(devinfo, addr);
-+ 
-+-	brcmf_dbg(PCIE, "Console: base %x, buf %x, size %d\n",
-++	brcmf_dbg(FWCON, "Console: base %x, buf %x, size %d\n",
-+ 		  console->base_addr, console->buf_addr, console->bufsize);
-+ }
-+ 
-+@@ -656,6 +656,9 @@ static void brcmf_pcie_bus_console_read(
-+ 	u8 ch;
-+ 	u32 newidx;
-+ 
-++	if (!BRCMF_FWCON_ON())
-++		return;
-++
-+ 	console = &devinfo->shared.console;
-+ 	addr = console->base_addr + BRCMF_CONSOLE_WRITEIDX_OFFSET;
-+ 	newidx = brcmf_pcie_read_tcm32(devinfo, addr);
-+@@ -677,7 +680,7 @@ static void brcmf_pcie_bus_console_read(
-+ 		}
-+ 		if (ch == '\n') {
-+ 			console->log_str[console->log_idx] = 0;
-+-			brcmf_dbg(PCIE, "CONSOLE: %s", console->log_str);
-++			pr_debug("CONSOLE: %s", console->log_str);
-+ 			console->log_idx = 0;
-+ 		}
-+ 	}
-+--- a/drivers/net/wireless/brcm80211/brcmfmac/sdio.c
-++++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio.c
-+@@ -123,6 +123,7 @@ struct rte_console {
-+ 
-+ #define BRCMF_FIRSTREAD	(1 << 6)
-+ 
-++#define BRCMF_CONSOLE	10	/* watchdog interval to poll console */
-+ 
-+ /* SBSDIO_DEVICE_CTL */
-+ 
-+@@ -3204,6 +3205,8 @@ static void brcmf_sdio_debugfs_create(st
-+ 	if (IS_ERR_OR_NULL(dentry))
-+ 		return;
-+ 
-++	bus->console_interval = BRCMF_CONSOLE;
-++
-+ 	brcmf_debugfs_add_entry(drvr, "forensics", brcmf_sdio_forensic_read);
-+ 	brcmf_debugfs_add_entry(drvr, "counters",
-+ 				brcmf_debugfs_sdio_count_read);
-+@@ -3613,7 +3616,7 @@ static void brcmf_sdio_bus_watchdog(stru
-+ 	}
-+ #ifdef DEBUG
-+ 	/* Poll for console output periodically */
-+-	if (bus->sdiodev->state == BRCMF_SDIOD_DATA &&
-++	if (bus->sdiodev->state == BRCMF_SDIOD_DATA && BRCMF_FWCON_ON() &&
-+ 	    bus->console_interval != 0) {
-+ 		bus->console.count += BRCMF_WD_POLL_MS;
-+ 		if (bus->console.count >= bus->console_interval) {
-diff --git a/package/kernel/mac80211/patches/328-ath9k-write-buffer-related-optimisation-in-ar5008_hw.patch b/package/kernel/mac80211/patches/328-ath9k-write-buffer-related-optimisation-in-ar5008_hw.patch
-deleted file mode 100644
-index 01c8011..0000000
---- a/package/kernel/mac80211/patches/328-ath9k-write-buffer-related-optimisation-in-ar5008_hw.patch
-+++ /dev/null
-@@ -1,27 +0,0 @@
--From: Oleksij Rempel <linux@rempel-privat.de>
--Date: Sun, 22 Mar 2015 19:29:55 +0100
--Subject: [PATCH] ath9k: write buffer related optimisation in
-- ar5008_hw_set_channel_regs
--
--Signed-off-by: Oleksij Rempel <linux@rempel-privat.de>
--Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
-----
--
----- a/drivers/net/wireless/ath/ath9k/ar5008_phy.c
--+++ b/drivers/net/wireless/ath/ath9k/ar5008_phy.c
--@@ -681,12 +681,13 @@ static void ar5008_hw_set_channel_regs(s
-- 			phymode |= AR_PHY_FC_DYN2040_PRI_CH;
-- 
-- 	}
--+	ENABLE_REGWRITE_BUFFER(ah);
-- 	REG_WRITE(ah, AR_PHY_TURBO, phymode);
-- 
--+	/* This function do only REG_WRITE, so
--+	 * we can include it to REGWRITE_BUFFER. */
-- 	ath9k_hw_set11nmac2040(ah, chan);
-- 
---	ENABLE_REGWRITE_BUFFER(ah);
---
-- 	REG_WRITE(ah, AR_GTXTO, 25 << AR_GTXTO_TIMEOUT_LIMIT_S);
-- 	REG_WRITE(ah, AR_CST, 0xF << AR_CST_TIMEOUT_LIMIT_S);
-- 
-diff --git a/package/kernel/mac80211/patches/328-brcmfmac-remove-ifidx-parameter-from-brcmf_fws_txsta.patch b/package/kernel/mac80211/patches/328-brcmfmac-remove-ifidx-parameter-from-brcmf_fws_txsta.patch
-new file mode 100644
-index 0000000..53e7ede
---- /dev/null
-+++ b/package/kernel/mac80211/patches/328-brcmfmac-remove-ifidx-parameter-from-brcmf_fws_txsta.patch
-@@ -0,0 +1,34 @@
-+From: Arend van Spriel <arend@broadcom.com>
-+Date: Wed, 26 Aug 2015 22:15:02 +0200
-+Subject: [PATCH] brcmfmac: remove ifidx parameter from
-+ brcmf_fws_txstatus_suppressed()
-+
-+The brcmf_fws_txstatus_suppressed() function prototype specifies an
-+ifidx parameter which is not used within the function implementation.
-+
-+Reviewed-by: Hante Meuleman <meuleman@broadcom.com>
-+Reviewed-by: Franky (Zhenhui) Lin <frankyl@broadcom.com>
-+Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
-+Signed-off-by: Arend van Spriel <arend@broadcom.com>
-+---
-+
-+--- a/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c
-++++ b/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c
-+@@ -1398,7 +1398,7 @@ done:
-+ }
-+ 
-+ static int brcmf_fws_txstatus_suppressed(struct brcmf_fws_info *fws, int fifo,
-+-					 struct sk_buff *skb, u8 ifidx,
-++					 struct sk_buff *skb,
-+ 					 u32 genbit, u16 seq)
-+ {
-+ 	struct brcmf_fws_mac_descriptor *entry = brcmf_skbcb(skb)->mac;
-+@@ -1503,7 +1503,7 @@ brcmf_fws_txs_process(struct brcmf_fws_i
-+ 		return -EINVAL;
-+ 	}
-+ 	if (!remove_from_hanger)
-+-		ret = brcmf_fws_txstatus_suppressed(fws, fifo, skb, ifp->ifidx,
-++		ret = brcmf_fws_txstatus_suppressed(fws, fifo, skb,
-+ 						    genbit, seq);
-+ 	if (remove_from_hanger || ret)
-+ 		brcmf_txfinalize(ifp, skb, true);
-diff --git a/package/kernel/mac80211/patches/329-ath9k-ath9k_hw_set_4k_power_cal_tabl-use-rmw-buffer.patch b/package/kernel/mac80211/patches/329-ath9k-ath9k_hw_set_4k_power_cal_tabl-use-rmw-buffer.patch
-deleted file mode 100644
-index e5219f2..0000000
---- a/package/kernel/mac80211/patches/329-ath9k-ath9k_hw_set_4k_power_cal_tabl-use-rmw-buffer.patch
-+++ /dev/null
-@@ -1,26 +0,0 @@
--From: Oleksij Rempel <linux@rempel-privat.de>
--Date: Sun, 22 Mar 2015 19:29:56 +0100
--Subject: [PATCH] ath9k: ath9k_hw_set_4k_power_cal_tabl: use rmw buffer
--
--Signed-off-by: Oleksij Rempel <linux@rempel-privat.de>
--Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
-----
--
----- a/drivers/net/wireless/ath/ath9k/eeprom_4k.c
--+++ b/drivers/net/wireless/ath/ath9k/eeprom_4k.c
--@@ -389,6 +389,7 @@ static void ath9k_hw_set_4k_power_cal_ta
-- 		}
-- 	}
-- 
--+	ENABLE_REG_RMW_BUFFER(ah);
-- 	REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_NUM_PD_GAIN,
-- 		      (numXpdGain - 1) & 0x3);
-- 	REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_1,
--@@ -396,6 +397,7 @@ static void ath9k_hw_set_4k_power_cal_ta
-- 	REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_2,
-- 		      xpdGainValues[1]);
-- 	REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_3, 0);
--+	REG_RMW_BUFFER_FLUSH(ah);
-- 
-- 	for (i = 0; i < AR5416_EEP4K_MAX_CHAINS; i++) {
-- 		regChainOffset = i * 0x1000;
-diff --git a/package/kernel/mac80211/patches/329-brcmfmac-change-prototype-for-brcmf_fws_hdrpull.patch b/package/kernel/mac80211/patches/329-brcmfmac-change-prototype-for-brcmf_fws_hdrpull.patch
-new file mode 100644
-index 0000000..bb05235
---- /dev/null
-+++ b/package/kernel/mac80211/patches/329-brcmfmac-change-prototype-for-brcmf_fws_hdrpull.patch
-@@ -0,0 +1,97 @@
-+From: Arend van Spriel <arend@broadcom.com>
-+Date: Wed, 26 Aug 2015 22:15:03 +0200
-+Subject: [PATCH] brcmfmac: change prototype for brcmf_fws_hdrpull()
-+
-+Instead of passing ifidx and drvr just pass struct brcmf_if pointer
-+which holds both parameters.
-+
-+Reviewed-by: Hante Meuleman <meuleman@broadcom.com>
-+Reviewed-by: Franky (Zhenhui) Lin <frankyl@broadcom.com>
-+Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
-+Signed-off-by: Arend van Spriel <arend@broadcom.com>
-+---
-+
-+--- a/drivers/net/wireless/brcm80211/brcmfmac/bcdc.c
-++++ b/drivers/net/wireless/brcm80211/brcmfmac/bcdc.c
-+@@ -312,8 +312,7 @@ brcmf_proto_bcdc_hdrpull(struct brcmf_pu
-+ 
-+ 	skb_pull(pktbuf, BCDC_HEADER_LEN);
-+ 	if (do_fws)
-+-		brcmf_fws_hdrpull(drvr, tmp_if->ifidx, h->data_offset << 2,
-+-				  pktbuf);
-++		brcmf_fws_hdrpull(tmp_if, h->data_offset << 2, pktbuf);
-+ 	else
-+ 		skb_pull(pktbuf, h->data_offset << 2);
-+ 
-+--- a/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c
-++++ b/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c
-+@@ -1616,11 +1616,10 @@ static int brcmf_fws_notify_bcmc_credit_
-+ 	return 0;
-+ }
-+ 
-+-int brcmf_fws_hdrpull(struct brcmf_pub *drvr, int ifidx, s16 signal_len,
-+-		      struct sk_buff *skb)
-++void brcmf_fws_hdrpull(struct brcmf_if *ifp, s16 siglen, struct sk_buff *skb)
-+ {
-+ 	struct brcmf_skb_reorder_data *rd;
-+-	struct brcmf_fws_info *fws = drvr->fws;
-++	struct brcmf_fws_info *fws = ifp->drvr->fws;
-+ 	u8 *signal_data;
-+ 	s16 data_len;
-+ 	u8 type;
-+@@ -1630,20 +1629,20 @@ int brcmf_fws_hdrpull(struct brcmf_pub *
-+ 	s32 err;
-+ 
-+ 	brcmf_dbg(HDRS, "enter: ifidx %d, skblen %u, sig %d\n",
-+-		  ifidx, skb->len, signal_len);
-++		  ifp->ifidx, skb->len, siglen);
-+ 
-+-	WARN_ON(signal_len > skb->len);
-++	WARN_ON(siglen > skb->len);
-+ 
-+-	if (!signal_len)
-+-		return 0;
-++	if (!siglen)
-++		return;
-+ 	/* if flow control disabled, skip to packet data and leave */
-+ 	if ((!fws) || (!fws->fw_signals)) {
-+-		skb_pull(skb, signal_len);
-+-		return 0;
-++		skb_pull(skb, siglen);
-++		return;
-+ 	}
-+ 
-+ 	fws->stats.header_pulls++;
-+-	data_len = signal_len;
-++	data_len = siglen;
-+ 	signal_data = skb->data;
-+ 
-+ 	status = BRCMF_FWS_RET_OK_NOSCHEDULE;
-+@@ -1731,14 +1730,12 @@ int brcmf_fws_hdrpull(struct brcmf_pub *
-+ 	/* signalling processing result does
-+ 	 * not affect the actual ethernet packet.
-+ 	 */
-+-	skb_pull(skb, signal_len);
-++	skb_pull(skb, siglen);
-+ 
-+ 	/* this may be a signal-only packet
-+ 	 */
-+ 	if (skb->len == 0)
-+ 		fws->stats.header_only_pkt++;
-+-
-+-	return 0;
-+ }
-+ 
-+ static u8 brcmf_fws_precommit_skb(struct brcmf_fws_info *fws, int fifo,
-+--- a/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.h
-++++ b/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.h
-+@@ -21,8 +21,7 @@
-+ int brcmf_fws_init(struct brcmf_pub *drvr);
-+ void brcmf_fws_deinit(struct brcmf_pub *drvr);
-+ bool brcmf_fws_fc_active(struct brcmf_fws_info *fws);
-+-int brcmf_fws_hdrpull(struct brcmf_pub *drvr, int ifidx, s16 signal_len,
-+-		      struct sk_buff *skb);
-++void brcmf_fws_hdrpull(struct brcmf_if *ifp, s16 siglen, struct sk_buff *skb);
-+ int brcmf_fws_process_skb(struct brcmf_if *ifp, struct sk_buff *skb);
-+ 
-+ void brcmf_fws_reset_interface(struct brcmf_if *ifp);
-diff --git a/package/kernel/mac80211/patches/330-ath9k-use-rmw-buffer-in-ath9k_hw_set_operating_mode-.patch b/package/kernel/mac80211/patches/330-ath9k-use-rmw-buffer-in-ath9k_hw_set_operating_mode-.patch
-deleted file mode 100644
-index 6ce3f40..0000000
---- a/package/kernel/mac80211/patches/330-ath9k-use-rmw-buffer-in-ath9k_hw_set_operating_mode-.patch
-+++ /dev/null
-@@ -1,43 +0,0 @@
--From: Oleksij Rempel <linux@rempel-privat.de>
--Date: Sun, 22 Mar 2015 19:29:57 +0100
--Subject: [PATCH] ath9k: use rmw buffer in ath9k_hw_set_operating_mode
-- and ath9k_hw_reset
--
--Signed-off-by: Oleksij Rempel <linux@rempel-privat.de>
--Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
-----
--
----- a/drivers/net/wireless/ath/ath9k/hw.c
--+++ b/drivers/net/wireless/ath/ath9k/hw.c
--@@ -1227,6 +1227,7 @@ static void ath9k_hw_set_operating_mode(
-- 	u32 mask = AR_STA_ID1_STA_AP | AR_STA_ID1_ADHOC;
-- 	u32 set = AR_STA_ID1_KSRCH_MODE;
-- 
--+	ENABLE_REG_RMW_BUFFER(ah);
-- 	switch (opmode) {
-- 	case NL80211_IFTYPE_ADHOC:
-- 		if (!AR_SREV_9340_13(ah)) {
--@@ -1248,6 +1249,7 @@ static void ath9k_hw_set_operating_mode(
-- 		break;
-- 	}
-- 	REG_RMW(ah, AR_STA_ID1, set, mask);
--+	REG_RMW_BUFFER_FLUSH(ah);
-- }
-- 
-- void ath9k_hw_get_delta_slope_vals(struct ath_hw *ah, u32 coef_scaled,
--@@ -1960,6 +1962,7 @@ int ath9k_hw_reset(struct ath_hw *ah, st
-- 	if (!ath9k_hw_mci_is_enabled(ah))
-- 		REG_WRITE(ah, AR_OBS, 8);
-- 
--+	ENABLE_REG_RMW_BUFFER(ah);
-- 	if (ah->config.rx_intr_mitigation) {
-- 		REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_LAST, ah->config.rimt_last);
-- 		REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_FIRST, ah->config.rimt_first);
--@@ -1969,6 +1972,7 @@ int ath9k_hw_reset(struct ath_hw *ah, st
-- 		REG_RMW_FIELD(ah, AR_TIMT, AR_TIMT_LAST, 300);
-- 		REG_RMW_FIELD(ah, AR_TIMT, AR_TIMT_FIRST, 750);
-- 	}
--+	REG_RMW_BUFFER_FLUSH(ah);
-- 
-- 	ath9k_hw_init_bb(ah, chan);
-- 
-diff --git a/package/kernel/mac80211/patches/330-brcmfmac-introduce-brcmf_net_detach-function.patch b/package/kernel/mac80211/patches/330-brcmfmac-introduce-brcmf_net_detach-function.patch
-new file mode 100644
-index 0000000..0651a2f
---- /dev/null
-+++ b/package/kernel/mac80211/patches/330-brcmfmac-introduce-brcmf_net_detach-function.patch
-@@ -0,0 +1,99 @@
-+From: Arend van Spriel <arend@broadcom.com>
-+Date: Wed, 26 Aug 2015 22:15:04 +0200
-+Subject: [PATCH] brcmfmac: introduce brcmf_net_detach() function
-+
-+In case of error during brcmf_bus_start() the network interfaces were
-+freed using free_netdev(). However, the interfaces may have additional
-+memory allocated which is not freed. The netdev has destructor set to
-+brcmf_cfg80211_free_netdev() which frees the additional memory if
-+allocated and call free_netdev(). The brcmf_net_detach() either calls
-+brcmf_cfg80211_free_netdev() directly or uses unregister_netdev() when
-+struct net_device::reg_state indicates the netdev was registered.
-+
-+Reported-by: Daniel (Deognyoun) Kim <dekim@broadcom.com>
-+Reviewed-by: Hante Meuleman <meuleman@broadcom.com>
-+Reviewed-by: Franky (Zhenhui) Lin <frankyl@broadcom.com>
-+Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
-+Signed-off-by: Arend van Spriel <arend@broadcom.com>
-+---
-+
-+--- a/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c
-++++ b/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c
-+@@ -4747,7 +4747,8 @@ void brcmf_cfg80211_free_netdev(struct n
-+ 	ifp = netdev_priv(ndev);
-+ 	vif = ifp->vif;
-+ 
-+-	brcmf_free_vif(vif);
-++	if (vif)
-++		brcmf_free_vif(vif);
-+ 	free_netdev(ndev);
-+ }
-+ 
-+--- a/drivers/net/wireless/brcm80211/brcmfmac/core.c
-++++ b/drivers/net/wireless/brcm80211/brcmfmac/core.c
-+@@ -718,8 +718,6 @@ int brcmf_net_attach(struct brcmf_if *if
-+ 	}
-+ 
-+ 	brcmf_dbg(INFO, "%s: Broadcom Dongle Host Driver\n", ndev->name);
-+-
-+-	ndev->destructor = brcmf_cfg80211_free_netdev;
-+ 	return 0;
-+ 
-+ fail:
-+@@ -729,6 +727,14 @@ fail:
-+ 	return -EBADE;
-+ }
-+ 
-++static void brcmf_net_detach(struct net_device *ndev)
-++{
-++	if (ndev->reg_state == NETREG_REGISTERED)
-++		unregister_netdev(ndev);
-++	else
-++		brcmf_cfg80211_free_netdev(ndev);
-++}
-++
-+ static int brcmf_net_p2p_open(struct net_device *ndev)
-+ {
-+ 	brcmf_dbg(TRACE, "Enter\n");
-+@@ -805,8 +811,7 @@ struct brcmf_if *brcmf_add_if(struct brc
-+ 			  ifp->ndev->name);
-+ 		if (ifidx) {
-+ 			netif_stop_queue(ifp->ndev);
-+-			unregister_netdev(ifp->ndev);
-+-			free_netdev(ifp->ndev);
-++			brcmf_net_detach(ifp->ndev);
-+ 			drvr->iflist[bssidx] = NULL;
-+ 		} else {
-+ 			brcmf_err("ignore IF event\n");
-+@@ -828,6 +833,7 @@ struct brcmf_if *brcmf_add_if(struct brc
-+ 		if (!ndev)
-+ 			return ERR_PTR(-ENOMEM);
-+ 
-++		ndev->destructor = brcmf_cfg80211_free_netdev;
-+ 		ifp = netdev_priv(ndev);
-+ 		ifp->ndev = ndev;
-+ 		/* store mapping ifidx to bssidx */
-+@@ -879,8 +885,7 @@ static void brcmf_del_if(struct brcmf_pu
-+ 			cancel_work_sync(&ifp->setmacaddr_work);
-+ 			cancel_work_sync(&ifp->multicast_work);
-+ 		}
-+-		/* unregister will take care of freeing it */
-+-		unregister_netdev(ifp->ndev);
-++		brcmf_net_detach(ifp->ndev);
-+ 	}
-+ }
-+ 
-+@@ -1056,11 +1061,11 @@ fail:
-+ 			brcmf_fws_deinit(drvr);
-+ 		}
-+ 		if (drvr->iflist[0]) {
-+-			free_netdev(ifp->ndev);
-++			brcmf_net_detach(ifp->ndev);
-+ 			drvr->iflist[0] = NULL;
-+ 		}
-+ 		if (p2p_ifp) {
-+-			free_netdev(p2p_ifp->ndev);
-++			brcmf_net_detach(p2p_ifp->ndev);
-+ 			drvr->iflist[1] = NULL;
-+ 		}
-+ 		return ret;
-diff --git a/package/kernel/mac80211/patches/331-ath9k-ath9k_hw_4k_set_board_values-use-rmw-buffer.patch b/package/kernel/mac80211/patches/331-ath9k-ath9k_hw_4k_set_board_values-use-rmw-buffer.patch
-deleted file mode 100644
-index edd6160..0000000
---- a/package/kernel/mac80211/patches/331-ath9k-ath9k_hw_4k_set_board_values-use-rmw-buffer.patch
-+++ /dev/null
-@@ -1,26 +0,0 @@
--From: Oleksij Rempel <linux@rempel-privat.de>
--Date: Sun, 22 Mar 2015 19:29:58 +0100
--Subject: [PATCH] ath9k: ath9k_hw_4k_set_board_values: use rmw buffer
--
--Signed-off-by: Oleksij Rempel <linux@rempel-privat.de>
--Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
-----
--
----- a/drivers/net/wireless/ath/ath9k/eeprom_4k.c
--+++ b/drivers/net/wireless/ath/ath9k/eeprom_4k.c
--@@ -1082,6 +1082,7 @@ static void ath9k_hw_4k_set_board_values
-- 		mask = BIT(0)|BIT(5)|BIT(10)|BIT(15)|BIT(20)|BIT(25);
-- 		pwrctrl = mask * bb_desired_scale;
-- 		clr = mask * 0x1f;
--+		ENABLE_REG_RMW_BUFFER(ah);
-- 		REG_RMW(ah, AR_PHY_TX_PWRCTRL8, pwrctrl, clr);
-- 		REG_RMW(ah, AR_PHY_TX_PWRCTRL10, pwrctrl, clr);
-- 		REG_RMW(ah, AR_PHY_CH0_TX_PWRCTRL12, pwrctrl, clr);
--@@ -1096,6 +1097,7 @@ static void ath9k_hw_4k_set_board_values
-- 		clr = mask * 0x1f;
-- 		REG_RMW(ah, AR_PHY_CH0_TX_PWRCTRL11, pwrctrl, clr);
-- 		REG_RMW(ah, AR_PHY_CH0_TX_PWRCTRL13, pwrctrl, clr);
--+		REG_RMW_BUFFER_FLUSH(ah);
-- 	}
-- }
-- 
-diff --git a/package/kernel/mac80211/patches/331-brcmfmac-Reset-PCIE-devices-after-recognition.patch b/package/kernel/mac80211/patches/331-brcmfmac-Reset-PCIE-devices-after-recognition.patch
-new file mode 100644
-index 0000000..5a7e447
---- /dev/null
-+++ b/package/kernel/mac80211/patches/331-brcmfmac-Reset-PCIE-devices-after-recognition.patch
-@@ -0,0 +1,193 @@
-+From: Hante Meuleman <meuleman@broadcom.com>
-+Date: Thu, 27 Aug 2015 16:14:06 +0200
-+Subject: [PATCH] brcmfmac: Reset PCIE devices after recognition.
-+
-+When PCIE type devices are being FW reloaded without being properly
-+reset then the device ends up in a locked state, requiring the
-+device to be completely powered down. This patch adds a reset
-+through watchdog at the moment the device (cores) has been
-+recognized. This will solve warm reboot issues.
-+
-+Cc: Rafal Milecki <zajec5@gmail.com>
-+Reviewed-by: Arend Van Spriel <arend@broadcom.com>
-+Reviewed-by: Franky (Zhenhui) Lin <frankyl@broadcom.com>
-+Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
-+Signed-off-by: Hante Meuleman <meuleman@broadcom.com>
-+Signed-off-by: Arend van Spriel <arend@broadcom.com>
-+---
-+
-+--- a/drivers/net/wireless/brcm80211/brcmfmac/chip.c
-++++ b/drivers/net/wireless/brcm80211/brcmfmac/chip.c
-+@@ -101,6 +101,9 @@
-+ /* ARM Cortex M3 core, ID 0x82a */
-+ #define BCM4329_CORE_ARM_BASE		0x18002000
-+ 
-++/* Max possibly supported memory size (limited by IO mapped memory) */
-++#define BRCMF_CHIP_MAX_MEMSIZE		(4 * 1024 * 1024)
-++
-+ #define CORE_SB(base, field) \
-+ 		(base + SBCONFIGOFF + offsetof(struct sbconfig, field))
-+ #define	SBCOREREV(sbidh) \
-+@@ -687,6 +690,12 @@ static int brcmf_chip_get_raminfo(struct
-+ 		brcmf_err("RAM size is undetermined\n");
-+ 		return -ENOMEM;
-+ 	}
-++
-++	if (ci->pub.ramsize > BRCMF_CHIP_MAX_MEMSIZE) {
-++		brcmf_err("RAM size is incorrect\n");
-++		return -ENOMEM;
-++	}
-++
-+ 	return 0;
-+ }
-+ 
-+@@ -899,6 +908,15 @@ static int brcmf_chip_recognition(struct
-+ 
-+ 	/* assure chip is passive for core access */
-+ 	brcmf_chip_set_passive(&ci->pub);
-++
-++	/* Call bus specific reset function now. Cores have been determined
-++	 * but further access may require a chip specific reset at this point.
-++	 */
-++	if (ci->ops->reset) {
-++		ci->ops->reset(ci->ctx, &ci->pub);
-++		brcmf_chip_set_passive(&ci->pub);
-++	}
-++
-+ 	return brcmf_chip_get_raminfo(ci);
-+ }
-+ 
-+--- a/drivers/net/wireless/brcm80211/brcmfmac/chip.h
-++++ b/drivers/net/wireless/brcm80211/brcmfmac/chip.h
-+@@ -73,6 +73,7 @@ struct brcmf_buscore_ops {
-+ 	u32 (*read32)(void *ctx, u32 addr);
-+ 	void (*write32)(void *ctx, u32 addr, u32 value);
-+ 	int (*prepare)(void *ctx);
-++	int (*reset)(void *ctx, struct brcmf_chip *chip);
-+ 	int (*setup)(void *ctx, struct brcmf_chip *chip);
-+ 	void (*activate)(void *ctx, struct brcmf_chip *chip, u32 rstvec);
-+ };
-+--- a/drivers/net/wireless/brcm80211/brcmfmac/pcie.c
-++++ b/drivers/net/wireless/brcm80211/brcmfmac/pcie.c
-+@@ -74,6 +74,8 @@ enum brcmf_pcie_state {
-+ #define BRCMF_PCIE_REG_INTMASK			0x94
-+ #define BRCMF_PCIE_REG_SBMBX			0x98
-+ 
-++#define BRCMF_PCIE_REG_LINK_STATUS_CTRL		0xBC
-++
-+ #define BRCMF_PCIE_PCIE2REG_INTMASK		0x24
-+ #define BRCMF_PCIE_PCIE2REG_MAILBOXINT		0x48
-+ #define BRCMF_PCIE_PCIE2REG_MAILBOXMASK		0x4C
-+@@ -466,6 +468,7 @@ brcmf_pcie_select_core(struct brcmf_pcie
-+ 
-+ static void brcmf_pcie_reset_device(struct brcmf_pciedev_info *devinfo)
-+ {
-++	struct brcmf_core *core;
-+ 	u16 cfg_offset[] = { BRCMF_PCIE_CFGREG_STATUS_CMD,
-+ 			     BRCMF_PCIE_CFGREG_PM_CSR,
-+ 			     BRCMF_PCIE_CFGREG_MSI_CAP,
-+@@ -484,32 +487,38 @@ static void brcmf_pcie_reset_device(stru
-+ 	if (!devinfo->ci)
-+ 		return;
-+ 
-++	/* Disable ASPM */
-+ 	brcmf_pcie_select_core(devinfo, BCMA_CORE_PCIE2);
-+-	brcmf_pcie_write_reg32(devinfo, BRCMF_PCIE_PCIE2REG_CONFIGADDR,
-+-			       BRCMF_PCIE_CFGREG_LINK_STATUS_CTRL);
-+-	lsc = brcmf_pcie_read_reg32(devinfo, BRCMF_PCIE_PCIE2REG_CONFIGDATA);
-++	pci_read_config_dword(devinfo->pdev, BRCMF_PCIE_REG_LINK_STATUS_CTRL,
-++			      &lsc);
-+ 	val = lsc & (~BRCMF_PCIE_LINK_STATUS_CTRL_ASPM_ENAB);
-+-	brcmf_pcie_write_reg32(devinfo, BRCMF_PCIE_PCIE2REG_CONFIGDATA, val);
-++	pci_write_config_dword(devinfo->pdev, BRCMF_PCIE_REG_LINK_STATUS_CTRL,
-++			       val);
-+ 
-++	/* Watchdog reset */
-+ 	brcmf_pcie_select_core(devinfo, BCMA_CORE_CHIPCOMMON);
-+ 	WRITECC32(devinfo, watchdog, 4);
-+ 	msleep(100);
-+ 
-++	/* Restore ASPM */
-+ 	brcmf_pcie_select_core(devinfo, BCMA_CORE_PCIE2);
-+-	brcmf_pcie_write_reg32(devinfo, BRCMF_PCIE_PCIE2REG_CONFIGADDR,
-+-			       BRCMF_PCIE_CFGREG_LINK_STATUS_CTRL);
-+-	brcmf_pcie_write_reg32(devinfo, BRCMF_PCIE_PCIE2REG_CONFIGDATA, lsc);
-++	pci_write_config_dword(devinfo->pdev, BRCMF_PCIE_REG_LINK_STATUS_CTRL,
-++			       lsc);
-+ 
-+-	brcmf_pcie_select_core(devinfo, BCMA_CORE_PCIE2);
-+-	for (i = 0; i < ARRAY_SIZE(cfg_offset); i++) {
-+-		brcmf_pcie_write_reg32(devinfo, BRCMF_PCIE_PCIE2REG_CONFIGADDR,
-+-				       cfg_offset[i]);
-+-		val = brcmf_pcie_read_reg32(devinfo,
-+-					    BRCMF_PCIE_PCIE2REG_CONFIGDATA);
-+-		brcmf_dbg(PCIE, "config offset 0x%04x, value 0x%04x\n",
-+-			  cfg_offset[i], val);
-+-		brcmf_pcie_write_reg32(devinfo, BRCMF_PCIE_PCIE2REG_CONFIGDATA,
-+-				       val);
-++	core = brcmf_chip_get_core(devinfo->ci, BCMA_CORE_PCIE2);
-++	if (core->rev <= 13) {
-++		for (i = 0; i < ARRAY_SIZE(cfg_offset); i++) {
-++			brcmf_pcie_write_reg32(devinfo,
-++					       BRCMF_PCIE_PCIE2REG_CONFIGADDR,
-++					       cfg_offset[i]);
-++			val = brcmf_pcie_read_reg32(devinfo,
-++				BRCMF_PCIE_PCIE2REG_CONFIGDATA);
-++			brcmf_dbg(PCIE, "config offset 0x%04x, value 0x%04x\n",
-++				  cfg_offset[i], val);
-++			brcmf_pcie_write_reg32(devinfo,
-++					       BRCMF_PCIE_PCIE2REG_CONFIGDATA,
-++					       val);
-++		}
-+ 	}
-+ }
-+ 
-+@@ -519,8 +528,6 @@ static void brcmf_pcie_attach(struct brc
-+ 	u32 config;
-+ 
-+ 	brcmf_pcie_select_core(devinfo, BCMA_CORE_PCIE2);
-+-	if (brcmf_pcie_read_reg32(devinfo, BRCMF_PCIE_PCIE2REG_INTMASK) != 0)
-+-		brcmf_pcie_reset_device(devinfo);
-+ 	/* BAR1 window may not be sized properly */
-+ 	brcmf_pcie_select_core(devinfo, BCMA_CORE_PCIE2);
-+ 	brcmf_pcie_write_reg32(devinfo, BRCMF_PCIE_PCIE2REG_CONFIGADDR, 0x4e0);
-+@@ -1636,6 +1643,23 @@ static int brcmf_pcie_buscoreprep(void *
-+ }
-+ 
-+ 
-++static int brcmf_pcie_buscore_reset(void *ctx, struct brcmf_chip *chip)
-++{
-++	struct brcmf_pciedev_info *devinfo = (struct brcmf_pciedev_info *)ctx;
-++	u32 val;
-++
-++	devinfo->ci = chip;
-++	brcmf_pcie_reset_device(devinfo);
-++
-++	val = brcmf_pcie_read_reg32(devinfo, BRCMF_PCIE_PCIE2REG_MAILBOXINT);
-++	if (val != 0xffffffff)
-++		brcmf_pcie_write_reg32(devinfo, BRCMF_PCIE_PCIE2REG_MAILBOXINT,
-++				       val);
-++
-++	return 0;
-++}
-++
-++
-+ static void brcmf_pcie_buscore_activate(void *ctx, struct brcmf_chip *chip,
-+ 					u32 rstvec)
-+ {
-+@@ -1647,6 +1671,7 @@ static void brcmf_pcie_buscore_activate(
-+ 
-+ static const struct brcmf_buscore_ops brcmf_pcie_buscore_ops = {
-+ 	.prepare = brcmf_pcie_buscoreprep,
-++	.reset = brcmf_pcie_buscore_reset,
-+ 	.activate = brcmf_pcie_buscore_activate,
-+ 	.read32 = brcmf_pcie_buscore_read32,
-+ 	.write32 = brcmf_pcie_buscore_write32,
-+@@ -1814,7 +1839,6 @@ brcmf_pcie_remove(struct pci_dev *pdev)
-+ 		brcmf_pcie_intr_disable(devinfo);
-+ 
-+ 	brcmf_detach(&pdev->dev);
-+-	brcmf_pcie_reset_device(devinfo);
-+ 
-+ 	kfree(bus->bus_priv.pcie);
-+ 	kfree(bus->msgbuf->flowrings);
-diff --git a/package/kernel/mac80211/patches/332-ath9k-ath9k_hw_analog_shift_rmw-use-REG_RMW.patch b/package/kernel/mac80211/patches/332-ath9k-ath9k_hw_analog_shift_rmw-use-REG_RMW.patch
-deleted file mode 100644
-index 3ce4428..0000000
---- a/package/kernel/mac80211/patches/332-ath9k-ath9k_hw_analog_shift_rmw-use-REG_RMW.patch
-+++ /dev/null
-@@ -1,27 +0,0 @@
--From: Oleksij Rempel <linux@rempel-privat.de>
--Date: Sun, 22 Mar 2015 19:29:59 +0100
--Subject: [PATCH] ath9k: ath9k_hw_analog_shift_rmw: use REG_RMW
--
--use REG_RMW in ath9k_hw_analog_shift_rmw.
--It will double execution speed on usb bus.
--
--Signed-off-by: Oleksij Rempel <linux@rempel-privat.de>
--Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
-----
--
----- a/drivers/net/wireless/ath/ath9k/eeprom.c
--+++ b/drivers/net/wireless/ath/ath9k/eeprom.c
--@@ -27,12 +27,7 @@ void ath9k_hw_analog_shift_regwrite(stru
-- void ath9k_hw_analog_shift_rmw(struct ath_hw *ah, u32 reg, u32 mask,
-- 			       u32 shift, u32 val)
-- {
---	u32 regVal;
---
---	regVal = REG_READ(ah, reg) & ~mask;
---	regVal |= (val << shift) & mask;
---
---	REG_WRITE(ah, reg, regVal);
--+	REG_RMW(ah, reg, ((val << shift) & mask), mask);
-- 
-- 	if (ah->config.analog_shiftreg)
-- 		udelay(100);
-diff --git a/package/kernel/mac80211/patches/333-ath9k-use-REG_RMW-and-rmw-buffer-in-ath9k_hw_4k_set_.patch b/package/kernel/mac80211/patches/333-ath9k-use-REG_RMW-and-rmw-buffer-in-ath9k_hw_4k_set_.patch
-deleted file mode 100644
-index 8f12b36..0000000
---- a/package/kernel/mac80211/patches/333-ath9k-use-REG_RMW-and-rmw-buffer-in-ath9k_hw_4k_set_.patch
-+++ /dev/null
-@@ -1,47 +0,0 @@
--From: Oleksij Rempel <linux@rempel-privat.de>
--Date: Sun, 22 Mar 2015 19:30:01 +0100
--Subject: [PATCH] ath9k: use REG_RMW and rmw buffer in
-- ath9k_hw_4k_set_gain
--
--it is possible to reduce time needed for this function
--by rplacing REG_WRITE with REG_RMW (plus dummy 0) and putt all commands
--in same buffer.
--
--Signed-off-by: Oleksij Rempel <linux@rempel-privat.de>
--Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
-----
--
----- a/drivers/net/wireless/ath/ath9k/eeprom_4k.c
--+++ b/drivers/net/wireless/ath/ath9k/eeprom_4k.c
--@@ -772,15 +772,14 @@ static void ath9k_hw_4k_set_gain(struct
-- 				 struct ar5416_eeprom_4k *eep,
-- 				 u8 txRxAttenLocal)
-- {
---	REG_WRITE(ah, AR_PHY_SWITCH_CHAIN_0,
---		  pModal->antCtrlChain[0]);
---
---	REG_WRITE(ah, AR_PHY_TIMING_CTRL4(0),
---		  (REG_READ(ah, AR_PHY_TIMING_CTRL4(0)) &
---		   ~(AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF |
---		     AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF)) |
---		  SM(pModal->iqCalICh[0], AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF) |
---		  SM(pModal->iqCalQCh[0], AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF));
--+	ENABLE_REG_RMW_BUFFER(ah);
--+	REG_RMW(ah, AR_PHY_SWITCH_CHAIN_0,
--+		pModal->antCtrlChain[0], 0);
--+
--+	REG_RMW(ah, AR_PHY_TIMING_CTRL4(0),
--+		SM(pModal->iqCalICh[0], AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF) |
--+		SM(pModal->iqCalQCh[0], AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF),
--+		AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF | AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF);
-- 
-- 	if ((eep->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >=
-- 	    AR5416_EEP_MINOR_VER_3) {
--@@ -819,6 +818,7 @@ static void ath9k_hw_4k_set_gain(struct
-- 		      AR9280_PHY_RXGAIN_TXRX_ATTEN, txRxAttenLocal);
-- 	REG_RMW_FIELD(ah, AR_PHY_RXGAIN + 0x1000,
-- 		      AR9280_PHY_RXGAIN_TXRX_MARGIN, pModal->rxTxMarginCh[0]);
--+	REG_RMW_BUFFER_FLUSH(ah);
-- }
-- 
-- /*
-diff --git a/package/kernel/mac80211/patches/334-ath9k-use-REG_RMW-and-rmw-buffer-in-ath9k_hw_def_set.patch b/package/kernel/mac80211/patches/334-ath9k-use-REG_RMW-and-rmw-buffer-in-ath9k_hw_def_set.patch
-deleted file mode 100644
-index f26e059..0000000
---- a/package/kernel/mac80211/patches/334-ath9k-use-REG_RMW-and-rmw-buffer-in-ath9k_hw_def_set.patch
-+++ /dev/null
-@@ -1,67 +0,0 @@
--From: Oleksij Rempel <linux@rempel-privat.de>
--Date: Sun, 22 Mar 2015 19:30:03 +0100
--Subject: [PATCH] ath9k: use REG_RMW and rmw buffer in
-- ath9k_hw_def_set_gain
--
--Signed-off-by: Oleksij Rempel <linux@rempel-privat.de>
--Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
-----
--
----- a/drivers/net/wireless/ath/ath9k/eeprom_def.c
--+++ b/drivers/net/wireless/ath/ath9k/eeprom_def.c
--@@ -466,6 +466,7 @@ static void ath9k_hw_def_set_gain(struct
-- 				  struct ar5416_eeprom_def *eep,
-- 				  u8 txRxAttenLocal, int regChainOffset, int i)
-- {
--+	ENABLE_REG_RMW_BUFFER(ah);
-- 	if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_3) {
-- 		txRxAttenLocal = pModal->txRxAttenCh[i];
-- 
--@@ -483,16 +484,12 @@ static void ath9k_hw_def_set_gain(struct
-- 			      AR_PHY_GAIN_2GHZ_XATTEN2_DB,
-- 			      pModal->xatten2Db[i]);
-- 		} else {
---			REG_WRITE(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
---			  (REG_READ(ah, AR_PHY_GAIN_2GHZ + regChainOffset) &
---			   ~AR_PHY_GAIN_2GHZ_BSW_MARGIN)
---			  | SM(pModal-> bswMargin[i],
---			       AR_PHY_GAIN_2GHZ_BSW_MARGIN));
---			REG_WRITE(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
---			  (REG_READ(ah, AR_PHY_GAIN_2GHZ + regChainOffset) &
---			   ~AR_PHY_GAIN_2GHZ_BSW_ATTEN)
---			  | SM(pModal->bswAtten[i],
---			       AR_PHY_GAIN_2GHZ_BSW_ATTEN));
--+			REG_RMW(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
--+				SM(pModal-> bswMargin[i], AR_PHY_GAIN_2GHZ_BSW_MARGIN),
--+				AR_PHY_GAIN_2GHZ_BSW_MARGIN);
--+			REG_RMW(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
--+				SM(pModal->bswAtten[i], AR_PHY_GAIN_2GHZ_BSW_ATTEN),
--+				AR_PHY_GAIN_2GHZ_BSW_ATTEN);
-- 		}
-- 	}
-- 
--@@ -504,17 +501,14 @@ static void ath9k_hw_def_set_gain(struct
-- 		      AR_PHY_RXGAIN + regChainOffset,
-- 		      AR9280_PHY_RXGAIN_TXRX_MARGIN, pModal->rxTxMarginCh[i]);
-- 	} else {
---		REG_WRITE(ah,
---			  AR_PHY_RXGAIN + regChainOffset,
---			  (REG_READ(ah, AR_PHY_RXGAIN + regChainOffset) &
---			   ~AR_PHY_RXGAIN_TXRX_ATTEN)
---			  | SM(txRxAttenLocal, AR_PHY_RXGAIN_TXRX_ATTEN));
---		REG_WRITE(ah,
---			  AR_PHY_GAIN_2GHZ + regChainOffset,
---			  (REG_READ(ah, AR_PHY_GAIN_2GHZ + regChainOffset) &
---			   ~AR_PHY_GAIN_2GHZ_RXTX_MARGIN) |
---			  SM(pModal->rxTxMarginCh[i], AR_PHY_GAIN_2GHZ_RXTX_MARGIN));
--+		REG_RMW(ah, AR_PHY_RXGAIN + regChainOffset,
--+			SM(txRxAttenLocal, AR_PHY_RXGAIN_TXRX_ATTEN),
--+			AR_PHY_RXGAIN_TXRX_ATTEN);
--+		REG_RMW(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
--+			SM(pModal->rxTxMarginCh[i], AR_PHY_GAIN_2GHZ_RXTX_MARGIN),
--+			AR_PHY_GAIN_2GHZ_RXTX_MARGIN);
-- 	}
--+	REG_RMW_BUFFER_FLUSH(ah);
-- }
-- 
-- static void ath9k_hw_def_set_board_values(struct ath_hw *ah,
-diff --git a/package/kernel/mac80211/patches/335-brcmfmac-Fix-oops-when-SDIO-device-is-removed.patch b/package/kernel/mac80211/patches/335-brcmfmac-Fix-oops-when-SDIO-device-is-removed.patch
-deleted file mode 100644
-index 5e63a80..0000000
---- a/package/kernel/mac80211/patches/335-brcmfmac-Fix-oops-when-SDIO-device-is-removed.patch
-+++ /dev/null
-@@ -1,44 +0,0 @@
--From: Hante Meuleman <meuleman@broadcom.com>
--Date: Fri, 6 Mar 2015 18:40:38 +0100
--Subject: [PATCH] brcmfmac: Fix oops when SDIO device is removed.
--
--On removal of SDIO card both functions of card will be getting
--a remove call. When the first is hanging in ctrl frame xmit then
--the second will cause oops. This patch fixes the xmit ctrl
--handling in case of serious errors and also limits the handling
--for remove to function 1 only.
--
--Reviewed-by: Arend Van Spriel <arend@broadcom.com>
--Reviewed-by: Franky (Zhenhui) Lin <frankyl@broadcom.com>
--Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
--Reviewed-by: Daniel (Deognyoun) Kim <dekim@broadcom.com>
--Signed-off-by: Hante Meuleman <meuleman@broadcom.com>
--Signed-off-by: Arend van Spriel <arend@broadcom.com>
--Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
-----
--
----- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
--+++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
--@@ -1194,7 +1194,7 @@ static void brcmf_ops_sdio_remove(struct
-- 	brcmf_dbg(SDIO, "sdio device ID: 0x%04x\n", func->device);
-- 	brcmf_dbg(SDIO, "Function: %d\n", func->num);
-- 
---	if (func->num != 1 && func->num != 2)
--+	if (func->num != 1)
-- 		return;
-- 
-- 	bus_if = dev_get_drvdata(&func->dev);
----- a/drivers/net/wireless/brcm80211/brcmfmac/sdio.c
--+++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio.c
--@@ -2740,6 +2740,11 @@ static void brcmf_sdio_dpc(struct brcmf_
-- 	if ((bus->sdiodev->state != BRCMF_SDIOD_DATA) || (err != 0)) {
-- 		brcmf_err("failed backplane access over SDIO, halting operation\n");
-- 		atomic_set(&bus->intstatus, 0);
--+		if (bus->ctrl_frame_stat) {
--+			bus->ctrl_frame_err = -ENODEV;
--+			bus->ctrl_frame_stat = false;
--+			brcmf_sdio_wait_event_wakeup(bus);
--+		}
-- 	} else if (atomic_read(&bus->intstatus) ||
-- 		   atomic_read(&bus->ipend) > 0 ||
-- 		   (!atomic_read(&bus->fcstate) &&
-diff --git a/package/kernel/mac80211/patches/336-brcmfmac-Simplify-watchdog-sleep.patch b/package/kernel/mac80211/patches/336-brcmfmac-Simplify-watchdog-sleep.patch
-deleted file mode 100644
-index 201da75..0000000
---- a/package/kernel/mac80211/patches/336-brcmfmac-Simplify-watchdog-sleep.patch
-+++ /dev/null
-@@ -1,157 +0,0 @@
--From: Hante Meuleman <meuleman@broadcom.com>
--Date: Fri, 6 Mar 2015 18:40:39 +0100
--Subject: [PATCH] brcmfmac: Simplify watchdog sleep.
--
--The watchdog thread is used to put the SDIO bus to sleep when the
--system is idling. This patch simplifies the way it is determined
--when sleep can be entered.
--
--Reviewed-by: Arend Van Spriel <arend@broadcom.com>
--Reviewed-by: Franky (Zhenhui) Lin <frankyl@broadcom.com>
--Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
--Reviewed-by: Daniel (Deognyoun) Kim <dekim@broadcom.com>
--Signed-off-by: Hante Meuleman <meuleman@broadcom.com>
--Signed-off-by: Arend van Spriel <arend@broadcom.com>
--Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
-----
--
----- a/drivers/net/wireless/brcm80211/brcmfmac/sdio.c
--+++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio.c
--@@ -485,10 +485,9 @@ struct brcmf_sdio {
-- #endif				/* DEBUG */
-- 
-- 	uint clkstate;		/* State of sd and backplane clock(s) */
---	bool activity;		/* Activity flag for clock down */
-- 	s32 idletime;		/* Control for activity timeout */
---	s32 idlecount;	/* Activity timeout counter */
---	s32 idleclock;	/* How to set bus driver when idle */
--+	s32 idlecount;		/* Activity timeout counter */
--+	s32 idleclock;		/* How to set bus driver when idle */
-- 	bool rxflow_mode;	/* Rx flow control mode */
-- 	bool rxflow;		/* Is rx flow control on */
-- 	bool alp_only;		/* Don't use HT clock (ALP only) */
--@@ -511,6 +510,7 @@ struct brcmf_sdio {
-- 	struct workqueue_struct *brcmf_wq;
-- 	struct work_struct datawork;
-- 	atomic_t dpc_tskcnt;
--+	atomic_t dpc_running;
-- 
-- 	bool txoff;		/* Transmit flow-controlled */
-- 	struct brcmf_sdio_count sdcnt;
--@@ -959,13 +959,8 @@ static int brcmf_sdio_clkctl(struct brcm
-- 	brcmf_dbg(SDIO, "Enter\n");
-- 
-- 	/* Early exit if we're already there */
---	if (bus->clkstate == target) {
---		if (target == CLK_AVAIL) {
---			brcmf_sdio_wd_timer(bus, BRCMF_WD_POLL_MS);
---			bus->activity = true;
---		}
--+	if (bus->clkstate == target)
-- 		return 0;
---	}
-- 
-- 	switch (target) {
-- 	case CLK_AVAIL:
--@@ -975,7 +970,6 @@ static int brcmf_sdio_clkctl(struct brcm
-- 		/* Now request HT Avail on the backplane */
-- 		brcmf_sdio_htclk(bus, true, pendok);
-- 		brcmf_sdio_wd_timer(bus, BRCMF_WD_POLL_MS);
---		bus->activity = true;
-- 		break;
-- 
-- 	case CLK_SDONLY:
--@@ -1024,17 +1018,6 @@ brcmf_sdio_bus_sleep(struct brcmf_sdio *
-- 
-- 		/* Going to sleep */
-- 		if (sleep) {
---			/* Don't sleep if something is pending */
---			if (atomic_read(&bus->intstatus) ||
---			    atomic_read(&bus->ipend) > 0 ||
---			    bus->ctrl_frame_stat ||
---			    (!atomic_read(&bus->fcstate) &&
---			    brcmu_pktq_mlen(&bus->txq, ~bus->flowcontrol) &&
---			    data_ok(bus))) {
---				 err = -EBUSY;
---				 goto done;
---			}
---
-- 			clkcsr = brcmf_sdiod_regrb(bus->sdiodev,
-- 						   SBSDIO_FUNC1_CHIPCLKCSR,
-- 						   &err);
--@@ -1045,11 +1028,7 @@ brcmf_sdio_bus_sleep(struct brcmf_sdio *
-- 						  SBSDIO_ALP_AVAIL_REQ, &err);
-- 			}
-- 			err = brcmf_sdio_kso_control(bus, false);
---			/* disable watchdog */
---			if (!err)
---				brcmf_sdio_wd_timer(bus, 0);
-- 		} else {
---			bus->idlecount = 0;
-- 			err = brcmf_sdio_kso_control(bus, true);
-- 		}
-- 		if (err) {
--@@ -3566,7 +3545,7 @@ void brcmf_sdio_isr(struct brcmf_sdio *b
-- 	queue_work(bus->brcmf_wq, &bus->datawork);
-- }
-- 
---static bool brcmf_sdio_bus_watchdog(struct brcmf_sdio *bus)
--+static void brcmf_sdio_bus_watchdog(struct brcmf_sdio *bus)
-- {
-- 	brcmf_dbg(TIMER, "Enter\n");
-- 
--@@ -3627,22 +3606,21 @@ static bool brcmf_sdio_bus_watchdog(stru
-- #endif				/* DEBUG */
-- 
-- 	/* On idle timeout clear activity flag and/or turn off clock */
---	if ((bus->idletime > 0) && (bus->clkstate == CLK_AVAIL)) {
---		if (++bus->idlecount >= bus->idletime) {
--+	if ((atomic_read(&bus->dpc_tskcnt) == 0) &&
--+	    (atomic_read(&bus->dpc_running) == 0) &&
--+	    (bus->idletime > 0) && (bus->clkstate == CLK_AVAIL)) {
--+		bus->idlecount++;
--+		if (bus->idlecount > bus->idletime) {
--+			brcmf_dbg(SDIO, "idle\n");
--+			sdio_claim_host(bus->sdiodev->func[1]);
--+			brcmf_sdio_wd_timer(bus, 0);
-- 			bus->idlecount = 0;
---			if (bus->activity) {
---				bus->activity = false;
---				brcmf_sdio_wd_timer(bus, BRCMF_WD_POLL_MS);
---			} else {
---				brcmf_dbg(SDIO, "idle\n");
---				sdio_claim_host(bus->sdiodev->func[1]);
---				brcmf_sdio_bus_sleep(bus, true, false);
---				sdio_release_host(bus->sdiodev->func[1]);
---			}
--+			brcmf_sdio_bus_sleep(bus, true, false);
--+			sdio_release_host(bus->sdiodev->func[1]);
-- 		}
--+	} else {
--+		bus->idlecount = 0;
-- 	}
---
---	return (atomic_read(&bus->ipend) > 0);
-- }
-- 
-- static void brcmf_sdio_dataworker(struct work_struct *work)
--@@ -3651,8 +3629,11 @@ static void brcmf_sdio_dataworker(struct
-- 					      datawork);
-- 
-- 	while (atomic_read(&bus->dpc_tskcnt)) {
--+		atomic_set(&bus->dpc_running, 1);
-- 		atomic_set(&bus->dpc_tskcnt, 0);
-- 		brcmf_sdio_dpc(bus);
--+		bus->idlecount = 0;
--+		atomic_set(&bus->dpc_running, 0);
-- 	}
-- 	if (brcmf_sdiod_freezing(bus->sdiodev)) {
-- 		brcmf_sdiod_change_state(bus->sdiodev, BRCMF_SDIOD_DOWN);
--@@ -4154,6 +4135,7 @@ struct brcmf_sdio *brcmf_sdio_probe(stru
-- 	}
-- 	/* Initialize DPC thread */
-- 	atomic_set(&bus->dpc_tskcnt, 0);
--+	atomic_set(&bus->dpc_running, 0);
-- 
-- 	/* Assign bus interface call back */
-- 	bus->sdiodev->bus_if->dev = bus->sdiodev->dev;
-diff --git a/package/kernel/mac80211/patches/337-brcmfmac-Fix-possible-race-condition.patch b/package/kernel/mac80211/patches/337-brcmfmac-Fix-possible-race-condition.patch
-deleted file mode 100644
-index 3a2de7a..0000000
---- a/package/kernel/mac80211/patches/337-brcmfmac-Fix-possible-race-condition.patch
-+++ /dev/null
-@@ -1,83 +0,0 @@
--From: Hante Meuleman <meuleman@broadcom.com>
--Date: Fri, 6 Mar 2015 18:40:40 +0100
--Subject: [PATCH] brcmfmac: Fix possible race-condition.
--
--SDIO is using a "shared" variable to handoff ctl frames to DPC
--and to see when they are done. In a timeout situation this can
--lead to erroneous situation where DPC started to handle the ctl
--frame while the timeout expired. This patch will fix this by
--adding locking around the shared variable.
--
--Reviewed-by: Arend Van Spriel <arend@broadcom.com>
--Reviewed-by: Franky (Zhenhui) Lin <frankyl@broadcom.com>
--Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
--Reviewed-by: Daniel (Deognyoun) Kim <dekim@broadcom.com>
--Signed-off-by: Hante Meuleman <meuleman@broadcom.com>
--Signed-off-by: Arend van Spriel <arend@broadcom.com>
--Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
-----
--
----- a/drivers/net/wireless/brcm80211/brcmfmac/sdio.c
--+++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio.c
--@@ -2700,11 +2700,13 @@ static void brcmf_sdio_dpc(struct brcmf_
-- 	if (bus->ctrl_frame_stat && (bus->clkstate == CLK_AVAIL) &&
-- 	    data_ok(bus)) {
-- 		sdio_claim_host(bus->sdiodev->func[1]);
---		err = brcmf_sdio_tx_ctrlframe(bus,  bus->ctrl_frame_buf,
---					      bus->ctrl_frame_len);
--+		if (bus->ctrl_frame_stat) {
--+			err = brcmf_sdio_tx_ctrlframe(bus,  bus->ctrl_frame_buf,
--+						      bus->ctrl_frame_len);
--+			bus->ctrl_frame_err = err;
--+			bus->ctrl_frame_stat = false;
--+		}
-- 		sdio_release_host(bus->sdiodev->func[1]);
---		bus->ctrl_frame_err = err;
---		bus->ctrl_frame_stat = false;
-- 		brcmf_sdio_wait_event_wakeup(bus);
-- 	}
-- 	/* Send queued frames (limit 1 if rx may still be pending) */
--@@ -2720,9 +2722,13 @@ static void brcmf_sdio_dpc(struct brcmf_
-- 		brcmf_err("failed backplane access over SDIO, halting operation\n");
-- 		atomic_set(&bus->intstatus, 0);
-- 		if (bus->ctrl_frame_stat) {
---			bus->ctrl_frame_err = -ENODEV;
---			bus->ctrl_frame_stat = false;
---			brcmf_sdio_wait_event_wakeup(bus);
--+			sdio_claim_host(bus->sdiodev->func[1]);
--+			if (bus->ctrl_frame_stat) {
--+				bus->ctrl_frame_err = -ENODEV;
--+				bus->ctrl_frame_stat = false;
--+				brcmf_sdio_wait_event_wakeup(bus);
--+			}
--+			sdio_release_host(bus->sdiodev->func[1]);
-- 		}
-- 	} else if (atomic_read(&bus->intstatus) ||
-- 		   atomic_read(&bus->ipend) > 0 ||
--@@ -2930,15 +2936,20 @@ brcmf_sdio_bus_txctl(struct device *dev,
-- 	brcmf_sdio_trigger_dpc(bus);
-- 	wait_event_interruptible_timeout(bus->ctrl_wait, !bus->ctrl_frame_stat,
-- 					 msecs_to_jiffies(CTL_DONE_TIMEOUT));
---
---	if (!bus->ctrl_frame_stat) {
--+	ret = 0;
--+	if (bus->ctrl_frame_stat) {
--+		sdio_claim_host(bus->sdiodev->func[1]);
--+		if (bus->ctrl_frame_stat) {
--+			brcmf_dbg(SDIO, "ctrl_frame timeout\n");
--+			bus->ctrl_frame_stat = false;
--+			ret = -ETIMEDOUT;
--+		}
--+		sdio_release_host(bus->sdiodev->func[1]);
--+	}
--+	if (!ret) {
-- 		brcmf_dbg(SDIO, "ctrl_frame complete, err=%d\n",
-- 			  bus->ctrl_frame_err);
-- 		ret = bus->ctrl_frame_err;
---	} else {
---		brcmf_dbg(SDIO, "ctrl_frame timeout\n");
---		bus->ctrl_frame_stat = false;
---		ret = -ETIMEDOUT;
-- 	}
-- 
-- 	if (ret)
-diff --git a/package/kernel/mac80211/patches/338-brcmfmac-Add-support-for-BCM4345-SDIO-chipset.patch b/package/kernel/mac80211/patches/338-brcmfmac-Add-support-for-BCM4345-SDIO-chipset.patch
-deleted file mode 100644
-index c9eb900..0000000
---- a/package/kernel/mac80211/patches/338-brcmfmac-Add-support-for-BCM4345-SDIO-chipset.patch
-+++ /dev/null
-@@ -1,86 +0,0 @@
--From: Syed Asifful Dayyan <syedd@broadcom.com>
--Date: Fri, 6 Mar 2015 18:40:42 +0100
--Subject: [PATCH] brcmfmac: Add support for BCM4345 SDIO chipset.
--
--These changes add support for BCM4345 SDIO chipset.
--
--Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
--Reviewed-by: Arend Van Spriel <arend@broadcom.com>
--Reviewed-by: Hante Meuleman <meuleman@broadcom.com>
--Reviewed-by: Daniel (Deognyoun) Kim <dekim@broadcom.com>
--Signed-off-by: Syed Asifful Dayyan <syedd@broadcom.com>
--Signed-off-by: Arend van Spriel <arend@broadcom.com>
--Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
-----
--
----- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
--+++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
--@@ -1096,6 +1096,7 @@ static const struct sdio_device_id brcmf
-- 	BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_43341),
-- 	BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_43362),
-- 	BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_4335_4339),
--+	BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_4345),
-- 	BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_4354),
-- 	{ /* end: all zeroes */ }
-- };
----- a/drivers/net/wireless/brcm80211/brcmfmac/chip.c
--+++ b/drivers/net/wireless/brcm80211/brcmfmac/chip.c
--@@ -491,6 +491,10 @@ static void brcmf_chip_get_raminfo(struc
-- 	case BRCM_CC_43362_CHIP_ID:
-- 		ci->pub.ramsize = 0x3c000;
-- 		break;
--+	case BRCM_CC_4345_CHIP_ID:
--+		ci->pub.ramsize = 0xc8000;
--+		ci->pub.rambase = 0x198000;
--+		break;
-- 	case BRCM_CC_4339_CHIP_ID:
-- 	case BRCM_CC_4354_CHIP_ID:
-- 	case BRCM_CC_4356_CHIP_ID:
----- a/drivers/net/wireless/brcm80211/brcmfmac/sdio.c
--+++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio.c
--@@ -617,6 +617,8 @@ static const struct sdiod_drive_str sdio
-- #define BCM43362_NVRAM_NAME		"brcm/brcmfmac43362-sdio.txt"
-- #define BCM4339_FIRMWARE_NAME		"brcm/brcmfmac4339-sdio.bin"
-- #define BCM4339_NVRAM_NAME		"brcm/brcmfmac4339-sdio.txt"
--+#define BCM4345_FIRMWARE_NAME		"brcm/brcmfmac4345-sdio.bin"
--+#define BCM4345_NVRAM_NAME		"brcm/brcmfmac4345-sdio.txt"
-- #define BCM4354_FIRMWARE_NAME		"brcm/brcmfmac4354-sdio.bin"
-- #define BCM4354_NVRAM_NAME		"brcm/brcmfmac4354-sdio.txt"
-- 
--@@ -640,6 +642,8 @@ MODULE_FIRMWARE(BCM43362_FIRMWARE_NAME);
-- MODULE_FIRMWARE(BCM43362_NVRAM_NAME);
-- MODULE_FIRMWARE(BCM4339_FIRMWARE_NAME);
-- MODULE_FIRMWARE(BCM4339_NVRAM_NAME);
--+MODULE_FIRMWARE(BCM4345_FIRMWARE_NAME);
--+MODULE_FIRMWARE(BCM4345_NVRAM_NAME);
-- MODULE_FIRMWARE(BCM4354_FIRMWARE_NAME);
-- MODULE_FIRMWARE(BCM4354_NVRAM_NAME);
-- 
--@@ -669,6 +673,7 @@ static const struct brcmf_firmware_names
-- 	{ BRCM_CC_4335_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4335) },
-- 	{ BRCM_CC_43362_CHIP_ID, 0xFFFFFFFE, BRCMF_FIRMWARE_NVRAM(BCM43362) },
-- 	{ BRCM_CC_4339_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4339) },
--+	{ BRCM_CC_4345_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4345) },
-- 	{ BRCM_CC_4354_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4354) }
-- };
-- 
----- a/drivers/net/wireless/brcm80211/include/brcm_hw_ids.h
--+++ b/drivers/net/wireless/brcm80211/include/brcm_hw_ids.h
--@@ -37,6 +37,7 @@
-- #define BRCM_CC_43362_CHIP_ID		43362
-- #define BRCM_CC_4335_CHIP_ID		0x4335
-- #define BRCM_CC_4339_CHIP_ID		0x4339
--+#define BRCM_CC_4345_CHIP_ID		0x4345
-- #define BRCM_CC_4354_CHIP_ID		0x4354
-- #define BRCM_CC_4356_CHIP_ID		0x4356
-- #define BRCM_CC_43566_CHIP_ID		43566
----- a/include/linux/mmc/sdio_ids.h
--+++ b/include/linux/mmc/sdio_ids.h
--@@ -33,6 +33,7 @@
-- #define SDIO_DEVICE_ID_BROADCOM_43341		0xa94d
-- #define SDIO_DEVICE_ID_BROADCOM_4335_4339	0x4335
-- #define SDIO_DEVICE_ID_BROADCOM_43362		0xa962
--+#define SDIO_DEVICE_ID_BROADCOM_4345		0x4345
-- #define SDIO_DEVICE_ID_BROADCOM_4354		0x4354
-- 
-- #define SDIO_VENDOR_ID_INTEL			0x0089
-diff --git a/package/kernel/mac80211/patches/339-brcmfmac-remove-duplication-of-ramsize-info.patch b/package/kernel/mac80211/patches/339-brcmfmac-remove-duplication-of-ramsize-info.patch
-deleted file mode 100644
-index 7a688c4..0000000
---- a/package/kernel/mac80211/patches/339-brcmfmac-remove-duplication-of-ramsize-info.patch
-+++ /dev/null
-@@ -1,48 +0,0 @@
--From: Arend van Spriel <arend@broadcom.com>
--Date: Wed, 11 Mar 2015 16:11:27 +0100
--Subject: [PATCH] brcmfmac: remove duplication of ramsize info
--
--Removing the ramsize from the brcmf_sdio structure to avoid
--duplication. The information is available in brcmf_chip
--structure.
--
--Reviewed-by: Hante Meuleman <meuleman@broadcom.com>
--Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
--Signed-off-by: Arend van Spriel <arend@broadcom.com>
--Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
-----
--
----- a/drivers/net/wireless/brcm80211/brcmfmac/sdio.c
--+++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio.c
--@@ -432,8 +432,6 @@ struct brcmf_sdio {
-- 	struct brcmf_sdio_dev *sdiodev;	/* sdio device handler */
-- 	struct brcmf_chip *ci;	/* Chip info struct */
-- 
---	u32 ramsize;		/* Size of RAM in SOCRAM (bytes) */
---
-- 	u32 hostintmask;	/* Copy of Host Interrupt Mask */
-- 	atomic_t intstatus;	/* Intstatus bits (events) pending */
-- 	atomic_t fcstate;	/* State of dongle flow-control */
--@@ -1075,7 +1073,7 @@ static int brcmf_sdio_readshared(struct
-- 	struct sdpcm_shared_le sh_le;
-- 	__le32 addr_le;
-- 
---	shaddr = bus->ci->rambase + bus->ramsize - 4;
--+	shaddr = bus->ci->rambase + bus->ci->ramsize - 4;
-- 
-- 	/*
-- 	 * Read last word in socram to determine
--@@ -3871,13 +3869,6 @@ brcmf_sdio_probe_attach(struct brcmf_sdi
-- 		drivestrength = DEFAULT_SDIO_DRIVE_STRENGTH;
-- 	brcmf_sdio_drivestrengthinit(bus->sdiodev, bus->ci, drivestrength);
-- 
---	/* Get info on the SOCRAM cores... */
---	bus->ramsize = bus->ci->ramsize;
---	if (!(bus->ramsize)) {
---		brcmf_err("failed to find SOCRAM memory!\n");
---		goto fail;
---	}
---
-- 	/* Set card control so an SDIO card reset does a WLAN backplane reset */
-- 	reg_val = brcmf_sdiod_regrb(bus->sdiodev,
-- 				    SDIO_CCCR_BRCM_CARDCTRL, &err);
-diff --git a/package/kernel/mac80211/patches/340-brcmfmac-always-perform-cores-checks.patch b/package/kernel/mac80211/patches/340-brcmfmac-always-perform-cores-checks.patch
-deleted file mode 100644
-index e2a2074..0000000
---- a/package/kernel/mac80211/patches/340-brcmfmac-always-perform-cores-checks.patch
-+++ /dev/null
-@@ -1,74 +0,0 @@
--From: Arend van Spriel <arend@broadcom.com>
--Date: Wed, 11 Mar 2015 16:11:28 +0100
--Subject: [PATCH] brcmfmac: always perform cores checks
--
--Instead of checking the cores in the chip only if CONFIG_BRCMDBG
--is selected perform the check always and extend it with more sanity
--checking.
--
--Reviewed-by: Hante Meuleman <meuleman@broadcom.com>
--Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
--Signed-off-by: Arend van Spriel <arend@broadcom.com>
--Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
-----
--
----- a/drivers/net/wireless/brcm80211/brcmfmac/chip.c
--+++ b/drivers/net/wireless/brcm80211/brcmfmac/chip.c
--@@ -419,13 +419,13 @@ static struct brcmf_core *brcmf_chip_add
-- 	return &core->pub;
-- }
-- 
---#ifdef DEBUG
-- /* safety check for chipinfo */
-- static int brcmf_chip_cores_check(struct brcmf_chip_priv *ci)
-- {
-- 	struct brcmf_core_priv *core;
-- 	bool need_socram = false;
-- 	bool has_socram = false;
--+	bool cpu_found = false;
-- 	int idx = 1;
-- 
-- 	list_for_each_entry(core, &ci->cores, list) {
--@@ -435,12 +435,14 @@ static int brcmf_chip_cores_check(struct
-- 
-- 		switch (core->pub.id) {
-- 		case BCMA_CORE_ARM_CM3:
--+			cpu_found = true;
-- 			need_socram = true;
-- 			break;
-- 		case BCMA_CORE_INTERNAL_MEM:
-- 			has_socram = true;
-- 			break;
-- 		case BCMA_CORE_ARM_CR4:
--+			cpu_found = true;
-- 			if (ci->pub.rambase == 0) {
-- 				brcmf_err("RAM base not provided with ARM CR4 core\n");
-- 				return -ENOMEM;
--@@ -451,19 +453,21 @@ static int brcmf_chip_cores_check(struct
-- 		}
-- 	}
-- 
--+	if (!cpu_found) {
--+		brcmf_err("CPU core not detected\n");
--+		return -ENXIO;
--+	}
-- 	/* check RAM core presence for ARM CM3 core */
-- 	if (need_socram && !has_socram) {
-- 		brcmf_err("RAM core not provided with ARM CM3 core\n");
-- 		return -ENODEV;
-- 	}
--+	if (!ci->pub.ramsize) {
--+		brcmf_err("RAM size is undetermined\n");
--+		return -ENOMEM;
--+	}
-- 	return 0;
-- }
---#else	/* DEBUG */
---static inline int brcmf_chip_cores_check(struct brcmf_chip_priv *ci)
---{
---	return 0;
---}
---#endif
-- 
-- static void brcmf_chip_get_raminfo(struct brcmf_chip_priv *ci)
-- {
-diff --git a/package/kernel/mac80211/patches/341-brcmfmac-rename-chip-download-functions.patch b/package/kernel/mac80211/patches/341-brcmfmac-rename-chip-download-functions.patch
-deleted file mode 100644
-index a272800..0000000
---- a/package/kernel/mac80211/patches/341-brcmfmac-rename-chip-download-functions.patch
-+++ /dev/null
-@@ -1,240 +0,0 @@
--From: Arend van Spriel <arend@broadcom.com>
--Date: Wed, 11 Mar 2015 16:11:29 +0100
--Subject: [PATCH] brcmfmac: rename chip download functions
--
--The functions brcmf_chip_[enter/exit]_download() are not exclusively
--used for firmware download so rename these more appropriate.
--
--Reviewed-by: Hante Meuleman <meuleman@broadcom.com>
--Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
--Signed-off-by: Arend van Spriel <arend@broadcom.com>
--Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
-----
--
----- a/drivers/net/wireless/brcm80211/brcmfmac/chip.c
--+++ b/drivers/net/wireless/brcm80211/brcmfmac/chip.c
--@@ -807,7 +807,7 @@ struct brcmf_chip *brcmf_chip_attach(voi
-- 		err = -EINVAL;
-- 	if (WARN_ON(!ops->prepare))
-- 		err = -EINVAL;
---	if (WARN_ON(!ops->exit_dl))
--+	if (WARN_ON(!ops->activate))
-- 		err = -EINVAL;
-- 	if (err < 0)
-- 		return ERR_PTR(-EINVAL);
--@@ -905,7 +905,7 @@ void brcmf_chip_resetcore(struct brcmf_c
-- }
-- 
-- static void
---brcmf_chip_cm3_enterdl(struct brcmf_chip_priv *chip)
--+brcmf_chip_cm3_set_passive(struct brcmf_chip_priv *chip)
-- {
-- 	struct brcmf_core *core;
-- 
--@@ -919,7 +919,7 @@ brcmf_chip_cm3_enterdl(struct brcmf_chip
-- 	brcmf_chip_resetcore(core, 0, 0, 0);
-- }
-- 
---static bool brcmf_chip_cm3_exitdl(struct brcmf_chip_priv *chip)
--+static bool brcmf_chip_cm3_set_active(struct brcmf_chip_priv *chip)
-- {
-- 	struct brcmf_core *core;
-- 
--@@ -929,7 +929,7 @@ static bool brcmf_chip_cm3_exitdl(struct
-- 		return false;
-- 	}
-- 
---	chip->ops->exit_dl(chip->ctx, &chip->pub, 0);
--+	chip->ops->activate(chip->ctx, &chip->pub, 0);
-- 
-- 	core = brcmf_chip_get_core(&chip->pub, BCMA_CORE_ARM_CM3);
-- 	brcmf_chip_resetcore(core, 0, 0, 0);
--@@ -938,7 +938,7 @@ static bool brcmf_chip_cm3_exitdl(struct
-- }
-- 
-- static inline void
---brcmf_chip_cr4_enterdl(struct brcmf_chip_priv *chip)
--+brcmf_chip_cr4_set_passive(struct brcmf_chip_priv *chip)
-- {
-- 	struct brcmf_core *core;
-- 
--@@ -951,11 +951,11 @@ brcmf_chip_cr4_enterdl(struct brcmf_chip
-- 			     D11_BCMA_IOCTL_PHYCLOCKEN);
-- }
-- 
---static bool brcmf_chip_cr4_exitdl(struct brcmf_chip_priv *chip, u32 rstvec)
--+static bool brcmf_chip_cr4_set_active(struct brcmf_chip_priv *chip, u32 rstvec)
-- {
-- 	struct brcmf_core *core;
-- 
---	chip->ops->exit_dl(chip->ctx, &chip->pub, rstvec);
--+	chip->ops->activate(chip->ctx, &chip->pub, rstvec);
-- 
-- 	/* restore ARM */
-- 	core = brcmf_chip_get_core(&chip->pub, BCMA_CORE_ARM_CR4);
--@@ -964,7 +964,7 @@ static bool brcmf_chip_cr4_exitdl(struct
-- 	return true;
-- }
-- 
---void brcmf_chip_enter_download(struct brcmf_chip *pub)
--+void brcmf_chip_set_passive(struct brcmf_chip *pub)
-- {
-- 	struct brcmf_chip_priv *chip;
-- 	struct brcmf_core *arm;
--@@ -974,14 +974,14 @@ void brcmf_chip_enter_download(struct br
-- 	chip = container_of(pub, struct brcmf_chip_priv, pub);
-- 	arm = brcmf_chip_get_core(pub, BCMA_CORE_ARM_CR4);
-- 	if (arm) {
---		brcmf_chip_cr4_enterdl(chip);
--+		brcmf_chip_cr4_set_passive(chip);
-- 		return;
-- 	}
-- 
---	brcmf_chip_cm3_enterdl(chip);
--+	brcmf_chip_cm3_set_passive(chip);
-- }
-- 
---bool brcmf_chip_exit_download(struct brcmf_chip *pub, u32 rstvec)
--+bool brcmf_chip_set_active(struct brcmf_chip *pub, u32 rstvec)
-- {
-- 	struct brcmf_chip_priv *chip;
-- 	struct brcmf_core *arm;
--@@ -991,9 +991,9 @@ bool brcmf_chip_exit_download(struct brc
-- 	chip = container_of(pub, struct brcmf_chip_priv, pub);
-- 	arm = brcmf_chip_get_core(pub, BCMA_CORE_ARM_CR4);
-- 	if (arm)
---		return brcmf_chip_cr4_exitdl(chip, rstvec);
--+		return brcmf_chip_cr4_set_active(chip, rstvec);
-- 
---	return brcmf_chip_cm3_exitdl(chip);
--+	return brcmf_chip_cm3_set_active(chip);
-- }
-- 
-- bool brcmf_chip_sr_capable(struct brcmf_chip *pub)
----- a/drivers/net/wireless/brcm80211/brcmfmac/chip.h
--+++ b/drivers/net/wireless/brcm80211/brcmfmac/chip.h
--@@ -64,7 +64,7 @@ struct brcmf_core {
--  * @write32: write 32-bit value over bus.
--  * @prepare: prepare bus for core configuration.
--  * @setup: bus-specific core setup.
--- * @exit_dl: exit download state.
--+ * @active: chip becomes active.
--  *	The callback should use the provided @rstvec when non-zero.
--  */
-- struct brcmf_buscore_ops {
--@@ -72,7 +72,7 @@ struct brcmf_buscore_ops {
-- 	void (*write32)(void *ctx, u32 addr, u32 value);
-- 	int (*prepare)(void *ctx);
-- 	int (*setup)(void *ctx, struct brcmf_chip *chip);
---	void (*exit_dl)(void *ctx, struct brcmf_chip *chip, u32 rstvec);
--+	void (*activate)(void *ctx, struct brcmf_chip *chip, u32 rstvec);
-- };
-- 
-- struct brcmf_chip *brcmf_chip_attach(void *ctx,
--@@ -84,8 +84,8 @@ bool brcmf_chip_iscoreup(struct brcmf_co
-- void brcmf_chip_coredisable(struct brcmf_core *core, u32 prereset, u32 reset);
-- void brcmf_chip_resetcore(struct brcmf_core *core, u32 prereset, u32 reset,
-- 			  u32 postreset);
---void brcmf_chip_enter_download(struct brcmf_chip *ci);
---bool brcmf_chip_exit_download(struct brcmf_chip *ci, u32 rstvec);
--+void brcmf_chip_set_passive(struct brcmf_chip *ci);
--+bool brcmf_chip_set_active(struct brcmf_chip *ci, u32 rstvec);
-- bool brcmf_chip_sr_capable(struct brcmf_chip *pub);
-- 
-- #endif /* BRCMF_AXIDMP_H */
----- a/drivers/net/wireless/brcm80211/brcmfmac/pcie.c
--+++ b/drivers/net/wireless/brcm80211/brcmfmac/pcie.c
--@@ -509,7 +509,7 @@ static void brcmf_pcie_attach(struct brc
-- 
-- static int brcmf_pcie_enter_download_state(struct brcmf_pciedev_info *devinfo)
-- {
---	brcmf_chip_enter_download(devinfo->ci);
--+	brcmf_chip_set_passive(devinfo->ci);
-- 
-- 	if (devinfo->ci->chip == BRCM_CC_43602_CHIP_ID) {
-- 		brcmf_pcie_select_core(devinfo, BCMA_CORE_ARM_CR4);
--@@ -536,7 +536,7 @@ static int brcmf_pcie_exit_download_stat
-- 		brcmf_chip_resetcore(core, 0, 0, 0);
-- 	}
-- 
---	return !brcmf_chip_exit_download(devinfo->ci, resetintr);
--+	return !brcmf_chip_set_active(devinfo->ci, resetintr);
-- }
-- 
-- 
--@@ -1566,8 +1566,8 @@ static int brcmf_pcie_buscoreprep(void *
-- }
-- 
-- 
---static void brcmf_pcie_buscore_exitdl(void *ctx, struct brcmf_chip *chip,
---				      u32 rstvec)
--+static void brcmf_pcie_buscore_activate(void *ctx, struct brcmf_chip *chip,
--+					u32 rstvec)
-- {
-- 	struct brcmf_pciedev_info *devinfo = (struct brcmf_pciedev_info *)ctx;
-- 
--@@ -1577,7 +1577,7 @@ static void brcmf_pcie_buscore_exitdl(vo
-- 
-- static const struct brcmf_buscore_ops brcmf_pcie_buscore_ops = {
-- 	.prepare = brcmf_pcie_buscoreprep,
---	.exit_dl = brcmf_pcie_buscore_exitdl,
--+	.activate = brcmf_pcie_buscore_activate,
-- 	.read32 = brcmf_pcie_buscore_read32,
-- 	.write32 = brcmf_pcie_buscore_write32,
-- };
----- a/drivers/net/wireless/brcm80211/brcmfmac/sdio.c
--+++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio.c
--@@ -3357,7 +3357,7 @@ static int brcmf_sdio_download_firmware(
-- 	brcmf_sdio_clkctl(bus, CLK_AVAIL, false);
-- 
-- 	/* Keep arm in reset */
---	brcmf_chip_enter_download(bus->ci);
--+	brcmf_chip_set_passive(bus->ci);
-- 
-- 	rstvec = get_unaligned_le32(fw->data);
-- 	brcmf_dbg(SDIO, "firmware rstvec: %x\n", rstvec);
--@@ -3378,7 +3378,7 @@ static int brcmf_sdio_download_firmware(
-- 	}
-- 
-- 	/* Take arm out of reset */
---	if (!brcmf_chip_exit_download(bus->ci, rstvec)) {
--+	if (!brcmf_chip_set_active(bus->ci, rstvec)) {
-- 		brcmf_err("error getting out of ARM core reset\n");
-- 		goto err;
-- 	}
--@@ -3771,8 +3771,8 @@ static int brcmf_sdio_buscoreprep(void *
-- 	return 0;
-- }
-- 
---static void brcmf_sdio_buscore_exitdl(void *ctx, struct brcmf_chip *chip,
---				      u32 rstvec)
--+static void brcmf_sdio_buscore_activate(void *ctx, struct brcmf_chip *chip,
--+					u32 rstvec)
-- {
-- 	struct brcmf_sdio_dev *sdiodev = ctx;
-- 	struct brcmf_core *core;
--@@ -3815,7 +3815,7 @@ static void brcmf_sdio_buscore_write32(v
-- 
-- static const struct brcmf_buscore_ops brcmf_sdio_buscore_ops = {
-- 	.prepare = brcmf_sdio_buscoreprep,
---	.exit_dl = brcmf_sdio_buscore_exitdl,
--+	.activate = brcmf_sdio_buscore_activate,
-- 	.read32 = brcmf_sdio_buscore_read32,
-- 	.write32 = brcmf_sdio_buscore_write32,
-- };
--@@ -4239,12 +4239,11 @@ void brcmf_sdio_remove(struct brcmf_sdio
-- 				sdio_claim_host(bus->sdiodev->func[1]);
-- 				brcmf_sdio_clkctl(bus, CLK_AVAIL, false);
-- 				/* Leave the device in state where it is
---				 * 'quiet'. This is done by putting it in
---				 * download_state which essentially resets
---				 * all necessary cores.
--+				 * 'passive'. This is done by resetting all
--+				 * necessary cores.
-- 				 */
-- 				msleep(20);
---				brcmf_chip_enter_download(bus->ci);
--+				brcmf_chip_set_passive(bus->ci);
-- 				brcmf_sdio_clkctl(bus, CLK_NONE, false);
-- 				sdio_release_host(bus->sdiodev->func[1]);
-- 			}
-diff --git a/package/kernel/mac80211/patches/342-brcmfmac-assure-device-is-ready-for-download-after-b.patch b/package/kernel/mac80211/patches/342-brcmfmac-assure-device-is-ready-for-download-after-b.patch
-deleted file mode 100644
-index 6b1dd81..0000000
---- a/package/kernel/mac80211/patches/342-brcmfmac-assure-device-is-ready-for-download-after-b.patch
-+++ /dev/null
-@@ -1,61 +0,0 @@
--From: Arend van Spriel <arend@broadcom.com>
--Date: Wed, 11 Mar 2015 16:11:30 +0100
--Subject: [PATCH] brcmfmac: assure device is ready for download after
-- brcmf_chip_attach()
--
--Make the brcmf_chip_attach() function responsible for putting the
--device in a state where it is accessible for firmware download.
--
--Reviewed-by: Hante Meuleman <meuleman@broadcom.com>
--Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
--Signed-off-by: Arend van Spriel <arend@broadcom.com>
--Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
-----
--
----- a/drivers/net/wireless/brcm80211/brcmfmac/chip.c
--+++ b/drivers/net/wireless/brcm80211/brcmfmac/chip.c
--@@ -786,12 +786,6 @@ static int brcmf_chip_setup(struct brcmf
-- 	if (chip->ops->setup)
-- 		ret = chip->ops->setup(chip->ctx, pub);
-- 
---	/*
---	 * Make sure any on-chip ARM is off (in case strapping is wrong),
---	 * or downloaded code was already running.
---	 */
---	brcmf_chip_disable_arm(chip, BCMA_CORE_ARM_CM3);
---	brcmf_chip_disable_arm(chip, BCMA_CORE_ARM_CR4);
-- 	return ret;
-- }
-- 
--@@ -833,6 +827,8 @@ struct brcmf_chip *brcmf_chip_attach(voi
-- 	if (err < 0)
-- 		goto fail;
-- 
--+	/* assure chip is passive for download */
--+	brcmf_chip_set_passive(&chip->pub);
-- 	return &chip->pub;
-- 
-- fail:
----- a/drivers/net/wireless/brcm80211/brcmfmac/pcie.c
--+++ b/drivers/net/wireless/brcm80211/brcmfmac/pcie.c
--@@ -509,8 +509,6 @@ static void brcmf_pcie_attach(struct brc
-- 
-- static int brcmf_pcie_enter_download_state(struct brcmf_pciedev_info *devinfo)
-- {
---	brcmf_chip_set_passive(devinfo->ci);
---
-- 	if (devinfo->ci->chip == BRCM_CC_43602_CHIP_ID) {
-- 		brcmf_pcie_select_core(devinfo, BCMA_CORE_ARM_CR4);
-- 		brcmf_pcie_write_reg32(devinfo, BRCMF_PCIE_ARMCR4REG_BANKIDX,
----- a/drivers/net/wireless/brcm80211/brcmfmac/sdio.c
--+++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio.c
--@@ -3356,9 +3356,6 @@ static int brcmf_sdio_download_firmware(
-- 	sdio_claim_host(bus->sdiodev->func[1]);
-- 	brcmf_sdio_clkctl(bus, CLK_AVAIL, false);
-- 
---	/* Keep arm in reset */
---	brcmf_chip_set_passive(bus->ci);
---
-- 	rstvec = get_unaligned_le32(fw->data);
-- 	brcmf_dbg(SDIO, "firmware rstvec: %x\n", rstvec);
-- 
-diff --git a/package/kernel/mac80211/patches/343-brcmfmac-extract-ram-size-info-from-internal-memory-.patch b/package/kernel/mac80211/patches/343-brcmfmac-extract-ram-size-info-from-internal-memory-.patch
-deleted file mode 100644
-index bcc2ed4..0000000
---- a/package/kernel/mac80211/patches/343-brcmfmac-extract-ram-size-info-from-internal-memory-.patch
-+++ /dev/null
-@@ -1,367 +0,0 @@
--From: Arend van Spriel <arend@broadcom.com>
--Date: Wed, 11 Mar 2015 16:11:31 +0100
--Subject: [PATCH] brcmfmac: extract ram size info from internal memory
-- registers
--
--Instead of hard-coded memory sizes it is possible to obtain that
--information from the internal memory registers.
--
--Reviewed-by: Hante Meuleman <meuleman@broadcom.com>
--Reviewed-by: Franky (Zhenhui) Lin <frankyl@broadcom.com>
--Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
--Signed-off-by: Arend van Spriel <arend@broadcom.com>
--Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
-----
--
----- a/drivers/net/wireless/brcm80211/brcmfmac/chip.c
--+++ b/drivers/net/wireless/brcm80211/brcmfmac/chip.c
--@@ -100,9 +100,6 @@
-- #define BCM4329_CORE_SOCRAM_BASE	0x18003000
-- /* ARM Cortex M3 core, ID 0x82a */
-- #define BCM4329_CORE_ARM_BASE		0x18002000
---#define BCM4329_RAMSIZE			0x48000
---/* bcm43143 */
---#define BCM43143_RAMSIZE		0x70000
-- 
-- #define CORE_SB(base, field) \
-- 		(base + SBCONFIGOFF + offsetof(struct sbconfig, field))
--@@ -150,6 +147,78 @@ struct sbconfig {
-- 	u32 sbidhigh;	/* identification */
-- };
-- 
--+/* bankidx and bankinfo reg defines corerev >= 8 */
--+#define SOCRAM_BANKINFO_RETNTRAM_MASK	0x00010000
--+#define SOCRAM_BANKINFO_SZMASK		0x0000007f
--+#define SOCRAM_BANKIDX_ROM_MASK		0x00000100
--+
--+#define SOCRAM_BANKIDX_MEMTYPE_SHIFT	8
--+/* socram bankinfo memtype */
--+#define SOCRAM_MEMTYPE_RAM		0
--+#define SOCRAM_MEMTYPE_R0M		1
--+#define SOCRAM_MEMTYPE_DEVRAM		2
--+
--+#define SOCRAM_BANKINFO_SZBASE		8192
--+#define SRCI_LSS_MASK		0x00f00000
--+#define SRCI_LSS_SHIFT		20
--+#define	SRCI_SRNB_MASK		0xf0
--+#define	SRCI_SRNB_SHIFT		4
--+#define	SRCI_SRBSZ_MASK		0xf
--+#define	SRCI_SRBSZ_SHIFT	0
--+#define SR_BSZ_BASE		14
--+
--+struct sbsocramregs {
--+	u32 coreinfo;
--+	u32 bwalloc;
--+	u32 extracoreinfo;
--+	u32 biststat;
--+	u32 bankidx;
--+	u32 standbyctrl;
--+
--+	u32 errlogstatus;	/* rev 6 */
--+	u32 errlogaddr;	/* rev 6 */
--+	/* used for patching rev 3 & 5 */
--+	u32 cambankidx;
--+	u32 cambankstandbyctrl;
--+	u32 cambankpatchctrl;
--+	u32 cambankpatchtblbaseaddr;
--+	u32 cambankcmdreg;
--+	u32 cambankdatareg;
--+	u32 cambankmaskreg;
--+	u32 PAD[1];
--+	u32 bankinfo;	/* corev 8 */
--+	u32 bankpda;
--+	u32 PAD[14];
--+	u32 extmemconfig;
--+	u32 extmemparitycsr;
--+	u32 extmemparityerrdata;
--+	u32 extmemparityerrcnt;
--+	u32 extmemwrctrlandsize;
--+	u32 PAD[84];
--+	u32 workaround;
--+	u32 pwrctl;		/* corerev >= 2 */
--+	u32 PAD[133];
--+	u32 sr_control;     /* corerev >= 15 */
--+	u32 sr_status;      /* corerev >= 15 */
--+	u32 sr_address;     /* corerev >= 15 */
--+	u32 sr_data;        /* corerev >= 15 */
--+};
--+
--+#define SOCRAMREGOFFS(_f)	offsetof(struct sbsocramregs, _f)
--+
--+#define ARMCR4_CAP		(0x04)
--+#define ARMCR4_BANKIDX		(0x40)
--+#define ARMCR4_BANKINFO		(0x44)
--+#define ARMCR4_BANKPDA		(0x4C)
--+
--+#define	ARMCR4_TCBBNB_MASK	0xf0
--+#define	ARMCR4_TCBBNB_SHIFT	4
--+#define	ARMCR4_TCBANB_MASK	0xf
--+#define	ARMCR4_TCBANB_SHIFT	0
--+
--+#define	ARMCR4_BSZ_MASK		0x3f
--+#define	ARMCR4_BSZ_MULT		8192
--+
-- struct brcmf_core_priv {
-- 	struct brcmf_core pub;
-- 	u32 wrapbase;
--@@ -443,10 +512,6 @@ static int brcmf_chip_cores_check(struct
-- 			break;
-- 		case BCMA_CORE_ARM_CR4:
-- 			cpu_found = true;
---			if (ci->pub.rambase == 0) {
---				brcmf_err("RAM base not provided with ARM CR4 core\n");
---				return -ENOMEM;
---			}
-- 			break;
-- 		default:
-- 			break;
--@@ -462,60 +527,160 @@ static int brcmf_chip_cores_check(struct
-- 		brcmf_err("RAM core not provided with ARM CM3 core\n");
-- 		return -ENODEV;
-- 	}
---	if (!ci->pub.ramsize) {
---		brcmf_err("RAM size is undetermined\n");
---		return -ENOMEM;
---	}
-- 	return 0;
-- }
-- 
---static void brcmf_chip_get_raminfo(struct brcmf_chip_priv *ci)
--+static u32 brcmf_chip_core_read32(struct brcmf_core_priv *core, u16 reg)
-- {
---	switch (ci->pub.chip) {
---	case BRCM_CC_4329_CHIP_ID:
---		ci->pub.ramsize = BCM4329_RAMSIZE;
---		break;
---	case BRCM_CC_43143_CHIP_ID:
---		ci->pub.ramsize = BCM43143_RAMSIZE;
---		break;
---	case BRCM_CC_43241_CHIP_ID:
---		ci->pub.ramsize = 0x90000;
---		break;
---	case BRCM_CC_4330_CHIP_ID:
---		ci->pub.ramsize = 0x48000;
---		break;
--+	return core->chip->ops->read32(core->chip->ctx, core->pub.base + reg);
--+}
--+
--+static void brcmf_chip_core_write32(struct brcmf_core_priv *core,
--+				    u16 reg, u32 val)
--+{
--+	core->chip->ops->write32(core->chip->ctx, core->pub.base + reg, val);
--+}
--+
--+static bool brcmf_chip_socram_banksize(struct brcmf_core_priv *core, u8 idx,
--+				       u32 *banksize)
--+{
--+	u32 bankinfo;
--+	u32 bankidx = (SOCRAM_MEMTYPE_RAM << SOCRAM_BANKIDX_MEMTYPE_SHIFT);
--+
--+	bankidx |= idx;
--+	brcmf_chip_core_write32(core, SOCRAMREGOFFS(bankidx), bankidx);
--+	bankinfo = brcmf_chip_core_read32(core, SOCRAMREGOFFS(bankinfo));
--+	*banksize = (bankinfo & SOCRAM_BANKINFO_SZMASK) + 1;
--+	*banksize *= SOCRAM_BANKINFO_SZBASE;
--+	return !!(bankinfo & SOCRAM_BANKINFO_RETNTRAM_MASK);
--+}
--+
--+static void brcmf_chip_socram_ramsize(struct brcmf_core_priv *sr, u32 *ramsize,
--+				      u32 *srsize)
--+{
--+	u32 coreinfo;
--+	uint nb, banksize, lss;
--+	bool retent;
--+	int i;
--+
--+	*ramsize = 0;
--+	*srsize = 0;
--+
--+	if (WARN_ON(sr->pub.rev < 4))
--+		return;
--+
--+	if (!brcmf_chip_iscoreup(&sr->pub))
--+		brcmf_chip_resetcore(&sr->pub, 0, 0, 0);
--+
--+	/* Get info for determining size */
--+	coreinfo = brcmf_chip_core_read32(sr, SOCRAMREGOFFS(coreinfo));
--+	nb = (coreinfo & SRCI_SRNB_MASK) >> SRCI_SRNB_SHIFT;
--+
--+	if ((sr->pub.rev <= 7) || (sr->pub.rev == 12)) {
--+		banksize = (coreinfo & SRCI_SRBSZ_MASK);
--+		lss = (coreinfo & SRCI_LSS_MASK) >> SRCI_LSS_SHIFT;
--+		if (lss != 0)
--+			nb--;
--+		*ramsize = nb * (1 << (banksize + SR_BSZ_BASE));
--+		if (lss != 0)
--+			*ramsize += (1 << ((lss - 1) + SR_BSZ_BASE));
--+	} else {
--+		nb = (coreinfo & SRCI_SRNB_MASK) >> SRCI_SRNB_SHIFT;
--+		for (i = 0; i < nb; i++) {
--+			retent = brcmf_chip_socram_banksize(sr, i, &banksize);
--+			*ramsize += banksize;
--+			if (retent)
--+				*srsize += banksize;
--+		}
--+	}
--+
--+	/* hardcoded save&restore memory sizes */
--+	switch (sr->chip->pub.chip) {
-- 	case BRCM_CC_4334_CHIP_ID:
---	case BRCM_CC_43340_CHIP_ID:
---		ci->pub.ramsize = 0x80000;
--+		if (sr->chip->pub.chiprev < 2)
--+			*srsize = (32 * 1024);
-- 		break;
---	case BRCM_CC_4335_CHIP_ID:
---		ci->pub.ramsize = 0xc0000;
---		ci->pub.rambase = 0x180000;
---		break;
---	case BRCM_CC_43362_CHIP_ID:
---		ci->pub.ramsize = 0x3c000;
--+	default:
-- 		break;
--+	}
--+}
--+
--+/** Return the TCM-RAM size of the ARMCR4 core. */
--+static u32 brcmf_chip_tcm_ramsize(struct brcmf_core_priv *cr4)
--+{
--+	u32 corecap;
--+	u32 memsize = 0;
--+	u32 nab;
--+	u32 nbb;
--+	u32 totb;
--+	u32 bxinfo;
--+	u32 idx;
--+
--+	corecap = brcmf_chip_core_read32(cr4, ARMCR4_CAP);
--+
--+	nab = (corecap & ARMCR4_TCBANB_MASK) >> ARMCR4_TCBANB_SHIFT;
--+	nbb = (corecap & ARMCR4_TCBBNB_MASK) >> ARMCR4_TCBBNB_SHIFT;
--+	totb = nab + nbb;
--+
--+	for (idx = 0; idx < totb; idx++) {
--+		brcmf_chip_core_write32(cr4, ARMCR4_BANKIDX, idx);
--+		bxinfo = brcmf_chip_core_read32(cr4, ARMCR4_BANKINFO);
--+		memsize += ((bxinfo & ARMCR4_BSZ_MASK) + 1) * ARMCR4_BSZ_MULT;
--+	}
--+
--+	return memsize;
--+}
--+
--+static u32 brcmf_chip_tcm_rambase(struct brcmf_chip_priv *ci)
--+{
--+	switch (ci->pub.chip) {
-- 	case BRCM_CC_4345_CHIP_ID:
---		ci->pub.ramsize = 0xc8000;
---		ci->pub.rambase = 0x198000;
---		break;
--+		return 0x198000;
--+	case BRCM_CC_4335_CHIP_ID:
-- 	case BRCM_CC_4339_CHIP_ID:
-- 	case BRCM_CC_4354_CHIP_ID:
-- 	case BRCM_CC_4356_CHIP_ID:
-- 	case BRCM_CC_43567_CHIP_ID:
-- 	case BRCM_CC_43569_CHIP_ID:
-- 	case BRCM_CC_43570_CHIP_ID:
---		ci->pub.ramsize = 0xc0000;
---		ci->pub.rambase = 0x180000;
---		break;
-- 	case BRCM_CC_43602_CHIP_ID:
---		ci->pub.ramsize = 0xf0000;
---		ci->pub.rambase = 0x180000;
---		break;
--+		return 0x180000;
-- 	default:
-- 		brcmf_err("unknown chip: %s\n", ci->pub.name);
-- 		break;
-- 	}
--+	return 0;
--+}
--+
--+static int brcmf_chip_get_raminfo(struct brcmf_chip_priv *ci)
--+{
--+	struct brcmf_core_priv *mem_core;
--+	struct brcmf_core *mem;
--+
--+	mem = brcmf_chip_get_core(&ci->pub, BCMA_CORE_ARM_CR4);
--+	if (mem) {
--+		mem_core = container_of(mem, struct brcmf_core_priv, pub);
--+		ci->pub.ramsize = brcmf_chip_tcm_ramsize(mem_core);
--+		ci->pub.rambase = brcmf_chip_tcm_rambase(ci);
--+		if (!ci->pub.rambase) {
--+			brcmf_err("RAM base not provided with ARM CR4 core\n");
--+			return -EINVAL;
--+		}
--+	} else {
--+		mem = brcmf_chip_get_core(&ci->pub, BCMA_CORE_INTERNAL_MEM);
--+		mem_core = container_of(mem, struct brcmf_core_priv, pub);
--+		brcmf_chip_socram_ramsize(mem_core, &ci->pub.ramsize,
--+					  &ci->pub.srsize);
--+	}
--+	brcmf_dbg(INFO, "RAM: base=0x%x size=%d (0x%x) sr=%d (0x%x)\n",
--+		  ci->pub.rambase, ci->pub.ramsize, ci->pub.ramsize,
--+		  ci->pub.srsize, ci->pub.srsize);
--+
--+	if (!ci->pub.ramsize) {
--+		brcmf_err("RAM size is undetermined\n");
--+		return -ENOMEM;
--+	}
--+	return 0;
-- }
-- 
-- static u32 brcmf_chip_dmp_get_desc(struct brcmf_chip_priv *ci, u32 *eromaddr,
--@@ -668,6 +833,7 @@ static int brcmf_chip_recognition(struct
-- 	struct brcmf_core *core;
-- 	u32 regdata;
-- 	u32 socitype;
--+	int ret;
-- 
-- 	/* Get CC core rev
-- 	 * Chipid is assume to be at offset 0 from SI_ENUM_BASE
--@@ -720,9 +886,13 @@ static int brcmf_chip_recognition(struct
-- 		return -ENODEV;
-- 	}
-- 
---	brcmf_chip_get_raminfo(ci);
---
---	return brcmf_chip_cores_check(ci);
--+	ret = brcmf_chip_cores_check(ci);
--+	if (ret)
--+		return ret;
--+
--+	/* assure chip is passive for core access */
--+	brcmf_chip_set_passive(&ci->pub);
--+	return brcmf_chip_get_raminfo(ci);
-- }
-- 
-- static void brcmf_chip_disable_arm(struct brcmf_chip_priv *chip, u16 id)
--@@ -827,8 +997,6 @@ struct brcmf_chip *brcmf_chip_attach(voi
-- 	if (err < 0)
-- 		goto fail;
-- 
---	/* assure chip is passive for download */
---	brcmf_chip_set_passive(&chip->pub);
-- 	return &chip->pub;
-- 
-- fail:
----- a/drivers/net/wireless/brcm80211/brcmfmac/chip.h
--+++ b/drivers/net/wireless/brcm80211/brcmfmac/chip.h
--@@ -30,7 +30,8 @@
--  * @pmucaps: PMU capabilities.
--  * @pmurev: PMU revision.
--  * @rambase: RAM base address (only applicable for ARM CR4 chips).
--- * @ramsize: amount of RAM on chip.
--+ * @ramsize: amount of RAM on chip including retention.
--+ * @srsize: amount of retention RAM on chip.
--  * @name: string representation of the chip identifier.
--  */
-- struct brcmf_chip {
--@@ -41,6 +42,7 @@ struct brcmf_chip {
-- 	u32 pmurev;
-- 	u32 rambase;
-- 	u32 ramsize;
--+	u32 srsize;
-- 	char name[8];
-- };
-- 
-diff --git a/package/kernel/mac80211/patches/344-brcmfmac-take-save-restore-memory-into-account-for-S.patch b/package/kernel/mac80211/patches/344-brcmfmac-take-save-restore-memory-into-account-for-S.patch
-deleted file mode 100644
-index 69618a7..0000000
---- a/package/kernel/mac80211/patches/344-brcmfmac-take-save-restore-memory-into-account-for-S.patch
-+++ /dev/null
-@@ -1,96 +0,0 @@
--From: Arend van Spriel <arend@broadcom.com>
--Date: Wed, 11 Mar 2015 16:11:32 +0100
--Subject: [PATCH] brcmfmac: take save&restore memory into account for SDIO
-- shared info
--
--The firmware provides pointer to SDIO shared information at end of
--RAM during firmware initialization. End of RAM is obviously determined
--by the actual ram size, but part of that may be used for save&restore
--memory. In that case another location in RAM will hold the pointer.
--
--Reviewed-by: Hante Meuleman <meuleman@broadcom.com>
--Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
--Signed-off-by: Arend van Spriel <arend@broadcom.com>
--Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
-----
--
----- a/drivers/net/wireless/brcm80211/brcmfmac/sdio.c
--+++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio.c
--@@ -1067,44 +1067,47 @@ static inline bool brcmf_sdio_valid_shar
-- static int brcmf_sdio_readshared(struct brcmf_sdio *bus,
-- 				 struct sdpcm_shared *sh)
-- {
---	u32 addr;
--+	u32 addr = 0;
-- 	int rv;
-- 	u32 shaddr = 0;
-- 	struct sdpcm_shared_le sh_le;
-- 	__le32 addr_le;
-- 
---	shaddr = bus->ci->rambase + bus->ci->ramsize - 4;
--+	sdio_claim_host(bus->sdiodev->func[1]);
--+	brcmf_sdio_bus_sleep(bus, false, false);
-- 
-- 	/*
-- 	 * Read last word in socram to determine
-- 	 * address of sdpcm_shared structure
-- 	 */
---	sdio_claim_host(bus->sdiodev->func[1]);
---	brcmf_sdio_bus_sleep(bus, false, false);
---	rv = brcmf_sdiod_ramrw(bus->sdiodev, false, shaddr, (u8 *)&addr_le, 4);
---	sdio_release_host(bus->sdiodev->func[1]);
--+	shaddr = bus->ci->rambase + bus->ci->ramsize - 4;
--+	if (!bus->ci->rambase && brcmf_chip_sr_capable(bus->ci))
--+		shaddr -= bus->ci->srsize;
--+	rv = brcmf_sdiod_ramrw(bus->sdiodev, false, shaddr,
--+			       (u8 *)&addr_le, 4);
-- 	if (rv < 0)
---		return rv;
---
---	addr = le32_to_cpu(addr_le);
---
---	brcmf_dbg(SDIO, "sdpcm_shared address 0x%08X\n", addr);
--+		goto fail;
-- 
-- 	/*
-- 	 * Check if addr is valid.
-- 	 * NVRAM length at the end of memory should have been overwritten.
-- 	 */
--+	addr = le32_to_cpu(addr_le);
-- 	if (!brcmf_sdio_valid_shared_address(addr)) {
---			brcmf_err("invalid sdpcm_shared address 0x%08X\n",
---				  addr);
---			return -EINVAL;
--+		brcmf_err("invalid sdpcm_shared address 0x%08X\n", addr);
--+		rv = -EINVAL;
--+		goto fail;
-- 	}
-- 
--+	brcmf_dbg(INFO, "sdpcm_shared address 0x%08X\n", addr);
--+
-- 	/* Read hndrte_shared structure */
-- 	rv = brcmf_sdiod_ramrw(bus->sdiodev, false, addr, (u8 *)&sh_le,
-- 			       sizeof(struct sdpcm_shared_le));
-- 	if (rv < 0)
---		return rv;
--+		goto fail;
--+
--+	sdio_release_host(bus->sdiodev->func[1]);
-- 
-- 	/* Endianness */
-- 	sh->flags = le32_to_cpu(sh_le.flags);
--@@ -1121,8 +1124,13 @@ static int brcmf_sdio_readshared(struct
-- 			  sh->flags & SDPCM_SHARED_VERSION_MASK);
-- 		return -EPROTO;
-- 	}
---
-- 	return 0;
--+
--+fail:
--+	brcmf_err("unable to obtain sdpcm_shared info: rv=%d (addr=0x%x)\n",
--+		  rv, addr);
--+	sdio_release_host(bus->sdiodev->func[1]);
--+	return rv;
-- }
-- 
-- static void brcmf_sdio_get_console_addr(struct brcmf_sdio *bus)
-diff --git a/package/kernel/mac80211/patches/345-brcmfmac-fix-watchdog-timer-regression.patch b/package/kernel/mac80211/patches/345-brcmfmac-fix-watchdog-timer-regression.patch
-deleted file mode 100644
-index 1b10dbb..0000000
---- a/package/kernel/mac80211/patches/345-brcmfmac-fix-watchdog-timer-regression.patch
-+++ /dev/null
-@@ -1,59 +0,0 @@
--From: Arend van Spriel <arend@broadcom.com>
--Date: Wed, 11 Mar 2015 16:11:33 +0100
--Subject: [PATCH] brcmfmac: fix watchdog timer regression
--
--The watchdog timer is used to put the device in a low-power mode when
--it is idle for some time. This timer is stopped during that mode and
--should be restarted upon activity. This has been broken by commit
--d4150fced0365 ("brcmfmac: Simplify watchdog sleep."). This patch
--restores the behaviour as it was before that commit.
--
--Reported-by: Pontus Fuchs <pontusf@broadcom.com>
--Reviewed-by: Hante Meuleman <meuleman@broadcom.com>
--Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
--Signed-off-by: Arend van Spriel <arend@broadcom.com>
--Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
-----
--
----- a/drivers/net/wireless/brcm80211/brcmfmac/sdio.c
--+++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio.c
--@@ -972,7 +972,6 @@ static int brcmf_sdio_clkctl(struct brcm
-- 			brcmf_sdio_sdclk(bus, true);
-- 		/* Now request HT Avail on the backplane */
-- 		brcmf_sdio_htclk(bus, true, pendok);
---		brcmf_sdio_wd_timer(bus, BRCMF_WD_POLL_MS);
-- 		break;
-- 
-- 	case CLK_SDONLY:
--@@ -984,7 +983,6 @@ static int brcmf_sdio_clkctl(struct brcm
-- 		else
-- 			brcmf_err("request for %d -> %d\n",
-- 				  bus->clkstate, target);
---		brcmf_sdio_wd_timer(bus, BRCMF_WD_POLL_MS);
-- 		break;
-- 
-- 	case CLK_NONE:
--@@ -993,7 +991,6 @@ static int brcmf_sdio_clkctl(struct brcm
-- 			brcmf_sdio_htclk(bus, false, false);
-- 		/* Now remove the SD clock */
-- 		brcmf_sdio_sdclk(bus, false);
---		brcmf_sdio_wd_timer(bus, 0);
-- 		break;
-- 	}
-- #ifdef DEBUG
--@@ -1048,6 +1045,7 @@ end:
-- 			brcmf_sdio_clkctl(bus, CLK_NONE, pendok);
-- 	} else {
-- 		brcmf_sdio_clkctl(bus, CLK_AVAIL, pendok);
--+		brcmf_sdio_wd_timer(bus, BRCMF_WD_POLL_MS);
-- 	}
-- 	bus->sleeping = sleep;
-- 	brcmf_dbg(SDIO, "new state %s\n",
--@@ -4242,6 +4240,7 @@ void brcmf_sdio_remove(struct brcmf_sdio
-- 		if (bus->ci) {
-- 			if (bus->sdiodev->state != BRCMF_SDIOD_NOMEDIUM) {
-- 				sdio_claim_host(bus->sdiodev->func[1]);
--+				brcmf_sdio_wd_timer(bus, 0);
-- 				brcmf_sdio_clkctl(bus, CLK_AVAIL, false);
-- 				/* Leave the device in state where it is
-- 				 * 'passive'. This is done by resetting all
-diff --git a/package/kernel/mac80211/patches/346-brcmfmac-avoid-runtime-pm-for-sdio-host-controller.patch b/package/kernel/mac80211/patches/346-brcmfmac-avoid-runtime-pm-for-sdio-host-controller.patch
-deleted file mode 100644
-index af76f13..0000000
---- a/package/kernel/mac80211/patches/346-brcmfmac-avoid-runtime-pm-for-sdio-host-controller.patch
-+++ /dev/null
-@@ -1,44 +0,0 @@
--From: Arend van Spriel <arend@broadcom.com>
--Date: Wed, 18 Mar 2015 13:25:21 +0100
--Subject: [PATCH] brcmfmac: avoid runtime-pm for sdio host controller
--
--Several host controllers supporting runtime-pm are causing issues
--with our sdio wireless cards because they disable the sdio interrupt
--upon going into runtime suspend. This patch avoids that by doing
--a pm_runtime_forbid() call during the probe. Tested with Sony Vaio
--Duo 13 which uses sdhci-acpi host controller.
--
--Reviewed-by: Hante Meuleman <meuleman@broadcom.com>
--Reviewed-by: Franky (Zhenhui) Lin <frankyl@broadcom.com>
--Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
--Signed-off-by: Arend van Spriel <arend@broadcom.com>
--Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
-----
--
----- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
--+++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
--@@ -29,6 +29,7 @@
-- #include <linux/mmc/host.h>
-- #include <linux/platform_device.h>
-- #include <linux/platform_data/brcmfmac-sdio.h>
--+#include <linux/pm_runtime.h>
-- #include <linux/suspend.h>
-- #include <linux/errno.h>
-- #include <linux/module.h>
--@@ -1006,6 +1007,7 @@ static int brcmf_sdiod_remove(struct brc
-- 	sg_free_table(&sdiodev->sgtable);
-- 	sdiodev->sbwad = 0;
-- 
--+	pm_runtime_allow(sdiodev->func[1]->card->host->parent);
-- 	return 0;
-- }
-- 
--@@ -1074,7 +1076,7 @@ static int brcmf_sdiod_probe(struct brcm
-- 		ret = -ENODEV;
-- 		goto out;
-- 	}
---
--+	pm_runtime_forbid(host->parent);
-- out:
-- 	if (ret)
-- 		brcmf_sdiod_remove(sdiodev);
-diff --git a/package/kernel/mac80211/patches/347-brcmfmac-Add-necessary-memory-barriers-for-SDIO.patch b/package/kernel/mac80211/patches/347-brcmfmac-Add-necessary-memory-barriers-for-SDIO.patch
-deleted file mode 100644
-index c419cc6..0000000
---- a/package/kernel/mac80211/patches/347-brcmfmac-Add-necessary-memory-barriers-for-SDIO.patch
-+++ /dev/null
-@@ -1,171 +0,0 @@
--From: Hante Meuleman <meuleman@broadcom.com>
--Date: Wed, 18 Mar 2015 13:25:22 +0100
--Subject: [PATCH] brcmfmac: Add necessary memory barriers for SDIO.
--
--SDIO uses a thread to handle all communication with the device,
--for this data is exchanged between threads. This data needs proper
--memory barriers to make sure that data "exchange" is going correct.
--
--Reviewed-by: Arend Van Spriel <arend@broadcom.com>
--Reviewed-by: Franky (Zhenhui) Lin <frankyl@broadcom.com>
--Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
--Reviewed-by: Daniel (Deognyoun) Kim <dekim@broadcom.com>
--Signed-off-by: Hante Meuleman <meuleman@broadcom.com>
--Signed-off-by: Arend van Spriel <arend@broadcom.com>
--Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
-----
--
----- a/drivers/net/wireless/brcm80211/brcmfmac/sdio.c
--+++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio.c
--@@ -507,8 +507,8 @@ struct brcmf_sdio {
-- 
-- 	struct workqueue_struct *brcmf_wq;
-- 	struct work_struct datawork;
---	atomic_t dpc_tskcnt;
---	atomic_t dpc_running;
--+	bool dpc_triggered;
--+	bool dpc_running;
-- 
-- 	bool txoff;		/* Transmit flow-controlled */
-- 	struct brcmf_sdio_count sdcnt;
--@@ -2713,6 +2713,7 @@ static void brcmf_sdio_dpc(struct brcmf_
-- 			err = brcmf_sdio_tx_ctrlframe(bus,  bus->ctrl_frame_buf,
-- 						      bus->ctrl_frame_len);
-- 			bus->ctrl_frame_err = err;
--+			wmb();
-- 			bus->ctrl_frame_stat = false;
-- 		}
-- 		sdio_release_host(bus->sdiodev->func[1]);
--@@ -2734,6 +2735,7 @@ static void brcmf_sdio_dpc(struct brcmf_
-- 			sdio_claim_host(bus->sdiodev->func[1]);
-- 			if (bus->ctrl_frame_stat) {
-- 				bus->ctrl_frame_err = -ENODEV;
--+				wmb();
-- 				bus->ctrl_frame_stat = false;
-- 				brcmf_sdio_wait_event_wakeup(bus);
-- 			}
--@@ -2744,7 +2746,7 @@ static void brcmf_sdio_dpc(struct brcmf_
-- 		   (!atomic_read(&bus->fcstate) &&
-- 		    brcmu_pktq_mlen(&bus->txq, ~bus->flowcontrol) &&
-- 		    data_ok(bus))) {
---		atomic_inc(&bus->dpc_tskcnt);
--+		bus->dpc_triggered = true;
-- 	}
-- }
-- 
--@@ -2940,6 +2942,7 @@ brcmf_sdio_bus_txctl(struct device *dev,
-- 	/* Send from dpc */
-- 	bus->ctrl_frame_buf = msg;
-- 	bus->ctrl_frame_len = msglen;
--+	wmb();
-- 	bus->ctrl_frame_stat = true;
-- 
-- 	brcmf_sdio_trigger_dpc(bus);
--@@ -2958,6 +2961,7 @@ brcmf_sdio_bus_txctl(struct device *dev,
-- 	if (!ret) {
-- 		brcmf_dbg(SDIO, "ctrl_frame complete, err=%d\n",
-- 			  bus->ctrl_frame_err);
--+		rmb();
-- 		ret = bus->ctrl_frame_err;
-- 	}
-- 
--@@ -3526,8 +3530,8 @@ done:
-- 
-- void brcmf_sdio_trigger_dpc(struct brcmf_sdio *bus)
-- {
---	if (atomic_read(&bus->dpc_tskcnt) == 0) {
---		atomic_inc(&bus->dpc_tskcnt);
--+	if (!bus->dpc_triggered) {
--+		bus->dpc_triggered = true;
-- 		queue_work(bus->brcmf_wq, &bus->datawork);
-- 	}
-- }
--@@ -3558,7 +3562,7 @@ void brcmf_sdio_isr(struct brcmf_sdio *b
-- 	if (!bus->intr)
-- 		brcmf_err("isr w/o interrupt configured!\n");
-- 
---	atomic_inc(&bus->dpc_tskcnt);
--+	bus->dpc_triggered = true;
-- 	queue_work(bus->brcmf_wq, &bus->datawork);
-- }
-- 
--@@ -3578,7 +3582,7 @@ static void brcmf_sdio_bus_watchdog(stru
-- 		if (!bus->intr ||
-- 		    (bus->sdcnt.intrcount == bus->sdcnt.lastintrs)) {
-- 
---			if (atomic_read(&bus->dpc_tskcnt) == 0) {
--+			if (!bus->dpc_triggered) {
-- 				u8 devpend;
-- 
-- 				sdio_claim_host(bus->sdiodev->func[1]);
--@@ -3596,7 +3600,7 @@ static void brcmf_sdio_bus_watchdog(stru
-- 				bus->sdcnt.pollcnt++;
-- 				atomic_set(&bus->ipend, 1);
-- 
---				atomic_inc(&bus->dpc_tskcnt);
--+				bus->dpc_triggered = true;
-- 				queue_work(bus->brcmf_wq, &bus->datawork);
-- 			}
-- 		}
--@@ -3623,17 +3627,21 @@ static void brcmf_sdio_bus_watchdog(stru
-- #endif				/* DEBUG */
-- 
-- 	/* On idle timeout clear activity flag and/or turn off clock */
---	if ((atomic_read(&bus->dpc_tskcnt) == 0) &&
---	    (atomic_read(&bus->dpc_running) == 0) &&
---	    (bus->idletime > 0) && (bus->clkstate == CLK_AVAIL)) {
---		bus->idlecount++;
---		if (bus->idlecount > bus->idletime) {
---			brcmf_dbg(SDIO, "idle\n");
---			sdio_claim_host(bus->sdiodev->func[1]);
---			brcmf_sdio_wd_timer(bus, 0);
--+	if (!bus->dpc_triggered) {
--+		rmb();
--+		if ((!bus->dpc_running) && (bus->idletime > 0) &&
--+		    (bus->clkstate == CLK_AVAIL)) {
--+			bus->idlecount++;
--+			if (bus->idlecount > bus->idletime) {
--+				brcmf_dbg(SDIO, "idle\n");
--+				sdio_claim_host(bus->sdiodev->func[1]);
--+				brcmf_sdio_wd_timer(bus, 0);
--+				bus->idlecount = 0;
--+				brcmf_sdio_bus_sleep(bus, true, false);
--+				sdio_release_host(bus->sdiodev->func[1]);
--+			}
--+		} else {
-- 			bus->idlecount = 0;
---			brcmf_sdio_bus_sleep(bus, true, false);
---			sdio_release_host(bus->sdiodev->func[1]);
-- 		}
-- 	} else {
-- 		bus->idlecount = 0;
--@@ -3645,13 +3653,14 @@ static void brcmf_sdio_dataworker(struct
-- 	struct brcmf_sdio *bus = container_of(work, struct brcmf_sdio,
-- 					      datawork);
-- 
---	while (atomic_read(&bus->dpc_tskcnt)) {
---		atomic_set(&bus->dpc_running, 1);
---		atomic_set(&bus->dpc_tskcnt, 0);
--+	bus->dpc_running = true;
--+	wmb();
--+	while (ACCESS_ONCE(bus->dpc_triggered)) {
--+		bus->dpc_triggered = false;
-- 		brcmf_sdio_dpc(bus);
-- 		bus->idlecount = 0;
---		atomic_set(&bus->dpc_running, 0);
-- 	}
--+	bus->dpc_running = false;
-- 	if (brcmf_sdiod_freezing(bus->sdiodev)) {
-- 		brcmf_sdiod_change_state(bus->sdiodev, BRCMF_SDIOD_DOWN);
-- 		brcmf_sdiod_try_freeze(bus->sdiodev);
--@@ -4144,8 +4153,8 @@ struct brcmf_sdio *brcmf_sdio_probe(stru
-- 		bus->watchdog_tsk = NULL;
-- 	}
-- 	/* Initialize DPC thread */
---	atomic_set(&bus->dpc_tskcnt, 0);
---	atomic_set(&bus->dpc_running, 0);
--+	bus->dpc_triggered = false;
--+	bus->dpc_running = false;
-- 
-- 	/* Assign bus interface call back */
-- 	bus->sdiodev->bus_if->dev = bus->sdiodev->dev;
-diff --git a/package/kernel/mac80211/patches/348-brcmfmac-Remove-unnecessary-new-line-in-pcie-console.patch b/package/kernel/mac80211/patches/348-brcmfmac-Remove-unnecessary-new-line-in-pcie-console.patch
-deleted file mode 100644
-index 1bc98a0..0000000
---- a/package/kernel/mac80211/patches/348-brcmfmac-Remove-unnecessary-new-line-in-pcie-console.patch
-+++ /dev/null
-@@ -1,26 +0,0 @@
--From: Hante Meuleman <meuleman@broadcom.com>
--Date: Wed, 18 Mar 2015 13:25:24 +0100
--Subject: [PATCH] brcmfmac: Remove unnecessary new-line in pcie console
-- logging.
--
--Reviewed-by: Arend Van Spriel <arend@broadcom.com>
--Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
--Signed-off-by: Hante Meuleman <meuleman@broadcom.com>
--Signed-off-by: Arend van Spriel <arend@broadcom.com>
--Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
-----
--
----- a/drivers/net/wireless/brcm80211/brcmfmac/pcie.c
--+++ b/drivers/net/wireless/brcm80211/brcmfmac/pcie.c
--@@ -651,10 +651,9 @@ static void brcmf_pcie_bus_console_read(
-- 			console->log_str[console->log_idx] = ch;
-- 			console->log_idx++;
-- 		}
---
-- 		if (ch == '\n') {
-- 			console->log_str[console->log_idx] = 0;
---			brcmf_dbg(PCIE, "CONSOLE: %s\n", console->log_str);
--+			brcmf_dbg(PCIE, "CONSOLE: %s", console->log_str);
-- 			console->log_idx = 0;
-- 		}
-- 	}
-diff --git a/package/kernel/mac80211/patches/349-brcmfmac-add-MODULE_FIRMWARE-macros-for-bcm4356-PCIe.patch b/package/kernel/mac80211/patches/349-brcmfmac-add-MODULE_FIRMWARE-macros-for-bcm4356-PCIe.patch
-deleted file mode 100644
-index fcf0bf3..0000000
---- a/package/kernel/mac80211/patches/349-brcmfmac-add-MODULE_FIRMWARE-macros-for-bcm4356-PCIe.patch
-+++ /dev/null
-@@ -1,26 +0,0 @@
--From: Arend van Spriel <arend@broadcom.com>
--Date: Wed, 18 Mar 2015 13:25:25 +0100
--Subject: [PATCH] brcmfmac: add MODULE_FIRMWARE() macros for bcm4356 PCIe
-- device
--
--The BCM4356 PCIe wireless device was added recently but overlooked
--the fact that the MODULE_FIRMWARE() macros were missing for the
--firmwares needed by this device.
--
--Reviewed-by: Hante Meuleman <meuleman@broadcom.com>
--Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
--Signed-off-by: Arend van Spriel <arend@broadcom.com>
--Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
-----
--
----- a/drivers/net/wireless/brcm80211/brcmfmac/pcie.c
--+++ b/drivers/net/wireless/brcm80211/brcmfmac/pcie.c
--@@ -189,6 +189,8 @@ MODULE_FIRMWARE(BRCMF_PCIE_43602_FW_NAME
-- MODULE_FIRMWARE(BRCMF_PCIE_43602_NVRAM_NAME);
-- MODULE_FIRMWARE(BRCMF_PCIE_4354_FW_NAME);
-- MODULE_FIRMWARE(BRCMF_PCIE_4354_NVRAM_NAME);
--+MODULE_FIRMWARE(BRCMF_PCIE_4356_FW_NAME);
--+MODULE_FIRMWARE(BRCMF_PCIE_4356_NVRAM_NAME);
-- MODULE_FIRMWARE(BRCMF_PCIE_43570_FW_NAME);
-- MODULE_FIRMWARE(BRCMF_PCIE_43570_NVRAM_NAME);
-- 
-diff --git a/package/kernel/mac80211/patches/350-brcmfmac-add-support-for-BCM43430-SDIO-chipset.patch b/package/kernel/mac80211/patches/350-brcmfmac-add-support-for-BCM43430-SDIO-chipset.patch
-deleted file mode 100644
-index b3e9bc9..0000000
---- a/package/kernel/mac80211/patches/350-brcmfmac-add-support-for-BCM43430-SDIO-chipset.patch
-+++ /dev/null
-@@ -1,138 +0,0 @@
--From: Arend van Spriel <arend@broadcom.com>
--Date: Wed, 18 Mar 2015 13:25:26 +0100
--Subject: [PATCH] brcmfmac: add support for BCM43430 SDIO chipset
--
--This patch added support for the BCM43430 802.11n SDIO chipset.
--
--Reviewed-by: Hante Meuleman <meuleman@broadcom.com>
--Reviewed-by: Daniel (Deognyoun) Kim <dekim@broadcom.com>
--Reviewed-by: Franky (Zhenhui) Lin <frankyl@broadcom.com>
--Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
--Signed-off-by: Arend van Spriel <arend@broadcom.com>
--Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
-----
--
----- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
--+++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
--@@ -1098,6 +1098,7 @@ static const struct sdio_device_id brcmf
-- 	BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_43341),
-- 	BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_43362),
-- 	BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_4335_4339),
--+	BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_43430),
-- 	BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_4345),
-- 	BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_4354),
-- 	{ /* end: all zeroes */ }
----- a/drivers/net/wireless/brcm80211/brcmfmac/chip.c
--+++ b/drivers/net/wireless/brcm80211/brcmfmac/chip.c
--@@ -600,6 +600,12 @@ static void brcmf_chip_socram_ramsize(st
-- 		if (sr->chip->pub.chiprev < 2)
-- 			*srsize = (32 * 1024);
-- 		break;
--+	case BRCM_CC_43430_CHIP_ID:
--+		/* assume sr for now as we can not check
--+		 * firmware sr capability at this point.
--+		 */
--+		*srsize = (64 * 1024);
--+		break;
-- 	default:
-- 		break;
-- 	}
--@@ -1072,6 +1078,7 @@ static void
-- brcmf_chip_cm3_set_passive(struct brcmf_chip_priv *chip)
-- {
-- 	struct brcmf_core *core;
--+	struct brcmf_core_priv *sr;
-- 
-- 	brcmf_chip_disable_arm(chip, BCMA_CORE_ARM_CM3);
-- 	core = brcmf_chip_get_core(&chip->pub, BCMA_CORE_80211);
--@@ -1081,6 +1088,13 @@ brcmf_chip_cm3_set_passive(struct brcmf_
-- 			     D11_BCMA_IOCTL_PHYCLOCKEN);
-- 	core = brcmf_chip_get_core(&chip->pub, BCMA_CORE_INTERNAL_MEM);
-- 	brcmf_chip_resetcore(core, 0, 0, 0);
--+
--+	/* disable bank #3 remap for this device */
--+	if (chip->pub.chip == BRCM_CC_43430_CHIP_ID) {
--+		sr = container_of(core, struct brcmf_core_priv, pub);
--+		brcmf_chip_core_write32(sr, SOCRAMREGOFFS(bankidx), 3);
--+		brcmf_chip_core_write32(sr, SOCRAMREGOFFS(bankpda), 0);
--+	}
-- }
-- 
-- static bool brcmf_chip_cm3_set_active(struct brcmf_chip_priv *chip)
--@@ -1188,6 +1202,10 @@ bool brcmf_chip_sr_capable(struct brcmf_
-- 		addr = CORE_CC_REG(base, chipcontrol_data);
-- 		reg = chip->ops->read32(chip->ctx, addr);
-- 		return (reg & pmu_cc3_mask) != 0;
--+	case BRCM_CC_43430_CHIP_ID:
--+		addr = CORE_CC_REG(base, sr_control1);
--+		reg = chip->ops->read32(chip->ctx, addr);
--+		return reg != 0;
-- 	default:
-- 		addr = CORE_CC_REG(base, pmucapabilities_ext);
-- 		reg = chip->ops->read32(chip->ctx, addr);
----- a/drivers/net/wireless/brcm80211/brcmfmac/sdio.c
--+++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio.c
--@@ -615,6 +615,8 @@ static const struct sdiod_drive_str sdio
-- #define BCM43362_NVRAM_NAME		"brcm/brcmfmac43362-sdio.txt"
-- #define BCM4339_FIRMWARE_NAME		"brcm/brcmfmac4339-sdio.bin"
-- #define BCM4339_NVRAM_NAME		"brcm/brcmfmac4339-sdio.txt"
--+#define BCM43430_FIRMWARE_NAME		"brcm/brcmfmac43430-sdio.bin"
--+#define BCM43430_NVRAM_NAME		"brcm/brcmfmac43430-sdio.txt"
-- #define BCM4345_FIRMWARE_NAME		"brcm/brcmfmac4345-sdio.bin"
-- #define BCM4345_NVRAM_NAME		"brcm/brcmfmac4345-sdio.txt"
-- #define BCM4354_FIRMWARE_NAME		"brcm/brcmfmac4354-sdio.bin"
--@@ -640,6 +642,8 @@ MODULE_FIRMWARE(BCM43362_FIRMWARE_NAME);
-- MODULE_FIRMWARE(BCM43362_NVRAM_NAME);
-- MODULE_FIRMWARE(BCM4339_FIRMWARE_NAME);
-- MODULE_FIRMWARE(BCM4339_NVRAM_NAME);
--+MODULE_FIRMWARE(BCM43430_FIRMWARE_NAME);
--+MODULE_FIRMWARE(BCM43430_NVRAM_NAME);
-- MODULE_FIRMWARE(BCM4345_FIRMWARE_NAME);
-- MODULE_FIRMWARE(BCM4345_NVRAM_NAME);
-- MODULE_FIRMWARE(BCM4354_FIRMWARE_NAME);
--@@ -671,6 +675,7 @@ static const struct brcmf_firmware_names
-- 	{ BRCM_CC_4335_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4335) },
-- 	{ BRCM_CC_43362_CHIP_ID, 0xFFFFFFFE, BRCMF_FIRMWARE_NVRAM(BCM43362) },
-- 	{ BRCM_CC_4339_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4339) },
--+	{ BRCM_CC_43430_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM43430) },
-- 	{ BRCM_CC_4345_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4345) },
-- 	{ BRCM_CC_4354_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4354) }
-- };
----- a/drivers/net/wireless/brcm80211/include/brcm_hw_ids.h
--+++ b/drivers/net/wireless/brcm80211/include/brcm_hw_ids.h
--@@ -37,6 +37,7 @@
-- #define BRCM_CC_43362_CHIP_ID		43362
-- #define BRCM_CC_4335_CHIP_ID		0x4335
-- #define BRCM_CC_4339_CHIP_ID		0x4339
--+#define BRCM_CC_43430_CHIP_ID		43430
-- #define BRCM_CC_4345_CHIP_ID		0x4345
-- #define BRCM_CC_4354_CHIP_ID		0x4354
-- #define BRCM_CC_4356_CHIP_ID		0x4356
----- a/drivers/net/wireless/brcm80211/include/chipcommon.h
--+++ b/drivers/net/wireless/brcm80211/include/chipcommon.h
--@@ -183,7 +183,14 @@ struct chipcregs {
-- 	u8 uart1lsr;
-- 	u8 uart1msr;
-- 	u8 uart1scratch;
---	u32 PAD[126];
--+	u32 PAD[62];
--+
--+	/* save/restore, corerev >= 48 */
--+	u32 sr_capability;          /* 0x500 */
--+	u32 sr_control0;            /* 0x504 */
--+	u32 sr_control1;            /* 0x508 */
--+	u32 gpio_control;           /* 0x50C */
--+	u32 PAD[60];
-- 
-- 	/* PMU registers (corerev >= 20) */
-- 	u32 pmucontrol;	/* 0x600 */
----- a/include/linux/mmc/sdio_ids.h
--+++ b/include/linux/mmc/sdio_ids.h
--@@ -33,6 +33,7 @@
-- #define SDIO_DEVICE_ID_BROADCOM_43341		0xa94d
-- #define SDIO_DEVICE_ID_BROADCOM_4335_4339	0x4335
-- #define SDIO_DEVICE_ID_BROADCOM_43362		0xa962
--+#define SDIO_DEVICE_ID_BROADCOM_43430		0xa9a6
-- #define SDIO_DEVICE_ID_BROADCOM_4345		0x4345
-- #define SDIO_DEVICE_ID_BROADCOM_4354		0x4354
-- 
-diff --git a/package/kernel/mac80211/patches/351-brcmfmac-only-support-the-BCM43455-7-device.patch b/package/kernel/mac80211/patches/351-brcmfmac-only-support-the-BCM43455-7-device.patch
-deleted file mode 100644
-index c3d7bc2..0000000
---- a/package/kernel/mac80211/patches/351-brcmfmac-only-support-the-BCM43455-7-device.patch
-+++ /dev/null
-@@ -1,50 +0,0 @@
--From: Arend van Spriel <arend@broadcom.com>
--Date: Wed, 18 Mar 2015 13:25:27 +0100
--Subject: [PATCH] brcmfmac: only support the BCM43455/7 device
--
--Recently support was added for the BCM4345 SDIO chipset by
--commit 9c51026509d7 ("brcmfmac: Add support for BCM4345 SDIO chipset")
--however this was verified using a BCM43455 device, which is
--a more recent revision of the chip. This patch assure that
--older revisions are not probed as they would fail.
--
--Reviewed-by: Hante Meuleman <meuleman@broadcom.com>
--Reviewed-by: Syed Asifful Dayyan <syedd@broadcom.com>
--Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
--Signed-off-by: Arend van Spriel <arend@broadcom.com>
--Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
-----
--
----- a/drivers/net/wireless/brcm80211/brcmfmac/sdio.c
--+++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio.c
--@@ -617,8 +617,8 @@ static const struct sdiod_drive_str sdio
-- #define BCM4339_NVRAM_NAME		"brcm/brcmfmac4339-sdio.txt"
-- #define BCM43430_FIRMWARE_NAME		"brcm/brcmfmac43430-sdio.bin"
-- #define BCM43430_NVRAM_NAME		"brcm/brcmfmac43430-sdio.txt"
---#define BCM4345_FIRMWARE_NAME		"brcm/brcmfmac4345-sdio.bin"
---#define BCM4345_NVRAM_NAME		"brcm/brcmfmac4345-sdio.txt"
--+#define BCM43455_FIRMWARE_NAME		"brcm/brcmfmac43455-sdio.bin"
--+#define BCM43455_NVRAM_NAME		"brcm/brcmfmac43455-sdio.txt"
-- #define BCM4354_FIRMWARE_NAME		"brcm/brcmfmac4354-sdio.bin"
-- #define BCM4354_NVRAM_NAME		"brcm/brcmfmac4354-sdio.txt"
-- 
--@@ -644,8 +644,8 @@ MODULE_FIRMWARE(BCM4339_FIRMWARE_NAME);
-- MODULE_FIRMWARE(BCM4339_NVRAM_NAME);
-- MODULE_FIRMWARE(BCM43430_FIRMWARE_NAME);
-- MODULE_FIRMWARE(BCM43430_NVRAM_NAME);
---MODULE_FIRMWARE(BCM4345_FIRMWARE_NAME);
---MODULE_FIRMWARE(BCM4345_NVRAM_NAME);
--+MODULE_FIRMWARE(BCM43455_FIRMWARE_NAME);
--+MODULE_FIRMWARE(BCM43455_NVRAM_NAME);
-- MODULE_FIRMWARE(BCM4354_FIRMWARE_NAME);
-- MODULE_FIRMWARE(BCM4354_NVRAM_NAME);
-- 
--@@ -676,7 +676,7 @@ static const struct brcmf_firmware_names
-- 	{ BRCM_CC_43362_CHIP_ID, 0xFFFFFFFE, BRCMF_FIRMWARE_NVRAM(BCM43362) },
-- 	{ BRCM_CC_4339_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4339) },
-- 	{ BRCM_CC_43430_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM43430) },
---	{ BRCM_CC_4345_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4345) },
--+	{ BRCM_CC_4345_CHIP_ID, 0xFFFFFFC0, BRCMF_FIRMWARE_NVRAM(BCM43455) },
-- 	{ BRCM_CC_4354_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4354) }
-- };
-- 
-diff --git a/package/kernel/mac80211/patches/352-brcmfmac-remove-support-for-unreleased-BCM4354-PCIe.patch b/package/kernel/mac80211/patches/352-brcmfmac-remove-support-for-unreleased-BCM4354-PCIe.patch
-deleted file mode 100644
-index a62cfdf..0000000
---- a/package/kernel/mac80211/patches/352-brcmfmac-remove-support-for-unreleased-BCM4354-PCIe.patch
-+++ /dev/null
-@@ -1,52 +0,0 @@
--From: Arend van Spriel <arend@broadcom.com>
--Date: Wed, 18 Mar 2015 13:25:28 +0100
--Subject: [PATCH] brcmfmac: remove support for unreleased BCM4354 PCIe
--
--There are no known BCM4354 PCIe devices released so removing
--support from the driver until proven otherwise.
--
--Reviewed-by: Hante Meuleman <meuleman@broadcom.com>
--Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
--Signed-off-by: Arend van Spriel <arend@broadcom.com>
--Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
-----
--
----- a/drivers/net/wireless/brcm80211/brcmfmac/pcie.c
--+++ b/drivers/net/wireless/brcm80211/brcmfmac/pcie.c
--@@ -47,8 +47,6 @@ enum brcmf_pcie_state {
-- 
-- #define BRCMF_PCIE_43602_FW_NAME		"brcm/brcmfmac43602-pcie.bin"
-- #define BRCMF_PCIE_43602_NVRAM_NAME		"brcm/brcmfmac43602-pcie.txt"
---#define BRCMF_PCIE_4354_FW_NAME			"brcm/brcmfmac4354-pcie.bin"
---#define BRCMF_PCIE_4354_NVRAM_NAME		"brcm/brcmfmac4354-pcie.txt"
-- #define BRCMF_PCIE_4356_FW_NAME			"brcm/brcmfmac4356-pcie.bin"
-- #define BRCMF_PCIE_4356_NVRAM_NAME		"brcm/brcmfmac4356-pcie.txt"
-- #define BRCMF_PCIE_43570_FW_NAME		"brcm/brcmfmac43570-pcie.bin"
--@@ -187,8 +185,6 @@ enum brcmf_pcie_state {
-- 
-- MODULE_FIRMWARE(BRCMF_PCIE_43602_FW_NAME);
-- MODULE_FIRMWARE(BRCMF_PCIE_43602_NVRAM_NAME);
---MODULE_FIRMWARE(BRCMF_PCIE_4354_FW_NAME);
---MODULE_FIRMWARE(BRCMF_PCIE_4354_NVRAM_NAME);
-- MODULE_FIRMWARE(BRCMF_PCIE_4356_FW_NAME);
-- MODULE_FIRMWARE(BRCMF_PCIE_4356_NVRAM_NAME);
-- MODULE_FIRMWARE(BRCMF_PCIE_43570_FW_NAME);
--@@ -1327,10 +1323,6 @@ static int brcmf_pcie_get_fwnames(struct
-- 		fw_name = BRCMF_PCIE_43602_FW_NAME;
-- 		nvram_name = BRCMF_PCIE_43602_NVRAM_NAME;
-- 		break;
---	case BRCM_CC_4354_CHIP_ID:
---		fw_name = BRCMF_PCIE_4354_FW_NAME;
---		nvram_name = BRCMF_PCIE_4354_NVRAM_NAME;
---		break;
-- 	case BRCM_CC_4356_CHIP_ID:
-- 		fw_name = BRCMF_PCIE_4356_FW_NAME;
-- 		nvram_name = BRCMF_PCIE_4356_NVRAM_NAME;
--@@ -1855,7 +1847,6 @@ cleanup:
-- 	PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_NETWORK_OTHER << 8, 0xffff00, 0 }
-- 
-- static struct pci_device_id brcmf_pcie_devid_table[] = {
---	BRCMF_PCIE_DEVICE(BRCM_PCIE_4354_DEVICE_ID),
-- 	BRCMF_PCIE_DEVICE(BRCM_PCIE_4356_DEVICE_ID),
-- 	BRCMF_PCIE_DEVICE(BRCM_PCIE_43567_DEVICE_ID),
-- 	BRCMF_PCIE_DEVICE(BRCM_PCIE_43570_DEVICE_ID),
-diff --git a/package/kernel/mac80211/patches/353-brcmfmac-disable-MBSS-feature-for-BCM43362.patch b/package/kernel/mac80211/patches/353-brcmfmac-disable-MBSS-feature-for-BCM43362.patch
-deleted file mode 100644
-index 366ff85..0000000
---- a/package/kernel/mac80211/patches/353-brcmfmac-disable-MBSS-feature-for-BCM43362.patch
-+++ /dev/null
-@@ -1,28 +0,0 @@
--From: Arend van Spriel <arend@broadcom.com>
--Date: Fri, 20 Mar 2015 22:18:17 +0100
--Subject: [PATCH] brcmfmac: disable MBSS feature for BCM43362
--
--The BCM43362 firmware falsely reports it is capable of providing
--MBSS. As a result AP mode no longer works for this device. Therefor
--disable MBSS in the driver for this chipset.
--
--Cc: stable@vger.kernel.org # 3.19.y
--Reported-by: Jorg Krause <jkrause@posteo.de>
--Reviewed-by: Hante Meuleman <meuleman@broadcom.com>
--Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
--Signed-off-by: Arend van Spriel <arend@broadcom.com>
--Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
-----
--
----- a/drivers/net/wireless/brcm80211/brcmfmac/feature.c
--+++ b/drivers/net/wireless/brcm80211/brcmfmac/feature.c
--@@ -126,7 +126,8 @@ void brcmf_feat_attach(struct brcmf_pub
-- 	brcmf_feat_iovar_int_get(ifp, BRCMF_FEAT_MCHAN, "mchan");
-- 	if (drvr->bus_if->wowl_supported)
-- 		brcmf_feat_iovar_int_get(ifp, BRCMF_FEAT_WOWL, "wowl");
---	brcmf_feat_iovar_int_set(ifp, BRCMF_FEAT_MBSS, "mbss", 0);
--+	if (drvr->bus_if->chip != BRCM_CC_43362_CHIP_ID)
--+		brcmf_feat_iovar_int_set(ifp, BRCMF_FEAT_MBSS, "mbss", 0);
-- 
-- 	/* set chip related quirks */
-- 	switch (drvr->bus_if->chip) {
-diff --git a/package/kernel/mac80211/patches/354-brcmfmac-use-static-superset-of-channels-for-wiphy-b.patch b/package/kernel/mac80211/patches/354-brcmfmac-use-static-superset-of-channels-for-wiphy-b.patch
-deleted file mode 100644
-index 6e461f6..0000000
---- a/package/kernel/mac80211/patches/354-brcmfmac-use-static-superset-of-channels-for-wiphy-b.patch
-+++ /dev/null
-@@ -1,300 +0,0 @@
--From: Arend van Spriel <arend@broadcom.com>
--Date: Tue, 14 Apr 2015 20:10:24 +0200
--Subject: [PATCH] brcmfmac: use static superset of channels for wiphy
-- bands
--
--The driver was constructing a list of channels per wiphy band
--by querying the device. This list is not what the hardware is
--able to do as it is already filtered by the country setting in
--the device. As user-space may change the country this would
--require updating the channel list which is not recommended [1].
--This patch introduces a superset of channels. The individual
--channels are disabled appropriately by querying the device.
--
--[1] http://mid.gmane.org/1426706320.3001.21.camel@sipsolutions.net
--
--Reviewed-by: Hante Meuleman <meuleman@broadcom.com>
--Reviewed-by: Daniel (Deognyoun) Kim <dekim@broadcom.com>
--Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
--Signed-off-by: Arend van Spriel <arend@broadcom.com>
-----
--
----- a/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c
--+++ b/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c
--@@ -129,13 +129,47 @@ static struct ieee80211_rate __wl_rates[
-- 	RATETAB_ENT(BRCM_RATE_54M, 0),
-- };
-- 
---#define wl_a_rates		(__wl_rates + 4)
---#define wl_a_rates_size	8
-- #define wl_g_rates		(__wl_rates + 0)
---#define wl_g_rates_size	12
--+#define wl_g_rates_size		ARRAY_SIZE(__wl_rates)
--+#define wl_a_rates		(__wl_rates + 4)
--+#define wl_a_rates_size		(wl_g_rates_size - 4)
--+
--+#define CHAN2G(_channel, _freq) {				\
--+	.band			= IEEE80211_BAND_2GHZ,		\
--+	.center_freq		= (_freq),			\
--+	.hw_value		= (_channel),			\
--+	.flags			= IEEE80211_CHAN_DISABLED,	\
--+	.max_antenna_gain	= 0,				\
--+	.max_power		= 30,				\
--+}
--+
--+#define CHAN5G(_channel) {					\
--+	.band			= IEEE80211_BAND_5GHZ,		\
--+	.center_freq		= 5000 + (5 * (_channel)),	\
--+	.hw_value		= (_channel),			\
--+	.flags			= IEEE80211_CHAN_DISABLED,	\
--+	.max_antenna_gain	= 0,				\
--+	.max_power		= 30,				\
--+}
--+
--+static struct ieee80211_channel __wl_2ghz_channels[] = {
--+	CHAN2G(1, 2412), CHAN2G(2, 2417), CHAN2G(3, 2422), CHAN2G(4, 2427),
--+	CHAN2G(5, 2432), CHAN2G(6, 2437), CHAN2G(7, 2442), CHAN2G(8, 2447),
--+	CHAN2G(9, 2452), CHAN2G(10, 2457), CHAN2G(11, 2462), CHAN2G(12, 2467),
--+	CHAN2G(13, 2472), CHAN2G(14, 2484)
--+};
--+
--+static struct ieee80211_channel __wl_5ghz_channels[] = {
--+	CHAN5G(34), CHAN5G(36), CHAN5G(38), CHAN5G(40), CHAN5G(42),
--+	CHAN5G(44), CHAN5G(46), CHAN5G(48), CHAN5G(52), CHAN5G(56),
--+	CHAN5G(60), CHAN5G(64), CHAN5G(100), CHAN5G(104), CHAN5G(108),
--+	CHAN5G(112), CHAN5G(116), CHAN5G(120), CHAN5G(124), CHAN5G(128),
--+	CHAN5G(132), CHAN5G(136), CHAN5G(140), CHAN5G(144), CHAN5G(149),
--+	CHAN5G(153), CHAN5G(157), CHAN5G(161), CHAN5G(165)
--+};
-- 
-- /* Band templates duplicated per wiphy. The channel info
--- * is filled in after querying the device.
--+ * above is added to the band during setup.
--  */
-- static const struct ieee80211_supported_band __wl_band_2ghz = {
-- 	.band = IEEE80211_BAND_2GHZ,
--@@ -143,7 +177,7 @@ static const struct ieee80211_supported_
-- 	.n_bitrates = wl_g_rates_size,
-- };
-- 
---static const struct ieee80211_supported_band __wl_band_5ghz_a = {
--+static const struct ieee80211_supported_band __wl_band_5ghz = {
-- 	.band = IEEE80211_BAND_5GHZ,
-- 	.bitrates = wl_a_rates,
-- 	.n_bitrates = wl_a_rates_size,
--@@ -5252,40 +5286,6 @@ dongle_scantime_out:
-- 	return err;
-- }
-- 
---/* Filter the list of channels received from firmware counting only
--- * the 20MHz channels. The wiphy band data only needs those which get
--- * flagged to indicate if they can take part in higher bandwidth.
--- */
---static void brcmf_count_20mhz_channels(struct brcmf_cfg80211_info *cfg,
---				       struct brcmf_chanspec_list *chlist,
---				       u32 chcnt[])
---{
---	u32 total = le32_to_cpu(chlist->count);
---	struct brcmu_chan ch;
---	int i;
---
---	for (i = 0; i < total; i++) {
---		ch.chspec = (u16)le32_to_cpu(chlist->element[i]);
---		cfg->d11inf.decchspec(&ch);
---
---		/* Firmware gives a ordered list. We skip non-20MHz
---		 * channels is 2G. For 5G we can abort upon reaching
---		 * a non-20MHz channel in the list.
---		 */
---		if (ch.bw != BRCMU_CHAN_BW_20) {
---			if (ch.band == BRCMU_CHAN_BAND_5G)
---				break;
---			else
---				continue;
---		}
---
---		if (ch.band == BRCMU_CHAN_BAND_2G)
---			chcnt[0] += 1;
---		else if (ch.band == BRCMU_CHAN_BAND_5G)
---			chcnt[1] += 1;
---	}
---}
---
-- static void brcmf_update_bw40_channel_flag(struct ieee80211_channel *channel,
-- 					   struct brcmu_chan *ch)
-- {
--@@ -5321,7 +5321,6 @@ static int brcmf_construct_chaninfo(stru
-- 	u32 i, j;
-- 	u32 total;
-- 	u32 chaninfo;
---	u32 chcnt[2] = { 0, 0 };
-- 	u32 index;
-- 
-- 	pbuf = kzalloc(BRCMF_DCMD_MEDLEN, GFP_KERNEL);
--@@ -5338,42 +5337,15 @@ static int brcmf_construct_chaninfo(stru
-- 		goto fail_pbuf;
-- 	}
-- 
---	brcmf_count_20mhz_channels(cfg, list, chcnt);
-- 	wiphy = cfg_to_wiphy(cfg);
---	if (chcnt[0]) {
---		band = kmemdup(&__wl_band_2ghz, sizeof(__wl_band_2ghz),
---			       GFP_KERNEL);
---		if (band == NULL) {
---			err = -ENOMEM;
---			goto fail_pbuf;
---		}
---		band->channels = kcalloc(chcnt[0], sizeof(*channel),
---					 GFP_KERNEL);
---		if (band->channels == NULL) {
---			kfree(band);
---			err = -ENOMEM;
---			goto fail_pbuf;
---		}
---		band->n_channels = 0;
---		wiphy->bands[IEEE80211_BAND_2GHZ] = band;
---	}
---	if (chcnt[1]) {
---		band = kmemdup(&__wl_band_5ghz_a, sizeof(__wl_band_5ghz_a),
---			       GFP_KERNEL);
---		if (band == NULL) {
---			err = -ENOMEM;
---			goto fail_band2g;
---		}
---		band->channels = kcalloc(chcnt[1], sizeof(*channel),
---					 GFP_KERNEL);
---		if (band->channels == NULL) {
---			kfree(band);
---			err = -ENOMEM;
---			goto fail_band2g;
---		}
---		band->n_channels = 0;
---		wiphy->bands[IEEE80211_BAND_5GHZ] = band;
---	}
--+	band = wiphy->bands[IEEE80211_BAND_2GHZ];
--+	if (band)
--+		for (i = 0; i < band->n_channels; i++)
--+			band->channels[i].flags = IEEE80211_CHAN_DISABLED;
--+	band = wiphy->bands[IEEE80211_BAND_5GHZ];
--+	if (band)
--+		for (i = 0; i < band->n_channels; i++)
--+			band->channels[i].flags = IEEE80211_CHAN_DISABLED;
-- 
-- 	total = le32_to_cpu(list->count);
-- 	for (i = 0; i < total; i++) {
--@@ -5388,6 +5360,8 @@ static int brcmf_construct_chaninfo(stru
-- 			brcmf_err("Invalid channel Spec. 0x%x.\n", ch.chspec);
-- 			continue;
-- 		}
--+		if (!band)
--+			continue;
-- 		if (!(bw_cap[band->band] & WLC_BW_40MHZ_BIT) &&
-- 		    ch.bw == BRCMU_CHAN_BW_40)
-- 			continue;
--@@ -5415,9 +5389,9 @@ static int brcmf_construct_chaninfo(stru
-- 		} else if (ch.bw == BRCMU_CHAN_BW_40) {
-- 			brcmf_update_bw40_channel_flag(&channel[index], &ch);
-- 		} else {
---			/* disable other bandwidths for now as mentioned
---			 * order assure they are enabled for subsequent
---			 * chanspecs.
--+			/* enable the channel and disable other bandwidths
--+			 * for now as mentioned order assure they are enabled
--+			 * for subsequent chanspecs.
-- 			 */
-- 			channel[index].flags = IEEE80211_CHAN_NO_HT40 |
-- 					       IEEE80211_CHAN_NO_80MHZ;
--@@ -5436,16 +5410,8 @@ static int brcmf_construct_chaninfo(stru
-- 						IEEE80211_CHAN_NO_IR;
-- 			}
-- 		}
---		if (index == band->n_channels)
---			band->n_channels++;
-- 	}
---	kfree(pbuf);
---	return 0;
-- 
---fail_band2g:
---	kfree(wiphy->bands[IEEE80211_BAND_2GHZ]->channels);
---	kfree(wiphy->bands[IEEE80211_BAND_2GHZ]);
---	wiphy->bands[IEEE80211_BAND_2GHZ] = NULL;
-- fail_pbuf:
-- 	kfree(pbuf);
-- 	return err;
--@@ -5778,7 +5744,12 @@ static void brcmf_wiphy_wowl_params(stru
-- 
-- static int brcmf_setup_wiphy(struct wiphy *wiphy, struct brcmf_if *ifp)
-- {
--+	struct ieee80211_supported_band *band;
-- 	struct ieee80211_iface_combination ifc_combo;
--+	__le32 bandlist[3];
--+	u32 n_bands;
--+	int err, i;
--+
-- 	wiphy->max_scan_ssids = WL_NUM_SCAN_MAX;
-- 	wiphy->max_scan_ie_len = BRCMF_SCAN_IE_LEN_MAX;
-- 	wiphy->max_num_pmkids = WL_NUM_PMKIDS_MAX;
--@@ -5820,7 +5791,52 @@ static int brcmf_setup_wiphy(struct wiph
-- 	if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_WOWL))
-- 		brcmf_wiphy_wowl_params(wiphy);
-- 
---	return brcmf_setup_wiphybands(wiphy);
--+	err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_BANDLIST, &bandlist,
--+				     sizeof(bandlist));
--+	if (err) {
--+		brcmf_err("could not obtain band info: err=%d\n", err);
--+		return err;
--+	}
--+	/* first entry in bandlist is number of bands */
--+	n_bands = le32_to_cpu(bandlist[0]);
--+	for (i = 1; i <= n_bands && i < ARRAY_SIZE(bandlist); i++) {
--+		if (bandlist[i] == cpu_to_le32(WLC_BAND_2G)) {
--+			band = kmemdup(&__wl_band_2ghz, sizeof(__wl_band_2ghz),
--+				       GFP_KERNEL);
--+			if (!band)
--+				return -ENOMEM;
--+
--+			band->channels = kmemdup(&__wl_2ghz_channels,
--+						 sizeof(__wl_2ghz_channels),
--+						 GFP_KERNEL);
--+			if (!band->channels) {
--+				kfree(band);
--+				return -ENOMEM;
--+			}
--+
--+			band->n_channels = ARRAY_SIZE(__wl_2ghz_channels);
--+			wiphy->bands[IEEE80211_BAND_2GHZ] = band;
--+		}
--+		if (bandlist[i] == cpu_to_le32(WLC_BAND_5G)) {
--+			band = kmemdup(&__wl_band_5ghz, sizeof(__wl_band_5ghz),
--+				       GFP_KERNEL);
--+			if (!band)
--+				return -ENOMEM;
--+
--+			band->channels = kmemdup(&__wl_5ghz_channels,
--+						 sizeof(__wl_5ghz_channels),
--+						 GFP_KERNEL);
--+			if (!band->channels) {
--+				kfree(band);
--+				return -ENOMEM;
--+			}
--+
--+			band->n_channels = ARRAY_SIZE(__wl_5ghz_channels);
--+			wiphy->bands[IEEE80211_BAND_5GHZ] = band;
--+		}
--+	}
--+	err = brcmf_setup_wiphybands(wiphy);
--+	return err;
-- }
-- 
-- static s32 brcmf_config_dongle(struct brcmf_cfg80211_info *cfg)
--@@ -6011,6 +6027,9 @@ static void brcmf_cfg80211_reg_notifier(
-- 
-- static void brcmf_free_wiphy(struct wiphy *wiphy)
-- {
--+	if (!wiphy)
--+		return;
--+
-- 	kfree(wiphy->iface_combinations);
-- 	if (wiphy->bands[IEEE80211_BAND_2GHZ]) {
-- 		kfree(wiphy->bands[IEEE80211_BAND_2GHZ]->channels);
-diff --git a/package/kernel/mac80211/patches/355-brcmfmac-update-wiphy-band-information-upon-updating.patch b/package/kernel/mac80211/patches/355-brcmfmac-update-wiphy-band-information-upon-updating.patch
-deleted file mode 100644
-index a0c22eb..0000000
---- a/package/kernel/mac80211/patches/355-brcmfmac-update-wiphy-band-information-upon-updating.patch
-+++ /dev/null
-@@ -1,29 +0,0 @@
--From: Arend van Spriel <arend@broadcom.com>
--Date: Tue, 14 Apr 2015 20:10:25 +0200
--Subject: [PATCH] brcmfmac: update wiphy band information upon updating
-- regulatory domain
--
--When change the country code the available channels may change. So
--the wiphy bands should be updated accordingly.
--
--Reviewed-by: Daniel (Deognyoun) Kim <dekim@broadcom.com>
--Reviewed-by: Hante Meuleman <meuleman@broadcom.com>
--Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
--Signed-off-by: Arend van Spriel <arend@broadcom.com>
-----
--
----- a/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c
--+++ b/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c
--@@ -6022,7 +6022,11 @@ static void brcmf_cfg80211_reg_notifier(
-- 	memset(&ccreq, 0, sizeof(ccreq));
-- 	ccreq.rev = cpu_to_le32(-1);
-- 	memcpy(ccreq.ccode, req->alpha2, sizeof(req->alpha2));
---	brcmf_fil_iovar_data_set(ifp, "country", &ccreq, sizeof(ccreq));
--+	if (brcmf_fil_iovar_data_set(ifp, "country", &ccreq, sizeof(ccreq))) {
--+		brcmf_err("firmware rejected country setting\n");
--+		return;
--+	}
--+	brcmf_setup_wiphybands(wiphy);
-- }
-- 
-- static void brcmf_free_wiphy(struct wiphy *wiphy)
-diff --git a/package/kernel/mac80211/patches/356-brcmfmac-add-description-for-feature-flags.patch b/package/kernel/mac80211/patches/356-brcmfmac-add-description-for-feature-flags.patch
-deleted file mode 100644
-index 193f507..0000000
---- a/package/kernel/mac80211/patches/356-brcmfmac-add-description-for-feature-flags.patch
-+++ /dev/null
-@@ -1,24 +0,0 @@
--From: Arend van Spriel <arend@broadcom.com>
--Date: Tue, 14 Apr 2015 20:10:26 +0200
--Subject: [PATCH] brcmfmac: add description for feature flags
--
--Some feature flags were not described in the header file. Adding
--the description.
--
--Reviewed-by: Hante Meuleman <meuleman@broadcom.com>
--Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
--Signed-off-by: Arend van Spriel <arend@broadcom.com>
-----
--
----- a/drivers/net/wireless/brcm80211/brcmfmac/feature.h
--+++ b/drivers/net/wireless/brcm80211/brcmfmac/feature.h
--@@ -19,7 +19,9 @@
-- /*
--  * Features:
--  *
--+ * MBSS: multiple BSSID support (eg. guest network in AP mode).
--  * MCHAN: multi-channel for concurrent P2P.
--+ * WOWL: Wake-On-WLAN.
--  */
-- #define BRCMF_FEAT_LIST \
-- 	BRCMF_FEAT_DEF(MBSS) \
-diff --git a/package/kernel/mac80211/patches/357-brcmfmac-make-scheduled-scan-support-conditional.patch b/package/kernel/mac80211/patches/357-brcmfmac-make-scheduled-scan-support-conditional.patch
-deleted file mode 100644
-index 42330b4..0000000
---- a/package/kernel/mac80211/patches/357-brcmfmac-make-scheduled-scan-support-conditional.patch
-+++ /dev/null
-@@ -1,51 +0,0 @@
--From: Arend van Spriel <arend@broadcom.com>
--Date: Tue, 14 Apr 2015 20:10:27 +0200
--Subject: [PATCH] brcmfmac: make scheduled scan support conditional
--
--The scheduled scan support depends on firmware supporting the PNO
--feature. This feature is optional so add a feature flag for this
--in the driver and announce scheduled scan support accordingly.
--
--Reviewed-by: Hante Meuleman <meuleman@broadcom.com>
--Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
--Signed-off-by: Arend van Spriel <arend@broadcom.com>
-----
--
----- a/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c
--+++ b/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c
--@@ -5782,7 +5782,8 @@ static int brcmf_setup_wiphy(struct wiph
-- 		wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
-- 	wiphy->mgmt_stypes = brcmf_txrx_stypes;
-- 	wiphy->max_remain_on_channel_duration = 5000;
---	brcmf_wiphy_pno_params(wiphy);
--+	if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_PNO))
--+		brcmf_wiphy_pno_params(wiphy);
-- 
-- 	/* vendor commands/events support */
-- 	wiphy->vendor_commands = brcmf_vendor_cmds;
----- a/drivers/net/wireless/brcm80211/brcmfmac/feature.c
--+++ b/drivers/net/wireless/brcm80211/brcmfmac/feature.c
--@@ -124,6 +124,7 @@ void brcmf_feat_attach(struct brcmf_pub
-- 	struct brcmf_if *ifp = drvr->iflist[0];
-- 
-- 	brcmf_feat_iovar_int_get(ifp, BRCMF_FEAT_MCHAN, "mchan");
--+	brcmf_feat_iovar_int_get(ifp, BRCMF_FEAT_PNO, "pfn");
-- 	if (drvr->bus_if->wowl_supported)
-- 		brcmf_feat_iovar_int_get(ifp, BRCMF_FEAT_WOWL, "wowl");
-- 	if (drvr->bus_if->chip != BRCM_CC_43362_CHIP_ID)
----- a/drivers/net/wireless/brcm80211/brcmfmac/feature.h
--+++ b/drivers/net/wireless/brcm80211/brcmfmac/feature.h
--@@ -21,11 +21,13 @@
--  *
--  * MBSS: multiple BSSID support (eg. guest network in AP mode).
--  * MCHAN: multi-channel for concurrent P2P.
--+ * PNO: preferred network offload.
--  * WOWL: Wake-On-WLAN.
--  */
-- #define BRCMF_FEAT_LIST \
-- 	BRCMF_FEAT_DEF(MBSS) \
-- 	BRCMF_FEAT_DEF(MCHAN) \
--+	BRCMF_FEAT_DEF(PNO) \
-- 	BRCMF_FEAT_DEF(WOWL)
-- /*
--  * Quirks:
-diff --git a/package/kernel/mac80211/patches/358-brcmfmac-add-support-for-BCM4324-rev-B5-chipset.patch b/package/kernel/mac80211/patches/358-brcmfmac-add-support-for-BCM4324-rev-B5-chipset.patch
-deleted file mode 100644
-index b859d46..0000000
---- a/package/kernel/mac80211/patches/358-brcmfmac-add-support-for-BCM4324-rev-B5-chipset.patch
-+++ /dev/null
-@@ -1,43 +0,0 @@
--From: Arend van Spriel <arend@broadcom.com>
--Date: Tue, 14 Apr 2015 20:10:28 +0200
--Subject: [PATCH] brcmfmac: add support for BCM4324 rev B5 chipset
--
--This patch adds support for the BCM4324 B5 revision. This device
--is similar to BCM43241 from driver and firmware perspective. It
--is known to be used in Lenovo Thinkpad Tablet devices.
--
--Reviewed-by: Hante Meuleman <meuleman@broadcom.com>
--Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
--Signed-off-by: Arend van Spriel <arend@broadcom.com>
-----
--
----- a/drivers/net/wireless/brcm80211/brcmfmac/sdio.c
--+++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio.c
--@@ -601,6 +601,8 @@ static const struct sdiod_drive_str sdio
-- #define BCM43241B0_NVRAM_NAME		"brcm/brcmfmac43241b0-sdio.txt"
-- #define BCM43241B4_FIRMWARE_NAME	"brcm/brcmfmac43241b4-sdio.bin"
-- #define BCM43241B4_NVRAM_NAME		"brcm/brcmfmac43241b4-sdio.txt"
--+#define BCM43241B5_FIRMWARE_NAME	"brcm/brcmfmac43241b5-sdio.bin"
--+#define BCM43241B5_NVRAM_NAME		"brcm/brcmfmac43241b5-sdio.txt"
-- #define BCM4329_FIRMWARE_NAME		"brcm/brcmfmac4329-sdio.bin"
-- #define BCM4329_NVRAM_NAME		"brcm/brcmfmac4329-sdio.txt"
-- #define BCM4330_FIRMWARE_NAME		"brcm/brcmfmac4330-sdio.bin"
--@@ -628,6 +630,8 @@ MODULE_FIRMWARE(BCM43241B0_FIRMWARE_NAME
-- MODULE_FIRMWARE(BCM43241B0_NVRAM_NAME);
-- MODULE_FIRMWARE(BCM43241B4_FIRMWARE_NAME);
-- MODULE_FIRMWARE(BCM43241B4_NVRAM_NAME);
--+MODULE_FIRMWARE(BCM43241B5_FIRMWARE_NAME);
--+MODULE_FIRMWARE(BCM43241B5_NVRAM_NAME);
-- MODULE_FIRMWARE(BCM4329_FIRMWARE_NAME);
-- MODULE_FIRMWARE(BCM4329_NVRAM_NAME);
-- MODULE_FIRMWARE(BCM4330_FIRMWARE_NAME);
--@@ -667,7 +671,8 @@ enum brcmf_firmware_type {
-- static const struct brcmf_firmware_names brcmf_fwname_data[] = {
-- 	{ BRCM_CC_43143_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM43143) },
-- 	{ BRCM_CC_43241_CHIP_ID, 0x0000001F, BRCMF_FIRMWARE_NVRAM(BCM43241B0) },
---	{ BRCM_CC_43241_CHIP_ID, 0xFFFFFFE0, BRCMF_FIRMWARE_NVRAM(BCM43241B4) },
--+	{ BRCM_CC_43241_CHIP_ID, 0x00000020, BRCMF_FIRMWARE_NVRAM(BCM43241B4) },
--+	{ BRCM_CC_43241_CHIP_ID, 0xFFFFFFC0, BRCMF_FIRMWARE_NVRAM(BCM43241B5) },
-- 	{ BRCM_CC_4329_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4329) },
-- 	{ BRCM_CC_4330_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4330) },
-- 	{ BRCM_CC_4334_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4334) },
-diff --git a/package/kernel/mac80211/patches/359-brcmfmac-process-interrupt-regardless-sdiod-state.patch b/package/kernel/mac80211/patches/359-brcmfmac-process-interrupt-regardless-sdiod-state.patch
-deleted file mode 100644
-index d420308..0000000
---- a/package/kernel/mac80211/patches/359-brcmfmac-process-interrupt-regardless-sdiod-state.patch
-+++ /dev/null
-@@ -1,27 +0,0 @@
--From: Arend van Spriel <arend@broadcom.com>
--Date: Tue, 14 Apr 2015 20:10:29 +0200
--Subject: [PATCH] brcmfmac: process interrupt regardless sdiod state
--
--When the sdio bus state is not ready to process we abort the
--interrupt service routine. This is not wanted as it keeps the
--interrupt source active. Better clear the interrupt source.
--
--Reviewed-by: Hante Meuleman <meuleman@broadcom.com>
--Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
--Reviewed-by: Franky (Zhenhui) Lin <frankyl@broadcom.com>
--Signed-off-by: Arend van Spriel <arend@broadcom.com>
-----
--
----- a/drivers/net/wireless/brcm80211/brcmfmac/sdio.c
--+++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio.c
--@@ -3555,10 +3555,6 @@ void brcmf_sdio_isr(struct brcmf_sdio *b
-- 		return;
-- 	}
-- 
---	if (bus->sdiodev->state != BRCMF_SDIOD_DATA) {
---		brcmf_err("bus is down. we have nothing to do\n");
---		return;
---	}
-- 	/* Count the interrupt call */
-- 	bus->sdcnt.intrcount++;
-- 	if (in_interrupt())
-diff --git a/package/kernel/mac80211/patches/360-brcmfmac-fix-sdio-suspend-and-resume.patch b/package/kernel/mac80211/patches/360-brcmfmac-fix-sdio-suspend-and-resume.patch
-deleted file mode 100644
-index ac5584e..0000000
---- a/package/kernel/mac80211/patches/360-brcmfmac-fix-sdio-suspend-and-resume.patch
-+++ /dev/null
-@@ -1,68 +0,0 @@
--From: Arend van Spriel <arend@broadcom.com>
--Date: Tue, 14 Apr 2015 20:10:30 +0200
--Subject: [PATCH] brcmfmac: fix sdio suspend and resume
--
--commit 330b4e4be937 ("brcmfmac: Add wowl support for SDIO devices.")
--changed the behaviour by removing the MMC_PM_KEEP_POWER flag for
--non-wowl scenario, which needs to be restored. Another necessary
--change is to mark the card as being non-removable. With this in place
--the suspend resume test passes successfully doing:
--
-- # echo devices > /sys/power/pm_test
-- # echo mem > /sys/power/state
--
--Note that power may still be switched off when system is going
--in S3 state.
--
--Reported-by: Fu, Zhonghui <<zhonghui.fu@linux.intel.com>
--Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
--Reviewed-by: Franky (Zhenhui) Lin <frankyl@broadcom.com>
--Signed-off-by: Arend van Spriel <arend@broadcom.com>
-----
--
----- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
--+++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
--@@ -1011,6 +1011,14 @@ static int brcmf_sdiod_remove(struct brc
-- 	return 0;
-- }
-- 
--+static void brcmf_sdiod_host_fixup(struct mmc_host *host)
--+{
--+	/* runtime-pm powers off the device */
--+	pm_runtime_forbid(host->parent);
--+	/* avoid removal detection upon resume */
--+	host->caps |= MMC_CAP_NONREMOVABLE;
--+}
--+
-- static int brcmf_sdiod_probe(struct brcmf_sdio_dev *sdiodev)
-- {
-- 	struct sdio_func *func;
--@@ -1076,7 +1084,7 @@ static int brcmf_sdiod_probe(struct brcm
-- 		ret = -ENODEV;
-- 		goto out;
-- 	}
---	pm_runtime_forbid(host->parent);
--+	brcmf_sdiod_host_fixup(host);
-- out:
-- 	if (ret)
-- 		brcmf_sdiod_remove(sdiodev);
--@@ -1246,15 +1254,15 @@ static int brcmf_ops_sdio_suspend(struct
-- 	brcmf_sdiod_freezer_on(sdiodev);
-- 	brcmf_sdio_wd_timer(sdiodev->bus, 0);
-- 
--+	sdio_flags = MMC_PM_KEEP_POWER;
-- 	if (sdiodev->wowl_enabled) {
---		sdio_flags = MMC_PM_KEEP_POWER;
-- 		if (sdiodev->pdata->oob_irq_supported)
-- 			enable_irq_wake(sdiodev->pdata->oob_irq_nr);
-- 		else
---			sdio_flags = MMC_PM_WAKE_SDIO_IRQ;
---		if (sdio_set_host_pm_flags(sdiodev->func[1], sdio_flags))
---			brcmf_err("Failed to set pm_flags %x\n", sdio_flags);
--+			sdio_flags |= MMC_PM_WAKE_SDIO_IRQ;
-- 	}
--+	if (sdio_set_host_pm_flags(sdiodev->func[1], sdio_flags))
--+		brcmf_err("Failed to set pm_flags %x\n", sdio_flags);
-- 	return 0;
-- }
-- 
-diff --git a/package/kernel/mac80211/patches/361-brcmfmac-add-support-for-BCM4358-PCIe-device.patch b/package/kernel/mac80211/patches/361-brcmfmac-add-support-for-BCM4358-PCIe-device.patch
-deleted file mode 100644
-index a521b65..0000000
---- a/package/kernel/mac80211/patches/361-brcmfmac-add-support-for-BCM4358-PCIe-device.patch
-+++ /dev/null
-@@ -1,77 +0,0 @@
--From: Arend van Spriel <arend@broadcom.com>
--Date: Tue, 14 Apr 2015 20:10:31 +0200
--Subject: [PATCH] brcmfmac: add support for BCM4358 PCIe device
--
--This patch adds support for the BCM4358 2x2 11ac device.
--
--Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
--Signed-off-by: Arend van Spriel <arend@broadcom.com>
-----
--
----- a/drivers/net/wireless/brcm80211/brcmfmac/chip.c
--+++ b/drivers/net/wireless/brcm80211/brcmfmac/chip.c
--@@ -649,6 +649,7 @@ static u32 brcmf_chip_tcm_rambase(struct
-- 	case BRCM_CC_43567_CHIP_ID:
-- 	case BRCM_CC_43569_CHIP_ID:
-- 	case BRCM_CC_43570_CHIP_ID:
--+	case BRCM_CC_4358_CHIP_ID:
-- 	case BRCM_CC_43602_CHIP_ID:
-- 		return 0x180000;
-- 	default:
----- a/drivers/net/wireless/brcm80211/brcmfmac/pcie.c
--+++ b/drivers/net/wireless/brcm80211/brcmfmac/pcie.c
--@@ -51,6 +51,8 @@ enum brcmf_pcie_state {
-- #define BRCMF_PCIE_4356_NVRAM_NAME		"brcm/brcmfmac4356-pcie.txt"
-- #define BRCMF_PCIE_43570_FW_NAME		"brcm/brcmfmac43570-pcie.bin"
-- #define BRCMF_PCIE_43570_NVRAM_NAME		"brcm/brcmfmac43570-pcie.txt"
--+#define BRCMF_PCIE_4358_FW_NAME			"brcm/brcmfmac4358-pcie.bin"
--+#define BRCMF_PCIE_4358_NVRAM_NAME		"brcm/brcmfmac4358-pcie.txt"
-- 
-- #define BRCMF_PCIE_FW_UP_TIMEOUT		2000 /* msec */
-- 
--@@ -189,6 +191,8 @@ MODULE_FIRMWARE(BRCMF_PCIE_4356_FW_NAME)
-- MODULE_FIRMWARE(BRCMF_PCIE_4356_NVRAM_NAME);
-- MODULE_FIRMWARE(BRCMF_PCIE_43570_FW_NAME);
-- MODULE_FIRMWARE(BRCMF_PCIE_43570_NVRAM_NAME);
--+MODULE_FIRMWARE(BRCMF_PCIE_4358_FW_NAME);
--+MODULE_FIRMWARE(BRCMF_PCIE_4358_NVRAM_NAME);
-- 
-- 
-- struct brcmf_pcie_console {
--@@ -1333,6 +1337,10 @@ static int brcmf_pcie_get_fwnames(struct
-- 		fw_name = BRCMF_PCIE_43570_FW_NAME;
-- 		nvram_name = BRCMF_PCIE_43570_NVRAM_NAME;
-- 		break;
--+	case BRCM_CC_4358_CHIP_ID:
--+		fw_name = BRCMF_PCIE_4358_FW_NAME;
--+		nvram_name = BRCMF_PCIE_4358_NVRAM_NAME;
--+		break;
-- 	default:
-- 		brcmf_err("Unsupported chip 0x%04x\n", devinfo->ci->chip);
-- 		return -ENODEV;
--@@ -1850,6 +1858,7 @@ static struct pci_device_id brcmf_pcie_d
-- 	BRCMF_PCIE_DEVICE(BRCM_PCIE_4356_DEVICE_ID),
-- 	BRCMF_PCIE_DEVICE(BRCM_PCIE_43567_DEVICE_ID),
-- 	BRCMF_PCIE_DEVICE(BRCM_PCIE_43570_DEVICE_ID),
--+	BRCMF_PCIE_DEVICE(BRCM_PCIE_4358_DEVICE_ID),
-- 	BRCMF_PCIE_DEVICE(BRCM_PCIE_43602_DEVICE_ID),
-- 	BRCMF_PCIE_DEVICE(BRCM_PCIE_43602_2G_DEVICE_ID),
-- 	BRCMF_PCIE_DEVICE(BRCM_PCIE_43602_5G_DEVICE_ID),
----- a/drivers/net/wireless/brcm80211/include/brcm_hw_ids.h
--+++ b/drivers/net/wireless/brcm80211/include/brcm_hw_ids.h
--@@ -45,6 +45,7 @@
-- #define BRCM_CC_43567_CHIP_ID		43567
-- #define BRCM_CC_43569_CHIP_ID		43569
-- #define BRCM_CC_43570_CHIP_ID		43570
--+#define BRCM_CC_4358_CHIP_ID		0x4358
-- #define BRCM_CC_43602_CHIP_ID		43602
-- 
-- /* USB Device IDs */
--@@ -59,6 +60,7 @@
-- #define BRCM_PCIE_4356_DEVICE_ID	0x43ec
-- #define BRCM_PCIE_43567_DEVICE_ID	0x43d3
-- #define BRCM_PCIE_43570_DEVICE_ID	0x43d9
--+#define BRCM_PCIE_4358_DEVICE_ID	0x43e9
-- #define BRCM_PCIE_43602_DEVICE_ID	0x43ba
-- #define BRCM_PCIE_43602_2G_DEVICE_ID	0x43bb
-- #define BRCM_PCIE_43602_5G_DEVICE_ID	0x43bc
-diff --git a/package/kernel/mac80211/patches/362-brcmfmac-add-additional-43602-pcie-device-id.patch b/package/kernel/mac80211/patches/362-brcmfmac-add-additional-43602-pcie-device-id.patch
-deleted file mode 100644
-index bcbb984..0000000
---- a/package/kernel/mac80211/patches/362-brcmfmac-add-additional-43602-pcie-device-id.patch
-+++ /dev/null
-@@ -1,30 +0,0 @@
--From: Hante Meuleman <meuleman@broadcom.com>
--Date: Tue, 14 Apr 2015 20:10:32 +0200
--Subject: [PATCH] brcmfmac: add additional 43602 pcie device id.
--
--Reviewed-by: Arend Van Spriel <arend@broadcom.com>
--Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
--Signed-off-by: Hante Meuleman <meuleman@broadcom.com>
--Signed-off-by: Arend van Spriel <arend@broadcom.com>
-----
--
----- a/drivers/net/wireless/brcm80211/brcmfmac/pcie.c
--+++ b/drivers/net/wireless/brcm80211/brcmfmac/pcie.c
--@@ -1862,6 +1862,7 @@ static struct pci_device_id brcmf_pcie_d
-- 	BRCMF_PCIE_DEVICE(BRCM_PCIE_43602_DEVICE_ID),
-- 	BRCMF_PCIE_DEVICE(BRCM_PCIE_43602_2G_DEVICE_ID),
-- 	BRCMF_PCIE_DEVICE(BRCM_PCIE_43602_5G_DEVICE_ID),
--+	BRCMF_PCIE_DEVICE(BRCM_PCIE_43602_RAW_DEVICE_ID),
-- 	{ /* end: all zeroes */ }
-- };
-- 
----- a/drivers/net/wireless/brcm80211/include/brcm_hw_ids.h
--+++ b/drivers/net/wireless/brcm80211/include/brcm_hw_ids.h
--@@ -64,6 +64,7 @@
-- #define BRCM_PCIE_43602_DEVICE_ID	0x43ba
-- #define BRCM_PCIE_43602_2G_DEVICE_ID	0x43bb
-- #define BRCM_PCIE_43602_5G_DEVICE_ID	0x43bc
--+#define BRCM_PCIE_43602_RAW_DEVICE_ID	43602
-- 
-- /* brcmsmac IDs */
-- #define BCM4313_D11N2G_ID	0x4727	/* 4313 802.11n 2.4G device */
-diff --git a/package/kernel/mac80211/patches/363-brcmfmac-Add-support-for-multiple-PCIE-devices-in-nv.patch b/package/kernel/mac80211/patches/363-brcmfmac-Add-support-for-multiple-PCIE-devices-in-nv.patch
-deleted file mode 100644
-index 5f9bbea..0000000
---- a/package/kernel/mac80211/patches/363-brcmfmac-Add-support-for-multiple-PCIE-devices-in-nv.patch
-+++ /dev/null
-@@ -1,351 +0,0 @@
--From: Hante Meuleman <meuleman@broadcom.com>
--Date: Tue, 14 Apr 2015 20:10:33 +0200
--Subject: [PATCH] brcmfmac: Add support for multiple PCIE devices in
-- nvram.
--
--With PCIE it is possible to support multiple devices with the
--same device type. They all load the same nvram file. In order to
--support this the nvram can specify which part of the nvram is
--for which pcie device. This patch adds support for these new
--types of nvram files.
--
--Reviewed-by: Arend Van Spriel <arend@broadcom.com>
--Reviewed-by: Franky (Zhenhui) Lin <frankyl@broadcom.com>
--Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
--Reviewed-by: Daniel (Deognyoun) Kim <dekim@broadcom.com>
--Signed-off-by: Hante Meuleman <meuleman@broadcom.com>
--Signed-off-by: Arend van Spriel <arend@broadcom.com>
-----
--
----- a/drivers/net/wireless/brcm80211/brcmfmac/firmware.c
--+++ b/drivers/net/wireless/brcm80211/brcmfmac/firmware.c
--@@ -23,6 +23,10 @@
-- #include "debug.h"
-- #include "firmware.h"
-- 
--+#define BRCMF_FW_MAX_NVRAM_SIZE			64000
--+#define BRCMF_FW_NVRAM_DEVPATH_LEN		19	/* devpath0=pcie/1/4/ */
--+#define BRCMF_FW_NVRAM_PCIEDEV_LEN		9	/* pcie/1/4/ */
--+
-- char brcmf_firmware_path[BRCMF_FW_PATH_LEN];
-- module_param_string(firmware_path, brcmf_firmware_path,
-- 		    BRCMF_FW_PATH_LEN, 0440);
--@@ -46,6 +50,8 @@ enum nvram_parser_state {
--  * @column: current column in line.
--  * @pos: byte offset in input buffer.
--  * @entry: start position of key,value entry.
--+ * @multi_dev_v1: detect pcie multi device v1 (compressed).
--+ * @multi_dev_v2: detect pcie multi device v2.
--  */
-- struct nvram_parser {
-- 	enum nvram_parser_state state;
--@@ -56,6 +62,8 @@ struct nvram_parser {
-- 	u32 column;
-- 	u32 pos;
-- 	u32 entry;
--+	bool multi_dev_v1;
--+	bool multi_dev_v2;
-- };
-- 
-- static bool is_nvram_char(char c)
--@@ -108,6 +116,10 @@ static enum nvram_parser_state brcmf_nvr
-- 			st = COMMENT;
-- 		else
-- 			st = VALUE;
--+		if (strncmp(&nvp->fwnv->data[nvp->entry], "devpath", 7) == 0)
--+			nvp->multi_dev_v1 = true;
--+		if (strncmp(&nvp->fwnv->data[nvp->entry], "pcie/", 5) == 0)
--+			nvp->multi_dev_v2 = true;
-- 	} else if (!is_nvram_char(c)) {
-- 		brcmf_dbg(INFO, "warning: ln=%d:col=%d: '=' expected, skip invalid key entry\n",
-- 			  nvp->line, nvp->column);
--@@ -133,6 +145,8 @@ brcmf_nvram_handle_value(struct nvram_pa
-- 		ekv = (u8 *)&nvp->fwnv->data[nvp->pos];
-- 		skv = (u8 *)&nvp->fwnv->data[nvp->entry];
-- 		cplen = ekv - skv;
--+		if (nvp->nvram_len + cplen + 1 >= BRCMF_FW_MAX_NVRAM_SIZE)
--+			return END;
-- 		/* copy to output buffer */
-- 		memcpy(&nvp->nvram[nvp->nvram_len], skv, cplen);
-- 		nvp->nvram_len += cplen;
--@@ -180,10 +194,18 @@ static enum nvram_parser_state
-- static int brcmf_init_nvram_parser(struct nvram_parser *nvp,
-- 				   const struct firmware *nv)
-- {
--+	size_t size;
--+
-- 	memset(nvp, 0, sizeof(*nvp));
-- 	nvp->fwnv = nv;
--+	/* Limit size to MAX_NVRAM_SIZE, some files contain lot of comment */
--+	if (nv->size > BRCMF_FW_MAX_NVRAM_SIZE)
--+		size = BRCMF_FW_MAX_NVRAM_SIZE;
--+	else
--+		size = nv->size;
-- 	/* Alloc for extra 0 byte + roundup by 4 + length field */
---	nvp->nvram = kzalloc(nv->size + 1 + 3 + sizeof(u32), GFP_KERNEL);
--+	size += 1 + 3 + sizeof(u32);
--+	nvp->nvram = kzalloc(size, GFP_KERNEL);
-- 	if (!nvp->nvram)
-- 		return -ENOMEM;
-- 
--@@ -192,12 +214,136 @@ static int brcmf_init_nvram_parser(struc
-- 	return 0;
-- }
-- 
--+/* brcmf_fw_strip_multi_v1 :Some nvram files contain settings for multiple
--+ * devices. Strip it down for one device, use domain_nr/bus_nr to determine
--+ * which data is to be returned. v1 is the version where nvram is stored
--+ * compressed and "devpath" maps to index for valid entries.
--+ */
--+static void brcmf_fw_strip_multi_v1(struct nvram_parser *nvp, u16 domain_nr,
--+				    u16 bus_nr)
--+{
--+	u32 i, j;
--+	bool found;
--+	u8 *nvram;
--+	u8 id;
--+
--+	nvram = kzalloc(nvp->nvram_len + 1 + 3 + sizeof(u32), GFP_KERNEL);
--+	if (!nvram)
--+		goto fail;
--+
--+	/* min length: devpath0=pcie/1/4/ + 0:x=y */
--+	if (nvp->nvram_len < BRCMF_FW_NVRAM_DEVPATH_LEN + 6)
--+		goto fail;
--+
--+	/* First search for the devpathX and see if it is the configuration
--+	 * for domain_nr/bus_nr. Search complete nvp
--+	 */
--+	found = false;
--+	i = 0;
--+	while (i < nvp->nvram_len - BRCMF_FW_NVRAM_DEVPATH_LEN) {
--+		/* Format: devpathX=pcie/Y/Z/
--+		 * Y = domain_nr, Z = bus_nr, X = virtual ID
--+		 */
--+		if ((strncmp(&nvp->nvram[i], "devpath", 7) == 0) &&
--+		    (strncmp(&nvp->nvram[i + 8], "=pcie/", 6) == 0)) {
--+			if (((nvp->nvram[i + 14] - '0') == domain_nr) &&
--+			    ((nvp->nvram[i + 16] - '0') == bus_nr)) {
--+				id = nvp->nvram[i + 7] - '0';
--+				found = true;
--+				break;
--+			}
--+		}
--+		while (nvp->nvram[i] != 0)
--+			i++;
--+		i++;
--+	}
--+	if (!found)
--+		goto fail;
--+
--+	/* Now copy all valid entries, release old nvram and assign new one */
--+	i = 0;
--+	j = 0;
--+	while (i < nvp->nvram_len) {
--+		if ((nvp->nvram[i] - '0' == id) && (nvp->nvram[i + 1] == ':')) {
--+			i += 2;
--+			while (nvp->nvram[i] != 0) {
--+				nvram[j] = nvp->nvram[i];
--+				i++;
--+				j++;
--+			}
--+			nvram[j] = 0;
--+			j++;
--+		}
--+		while (nvp->nvram[i] != 0)
--+			i++;
--+		i++;
--+	}
--+	kfree(nvp->nvram);
--+	nvp->nvram = nvram;
--+	nvp->nvram_len = j;
--+	return;
--+
--+fail:
--+	kfree(nvram);
--+	nvp->nvram_len = 0;
--+}
--+
--+/* brcmf_fw_strip_multi_v2 :Some nvram files contain settings for multiple
--+ * devices. Strip it down for one device, use domain_nr/bus_nr to determine
--+ * which data is to be returned. v2 is the version where nvram is stored
--+ * uncompressed, all relevant valid entries are identified by
--+ * pcie/domain_nr/bus_nr:
--+ */
--+static void brcmf_fw_strip_multi_v2(struct nvram_parser *nvp, u16 domain_nr,
--+				    u16 bus_nr)
--+{
--+	u32 i, j;
--+	u8 *nvram;
--+
--+	nvram = kzalloc(nvp->nvram_len + 1 + 3 + sizeof(u32), GFP_KERNEL);
--+	if (!nvram)
--+		goto fail;
--+
--+	/* Copy all valid entries, release old nvram and assign new one.
--+	 * Valid entries are of type pcie/X/Y/ where X = domain_nr and
--+	 * Y = bus_nr.
--+	 */
--+	i = 0;
--+	j = 0;
--+	while (i < nvp->nvram_len - BRCMF_FW_NVRAM_PCIEDEV_LEN) {
--+		if ((strncmp(&nvp->nvram[i], "pcie/", 5) == 0) &&
--+		    (nvp->nvram[i + 6] == '/') && (nvp->nvram[i + 8] == '/') &&
--+		    ((nvp->nvram[i + 5] - '0') == domain_nr) &&
--+		    ((nvp->nvram[i + 7] - '0') == bus_nr)) {
--+			i += BRCMF_FW_NVRAM_PCIEDEV_LEN;
--+			while (nvp->nvram[i] != 0) {
--+				nvram[j] = nvp->nvram[i];
--+				i++;
--+				j++;
--+			}
--+			nvram[j] = 0;
--+			j++;
--+		}
--+		while (nvp->nvram[i] != 0)
--+			i++;
--+		i++;
--+	}
--+	kfree(nvp->nvram);
--+	nvp->nvram = nvram;
--+	nvp->nvram_len = j;
--+	return;
--+fail:
--+	kfree(nvram);
--+	nvp->nvram_len = 0;
--+}
--+
-- /* brcmf_nvram_strip :Takes a buffer of "<var>=<value>\n" lines read from a fil
--  * and ending in a NUL. Removes carriage returns, empty lines, comment lines,
--  * and converts newlines to NULs. Shortens buffer as needed and pads with NULs.
--  * End of buffer is completed with token identifying length of buffer.
--  */
---static void *brcmf_fw_nvram_strip(const struct firmware *nv, u32 *new_length)
--+static void *brcmf_fw_nvram_strip(const struct firmware *nv, u32 *new_length,
--+				  u16 domain_nr, u16 bus_nr)
-- {
-- 	struct nvram_parser nvp;
-- 	u32 pad;
--@@ -212,6 +358,16 @@ static void *brcmf_fw_nvram_strip(const
-- 		if (nvp.state == END)
-- 			break;
-- 	}
--+	if (nvp.multi_dev_v1)
--+		brcmf_fw_strip_multi_v1(&nvp, domain_nr, bus_nr);
--+	else if (nvp.multi_dev_v2)
--+		brcmf_fw_strip_multi_v2(&nvp, domain_nr, bus_nr);
--+
--+	if (nvp.nvram_len == 0) {
--+		kfree(nvp.nvram);
--+		return NULL;
--+	}
--+
-- 	pad = nvp.nvram_len;
-- 	*new_length = roundup(nvp.nvram_len + 1, 4);
-- 	while (pad != *new_length) {
--@@ -239,6 +395,8 @@ struct brcmf_fw {
-- 	u16 flags;
-- 	const struct firmware *code;
-- 	const char *nvram_name;
--+	u16 domain_nr;
--+	u16 bus_nr;
-- 	void (*done)(struct device *dev, const struct firmware *fw,
-- 		     void *nvram_image, u32 nvram_len);
-- };
--@@ -254,7 +412,8 @@ static void brcmf_fw_request_nvram_done(
-- 		goto fail;
-- 
-- 	if (fw) {
---		nvram = brcmf_fw_nvram_strip(fw, &nvram_length);
--+		nvram = brcmf_fw_nvram_strip(fw, &nvram_length,
--+					     fwctx->domain_nr, fwctx->bus_nr);
-- 		release_firmware(fw);
-- 		if (!nvram && !(fwctx->flags & BRCMF_FW_REQ_NV_OPTIONAL))
-- 			goto fail;
--@@ -309,11 +468,12 @@ fail:
-- 	kfree(fwctx);
-- }
-- 
---int brcmf_fw_get_firmwares(struct device *dev, u16 flags,
---			   const char *code, const char *nvram,
---			   void (*fw_cb)(struct device *dev,
---					 const struct firmware *fw,
---					 void *nvram_image, u32 nvram_len))
--+int brcmf_fw_get_firmwares_pcie(struct device *dev, u16 flags,
--+				const char *code, const char *nvram,
--+				void (*fw_cb)(struct device *dev,
--+					      const struct firmware *fw,
--+					      void *nvram_image, u32 nvram_len),
--+				u16 domain_nr, u16 bus_nr)
-- {
-- 	struct brcmf_fw *fwctx;
-- 
--@@ -333,8 +493,21 @@ int brcmf_fw_get_firmwares(struct device
-- 	fwctx->done = fw_cb;
-- 	if (flags & BRCMF_FW_REQUEST_NVRAM)
-- 		fwctx->nvram_name = nvram;
--+	fwctx->domain_nr = domain_nr;
--+	fwctx->bus_nr = bus_nr;
-- 
-- 	return request_firmware_nowait(THIS_MODULE, true, code, dev,
-- 				       GFP_KERNEL, fwctx,
-- 				       brcmf_fw_request_code_done);
-- }
--+
--+int brcmf_fw_get_firmwares(struct device *dev, u16 flags,
--+			   const char *code, const char *nvram,
--+			   void (*fw_cb)(struct device *dev,
--+					 const struct firmware *fw,
--+					 void *nvram_image, u32 nvram_len))
--+{
--+	return brcmf_fw_get_firmwares_pcie(dev, flags, code, nvram, fw_cb, 0,
--+					   0);
--+}
--+
----- a/drivers/net/wireless/brcm80211/brcmfmac/firmware.h
--+++ b/drivers/net/wireless/brcm80211/brcmfmac/firmware.h
--@@ -32,6 +32,12 @@ void brcmf_fw_nvram_free(void *nvram);
--  * fails it will not use the callback, but call device_release_driver()
--  * instead which will call the driver .remove() callback.
--  */
--+int brcmf_fw_get_firmwares_pcie(struct device *dev, u16 flags,
--+				const char *code, const char *nvram,
--+				void (*fw_cb)(struct device *dev,
--+					      const struct firmware *fw,
--+					      void *nvram_image, u32 nvram_len),
--+				u16 domain_nr, u16 bus_nr);
-- int brcmf_fw_get_firmwares(struct device *dev, u16 flags,
-- 			   const char *code, const char *nvram,
-- 			   void (*fw_cb)(struct device *dev,
----- a/drivers/net/wireless/brcm80211/brcmfmac/pcie.c
--+++ b/drivers/net/wireless/brcm80211/brcmfmac/pcie.c
--@@ -1649,8 +1649,13 @@ brcmf_pcie_probe(struct pci_dev *pdev, c
-- 	struct brcmf_pciedev_info *devinfo;
-- 	struct brcmf_pciedev *pcie_bus_dev;
-- 	struct brcmf_bus *bus;
--+	u16 domain_nr;
--+	u16 bus_nr;
-- 
---	brcmf_dbg(PCIE, "Enter %x:%x\n", pdev->vendor, pdev->device);
--+	domain_nr = pci_domain_nr(pdev->bus) + 1;
--+	bus_nr = pdev->bus->number;
--+	brcmf_dbg(PCIE, "Enter %x:%x (%d/%d)\n", pdev->vendor, pdev->device,
--+		  domain_nr, bus_nr);
-- 
-- 	ret = -ENOMEM;
-- 	devinfo = kzalloc(sizeof(*devinfo), GFP_KERNEL);
--@@ -1699,10 +1704,10 @@ brcmf_pcie_probe(struct pci_dev *pdev, c
-- 	if (ret)
-- 		goto fail_bus;
-- 
---	ret = brcmf_fw_get_firmwares(bus->dev, BRCMF_FW_REQUEST_NVRAM |
---					       BRCMF_FW_REQ_NV_OPTIONAL,
---				     devinfo->fw_name, devinfo->nvram_name,
---				     brcmf_pcie_setup);
--+	ret = brcmf_fw_get_firmwares_pcie(bus->dev, BRCMF_FW_REQUEST_NVRAM |
--+						    BRCMF_FW_REQ_NV_OPTIONAL,
--+					  devinfo->fw_name, devinfo->nvram_name,
--+					  brcmf_pcie_setup, domain_nr, bus_nr);
-- 	if (ret == 0)
-- 		return 0;
-- fail_bus:
-diff --git a/package/kernel/mac80211/patches/364-brcmfmac-cleanup-a-sizeof.patch b/package/kernel/mac80211/patches/364-brcmfmac-cleanup-a-sizeof.patch
-deleted file mode 100644
-index d26e118..0000000
---- a/package/kernel/mac80211/patches/364-brcmfmac-cleanup-a-sizeof.patch
-+++ /dev/null
-@@ -1,23 +0,0 @@
--From: Dan Carpenter <dan.carpenter@oracle.com>
--Date: Thu, 7 May 2015 12:59:19 +0300
--Subject: [PATCH] brcmfmac: cleanup a sizeof()
--
--"flowrings" and "*flowrings" are both pointers so this always returns
--sizeof(void *) and the current code works fine.  But "*flowrings" is
--intended here and static checkers complain, so lets change it.
--
--Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
--Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
-----
--
----- a/drivers/net/wireless/brcm80211/brcmfmac/pcie.c
--+++ b/drivers/net/wireless/brcm80211/brcmfmac/pcie.c
--@@ -1617,7 +1617,7 @@ static void brcmf_pcie_setup(struct devi
-- 		bus->msgbuf->commonrings[i] =
-- 				&devinfo->shared.commonrings[i]->commonring;
-- 
---	flowrings = kcalloc(devinfo->shared.nrof_flowrings, sizeof(flowrings),
--+	flowrings = kcalloc(devinfo->shared.nrof_flowrings, sizeof(*flowrings),
-- 			    GFP_KERNEL);
-- 	if (!flowrings)
-- 		goto fail;
-diff --git a/package/kernel/mac80211/patches/365-brcmfmac-check-result-of-USB-firmware-request.patch b/package/kernel/mac80211/patches/365-brcmfmac-check-result-of-USB-firmware-request.patch
-deleted file mode 100644
-index 9b2880d..0000000
---- a/package/kernel/mac80211/patches/365-brcmfmac-check-result-of-USB-firmware-request.patch
-+++ /dev/null
-@@ -1,33 +0,0 @@
--From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <zajec5@gmail.com>
--Date: Thu, 7 May 2015 14:13:03 +0200
--Subject: [PATCH] brcmfmac: check result of USB firmware request
--MIME-Version: 1.0
--Content-Type: text/plain; charset=UTF-8
--Content-Transfer-Encoding: 8bit
--
--This prevents silence failures with driver waiting (infinitely) for a
--callback.
--
--Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
--Acked-by: Arend van Spriel <arend@broadcom.com>
--Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
-----
--
----- a/drivers/net/wireless/brcm80211/brcmfmac/usb.c
--+++ b/drivers/net/wireless/brcm80211/brcmfmac/usb.c
--@@ -1270,8 +1270,13 @@ static int brcmf_usb_probe_cb(struct brc
-- 	bus->chiprev = bus_pub->chiprev;
-- 
-- 	/* request firmware here */
---	brcmf_fw_get_firmwares(dev, 0, brcmf_usb_get_fwname(devinfo), NULL,
---			       brcmf_usb_probe_phase2);
--+	ret = brcmf_fw_get_firmwares(dev, 0, brcmf_usb_get_fwname(devinfo),
--+				     NULL, brcmf_usb_probe_phase2);
--+	if (ret) {
--+		brcmf_err("firmware request failed: %d\n", ret);
--+		goto fail;
--+	}
--+
-- 	return 0;
-- 
-- fail:
-diff --git a/package/kernel/mac80211/patches/366-brcmfmac-prohibit-ACPI-power-management-for-brcmfmac.patch b/package/kernel/mac80211/patches/366-brcmfmac-prohibit-ACPI-power-management-for-brcmfmac.patch
-deleted file mode 100644
-index d46b300..0000000
---- a/package/kernel/mac80211/patches/366-brcmfmac-prohibit-ACPI-power-management-for-brcmfmac.patch
-+++ /dev/null
-@@ -1,47 +0,0 @@
--From: "Fu, Zhonghui" <zhonghui.fu@linux.intel.com>
--Date: Mon, 11 May 2015 10:41:32 +0800
--Subject: [PATCH] brcmfmac: prohibit ACPI power management for brcmfmac driver
--
--ACPI will manage WiFi chip's power state during suspend/resume
--process on some tablet platforms(such as ASUS T100TA). This is
--not supported by brcmfmac driver now, and the context of WiFi
--chip will be damaged after resume. This patch informs ACPI not
--to manage WiFi chip's power state.
--
--Signed-off-by: Zhonghui Fu <zhonghui.fu@linux.intel.com>
--Acked-by: Arend van Spriel <arend@broadcom.com>
--Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
-----
--
----- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
--+++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
--@@ -33,6 +33,7 @@
-- #include <linux/suspend.h>
-- #include <linux/errno.h>
-- #include <linux/module.h>
--+#include <linux/acpi.h>
-- #include <net/cfg80211.h>
-- 
-- #include <defs.h>
--@@ -1122,6 +1123,8 @@ static int brcmf_ops_sdio_probe(struct s
-- 	int err;
-- 	struct brcmf_sdio_dev *sdiodev;
-- 	struct brcmf_bus *bus_if;
--+	struct device *dev;
--+	struct acpi_device *adev;
-- 
-- 	brcmf_dbg(SDIO, "Enter\n");
-- 	brcmf_dbg(SDIO, "Class=%x\n", func->class);
--@@ -1129,6 +1132,12 @@ static int brcmf_ops_sdio_probe(struct s
-- 	brcmf_dbg(SDIO, "sdio device ID: 0x%04x\n", func->device);
-- 	brcmf_dbg(SDIO, "Function#: %d\n", func->num);
-- 
--+	/* prohibit ACPI power management for this device */
--+	dev = &func->dev;
--+	adev = ACPI_COMPANION(dev);
--+	if (adev)
--+		adev->flags.power_manageable = 0;
--+
-- 	/* Consume func num 1 but dont do anything with it. */
-- 	if (func->num == 1)
-- 		return 0;
-diff --git a/package/kernel/mac80211/patches/367-brcmfmac-avoid-gcc-5.1-warning.patch b/package/kernel/mac80211/patches/367-brcmfmac-avoid-gcc-5.1-warning.patch
-deleted file mode 100644
-index 9b4609f..0000000
---- a/package/kernel/mac80211/patches/367-brcmfmac-avoid-gcc-5.1-warning.patch
-+++ /dev/null
-@@ -1,30 +0,0 @@
--From: Arnd Bergmann <arnd@arndb.de>
--Date: Tue, 12 May 2015 23:54:25 +0200
--Subject: [PATCH] brcmfmac: avoid gcc-5.1 warning
--
--gcc-5.0 gained a new warning in the fwsignal portion of the brcmfmac
--driver:
--
--drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c: In function 'brcmf_fws_txs_process':
--drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c:1478:8: warning: 'skb' may be used uninitialized in this function [-Wmaybe-uninitialized]
--
--This is a false positive, and marking the brcmf_fws_hanger_poppkt function
--as 'static inline' makes the warning go away. I have checked the object
--file output and while a little code gets moved around, the size of
--the binary remains identical.
--
--Signed-off-by: Arnd Bergmann <arnd@arndb.de>
--Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
-----
--
----- a/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c
--+++ b/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c
--@@ -635,7 +635,7 @@ static int brcmf_fws_hanger_pushpkt(stru
-- 	return 0;
-- }
-- 
---static int brcmf_fws_hanger_poppkt(struct brcmf_fws_hanger *h,
--+static inline int brcmf_fws_hanger_poppkt(struct brcmf_fws_hanger *h,
-- 					  u32 slot_id, struct sk_buff **pktout,
-- 					  bool remove_item)
-- {
-diff --git a/package/kernel/mac80211/patches/368-brcmfmac-allow-device-tree-node-without-interrupts-p.patch b/package/kernel/mac80211/patches/368-brcmfmac-allow-device-tree-node-without-interrupts-p.patch
-deleted file mode 100644
-index b16782d..0000000
---- a/package/kernel/mac80211/patches/368-brcmfmac-allow-device-tree-node-without-interrupts-p.patch
-+++ /dev/null
-@@ -1,45 +0,0 @@
--From: Arend van Spriel <arend@broadcom.com>
--Date: Wed, 20 May 2015 14:09:47 +0200
--Subject: [PATCH] brcmfmac: allow device tree node without 'interrupts'
-- property
--
--As described in the device tree bindings for 'brcm,bcm4329-fmac'
--nodes, the interrupts property is optional. So adding a check
--for the presence of this property before attempting to parse
--and map the interrupt. If not present or parsing fails return
--and fallback to in-band sdio interrupt.
--
--Reviewed-by: Hante Meuleman <meuleman@broadcom.com>
--Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
--Signed-off-by: Arend van Spriel <arend@broadcom.com>
--Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
-----
--
----- a/drivers/net/wireless/brcm80211/brcmfmac/of.c
--+++ b/drivers/net/wireless/brcm80211/brcmfmac/of.c
--@@ -39,10 +39,16 @@ void brcmf_of_probe(struct brcmf_sdio_de
-- 	if (!sdiodev->pdata)
-- 		return;
-- 
--+	if (of_property_read_u32(np, "brcm,drive-strength", &val) == 0)
--+		sdiodev->pdata->drive_strength = val;
--+
--+	/* make sure there are interrupts defined in the node */
--+	if (!of_find_property(np, "interrupts", NULL))
--+		return;
--+
-- 	irq = irq_of_parse_and_map(np, 0);
-- 	if (!irq) {
-- 		brcmf_err("interrupt could not be mapped\n");
---		devm_kfree(dev, sdiodev->pdata);
-- 		return;
-- 	}
-- 	irqf = irqd_get_trigger_type(irq_get_irq_data(irq));
--@@ -50,7 +56,4 @@ void brcmf_of_probe(struct brcmf_sdio_de
-- 	sdiodev->pdata->oob_irq_supported = true;
-- 	sdiodev->pdata->oob_irq_nr = irq;
-- 	sdiodev->pdata->oob_irq_flags = irqf;
---
---	if (of_property_read_u32(np, "brcm,drive-strength", &val) == 0)
---		sdiodev->pdata->drive_strength = val;
-- }
-diff --git a/package/kernel/mac80211/patches/369-brcmfmac-Improve-throughput-by-scheduling-msbug-flow.patch b/package/kernel/mac80211/patches/369-brcmfmac-Improve-throughput-by-scheduling-msbug-flow.patch
-deleted file mode 100644
-index f81250e..0000000
---- a/package/kernel/mac80211/patches/369-brcmfmac-Improve-throughput-by-scheduling-msbug-flow.patch
-+++ /dev/null
-@@ -1,87 +0,0 @@
--From: Hante Meuleman <meuleman@broadcom.com>
--Date: Wed, 20 May 2015 14:09:48 +0200
--Subject: [PATCH] brcmfmac: Improve throughput by scheduling msbug flow worker.
--
--The tx flow worker in msgbuf gets scheduled at tx till a certain
--threshold has been reached. Then the tx completes will take over
--the scheduling. When amsdu and ampdu is used the frames are
--transferred wireless in a very bulky fashion, in combination
--with this scheduling algorithm and buffer limiters in the stack
--this can result in limited throughput. This change causes the
--flow worker to be scheduled more frequently from tx.
--
--Reviewed-by: Arend Van Spriel <arend@broadcom.com>
--Reviewed-by: Franky (Zhenhui) Lin <frankyl@broadcom.com>
--Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
--Reviewed-by: Daniel (Deognyoun) Kim <dekim@broadcom.com>
--Signed-off-by: Hante Meuleman <meuleman@broadcom.com>
--Signed-off-by: Arend van Spriel <arend@broadcom.com>
--Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
-----
--
----- a/drivers/net/wireless/brcm80211/brcmfmac/flowring.c
--+++ b/drivers/net/wireless/brcm80211/brcmfmac/flowring.c
--@@ -249,8 +249,8 @@ void brcmf_flowring_delete(struct brcmf_
-- }
-- 
-- 
---void brcmf_flowring_enqueue(struct brcmf_flowring *flow, u8 flowid,
---			    struct sk_buff *skb)
--+u32 brcmf_flowring_enqueue(struct brcmf_flowring *flow, u8 flowid,
--+			   struct sk_buff *skb)
-- {
-- 	struct brcmf_flowring_ring *ring;
-- 
--@@ -271,6 +271,7 @@ void brcmf_flowring_enqueue(struct brcmf
-- 		if (skb_queue_len(&ring->skblist) < BRCMF_FLOWRING_LOW)
-- 			brcmf_flowring_block(flow, flowid, false);
-- 	}
--+	return skb_queue_len(&ring->skblist);
-- }
-- 
-- 
----- a/drivers/net/wireless/brcm80211/brcmfmac/flowring.h
--+++ b/drivers/net/wireless/brcm80211/brcmfmac/flowring.h
--@@ -64,8 +64,8 @@ u32 brcmf_flowring_create(struct brcmf_f
-- void brcmf_flowring_delete(struct brcmf_flowring *flow, u8 flowid);
-- void brcmf_flowring_open(struct brcmf_flowring *flow, u8 flowid);
-- u8 brcmf_flowring_tid(struct brcmf_flowring *flow, u8 flowid);
---void brcmf_flowring_enqueue(struct brcmf_flowring *flow, u8 flowid,
---			    struct sk_buff *skb);
--+u32 brcmf_flowring_enqueue(struct brcmf_flowring *flow, u8 flowid,
--+			   struct sk_buff *skb);
-- struct sk_buff *brcmf_flowring_dequeue(struct brcmf_flowring *flow, u8 flowid);
-- void brcmf_flowring_reinsert(struct brcmf_flowring *flow, u8 flowid,
-- 			     struct sk_buff *skb);
----- a/drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c
--+++ b/drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c
--@@ -73,7 +73,7 @@
-- #define BRCMF_MSGBUF_TX_FLUSH_CNT1		32
-- #define BRCMF_MSGBUF_TX_FLUSH_CNT2		96
-- 
---#define BRCMF_MSGBUF_DELAY_TXWORKER_THRS	64
--+#define BRCMF_MSGBUF_DELAY_TXWORKER_THRS	96
-- #define BRCMF_MSGBUF_TRICKLE_TXWORKER_THRS	32
-- 
-- struct msgbuf_common_hdr {
--@@ -797,6 +797,8 @@ static int brcmf_msgbuf_txdata(struct br
-- 	struct brcmf_flowring *flow = msgbuf->flow;
-- 	struct ethhdr *eh = (struct ethhdr *)(skb->data);
-- 	u32 flowid;
--+	u32 queue_count;
--+	bool force;
-- 
-- 	flowid = brcmf_flowring_lookup(flow, eh->h_dest, skb->priority, ifidx);
-- 	if (flowid == BRCMF_FLOWRING_INVALID_ID) {
--@@ -804,8 +806,9 @@ static int brcmf_msgbuf_txdata(struct br
-- 		if (flowid == BRCMF_FLOWRING_INVALID_ID)
-- 			return -ENOMEM;
-- 	}
---	brcmf_flowring_enqueue(flow, flowid, skb);
---	brcmf_msgbuf_schedule_txdata(msgbuf, flowid, false);
--+	queue_count = brcmf_flowring_enqueue(flow, flowid, skb);
--+	force = ((queue_count % BRCMF_MSGBUF_TRICKLE_TXWORKER_THRS) == 0);
--+	brcmf_msgbuf_schedule_txdata(msgbuf, flowid, force);
-- 
-- 	return 0;
-- }
-diff --git a/package/kernel/mac80211/patches/370-brcmfmac-remove-pci-shared-structure-rev4-support.patch b/package/kernel/mac80211/patches/370-brcmfmac-remove-pci-shared-structure-rev4-support.patch
-deleted file mode 100644
-index 61153c4..0000000
---- a/package/kernel/mac80211/patches/370-brcmfmac-remove-pci-shared-structure-rev4-support.patch
-+++ /dev/null
-@@ -1,41 +0,0 @@
--From: Franky Lin <frankyl@broadcom.com>
--Date: Wed, 20 May 2015 14:09:49 +0200
--Subject: [PATCH] brcmfmac: remove pci shared structure rev4 support
--
--All pcie full dongle chips supported by fmac are using rev 5+ shared
--structure. This patch removes the rev4 related code.
--
--Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
--Reviewed-by: Hante Meuleman <meuleman@broadcom.com>
--Reviewed-by: Arend Van Spriel <arend@broadcom.com>
--Signed-off-by: Franky Lin <frankyl@broadcom.com>
--Signed-off-by: Arend van Spriel <arend@broadcom.com>
--Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
-----
--
----- a/drivers/net/wireless/brcm80211/brcmfmac/pcie.c
--+++ b/drivers/net/wireless/brcm80211/brcmfmac/pcie.c
--@@ -112,10 +112,9 @@ enum brcmf_pcie_state {
-- 						 BRCMF_PCIE_MB_INT_D2H3_DB0 | \
-- 						 BRCMF_PCIE_MB_INT_D2H3_DB1)
-- 
---#define BRCMF_PCIE_MIN_SHARED_VERSION		4
--+#define BRCMF_PCIE_MIN_SHARED_VERSION		5
-- #define BRCMF_PCIE_MAX_SHARED_VERSION		5
-- #define BRCMF_PCIE_SHARED_VERSION_MASK		0x00FF
---#define BRCMF_PCIE_SHARED_TXPUSH_SUPPORT	0x4000
-- 
-- #define BRCMF_PCIE_FLAGS_HTOD_SPLIT		0x4000
-- #define BRCMF_PCIE_FLAGS_DTOH_SPLIT		0x8000
--@@ -1280,11 +1279,6 @@ brcmf_pcie_init_share_ram_info(struct br
-- 		brcmf_err("Unsupported PCIE version %d\n", version);
-- 		return -EINVAL;
-- 	}
---	if (shared->flags & BRCMF_PCIE_SHARED_TXPUSH_SUPPORT) {
---		brcmf_err("Unsupported legacy TX mode 0x%x\n",
---			  shared->flags & BRCMF_PCIE_SHARED_TXPUSH_SUPPORT);
---		return -EINVAL;
---	}
-- 
-- 	addr = sharedram_addr + BRCMF_SHARED_MAX_RXBUFPOST_OFFSET;
-- 	shared->max_rxbufpost = brcmf_pcie_read_tcm16(devinfo, addr);
-diff --git a/package/kernel/mac80211/patches/371-brcmfmac-remove-dummy-cache-flush-invalidate-functio.patch b/package/kernel/mac80211/patches/371-brcmfmac-remove-dummy-cache-flush-invalidate-functio.patch
-deleted file mode 100644
-index 8c8eebe..0000000
---- a/package/kernel/mac80211/patches/371-brcmfmac-remove-dummy-cache-flush-invalidate-functio.patch
-+++ /dev/null
-@@ -1,120 +0,0 @@
--From: Franky Lin <frankyl@broadcom.com>
--Date: Wed, 20 May 2015 14:09:50 +0200
--Subject: [PATCH] brcmfmac: remove dummy cache flush/invalidate function
--
--brcmf_dma_flush and brcmf_dma_invalidate_cache are not necessary and
--have never been implemented.
--
--Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
--Reviewed-by: Hante Meuleman <meuleman@broadcom.com>
--Reviewed-by: Arend Van Spriel <arend@broadcom.com>
--Signed-off-by: Franky Lin <frankyl@broadcom.com>
--Signed-off-by: Arend van Spriel <arend@broadcom.com>
--Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
-----
--
----- a/drivers/net/wireless/brcm80211/brcmfmac/commonring.c
--+++ b/drivers/net/wireless/brcm80211/brcmfmac/commonring.c
--@@ -22,17 +22,6 @@
-- #include "core.h"
-- #include "commonring.h"
-- 
---
---/* dma flushing needs implementation for mips and arm platforms. Should
--- * be put in util. Note, this is not real flushing. It is virtual non
--- * cached memory. Only write buffers should have to be drained. Though
--- * this may be different depending on platform......
--- * SEE ALSO msgbuf.c
--- */
---#define brcmf_dma_flush(addr, len)
---#define brcmf_dma_invalidate_cache(addr, len)
---
---
-- void brcmf_commonring_register_cb(struct brcmf_commonring *commonring,
-- 				  int (*cr_ring_bell)(void *ctx),
-- 				  int (*cr_update_rptr)(void *ctx),
--@@ -206,14 +195,9 @@ int brcmf_commonring_write_complete(stru
-- 	address = commonring->buf_addr;
-- 	address += (commonring->f_ptr * commonring->item_len);
-- 	if (commonring->f_ptr > commonring->w_ptr) {
---		brcmf_dma_flush(address,
---				(commonring->depth - commonring->f_ptr) *
---				commonring->item_len);
-- 		address = commonring->buf_addr;
-- 		commonring->f_ptr = 0;
-- 	}
---	brcmf_dma_flush(address, (commonring->w_ptr - commonring->f_ptr) *
---			commonring->item_len);
-- 
-- 	commonring->f_ptr = commonring->w_ptr;
-- 
--@@ -258,8 +242,6 @@ void *brcmf_commonring_get_read_ptr(stru
-- 	if (commonring->r_ptr == commonring->depth)
-- 		commonring->r_ptr = 0;
-- 
---	brcmf_dma_invalidate_cache(ret_addr, *n_ items * commonring->item_len);
---
-- 	return ret_addr;
-- }
-- 
----- a/drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c
--+++ b/drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c
--@@ -278,16 +278,6 @@ struct brcmf_msgbuf_pktids {
-- 	struct brcmf_msgbuf_pktid *array;
-- };
-- 
---
---/* dma flushing needs implementation for mips and arm platforms. Should
--- * be put in util. Note, this is not real flushing. It is virtual non
--- * cached memory. Only write buffers should have to be drained. Though
--- * this may be different depending on platform......
--- */
---#define brcmf_dma_flush(addr, len)
---#define brcmf_dma_invalidate_cache(addr, len)
---
---
-- static void brcmf_msgbuf_rxbuf_ioctlresp_post(struct brcmf_msgbuf *msgbuf);
-- 
-- 
--@@ -462,7 +452,6 @@ static int brcmf_msgbuf_tx_ioctl(struct
-- 		memcpy(msgbuf->ioctbuf, buf, buf_len);
-- 	else
-- 		memset(msgbuf->ioctbuf, 0, buf_len);
---	brcmf_dma_flush(ioctl_buf, buf_len);
-- 
-- 	err = brcmf_commonring_write_complete(commonring);
-- 	brcmf_commonring_unlock(commonring);
----- a/drivers/net/wireless/brcm80211/brcmfmac/pcie.c
--+++ b/drivers/net/wireless/brcm80211/brcmfmac/pcie.c
--@@ -276,15 +276,6 @@ static const u32 brcmf_ring_itemsize[BRC
-- };
-- 
-- 
---/* dma flushing needs implementation for mips and arm platforms. Should
--- * be put in util. Note, this is not real flushing. It is virtual non
--- * cached memory. Only write buffers should have to be drained. Though
--- * this may be different depending on platform......
--- */
---#define brcmf_dma_flush(addr, len)
---#define brcmf_dma_invalidate_cache(addr, len)
---
---
-- static u32
-- brcmf_pcie_read_reg32(struct brcmf_pciedev_info *devinfo, u32 reg_offset)
-- {
--@@ -1174,7 +1165,6 @@ static int brcmf_pcie_init_scratchbuffer
-- 		goto fail;
-- 
-- 	memset(devinfo->shared.scratch, 0, BRCMF_DMA_D2H_SCRATCH_BUF_LEN);
---	brcmf_dma_flush(devinfo->shared.scratch, BRCMF_DMA_D2H_SCRATCH_BUF_LEN);
-- 
-- 	addr = devinfo->shared.tcm_base_address +
-- 	       BRCMF_SHARED_DMA_SCRATCH_ADDR_OFFSET;
--@@ -1192,7 +1182,6 @@ static int brcmf_pcie_init_scratchbuffer
-- 		goto fail;
-- 
-- 	memset(devinfo->shared.ringupd, 0, BRCMF_DMA_D2H_RINGUPD_BUF_LEN);
---	brcmf_dma_flush(devinfo->shared.ringupd, BRCMF_DMA_D2H_RINGUPD_BUF_LEN);
-- 
-- 	addr = devinfo->shared.tcm_base_address +
-- 	       BRCMF_SHARED_DMA_RINGUPD_ADDR_OFFSET;
-diff --git a/package/kernel/mac80211/patches/372-brcmfmac-add-support-for-dma-indices-feature.patch b/package/kernel/mac80211/patches/372-brcmfmac-add-support-for-dma-indices-feature.patch
-deleted file mode 100644
-index 2f50abd..0000000
---- a/package/kernel/mac80211/patches/372-brcmfmac-add-support-for-dma-indices-feature.patch
-+++ /dev/null
-@@ -1,270 +0,0 @@
--From: Franky Lin <frankyl@broadcom.com>
--Date: Wed, 20 May 2015 14:09:51 +0200
--Subject: [PATCH] brcmfmac: add support for dma indices feature
--
--PCIe full dongle firmware can support a dma indices feature with which
--firmware can update/fetch the read/write indices of message buffer
--rings on both host to dongle and dongle to host directions. The support is
--announced by firmware through shared flags.
--
--Reviewed-by: Arend Van Spriel <arend@broadcom.com>
--Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
--Signed-off-by: Franky Lin <frankyl@broadcom.com>
--Signed-off-by: Arend van Spriel <arend@broadcom.com>
--Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
-----
--
----- a/drivers/net/wireless/brcm80211/brcmfmac/pcie.c
--+++ b/drivers/net/wireless/brcm80211/brcmfmac/pcie.c
--@@ -115,6 +115,8 @@ enum brcmf_pcie_state {
-- #define BRCMF_PCIE_MIN_SHARED_VERSION		5
-- #define BRCMF_PCIE_MAX_SHARED_VERSION		5
-- #define BRCMF_PCIE_SHARED_VERSION_MASK		0x00FF
--+#define BRCMF_PCIE_SHARED_DMA_INDEX		0x10000
--+#define BRCMF_PCIE_SHARED_DMA_2B_IDX		0x100000
-- 
-- #define BRCMF_PCIE_FLAGS_HTOD_SPLIT		0x4000
-- #define BRCMF_PCIE_FLAGS_DTOH_SPLIT		0x8000
--@@ -146,6 +148,10 @@ enum brcmf_pcie_state {
-- #define BRCMF_SHARED_RING_H2D_R_IDX_PTR_OFFSET	8
-- #define BRCMF_SHARED_RING_D2H_W_IDX_PTR_OFFSET	12
-- #define BRCMF_SHARED_RING_D2H_R_IDX_PTR_OFFSET	16
--+#define BRCMF_SHARED_RING_H2D_WP_HADDR_OFFSET	20
--+#define BRCMF_SHARED_RING_H2D_RP_HADDR_OFFSET	28
--+#define BRCMF_SHARED_RING_D2H_WP_HADDR_OFFSET	36
--+#define BRCMF_SHARED_RING_D2H_RP_HADDR_OFFSET	44
-- #define BRCMF_SHARED_RING_TCM_MEMLOC_OFFSET	0
-- #define BRCMF_SHARED_RING_MAX_SUB_QUEUES	52
-- 
--@@ -247,6 +253,13 @@ struct brcmf_pciedev_info {
-- 	bool mbdata_completed;
-- 	bool irq_allocated;
-- 	bool wowl_enabled;
--+	u8 dma_idx_sz;
--+	void *idxbuf;
--+	u32 idxbuf_sz;
--+	dma_addr_t idxbuf_dmahandle;
--+	u16 (*read_ptr)(struct brcmf_pciedev_info *devinfo, u32 mem_offset);
--+	void (*write_ptr)(struct brcmf_pciedev_info *devinfo, u32 mem_offset,
--+			  u16 value);
-- };
-- 
-- struct brcmf_pcie_ringbuf {
--@@ -323,6 +336,25 @@ brcmf_pcie_write_tcm16(struct brcmf_pcie
-- }
-- 
-- 
--+static u16
--+brcmf_pcie_read_idx(struct brcmf_pciedev_info *devinfo, u32 mem_offset)
--+{
--+	u16 *address = devinfo->idxbuf + mem_offset;
--+
--+	return (*(address));
--+}
--+
--+
--+static void
--+brcmf_pcie_write_idx(struct brcmf_pciedev_info *devinfo, u32 mem_offset,
--+		     u16 value)
--+{
--+	u16 *address = devinfo->idxbuf + mem_offset;
--+
--+	*(address) = value;
--+}
--+
--+
-- static u32
-- brcmf_pcie_read_tcm32(struct brcmf_pciedev_info *devinfo, u32 mem_offset)
-- {
--@@ -868,7 +900,7 @@ static int brcmf_pcie_ring_mb_write_rptr
-- 	brcmf_dbg(PCIE, "W r_ptr %d (%d), ring %d\n", commonring->r_ptr,
-- 		  commonring->w_ptr, ring->id);
-- 
---	brcmf_pcie_write_tcm16(devinfo, ring->r_idx_addr, commonring->r_ptr);
--+	devinfo->write_ptr(devinfo, ring->r_idx_addr, commonring->r_ptr);
-- 
-- 	return 0;
-- }
--@@ -886,7 +918,7 @@ static int brcmf_pcie_ring_mb_write_wptr
-- 	brcmf_dbg(PCIE, "W w_ptr %d (%d), ring %d\n", commonring->w_ptr,
-- 		  commonring->r_ptr, ring->id);
-- 
---	brcmf_pcie_write_tcm16(devinfo, ring->w_idx_addr, commonring->w_ptr);
--+	devinfo->write_ptr(devinfo, ring->w_idx_addr, commonring->w_ptr);
-- 
-- 	return 0;
-- }
--@@ -915,7 +947,7 @@ static int brcmf_pcie_ring_mb_update_rpt
-- 	if (devinfo->state != BRCMFMAC_PCIE_STATE_UP)
-- 		return -EIO;
-- 
---	commonring->r_ptr = brcmf_pcie_read_tcm16(devinfo, ring->r_idx_addr);
--+	commonring->r_ptr = devinfo->read_ptr(devinfo, ring->r_idx_addr);
-- 
-- 	brcmf_dbg(PCIE, "R r_ptr %d (%d), ring %d\n", commonring->r_ptr,
-- 		  commonring->w_ptr, ring->id);
--@@ -933,7 +965,7 @@ static int brcmf_pcie_ring_mb_update_wpt
-- 	if (devinfo->state != BRCMFMAC_PCIE_STATE_UP)
-- 		return -EIO;
-- 
---	commonring->w_ptr = brcmf_pcie_read_tcm16(devinfo, ring->w_idx_addr);
--+	commonring->w_ptr = devinfo->read_ptr(devinfo, ring->w_idx_addr);
-- 
-- 	brcmf_dbg(PCIE, "R w_ptr %d (%d), ring %d\n", commonring->w_ptr,
-- 		  commonring->r_ptr, ring->id);
--@@ -1038,6 +1070,13 @@ static void brcmf_pcie_release_ringbuffe
-- 	}
-- 	kfree(devinfo->shared.flowrings);
-- 	devinfo->shared.flowrings = NULL;
--+	if (devinfo->idxbuf) {
--+		dma_free_coherent(&devinfo->pdev->dev,
--+				  devinfo->idxbuf_sz,
--+				  devinfo->idxbuf,
--+				  devinfo->idxbuf_dmahandle);
--+		devinfo->idxbuf = NULL;
--+	}
-- }
-- 
-- 
--@@ -1053,19 +1092,72 @@ static int brcmf_pcie_init_ringbuffers(s
-- 	u32 addr;
-- 	u32 ring_mem_ptr;
-- 	u32 i;
--+	u64 address;
--+	u32 bufsz;
-- 	u16 max_sub_queues;
--+	u8 idx_offset;
-- 
-- 	ring_addr = devinfo->shared.ring_info_addr;
-- 	brcmf_dbg(PCIE, "Base ring addr = 0x%08x\n", ring_addr);
--+	addr = ring_addr + BRCMF_SHARED_RING_MAX_SUB_QUEUES;
--+	max_sub_queues = brcmf_pcie_read_tcm16(devinfo, addr);
-- 
---	addr = ring_addr + BRCMF_SHARED_RING_D2H_W_IDX_PTR_OFFSET;
---	d2h_w_idx_ptr = brcmf_pcie_read_tcm32(devinfo, addr);
---	addr = ring_addr + BRCMF_SHARED_RING_D2H_R_IDX_PTR_OFFSET;
---	d2h_r_idx_ptr = brcmf_pcie_read_tcm32(devinfo, addr);
---	addr = ring_addr + BRCMF_SHARED_RING_H2D_W_IDX_PTR_OFFSET;
---	h2d_w_idx_ptr = brcmf_pcie_read_tcm32(devinfo, addr);
---	addr = ring_addr + BRCMF_SHARED_RING_H2D_R_IDX_PTR_OFFSET;
---	h2d_r_idx_ptr = brcmf_pcie_read_tcm32(devinfo, addr);
--+	if (devinfo->dma_idx_sz != 0) {
--+		bufsz = (BRCMF_NROF_D2H_COMMON_MSGRINGS + max_sub_queues) *
--+			devinfo->dma_idx_sz * 2;
--+		devinfo->idxbuf = dma_alloc_coherent(&devinfo->pdev->dev, bufsz,
--+						     &devinfo->idxbuf_dmahandle,
--+						     GFP_KERNEL);
--+		if (!devinfo->idxbuf)
--+			devinfo->dma_idx_sz = 0;
--+	}
--+
--+	if (devinfo->dma_idx_sz == 0) {
--+		addr = ring_addr + BRCMF_SHARED_RING_D2H_W_IDX_PTR_OFFSET;
--+		d2h_w_idx_ptr = brcmf_pcie_read_tcm32(devinfo, addr);
--+		addr = ring_addr + BRCMF_SHARED_RING_D2H_R_IDX_PTR_OFFSET;
--+		d2h_r_idx_ptr = brcmf_pcie_read_tcm32(devinfo, addr);
--+		addr = ring_addr + BRCMF_SHARED_RING_H2D_W_IDX_PTR_OFFSET;
--+		h2d_w_idx_ptr = brcmf_pcie_read_tcm32(devinfo, addr);
--+		addr = ring_addr + BRCMF_SHARED_RING_H2D_R_IDX_PTR_OFFSET;
--+		h2d_r_idx_ptr = brcmf_pcie_read_tcm32(devinfo, addr);
--+		idx_offset = sizeof(u32);
--+		devinfo->write_ptr = brcmf_pcie_write_tcm16;
--+		devinfo->read_ptr = brcmf_pcie_read_tcm16;
--+		brcmf_dbg(PCIE, "Using TCM indices\n");
--+	} else {
--+		memset(devinfo->idxbuf, 0, bufsz);
--+		devinfo->idxbuf_sz = bufsz;
--+		idx_offset = devinfo->dma_idx_sz;
--+		devinfo->write_ptr = brcmf_pcie_write_idx;
--+		devinfo->read_ptr = brcmf_pcie_read_idx;
--+
--+		h2d_w_idx_ptr = 0;
--+		addr = ring_addr + BRCMF_SHARED_RING_H2D_WP_HADDR_OFFSET;
--+		address = (u64)devinfo->idxbuf_dmahandle;
--+		brcmf_pcie_write_tcm32(devinfo, addr, address & 0xffffffff);
--+		brcmf_pcie_write_tcm32(devinfo, addr + 4, address >> 32);
--+
--+		h2d_r_idx_ptr = h2d_w_idx_ptr + max_sub_queues * idx_offset;
--+		addr = ring_addr + BRCMF_SHARED_RING_H2D_RP_HADDR_OFFSET;
--+		address += max_sub_queues * idx_offset;
--+		brcmf_pcie_write_tcm32(devinfo, addr, address & 0xffffffff);
--+		brcmf_pcie_write_tcm32(devinfo, addr + 4, address >> 32);
--+
--+		d2h_w_idx_ptr = h2d_r_idx_ptr + max_sub_queues * idx_offset;
--+		addr = ring_addr + BRCMF_SHARED_RING_D2H_WP_HADDR_OFFSET;
--+		address += max_sub_queues * idx_offset;
--+		brcmf_pcie_write_tcm32(devinfo, addr, address & 0xffffffff);
--+		brcmf_pcie_write_tcm32(devinfo, addr + 4, address >> 32);
--+
--+		d2h_r_idx_ptr = d2h_w_idx_ptr +
--+				BRCMF_NROF_D2H_COMMON_MSGRINGS * idx_offset;
--+		addr = ring_addr + BRCMF_SHARED_RING_D2H_RP_HADDR_OFFSET;
--+		address += BRCMF_NROF_D2H_COMMON_MSGRINGS * idx_offset;
--+		brcmf_pcie_write_tcm32(devinfo, addr, address & 0xffffffff);
--+		brcmf_pcie_write_tcm32(devinfo, addr + 4, address >> 32);
--+		brcmf_dbg(PCIE, "Using host memory indices\n");
--+	}
-- 
-- 	addr = ring_addr + BRCMF_SHARED_RING_TCM_MEMLOC_OFFSET;
-- 	ring_mem_ptr = brcmf_pcie_read_tcm32(devinfo, addr);
--@@ -1079,8 +1171,8 @@ static int brcmf_pcie_init_ringbuffers(s
-- 		ring->id = i;
-- 		devinfo->shared.commonrings[i] = ring;
-- 
---		h2d_w_idx_ptr += sizeof(u32);
---		h2d_r_idx_ptr += sizeof(u32);
--+		h2d_w_idx_ptr += idx_offset;
--+		h2d_r_idx_ptr += idx_offset;
-- 		ring_mem_ptr += BRCMF_RING_MEM_SZ;
-- 	}
-- 
--@@ -1094,13 +1186,11 @@ static int brcmf_pcie_init_ringbuffers(s
-- 		ring->id = i;
-- 		devinfo->shared.commonrings[i] = ring;
-- 
---		d2h_w_idx_ptr += sizeof(u32);
---		d2h_r_idx_ptr += sizeof(u32);
--+		d2h_w_idx_ptr += idx_offset;
--+		d2h_r_idx_ptr += idx_offset;
-- 		ring_mem_ptr += BRCMF_RING_MEM_SZ;
-- 	}
-- 
---	addr = ring_addr + BRCMF_SHARED_RING_MAX_SUB_QUEUES;
---	max_sub_queues = brcmf_pcie_read_tcm16(devinfo, addr);
-- 	devinfo->shared.nrof_flowrings =
-- 			max_sub_queues - BRCMF_NROF_H2D_COMMON_MSGRINGS;
-- 	rings = kcalloc(devinfo->shared.nrof_flowrings, sizeof(*ring),
--@@ -1124,15 +1214,15 @@ static int brcmf_pcie_init_ringbuffers(s
-- 					     ring);
-- 		ring->w_idx_addr = h2d_w_idx_ptr;
-- 		ring->r_idx_addr = h2d_r_idx_ptr;
---		h2d_w_idx_ptr += sizeof(u32);
---		h2d_r_idx_ptr += sizeof(u32);
--+		h2d_w_idx_ptr += idx_offset;
--+		h2d_r_idx_ptr += idx_offset;
-- 	}
-- 	devinfo->shared.flowrings = rings;
-- 
-- 	return 0;
-- 
-- fail:
---	brcmf_err("Allocating commonring buffers failed\n");
--+	brcmf_err("Allocating ring buffers failed\n");
-- 	brcmf_pcie_release_ringbuffers(devinfo);
-- 	return -ENOMEM;
-- }
--@@ -1269,6 +1359,14 @@ brcmf_pcie_init_share_ram_info(struct br
-- 		return -EINVAL;
-- 	}
-- 
--+	/* check firmware support dma indicies */
--+	if (shared->flags & BRCMF_PCIE_SHARED_DMA_INDEX) {
--+		if (shared->flags & BRCMF_PCIE_SHARED_DMA_2B_IDX)
--+			devinfo->dma_idx_sz = sizeof(u16);
--+		else
--+			devinfo->dma_idx_sz = sizeof(u32);
--+	}
--+
-- 	addr = sharedram_addr + BRCMF_SHARED_MAX_RXBUFPOST_OFFSET;
-- 	shared->max_rxbufpost = brcmf_pcie_read_tcm16(devinfo, addr);
-- 	if (shared->max_rxbufpost == 0)
-diff --git a/package/kernel/mac80211/patches/373-brcmfmac-avoid-null-pointer-access-when-brcmf_msgbuf.patch b/package/kernel/mac80211/patches/373-brcmfmac-avoid-null-pointer-access-when-brcmf_msgbuf.patch
-deleted file mode 100644
-index 28408d2..0000000
---- a/package/kernel/mac80211/patches/373-brcmfmac-avoid-null-pointer-access-when-brcmf_msgbuf.patch
-+++ /dev/null
-@@ -1,102 +0,0 @@
--From: Arend van Spriel <arend@broadcom.com>
--Date: Tue, 26 May 2015 13:19:46 +0200
--Subject: [PATCH] brcmfmac: avoid null pointer access when
-- brcmf_msgbuf_get_pktid() fails
--
--The function brcmf_msgbuf_get_pktid() may return a NULL pointer so
--the callers should check the return pointer before accessing it to
--avoid the crash below (see [1]):
--
--brcmfmac: brcmf_msgbuf_get_pktid: Invalid packet id 273 (not in use)
--BUG: unable to handle kernel NULL pointer dereference at 0000000000000080
--IP: [<ffffffff8145b225>] skb_pull+0x5/0x50
--PGD 0
--Oops: 0000 [#1] PREEMPT SMP
--Modules linked in: pci_stub vboxpci(O) vboxnetflt(O) vboxnetadp(O) vboxdrv(O)
-- snd_hda_codec_hdmi bnep mousedev hid_generic ushwmon msr ext4 crc16 mbcache
-- jbd2 sd_mod uas usb_storage ahci libahci libata scsi_mod xhci_pci xhci_hcd
-- usbcore usb_common
--CPU: 0 PID: 1661 Comm: irq/61-brcmf_pc Tainted: G O    4.0.1-MacbookPro-ARCH #1
--Hardware name: Apple Inc. MacBookPro12,1/Mac-E43C1C25D4880AD6,
-- BIOS MBP121.88Z.0167.B02.1503241251 03/24/2015
--task: ffff880264203cc0 ti: ffff88025ffe4000 task.ti: ffff88025ffe4000
--RIP: 0010:[<ffffffff8145b225>]  [<ffffffff8145b225>] skb_pull+0x5/0x50
--RSP: 0018:ffff88025ffe7d40  EFLAGS: 00010202
--RAX: 0000000000000000 RBX: ffff88008a33c000 RCX: 0000000000000044
--RDX: 0000000000000000 RSI: 000000000000004a RDI: 0000000000000000
--RBP: ffff88025ffe7da8 R08: 0000000000000096 R09: 000000000000004a
--R10: 0000000000000000 R11: 000000000000048e R12: ffff88025ff14f00
--R13: 0000000000000000 R14: ffff880263b48200 R15: ffff88008a33c000
--FS:  0000000000000000(0000) GS:ffff88026ec00000(0000) knlGS:0000000000000000
--CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
--CR2: 0000000000000080 CR3: 000000000180b000 CR4: 00000000003407f0
--Stack:
-- ffffffffa06aed74 ffff88025ffe7dc8 ffff880263b48270 ffff880263b48278
-- 05ea88020000004a 0002ffff81014635 000000001720b2f6 ffff88026ec116c0
-- ffff880263b48200 0000000000010000 ffff880263b4ae00 ffff880264203cc0
--Call Trace:
-- [<ffffffffa06aed74>] ? brcmf_msgbuf_process_rx+0x404/0x480 [brcmfmac]
-- [<ffffffff810cea60>] ? irq_finalize_oneshot.part.30+0xf0/0xf0
-- [<ffffffffa06afb55>] brcmf_proto_msgbuf_rx_trigger+0x35/0xf0 [brcmfmac]
-- [<ffffffffa06baf2a>] brcmf_pcie_isr_thread_v2+0x8a/0x130 [brcmfmac]
-- [<ffffffff810cea80>] irq_thread_fn+0x20/0x50
-- [<ffffffff810ceddf>] irq_thread+0x13f/0x170
-- [<ffffffff810cebf0>] ? wake_threads_waitq+0x30/0x30
-- [<ffffffff810ceca0>] ? irq_thread_dtor+0xb0/0xb0
-- [<ffffffff81092a08>] kthread+0xd8/0xf0
-- [<ffffffff81092930>] ? kthread_create_on_node+0x1c0/0x1c0
-- [<ffffffff8156d898>] ret_from_fork+0x58/0x90
-- [<ffffffff81092930>] ? kthread_create_on_node+0x1c0/0x1c0
--Code: 01 83 e2 f7 88 50 01 48 83 c4 08 5b 5d f3 c3 0f 1f 80 00 00 00 00 83 e2
-- f7 88 50 01 c3 66 0f 1f 84 00 00 00 00 00 0f 1f
--RIP  [<ffffffff8145b225>] skb_pull+0x5/0x50
-- RSP <ffff88025ffe7d40>
--CR2: 0000000000000080
-----[ end trace b074c0f90e7c997d ]---
--
--[1] http://mid.gmane.org/20150430193259.GA5630@googlemail.com
--
--Cc: <stable@vger.kernel.org> # v3.18, v3.19, v4.0, v4.1
--Reported-by: Michael Hornung <mhornung.linux@gmail.com>
--Reviewed-by: Hante Meuleman <meuleman@broadcom.com>
--Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
--Signed-off-by: Arend van Spriel <arend@broadcom.com>
-----
--
----- a/drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c
--+++ b/drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c
--@@ -500,11 +500,9 @@ static int brcmf_msgbuf_query_dcmd(struc
-- 				     msgbuf->rx_pktids,
-- 				     msgbuf->ioctl_resp_pktid);
-- 	if (msgbuf->ioctl_resp_ret_len != 0) {
---		if (!skb) {
---			brcmf_err("Invalid packet id idx recv'd %d\n",
---				  msgbuf->ioctl_resp_pktid);
--+		if (!skb)
-- 			return -EBADF;
---		}
--+
-- 		memcpy(buf, skb->data, (len < msgbuf->ioctl_resp_ret_len) ?
-- 				       len : msgbuf->ioctl_resp_ret_len);
-- 	}
--@@ -866,10 +864,8 @@ brcmf_msgbuf_process_txstatus(struct brc
-- 	flowid -= BRCMF_NROF_H2D_COMMON_MSGRINGS;
-- 	skb = brcmf_msgbuf_get_pktid(msgbuf->drvr->bus_if->dev,
-- 				     msgbuf->tx_pktids, idx);
---	if (!skb) {
---		brcmf_err("Invalid packet id idx recv'd %d\n", idx);
--+	if (!skb)
-- 		return;
---	}
-- 
-- 	set_bit(flowid, msgbuf->txstatus_done_map);
-- 	commonring = msgbuf->flowrings[flowid];
--@@ -1148,6 +1144,8 @@ brcmf_msgbuf_process_rx_complete(struct
-- 
-- 	skb = brcmf_msgbuf_get_pktid(msgbuf->drvr->bus_if->dev,
-- 				     msgbuf->rx_pktids, idx);
--+	if (!skb)
--+		return;
-- 
-- 	if (data_offset)
-- 		skb_pull(skb, data_offset);
-diff --git a/package/kernel/mac80211/patches/374-brcmfmac-fix-invalid-access-to-struct-acpi_device-fi.patch b/package/kernel/mac80211/patches/374-brcmfmac-fix-invalid-access-to-struct-acpi_device-fi.patch
-deleted file mode 100644
-index f023034..0000000
---- a/package/kernel/mac80211/patches/374-brcmfmac-fix-invalid-access-to-struct-acpi_device-fi.patch
-+++ /dev/null
-@@ -1,63 +0,0 @@
--From: Arend van Spriel <arend@broadcom.com>
--Date: Wed, 27 May 2015 19:31:41 +0200
--Subject: [PATCH] brcmfmac: fix invalid access to struct acpi_device fields
--
--The fields of struct acpi_device are only known when CONFIG_ACPI is
--defined. Fix this by using a helper function. This will resolve the
--issue found in linux-next:
--
-- ../brcmfmac/bcmsdh.c: In function 'brcmf_ops_sdio_probe':
-- ../brcmfmac/bcmsdh.c:1139:7: error: dereferencing pointer to incomplete type
--   adev->flags.power_manageable = 0;
--       ^
--
--Fixes: f0992ace680c ("brcmfmac: prohibit ACPI power management ...")
--Cc: Fu, Zhonghui <zhonghui.fu@linux.intel.com>
--Reported-by: Stephen Rothwell <sfr@canb.auug.org.au>
--Signed-off-by: Arend van Spriel <arend@broadcom.com>
--Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
-----
--
----- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
--+++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
--@@ -1117,6 +1117,18 @@ MODULE_DEVICE_TABLE(sdio, brcmf_sdmmc_id
-- static struct brcmfmac_sdio_platform_data *brcmfmac_sdio_pdata;
-- 
-- 
--+static void brcmf_sdiod_acpi_set_power_manageable(struct device *dev,
--+						  int val)
--+{
--+#if IS_ENABLED(CONFIG_ACPI)
--+	struct acpi_device *adev;
--+
--+	adev = ACPI_COMPANION(dev);
--+	if (adev)
--+		adev->flags.power_manageable = 0;
--+#endif
--+}
--+
-- static int brcmf_ops_sdio_probe(struct sdio_func *func,
-- 				const struct sdio_device_id *id)
-- {
--@@ -1124,7 +1136,6 @@ static int brcmf_ops_sdio_probe(struct s
-- 	struct brcmf_sdio_dev *sdiodev;
-- 	struct brcmf_bus *bus_if;
-- 	struct device *dev;
---	struct acpi_device *adev;
-- 
-- 	brcmf_dbg(SDIO, "Enter\n");
-- 	brcmf_dbg(SDIO, "Class=%x\n", func->class);
--@@ -1132,11 +1143,9 @@ static int brcmf_ops_sdio_probe(struct s
-- 	brcmf_dbg(SDIO, "sdio device ID: 0x%04x\n", func->device);
-- 	brcmf_dbg(SDIO, "Function#: %d\n", func->num);
-- 
---	/* prohibit ACPI power management for this device */
-- 	dev = &func->dev;
---	adev = ACPI_COMPANION(dev);
---	if (adev)
---		adev->flags.power_manageable = 0;
--+	/* prohibit ACPI power management for this device */
--+	brcmf_sdiod_acpi_set_power_manageable(dev, 0);
-- 
-- 	/* Consume func num 1 but dont do anything with it. */
-- 	if (func->num == 1)
-diff --git a/package/kernel/mac80211/patches/375-brcmfmac-simplify-check-stripping-v2-NVRAM.patch b/package/kernel/mac80211/patches/375-brcmfmac-simplify-check-stripping-v2-NVRAM.patch
-deleted file mode 100644
-index 2bfd44f..0000000
---- a/package/kernel/mac80211/patches/375-brcmfmac-simplify-check-stripping-v2-NVRAM.patch
-+++ /dev/null
-@@ -1,56 +0,0 @@
--From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <zajec5@gmail.com>
--Date: Wed, 20 May 2015 09:34:21 +0200
--Subject: [PATCH] brcmfmac: simplify check stripping v2 NVRAM
--MIME-Version: 1.0
--Content-Type: text/plain; charset=UTF-8
--Content-Transfer-Encoding: 8bit
--
--Comparing NVRAM entry with a full filtering string is simpler than
--comparing it with a short prefix and then checking random chars at magic
--offsets. The cost of snprintf relatively low, we execute it just once.
--Tested on BCM43602 with NVRAM hacked to use V2 format.
--
--Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
--Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
-----
--
----- a/drivers/net/wireless/brcm80211/brcmfmac/firmware.c
--+++ b/drivers/net/wireless/brcm80211/brcmfmac/firmware.c
--@@ -25,7 +25,7 @@
-- 
-- #define BRCMF_FW_MAX_NVRAM_SIZE			64000
-- #define BRCMF_FW_NVRAM_DEVPATH_LEN		19	/* devpath0=pcie/1/4/ */
---#define BRCMF_FW_NVRAM_PCIEDEV_LEN		9	/* pcie/1/4/ */
--+#define BRCMF_FW_NVRAM_PCIEDEV_LEN		10	/* pcie/1/4/ + \0 */
-- 
-- char brcmf_firmware_path[BRCMF_FW_PATH_LEN];
-- module_param_string(firmware_path, brcmf_firmware_path,
--@@ -297,6 +297,8 @@ fail:
-- static void brcmf_fw_strip_multi_v2(struct nvram_parser *nvp, u16 domain_nr,
-- 				    u16 bus_nr)
-- {
--+	char prefix[BRCMF_FW_NVRAM_PCIEDEV_LEN];
--+	size_t len;
-- 	u32 i, j;
-- 	u8 *nvram;
-- 
--@@ -308,14 +310,13 @@ static void brcmf_fw_strip_multi_v2(stru
-- 	 * Valid entries are of type pcie/X/Y/ where X = domain_nr and
-- 	 * Y = bus_nr.
-- 	 */
--+	snprintf(prefix, sizeof(prefix), "pcie/%d/%d/", domain_nr, bus_nr);
--+	len = strlen(prefix);
-- 	i = 0;
-- 	j = 0;
---	while (i < nvp->nvram_len - BRCMF_FW_NVRAM_PCIEDEV_LEN) {
---		if ((strncmp(&nvp->nvram[i], "pcie/", 5) == 0) &&
---		    (nvp->nvram[i + 6] == '/') && (nvp->nvram[i + 8] == '/') &&
---		    ((nvp->nvram[i + 5] - '0') == domain_nr) &&
---		    ((nvp->nvram[i + 7] - '0') == bus_nr)) {
---			i += BRCMF_FW_NVRAM_PCIEDEV_LEN;
--+	while (i < nvp->nvram_len - len) {
--+		if (strncmp(&nvp->nvram[i], prefix, len) == 0) {
--+			i += len;
-- 			while (nvp->nvram[i] != 0) {
-- 				nvram[j] = nvp->nvram[i];
-- 				i++;
-diff --git a/package/kernel/mac80211/patches/376-brcmfmac-simplify-check-finding-NVRAM-v1-device-path.patch b/package/kernel/mac80211/patches/376-brcmfmac-simplify-check-finding-NVRAM-v1-device-path.patch
-deleted file mode 100644
-index 0e65114..0000000
---- a/package/kernel/mac80211/patches/376-brcmfmac-simplify-check-finding-NVRAM-v1-device-path.patch
-+++ /dev/null
-@@ -1,57 +0,0 @@
--From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <zajec5@gmail.com>
--Date: Wed, 20 May 2015 11:01:08 +0200
--Subject: [PATCH] brcmfmac: simplify check finding NVRAM v1 device path
--MIME-Version: 1.0
--Content-Type: text/plain; charset=UTF-8
--Content-Transfer-Encoding: 8bit
--
--With a simple use of snprintf and small buffer we can compare NVRAM
--entry value with a full string. This way we avoid checking random chars
--at magic offsets.
--Tested on BCM43602 with NVRAM hacked to use v1 format.
--
--Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
--Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
-----
--
----- a/drivers/net/wireless/brcm80211/brcmfmac/firmware.c
--+++ b/drivers/net/wireless/brcm80211/brcmfmac/firmware.c
--@@ -222,6 +222,10 @@ static int brcmf_init_nvram_parser(struc
-- static void brcmf_fw_strip_multi_v1(struct nvram_parser *nvp, u16 domain_nr,
-- 				    u16 bus_nr)
-- {
--+	/* Device path with a leading '=' key-value separator */
--+	char pcie_path[] = "=pcie/?/?";
--+	size_t pcie_len;
--+
-- 	u32 i, j;
-- 	bool found;
-- 	u8 *nvram;
--@@ -238,6 +242,9 @@ static void brcmf_fw_strip_multi_v1(stru
-- 	/* First search for the devpathX and see if it is the configuration
-- 	 * for domain_nr/bus_nr. Search complete nvp
-- 	 */
--+	snprintf(pcie_path, sizeof(pcie_path), "=pcie/%d/%d", domain_nr,
--+		 bus_nr);
--+	pcie_len = strlen(pcie_path);
-- 	found = false;
-- 	i = 0;
-- 	while (i < nvp->nvram_len - BRCMF_FW_NVRAM_DEVPATH_LEN) {
--@@ -245,13 +252,10 @@ static void brcmf_fw_strip_multi_v1(stru
-- 		 * Y = domain_nr, Z = bus_nr, X = virtual ID
-- 		 */
-- 		if ((strncmp(&nvp->nvram[i], "devpath", 7) == 0) &&
---		    (strncmp(&nvp->nvram[i + 8], "=pcie/", 6) == 0)) {
---			if (((nvp->nvram[i + 14] - '0') == domain_nr) &&
---			    ((nvp->nvram[i + 16] - '0') == bus_nr)) {
---				id = nvp->nvram[i + 7] - '0';
---				found = true;
---				break;
---			}
--+		    (strncmp(&nvp->nvram[i + 8], pcie_path, pcie_len) == 0)) {
--+			id = nvp->nvram[i + 7] - '0';
--+			found = true;
--+			break;
-- 		}
-- 		while (nvp->nvram[i] != 0)
-- 			i++;
-diff --git a/package/kernel/mac80211/patches/377-brcmfmac-treat-0-as-end-of-comment-when-parsing-NVRA.patch b/package/kernel/mac80211/patches/377-brcmfmac-treat-0-as-end-of-comment-when-parsing-NVRA.patch
-deleted file mode 100644
-index dc174e5..0000000
---- a/package/kernel/mac80211/patches/377-brcmfmac-treat-0-as-end-of-comment-when-parsing-NVRA.patch
-+++ /dev/null
-@@ -1,45 +0,0 @@
--From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <zajec5@gmail.com>
--Date: Wed, 20 May 2015 13:59:54 +0200
--Subject: [PATCH] brcmfmac: treat \0 as end of comment when parsing NVRAM
--MIME-Version: 1.0
--Content-Type: text/plain; charset=UTF-8
--Content-Transfer-Encoding: 8bit
--
--This fixes brcmfmac dealing with NVRAM coming from platform e.g. from a
--flash MTD partition. In such cases entries are separated by \0 instead
--of \n which caused ignoring whole content after the first "comment".
--While platform NVRAM doesn't usually contain comments, we switch to
--COMMENT state after e.g. finding an unexpected char in key name.
--
--Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
--Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
-----
--
----- a/drivers/net/wireless/brcm80211/brcmfmac/firmware.c
--+++ b/drivers/net/wireless/brcm80211/brcmfmac/firmware.c
--@@ -162,17 +162,20 @@ brcmf_nvram_handle_value(struct nvram_pa
-- static enum nvram_parser_state
-- brcmf_nvram_handle_comment(struct nvram_parser *nvp)
-- {
---	char *eol, *sol;
--+	char *eoc, *sol;
-- 
-- 	sol = (char *)&nvp->fwnv->data[nvp->pos];
---	eol = strchr(sol, '\n');
---	if (eol == NULL)
---		return END;
--+	eoc = strchr(sol, '\n');
--+	if (!eoc) {
--+		eoc = strchr(sol, '\0');
--+		if (!eoc)
--+			return END;
--+	}
-- 
-- 	/* eat all moving to next line */
-- 	nvp->line++;
-- 	nvp->column = 1;
---	nvp->pos += (eol - sol) + 1;
--+	nvp->pos += (eoc - sol) + 1;
-- 	return IDLE;
-- }
-- 
-diff --git a/package/kernel/mac80211/patches/378-brcmfmac-allow-NVRAM-values-to-contain-spaces.patch b/package/kernel/mac80211/patches/378-brcmfmac-allow-NVRAM-values-to-contain-spaces.patch
-deleted file mode 100644
-index 5700142..0000000
---- a/package/kernel/mac80211/patches/378-brcmfmac-allow-NVRAM-values-to-contain-spaces.patch
-+++ /dev/null
-@@ -1,50 +0,0 @@
--From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <zajec5@gmail.com>
--Date: Sat, 23 May 2015 09:15:33 +0200
--Subject: [PATCH] brcmfmac: allow NVRAM values to contain spaces
--MIME-Version: 1.0
--Content-Type: text/plain; charset=UTF-8
--Content-Transfer-Encoding: 8bit
--
--Platform NVRAMs often contain values with spaces. Even if right now most
--firmware-supported entries are simple values, we shouldn't reject these
--with spaces. It was semi-confirmed by Broadcom in the early patch adding
--support for platform NVRAMs.
--
--Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
--Acked-by: Arend van Spriel <arend@broadcom.com>
--Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
-----
--
----- a/drivers/net/wireless/brcm80211/brcmfmac/firmware.c
--+++ b/drivers/net/wireless/brcm80211/brcmfmac/firmware.c
--@@ -66,6 +66,12 @@ struct nvram_parser {
-- 	bool multi_dev_v2;
-- };
-- 
--+/**
--+ * is_nvram_char() - check if char is a valid one for NVRAM entry
--+ *
--+ * It accepts all printable ASCII chars except for '#' which opens a comment.
--+ * Please note that ' ' (space) while accepted is not a valid key name char.
--+ */
-- static bool is_nvram_char(char c)
-- {
-- 	/* comment marker excluded */
--@@ -73,7 +79,7 @@ static bool is_nvram_char(char c)
-- 		return false;
-- 
-- 	/* key and value may have any other readable character */
---	return (c > 0x20 && c < 0x7f);
--+	return (c >= 0x20 && c < 0x7f);
-- }
-- 
-- static bool is_whitespace(char c)
--@@ -120,7 +126,7 @@ static enum nvram_parser_state brcmf_nvr
-- 			nvp->multi_dev_v1 = true;
-- 		if (strncmp(&nvp->fwnv->data[nvp->entry], "pcie/", 5) == 0)
-- 			nvp->multi_dev_v2 = true;
---	} else if (!is_nvram_char(c)) {
--+	} else if (!is_nvram_char(c) || c == ' ') {
-- 		brcmf_dbg(INFO, "warning: ln=%d:col=%d: '=' expected, skip invalid key entry\n",
-- 			  nvp->line, nvp->column);
-- 		return COMMENT;
-diff --git a/package/kernel/mac80211/patches/379-ath9k-fix-DMA-stop-sequence-for-AR9003.patch b/package/kernel/mac80211/patches/379-ath9k-fix-DMA-stop-sequence-for-AR9003.patch
-deleted file mode 100644
-index 814b0d7..0000000
---- a/package/kernel/mac80211/patches/379-ath9k-fix-DMA-stop-sequence-for-AR9003.patch
-+++ /dev/null
-@@ -1,33 +0,0 @@
--From: Felix Fietkau <nbd@openwrt.org>
--Date: Tue, 2 Jun 2015 10:35:46 +0200
--Subject: [PATCH] ath9k: fix DMA stop sequence for AR9003+
--
--AR93xx and newer needs to stop rx before tx to avoid getting the DMA
--engine or MAC into a stuck state.
--This should reduce/fix the occurence of "Failed to stop Tx DMA" logspam.
--
--Cc: stable@vger.kernel.org
--Signed-off-by: Felix Fietkau <nbd@openwrt.org>
-----
--
----- a/drivers/net/wireless/ath/ath9k/main.c
--+++ b/drivers/net/wireless/ath/ath9k/main.c
--@@ -216,11 +216,13 @@ static bool ath_prepare_reset(struct ath
-- 	ath_stop_ani(sc);
-- 	ath9k_hw_disable_interrupts(ah);
-- 
---	if (!ath_drain_all_txq(sc))
---		ret = false;
---
---	if (!ath_stoprecv(sc))
---		ret = false;
--+	if (AR_SREV_9300_20_OR_LATER(ah)) {
--+		ret &= ath_stoprecv(sc);
--+		ret &= ath_drain_all_txq(sc);
--+	} else {
--+		ret &= ath_drain_all_txq(sc);
--+		ret &= ath_stoprecv(sc);
--+	}
-- 
-- 	return ret;
-- }
-diff --git a/package/kernel/mac80211/patches/380-brcmfmac-support-NVRAMs-containing-pci-devpaths-inst.patch b/package/kernel/mac80211/patches/380-brcmfmac-support-NVRAMs-containing-pci-devpaths-inst.patch
-deleted file mode 100644
-index 7bbd57e..0000000
---- a/package/kernel/mac80211/patches/380-brcmfmac-support-NVRAMs-containing-pci-devpaths-inst.patch
-+++ /dev/null
-@@ -1,56 +0,0 @@
--From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <zajec5@gmail.com>
--Date: Thu, 28 May 2015 14:19:21 +0200
--Subject: [PATCH] brcmfmac: support NVRAMs containing pci devpaths (instead of
-- pcie)
--MIME-Version: 1.0
--Content-Type: text/plain; charset=UTF-8
--Content-Transfer-Encoding: 8bit
--
--Recently Broadcom added support for NVRAMs with entries for multiple
--PCIe devices. One of the supported formats is based on prefixes defined
--like: devpath0=pcie/1/4/ and entries like 0:foo=bar 0:baz=qux etc.
--
--Unfortunately there are also a bit older devices using different way of
--defining prefixes, e.g. SmartRG SR400ac (2 x BCM43602) with entries:
--devpath0=pci/1/1/
--devpath1=pci/2/1
--Broadcom stated this old format will never be used/supported by brcmfmac
--but given the simplicity of this patch I'll insist on supporting it.
--
--Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
--Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
-----
--
----- a/drivers/net/wireless/brcm80211/brcmfmac/firmware.c
--+++ b/drivers/net/wireless/brcm80211/brcmfmac/firmware.c
--@@ -232,6 +232,8 @@ static void brcmf_fw_strip_multi_v1(stru
-- 				    u16 bus_nr)
-- {
-- 	/* Device path with a leading '=' key-value separator */
--+	char pci_path[] = "=pci/?/?";
--+	size_t pci_len;
-- 	char pcie_path[] = "=pcie/?/?";
-- 	size_t pcie_len;
-- 
--@@ -251,6 +253,9 @@ static void brcmf_fw_strip_multi_v1(stru
-- 	/* First search for the devpathX and see if it is the configuration
-- 	 * for domain_nr/bus_nr. Search complete nvp
-- 	 */
--+	snprintf(pci_path, sizeof(pci_path), "=pci/%d/%d", domain_nr,
--+		 bus_nr);
--+	pci_len = strlen(pci_path);
-- 	snprintf(pcie_path, sizeof(pcie_path), "=pcie/%d/%d", domain_nr,
-- 		 bus_nr);
-- 	pcie_len = strlen(pcie_path);
--@@ -260,8 +265,9 @@ static void brcmf_fw_strip_multi_v1(stru
-- 		/* Format: devpathX=pcie/Y/Z/
-- 		 * Y = domain_nr, Z = bus_nr, X = virtual ID
-- 		 */
---		if ((strncmp(&nvp->nvram[i], "devpath", 7) == 0) &&
---		    (strncmp(&nvp->nvram[i + 8], pcie_path, pcie_len) == 0)) {
--+		if (strncmp(&nvp->nvram[i], "devpath", 7) == 0 &&
--+		    (!strncmp(&nvp->nvram[i + 8], pci_path, pci_len) ||
--+		     !strncmp(&nvp->nvram[i + 8], pcie_path, pcie_len))) {
-- 			id = nvp->nvram[i + 7] - '0';
-- 			found = true;
-- 			break;
-diff --git a/package/kernel/mac80211/patches/381-brcmfmac-set-wiphy-perm_addr-to-hardware-MAC-address.patch b/package/kernel/mac80211/patches/381-brcmfmac-set-wiphy-perm_addr-to-hardware-MAC-address.patch
-deleted file mode 100644
-index 1eff6ed..0000000
---- a/package/kernel/mac80211/patches/381-brcmfmac-set-wiphy-perm_addr-to-hardware-MAC-address.patch
-+++ /dev/null
-@@ -1,23 +0,0 @@
--From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <zajec5@gmail.com>
--Date: Sun, 31 May 2015 02:52:26 +0200
--Subject: [PATCH] brcmfmac: set wiphy perm_addr to hardware MAC address
--MIME-Version: 1.0
--Content-Type: text/plain; charset=UTF-8
--Content-Transfer-Encoding: 8bit
--
--This allows e.g. user space to use /sys/class/ieee80211/*/macaddress
--
--Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
--Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
-----
--
----- a/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c
--+++ b/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c
--@@ -6070,6 +6070,7 @@ struct brcmf_cfg80211_info *brcmf_cfg802
-- 		brcmf_err("Could not allocate wiphy device\n");
-- 		return NULL;
-- 	}
--+	memcpy(wiphy->perm_addr, drvr->mac, ETH_ALEN);
-- 	set_wiphy_dev(wiphy, busdev);
-- 
-- 	cfg = wiphy_priv(wiphy);
-diff --git a/package/kernel/mac80211/patches/382-brcmfmac-use-direct-data-pointer-in-NVRAM-parser-str.patch b/package/kernel/mac80211/patches/382-brcmfmac-use-direct-data-pointer-in-NVRAM-parser-str.patch
-deleted file mode 100644
-index c6e83dd..0000000
---- a/package/kernel/mac80211/patches/382-brcmfmac-use-direct-data-pointer-in-NVRAM-parser-str.patch
-+++ /dev/null
-@@ -1,144 +0,0 @@
--From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <zajec5@gmail.com>
--Date: Thu, 4 Jun 2015 22:11:07 +0200
--Subject: [PATCH] brcmfmac: use direct data pointer in NVRAM parser struct
--MIME-Version: 1.0
--Content-Type: text/plain; charset=UTF-8
--Content-Transfer-Encoding: 8bit
--
--As we plan to add support for platform NVRAM we should store direct
--data pointer without the extra struct firmware layer. This will allow
--us to support other sources with the only requirement being u8 buffer.
--
--Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
--Acked-by: Arend van Spriel <arend@broadcom.com>
--Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
-----
--
----- a/drivers/net/wireless/brcm80211/brcmfmac/firmware.c
--+++ b/drivers/net/wireless/brcm80211/brcmfmac/firmware.c
--@@ -43,7 +43,7 @@ enum nvram_parser_state {
--  * struct nvram_parser - internal info for parser.
--  *
--  * @state: current parser state.
--- * @fwnv: input buffer being parsed.
--+ * @data: input buffer being parsed.
--  * @nvram: output buffer with parse result.
--  * @nvram_len: lenght of parse result.
--  * @line: current line.
--@@ -55,7 +55,7 @@ enum nvram_parser_state {
--  */
-- struct nvram_parser {
-- 	enum nvram_parser_state state;
---	const struct firmware *fwnv;
--+	const u8 *data;
-- 	u8 *nvram;
-- 	u32 nvram_len;
-- 	u32 line;
--@@ -91,7 +91,7 @@ static enum nvram_parser_state brcmf_nvr
-- {
-- 	char c;
-- 
---	c = nvp->fwnv->data[nvp->pos];
--+	c = nvp->data[nvp->pos];
-- 	if (c == '\n')
-- 		return COMMENT;
-- 	if (is_whitespace(c))
--@@ -115,16 +115,16 @@ static enum nvram_parser_state brcmf_nvr
-- 	enum nvram_parser_state st = nvp->state;
-- 	char c;
-- 
---	c = nvp->fwnv->data[nvp->pos];
--+	c = nvp->data[nvp->pos];
-- 	if (c == '=') {
-- 		/* ignore RAW1 by treating as comment */
---		if (strncmp(&nvp->fwnv->data[nvp->entry], "RAW1", 4) == 0)
--+		if (strncmp(&nvp->data[nvp->entry], "RAW1", 4) == 0)
-- 			st = COMMENT;
-- 		else
-- 			st = VALUE;
---		if (strncmp(&nvp->fwnv->data[nvp->entry], "devpath", 7) == 0)
--+		if (strncmp(&nvp->data[nvp->entry], "devpath", 7) == 0)
-- 			nvp->multi_dev_v1 = true;
---		if (strncmp(&nvp->fwnv->data[nvp->entry], "pcie/", 5) == 0)
--+		if (strncmp(&nvp->data[nvp->entry], "pcie/", 5) == 0)
-- 			nvp->multi_dev_v2 = true;
-- 	} else if (!is_nvram_char(c) || c == ' ') {
-- 		brcmf_dbg(INFO, "warning: ln=%d:col=%d: '=' expected, skip invalid key entry\n",
--@@ -145,11 +145,11 @@ brcmf_nvram_handle_value(struct nvram_pa
-- 	char *ekv;
-- 	u32 cplen;
-- 
---	c = nvp->fwnv->data[nvp->pos];
--+	c = nvp->data[nvp->pos];
-- 	if (!is_nvram_char(c)) {
-- 		/* key,value pair complete */
---		ekv = (u8 *)&nvp->fwnv->data[nvp->pos];
---		skv = (u8 *)&nvp->fwnv->data[nvp->entry];
--+		ekv = (u8 *)&nvp->data[nvp->pos];
--+		skv = (u8 *)&nvp->data[nvp->entry];
-- 		cplen = ekv - skv;
-- 		if (nvp->nvram_len + cplen + 1 >= BRCMF_FW_MAX_NVRAM_SIZE)
-- 			return END;
--@@ -170,7 +170,7 @@ brcmf_nvram_handle_comment(struct nvram_
-- {
-- 	char *eoc, *sol;
-- 
---	sol = (char *)&nvp->fwnv->data[nvp->pos];
--+	sol = (char *)&nvp->data[nvp->pos];
-- 	eoc = strchr(sol, '\n');
-- 	if (!eoc) {
-- 		eoc = strchr(sol, '\0');
--@@ -201,17 +201,17 @@ static enum nvram_parser_state
-- };
-- 
-- static int brcmf_init_nvram_parser(struct nvram_parser *nvp,
---				   const struct firmware *nv)
--+				   const u8 *data, size_t data_len)
-- {
-- 	size_t size;
-- 
-- 	memset(nvp, 0, sizeof(*nvp));
---	nvp->fwnv = nv;
--+	nvp->data = data;
-- 	/* Limit size to MAX_NVRAM_SIZE, some files contain lot of comment */
---	if (nv->size > BRCMF_FW_MAX_NVRAM_SIZE)
--+	if (data_len > BRCMF_FW_MAX_NVRAM_SIZE)
-- 		size = BRCMF_FW_MAX_NVRAM_SIZE;
-- 	else
---		size = nv->size;
--+		size = data_len;
-- 	/* Alloc for extra 0 byte + roundup by 4 + length field */
-- 	size += 1 + 3 + sizeof(u32);
-- 	nvp->nvram = kzalloc(size, GFP_KERNEL);
--@@ -362,18 +362,18 @@ fail:
--  * and converts newlines to NULs. Shortens buffer as needed and pads with NULs.
--  * End of buffer is completed with token identifying length of buffer.
--  */
---static void *brcmf_fw_nvram_strip(const struct firmware *nv, u32 *new_length,
---				  u16 domain_nr, u16 bus_nr)
--+static void *brcmf_fw_nvram_strip(const u8 *data, size_t data_len,
--+				  u32 *new_length, u16 domain_nr, u16 bus_nr)
-- {
-- 	struct nvram_parser nvp;
-- 	u32 pad;
-- 	u32 token;
-- 	__le32 token_le;
-- 
---	if (brcmf_init_nvram_parser(&nvp, nv) < 0)
--+	if (brcmf_init_nvram_parser(&nvp, data, data_len) < 0)
-- 		return NULL;
-- 
---	while (nvp.pos < nv->size) {
--+	while (nvp.pos < data_len) {
-- 		nvp.state = nv_parser_states[nvp.state](&nvp);
-- 		if (nvp.state == END)
-- 			break;
--@@ -432,7 +432,7 @@ static void brcmf_fw_request_nvram_done(
-- 		goto fail;
-- 
-- 	if (fw) {
---		nvram = brcmf_fw_nvram_strip(fw, &nvram_length,
--+		nvram = brcmf_fw_nvram_strip(fw->data, fw->size, &nvram_length,
-- 					     fwctx->domain_nr, fwctx->bus_nr);
-- 		release_firmware(fw);
-- 		if (!nvram && !(fwctx->flags & BRCMF_FW_REQ_NV_OPTIONAL))
-diff --git a/package/kernel/mac80211/patches/383-b43-fix-support-for-14e4-4321-PCI-dev-with-BCM4321-c.patch b/package/kernel/mac80211/patches/383-b43-fix-support-for-14e4-4321-PCI-dev-with-BCM4321-c.patch
-deleted file mode 100644
-index 4ecef3b..0000000
---- a/package/kernel/mac80211/patches/383-b43-fix-support-for-14e4-4321-PCI-dev-with-BCM4321-c.patch
-+++ /dev/null
-@@ -1,32 +0,0 @@
--From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <zajec5@gmail.com>
--Date: Sat, 6 Jun 2015 22:45:59 +0200
--Subject: [PATCH] b43: fix support for 14e4:4321 PCI dev with BCM4321 chipset
--MIME-Version: 1.0
--Content-Type: text/plain; charset=UTF-8
--Content-Transfer-Encoding: 8bit
--
--It seems Broadcom released two devices with conflicting device id. There
--are for sure 14e4:4321 PCI devices with BCM4321 (N-PHY) chipset, they
--can be found in routers, e.g. Netgear WNR834Bv2. However, according to
--Broadcom public sources 0x4321 is also used for 5 GHz BCM4306 (G-PHY).
--It's unsure if they meant PCI device id, or "virtual" id (from SPROM).
--To distinguish these devices lets check PHY type (G vs. N).
--
--Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
--Cc: <stable@vger.kernel.org> # 3.16+
--Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
-----
--
----- a/drivers/net/wireless/b43/main.c
--+++ b/drivers/net/wireless/b43/main.c
--@@ -5365,6 +5365,10 @@ static void b43_supported_bands(struct b
-- 		*have_5ghz_phy = true;
-- 		return;
-- 	case 0x4321: /* BCM4306 */
--+		/* There are 14e4:4321 PCI devs with 2.4 GHz BCM4321 (N-PHY) */
--+		if (dev->phy.type != B43_PHYTYPE_G)
--+			break;
--+		/* fall through */
-- 	case 0x4313: /* BCM4311 */
-- 	case 0x431a: /* BCM4318 */
-- 	case 0x432a: /* BCM4321 */
-diff --git a/package/kernel/mac80211/patches/384-ath9k-force-rx_clear-when-disabling-rx.patch b/package/kernel/mac80211/patches/384-ath9k-force-rx_clear-when-disabling-rx.patch
-deleted file mode 100644
-index bddb15a..0000000
---- a/package/kernel/mac80211/patches/384-ath9k-force-rx_clear-when-disabling-rx.patch
-+++ /dev/null
-@@ -1,31 +0,0 @@
--From: Felix Fietkau <nbd@openwrt.org>
--Date: Sun, 7 Jun 2015 13:53:35 +0200
--Subject: [PATCH] ath9k: force rx_clear when disabling rx
--
--This makes stopping Rx more reliable and should reduce the frequency of
--Rx related DMA stop warnings
--
--Cc: stable@vger.kernel.org
--Signed-off-by: Felix Fietkau <nbd@openwrt.org>
-----
--
----- a/drivers/net/wireless/ath/ath9k/mac.c
--+++ b/drivers/net/wireless/ath/ath9k/mac.c
--@@ -677,13 +677,15 @@ void ath9k_hw_startpcureceive(struct ath
-- 
-- 	ath9k_ani_reset(ah, is_scanning);
-- 
---	REG_CLR_BIT(ah, AR_DIAG_SW, (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT));
--+	REG_CLR_BIT(ah, AR_DIAG_SW,
--+		    AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT | AR_DIAG_FORCE_RX_CLEAR);
-- }
-- EXPORT_SYMBOL(ath9k_hw_startpcureceive);
-- 
-- void ath9k_hw_abortpcurecv(struct ath_hw *ah)
-- {
---	REG_SET_BIT(ah, AR_DIAG_SW, AR_DIAG_RX_ABORT | AR_DIAG_RX_DIS);
--+	REG_SET_BIT(ah, AR_DIAG_SW,
--+		    AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT | AR_DIAG_FORCE_RX_CLEAR);
-- 
-- 	ath9k_hw_disable_mib_counters(ah);
-- }
-diff --git a/package/kernel/mac80211/patches/385-ath9k_hw-fix-device-ID-check-for-AR956x.patch b/package/kernel/mac80211/patches/385-ath9k_hw-fix-device-ID-check-for-AR956x.patch
-deleted file mode 100644
-index 2674efb..0000000
---- a/package/kernel/mac80211/patches/385-ath9k_hw-fix-device-ID-check-for-AR956x.patch
-+++ /dev/null
-@@ -1,20 +0,0 @@
--From: Felix Fietkau <nbd@openwrt.org>
--Date: Sun, 21 Jun 2015 19:45:59 +0200
--Subject: [PATCH] ath9k_hw: fix device ID check for AR956x
--
--Because of the missing return, the macVersion value was being
--overwritten with an invalid register read
--
--Signed-off-by: Felix Fietkau <nbd@openwrt.org>
-----
--
----- a/drivers/net/wireless/ath/ath9k/hw.c
--+++ b/drivers/net/wireless/ath/ath9k/hw.c
--@@ -278,6 +278,7 @@ static void ath9k_hw_read_revisions(stru
-- 		return;
-- 	case AR9300_DEVID_QCA956X:
-- 		ah->hw_version.macVersion = AR_SREV_VERSION_9561;
--+		return;
-- 	}
-- 
-- 	val = REG_READ(ah, AR_SREV) & AR_SREV_ID;
-diff --git a/package/kernel/mac80211/patches/385-brcmfmac-Update-msgbuf-read-pointer-quicker.patch b/package/kernel/mac80211/patches/385-brcmfmac-Update-msgbuf-read-pointer-quicker.patch
-deleted file mode 100644
-index 74df9f9..0000000
---- a/package/kernel/mac80211/patches/385-brcmfmac-Update-msgbuf-read-pointer-quicker.patch
-+++ /dev/null
-@@ -1,109 +0,0 @@
--From: Hante Meuleman <meuleman@broadcom.com>
--Date: Mon, 8 Jun 2015 14:38:32 +0200
--Subject: [PATCH] brcmfmac: Update msgbuf read pointer quicker.
--
--On device to host data using msgbuf the read pointer gets updated
--once all data is processed. Updating this pointer more frequently
--allows the firmware to add more data quicker. This will result in
--slightly higher and more stable throughput on CPU bounded host
--processors.
--
--Reviewed-by: Arend Van Spriel <arend@broadcom.com>
--Reviewed-by: Franky (Zhenhui) Lin <frankyl@broadcom.com>
--Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
--Signed-off-by: Hante Meuleman <meuleman@broadcom.com>
--Signed-off-by: Arend van Spriel <arend@broadcom.com>
--Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
-----
--
----- a/drivers/net/wireless/brcm80211/brcmfmac/commonring.c
--+++ b/drivers/net/wireless/brcm80211/brcmfmac/commonring.c
--@@ -223,8 +223,6 @@ void brcmf_commonring_write_cancel(struc
-- void *brcmf_commonring_get_read_ptr(struct brcmf_commonring *commonring,
-- 				    u16 *n_items)
-- {
---	void *ret_addr;
---
-- 	if (commonring->cr_update_wptr)
-- 		commonring->cr_update_wptr(commonring->cr_ctx);
-- 
--@@ -235,19 +233,18 @@ void *brcmf_commonring_get_read_ptr(stru
-- 	if (*n_items == 0)
-- 		return NULL;
-- 
---	ret_addr = commonring->buf_addr +
---		   (commonring->r_ptr * commonring->item_len);
---
---	commonring->r_ptr += *n_items;
---	if (commonring->r_ptr == commonring->depth)
---		commonring->r_ptr = 0;
---
---	return ret_addr;
--+	return commonring->buf_addr +
--+	       (commonring->r_ptr * commonring->item_len);
-- }
-- 
-- 
---int brcmf_commonring_read_complete(struct brcmf_commonring *commonring)
--+int brcmf_commonring_read_complete(struct brcmf_commonring *commonring,
--+				   u16 n_items)
-- {
--+	commonring->r_ptr += n_items;
--+	if (commonring->r_ptr == commonring->depth)
--+		commonring->r_ptr = 0;
--+
-- 	if (commonring->cr_write_rptr)
-- 		return commonring->cr_write_rptr(commonring->cr_ctx);
-- 
----- a/drivers/net/wireless/brcm80211/brcmfmac/commonring.h
--+++ b/drivers/net/wireless/brcm80211/brcmfmac/commonring.h
--@@ -62,7 +62,8 @@ void brcmf_commonring_write_cancel(struc
-- 				   u16 n_items);
-- void *brcmf_commonring_get_read_ptr(struct brcmf_commonring *commonring,
-- 				    u16 *n_items);
---int brcmf_commonring_read_complete(struct brcmf_commonring *commonring);
--+int brcmf_commonring_read_complete(struct brcmf_commonring *commonring,
--+				   u16 n_items);
-- 
-- #define brcmf_commonring_n_items(commonring) (commonring->depth)
-- #define brcmf_commonring_len_item(commonring) (commonring->item_len)
----- a/drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c
--+++ b/drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c
--@@ -75,6 +75,8 @@
-- 
-- #define BRCMF_MSGBUF_DELAY_TXWORKER_THRS	96
-- #define BRCMF_MSGBUF_TRICKLE_TXWORKER_THRS	32
--+#define BRCMF_MSGBUF_UPDATE_RX_PTR_THRS		48
--+
-- 
-- struct msgbuf_common_hdr {
-- 	u8				msgtype;
--@@ -1257,19 +1259,27 @@ static void brcmf_msgbuf_process_rx(stru
-- {
-- 	void *buf;
-- 	u16 count;
--+	u16 processed;
-- 
-- again:
-- 	buf = brcmf_commonring_get_read_ptr(commonring, &count);
-- 	if (buf == NULL)
-- 		return;
-- 
--+	processed = 0;
-- 	while (count) {
-- 		brcmf_msgbuf_process_msgtype(msgbuf,
-- 					     buf + msgbuf->rx_dataoffset);
-- 		buf += brcmf_commonring_len_item(commonring);
--+		processed++;
--+		if (processed == BRCMF_MSGBUF_UPDATE_RX_PTR_THRS) {
--+			brcmf_commonring_read_complete(commonring, processed);
--+			processed = 0;
--+		}
-- 		count--;
-- 	}
---	brcmf_commonring_read_complete(commonring);
--+	if (processed)
--+		brcmf_commonring_read_complete(commonring, processed);
-- 
-- 	if (commonring->r_ptr == 0)
-- 		goto again;
-diff --git a/package/kernel/mac80211/patches/386-brcmfmac-remove-chipinfo-debugfs-entry.patch b/package/kernel/mac80211/patches/386-brcmfmac-remove-chipinfo-debugfs-entry.patch
-deleted file mode 100644
-index 9e5b486..0000000
---- a/package/kernel/mac80211/patches/386-brcmfmac-remove-chipinfo-debugfs-entry.patch
-+++ /dev/null
-@@ -1,39 +0,0 @@
--From: Arend van Spriel <arend@broadcom.com>
--Date: Mon, 8 Jun 2015 14:38:33 +0200
--Subject: [PATCH] brcmfmac: remove chipinfo debugfs entry
--
--The information provided by chipinfo is also provided by the
--revinfo debugfs entry. Removing it from debugfs.
--
--Reviewed-by: Hante Meuleman <meuleman@broadcom.com>
--Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
--Signed-off-by: Arend van Spriel <arend@broadcom.com>
--Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
-----
--
----- a/drivers/net/wireless/brcm80211/brcmfmac/debug.c
--+++ b/drivers/net/wireless/brcm80211/brcmfmac/debug.c
--@@ -41,15 +41,6 @@ void brcmf_debugfs_exit(void)
-- 	root_folder = NULL;
-- }
-- 
---static int brcmf_debugfs_chipinfo_read(struct seq_file *seq, void *data)
---{
---	struct brcmf_bus *bus = dev_get_drvdata(seq->private);
---
---	seq_printf(seq, "chip: %x(%u) rev %u\n",
---		   bus->chip, bus->chip, bus->chiprev);
---	return 0;
---}
---
-- int brcmf_debugfs_attach(struct brcmf_pub *drvr)
-- {
-- 	struct device *dev = drvr->bus_if->dev;
--@@ -58,7 +49,6 @@ int brcmf_debugfs_attach(struct brcmf_pu
-- 		return -ENODEV;
-- 
-- 	drvr->dbgfs_dir = debugfs_create_dir(dev_name(dev), root_folder);
---	brcmf_debugfs_add_entry(drvr, "chipinfo", brcmf_debugfs_chipinfo_read);
-- 
-- 	return PTR_ERR_OR_ZERO(drvr->dbgfs_dir);
-- }
-diff --git a/package/kernel/mac80211/patches/387-brcmfmac-remove-watchdog-reset-from-brcmf_pcie_busco.patch b/package/kernel/mac80211/patches/387-brcmfmac-remove-watchdog-reset-from-brcmf_pcie_busco.patch
-deleted file mode 100644
-index c38b2cd..0000000
---- a/package/kernel/mac80211/patches/387-brcmfmac-remove-watchdog-reset-from-brcmf_pcie_busco.patch
-+++ /dev/null
-@@ -1,53 +0,0 @@
--From: Arend van Spriel <arend@broadcom.com>
--Date: Mon, 8 Jun 2015 14:38:34 +0200
--Subject: [PATCH] brcmfmac: remove watchdog reset from
-- brcmf_pcie_buscoreprep()
--
--The watchdog reset as done in brcmf_pcie_buscoreprep() is not
--sufficient. It needs to modify PCIe core registers as well
--which is properly done by brcmf_pcie_reset_device() after the
--chip recognition is done. So the faulty watchdog reset can be
--removed as it was causing driver reload to fail and hang the
--system requiring a power-cycle. Instead the call to to the
--brcmf_pcie_reset_device() function is done twice in the unload.
--
--Reviewed-by: Hante Meuleman <meuleman@broadcom.com>
--Reviewed-by: Daniel (Deognyoun) Kim <dekim@broadcom.com>
--Reviewed-by: Franky (Zhenhui) Lin <frankyl@broadcom.com>
--Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
--Signed-off-by: Arend van Spriel <arend@broadcom.com>
--Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
-----
--
----- a/drivers/net/wireless/brcm80211/brcmfmac/pcie.c
--+++ b/drivers/net/wireless/brcm80211/brcmfmac/pcie.c
--@@ -1629,20 +1629,7 @@ static void brcmf_pcie_buscore_write32(v
-- 
-- static int brcmf_pcie_buscoreprep(void *ctx)
-- {
---	struct brcmf_pciedev_info *devinfo = (struct brcmf_pciedev_info *)ctx;
---	int err;
---
---	err = brcmf_pcie_get_resource(devinfo);
---	if (err == 0) {
---		/* Set CC watchdog to reset all the cores on the chip to bring
---		 * back dongle to a sane state.
---		 */
---		brcmf_pcie_buscore_write32(ctx, CORE_CC_REG(SI_ENUM_BASE,
---							    watchdog), 4);
---		msleep(100);
---	}
---
---	return err;
--+	return brcmf_pcie_get_resource(ctx);
-- }
-- 
-- 
--@@ -1824,6 +1811,7 @@ brcmf_pcie_remove(struct pci_dev *pdev)
-- 		brcmf_pcie_intr_disable(devinfo);
-- 
-- 	brcmf_detach(&pdev->dev);
--+	brcmf_pcie_reset_device(devinfo);
-- 
-- 	kfree(bus->bus_priv.pcie);
-- 	kfree(bus->msgbuf->flowrings);
-diff --git a/package/kernel/mac80211/patches/388-brcmfmac-use-debugfs_create_devm_seqfile-helper-func.patch b/package/kernel/mac80211/patches/388-brcmfmac-use-debugfs_create_devm_seqfile-helper-func.patch
-deleted file mode 100644
-index 756fbb2..0000000
---- a/package/kernel/mac80211/patches/388-brcmfmac-use-debugfs_create_devm_seqfile-helper-func.patch
-+++ /dev/null
-@@ -1,69 +0,0 @@
--From: Arend van Spriel <arend@broadcom.com>
--Date: Mon, 8 Jun 2015 14:38:35 +0200
--Subject: [PATCH] brcmfmac: use debugfs_create_devm_seqfile() helper
-- function
--
--Some time ago the function debugfs_create_devm_seqfile() was
--introduced in debugfs. The caller simply needs to provide a
--device pointer and read function. The function brcmf_debugfs_add_entry()
--is now simply a wrapper only doing the work for CONFIG_BRCMDBG.
--
--Reviewed-by: Hante Meuleman <meuleman@broadcom.com>
--Reviewed-by: Franky (Zhenhui) Lin <frankyl@broadcom.com>
--Reviewed-by: Daniel (Deognyoun) Kim <dekim@broadcom.com>
--Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
--Signed-off-by: Arend van Spriel <arend@broadcom.com>
--Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
-----
--
----- a/drivers/net/wireless/brcm80211/brcmfmac/debug.c
--+++ b/drivers/net/wireless/brcm80211/brcmfmac/debug.c
--@@ -64,44 +64,12 @@ struct dentry *brcmf_debugfs_get_devdir(
-- 	return drvr->dbgfs_dir;
-- }
-- 
---struct brcmf_debugfs_entry {
---	int (*read)(struct seq_file *seq, void *data);
---	struct brcmf_pub *drvr;
---};
---
---static int brcmf_debugfs_entry_open(struct inode *inode, struct file *f)
---{
---	struct brcmf_debugfs_entry *entry = inode->i_private;
---
---	return single_open(f, entry->read, entry->drvr->bus_if->dev);
---}
---
---static const struct file_operations brcmf_debugfs_def_ops = {
---	.owner = THIS_MODULE,
---	.open = brcmf_debugfs_entry_open,
---	.release = single_release,
---	.read = seq_read,
---	.llseek = seq_lseek
---};
---
-- int brcmf_debugfs_add_entry(struct brcmf_pub *drvr, const char *fn,
-- 			    int (*read_fn)(struct seq_file *seq, void *data))
-- {
---	struct dentry *dentry =  drvr->dbgfs_dir;
---	struct brcmf_debugfs_entry *entry;
---
---	if (IS_ERR_OR_NULL(dentry))
---		return -ENOENT;
---
---	entry = devm_kzalloc(drvr->bus_if->dev, sizeof(*entry), GFP_KERNEL);
---	if (!entry)
---		return -ENOMEM;
---
---	entry->read = read_fn;
---	entry->drvr = drvr;
---
---	dentry = debugfs_create_file(fn, S_IRUGO, dentry, entry,
---				     &brcmf_debugfs_def_ops);
--+	struct dentry *e;
-- 
---	return PTR_ERR_OR_ZERO(dentry);
--+	e = debugfs_create_devm_seqfile(drvr->bus_if->dev, fn,
--+					drvr->dbgfs_dir, read_fn);
--+	return PTR_ERR_OR_ZERO(e);
-- }
-diff --git a/package/kernel/mac80211/patches/389-0001-brcmfmac-Check-if-firmware-supports-p2p.patch b/package/kernel/mac80211/patches/389-0001-brcmfmac-Check-if-firmware-supports-p2p.patch
-deleted file mode 100644
-index ff24a4a..0000000
---- a/package/kernel/mac80211/patches/389-0001-brcmfmac-Check-if-firmware-supports-p2p.patch
-+++ /dev/null
-@@ -1,42 +0,0 @@
--From: Pontus Fuchs <pontusf@broadcom.com>
--Date: Thu, 11 Jun 2015 00:12:17 +0200
--Subject: [PATCH] brcmfmac: Check if firmware supports p2p
--
--Add a feature flag to reflect the firmware's p2p capability.
--
--Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
--Reviewed-by: Hante Meuleman <meuleman@broadcom.com>
--Reviewed-by: Arend Van Spriel <arend@broadcom.com>
--Signed-off-by: Pontus Fuchs <pontusf@broadcom.com>
--Signed-off-by: Arend van Spriel <arend@broadcom.com>
--Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
-----
--
----- a/drivers/net/wireless/brcm80211/brcmfmac/feature.c
--+++ b/drivers/net/wireless/brcm80211/brcmfmac/feature.c
--@@ -129,6 +129,7 @@ void brcmf_feat_attach(struct brcmf_pub
-- 		brcmf_feat_iovar_int_get(ifp, BRCMF_FEAT_WOWL, "wowl");
-- 	if (drvr->bus_if->chip != BRCM_CC_43362_CHIP_ID)
-- 		brcmf_feat_iovar_int_set(ifp, BRCMF_FEAT_MBSS, "mbss", 0);
--+	brcmf_feat_iovar_int_get(ifp, BRCMF_FEAT_P2P, "p2p");
-- 
-- 	/* set chip related quirks */
-- 	switch (drvr->bus_if->chip) {
----- a/drivers/net/wireless/brcm80211/brcmfmac/feature.h
--+++ b/drivers/net/wireless/brcm80211/brcmfmac/feature.h
--@@ -23,12 +23,14 @@
--  * MCHAN: multi-channel for concurrent P2P.
--  * PNO: preferred network offload.
--  * WOWL: Wake-On-WLAN.
--+ * P2P: peer-to-peer
--  */
-- #define BRCMF_FEAT_LIST \
-- 	BRCMF_FEAT_DEF(MBSS) \
-- 	BRCMF_FEAT_DEF(MCHAN) \
-- 	BRCMF_FEAT_DEF(PNO) \
---	BRCMF_FEAT_DEF(WOWL)
--+	BRCMF_FEAT_DEF(WOWL) \
--+	BRCMF_FEAT_DEF(P2P)
-- /*
--  * Quirks:
--  *
-diff --git a/package/kernel/mac80211/patches/389-0002-brcmfmac-Build-wiphy-mode-and-interface-combinations.patch b/package/kernel/mac80211/patches/389-0002-brcmfmac-Build-wiphy-mode-and-interface-combinations.patch
-deleted file mode 100644
-index 3876ba0..0000000
---- a/package/kernel/mac80211/patches/389-0002-brcmfmac-Build-wiphy-mode-and-interface-combinations.patch
-+++ /dev/null
-@@ -1,198 +0,0 @@
--From: Pontus Fuchs <pontusf@broadcom.com>
--Date: Thu, 11 Jun 2015 00:12:18 +0200
--Subject: [PATCH] brcmfmac: Build wiphy mode and interface combinations
-- dynamically
--
--Switch from using semi hard coded interface combinations. This makes
--it easier to announce what the firmware actually supports. This fixes
--the case where brcmfmac announces p2p but the firmware doesn't
--support it.
--
--Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
--Reviewed-by: Hante Meuleman <meuleman@broadcom.com>
--Reviewed-by: Arend Van Spriel <arend@broadcom.com>
--Signed-off-by: Pontus Fuchs <pontusf@broadcom.com>
--Signed-off-by: Arend van Spriel <arend@broadcom.com>
--Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
-----
--
----- a/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c
--+++ b/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c
--@@ -52,8 +52,6 @@
-- #define BRCMF_PNO_SCAN_COMPLETE		1
-- #define BRCMF_PNO_SCAN_INCOMPLETE	0
-- 
---#define BRCMF_IFACE_MAX_CNT		3
---
-- #define WPA_OUI				"\x00\x50\xF2"	/* WPA OUI */
-- #define WPA_OUI_TYPE			1
-- #define RSN_OUI				"\x00\x0F\xAC"	/* RSN OUI */
--@@ -5639,53 +5637,6 @@ static int brcmf_setup_wiphybands(struct
-- 	return 0;
-- }
-- 
---static const struct ieee80211_iface_limit brcmf_iface_limits_mbss[] = {
---	{
---		.max = 1,
---		.types = BIT(NL80211_IFTYPE_STATION) |
---			 BIT(NL80211_IFTYPE_ADHOC)
---	},
---	{
---		.max = 4,
---		.types = BIT(NL80211_IFTYPE_AP)
---	},
---	{
---		.max = 1,
---		.types = BIT(NL80211_IFTYPE_P2P_CLIENT) |
---			 BIT(NL80211_IFTYPE_P2P_GO)
---	},
---	{
---		.max = 1,
---		.types = BIT(NL80211_IFTYPE_P2P_DEVICE)
---	}
---};
---
---static const struct ieee80211_iface_limit brcmf_iface_limits_sbss[] = {
---	{
---		.max = 2,
---		.types = BIT(NL80211_IFTYPE_STATION) |
---			 BIT(NL80211_IFTYPE_ADHOC) |
---			 BIT(NL80211_IFTYPE_AP)
---	},
---	{
---		.max = 1,
---		.types = BIT(NL80211_IFTYPE_P2P_CLIENT) |
---			 BIT(NL80211_IFTYPE_P2P_GO)
---	},
---	{
---		.max = 1,
---		.types = BIT(NL80211_IFTYPE_P2P_DEVICE)
---	}
---};
---static struct ieee80211_iface_combination brcmf_iface_combos[] = {
---	{
---		 .max_interfaces = BRCMF_IFACE_MAX_CNT,
---		 .num_different_channels = 1,
---		 .n_limits = ARRAY_SIZE(brcmf_iface_limits_sbss),
---		 .limits = brcmf_iface_limits_sbss,
---	}
---};
---
-- static const struct ieee80211_txrx_stypes
-- brcmf_txrx_stypes[NUM_NL80211_IFTYPES] = {
-- 	[NL80211_IFTYPE_STATION] = {
--@@ -5715,6 +5666,67 @@ brcmf_txrx_stypes[NUM_NL80211_IFTYPES] =
-- 	}
-- };
-- 
--+static int brcmf_setup_ifmodes(struct wiphy *wiphy, struct brcmf_if *ifp)
--+{
--+	struct ieee80211_iface_combination *combo = NULL;
--+	struct ieee80211_iface_limit *limits = NULL;
--+	int i = 0, max_iface_cnt;
--+
--+	combo = kzalloc(sizeof(*combo), GFP_KERNEL);
--+	if (!combo)
--+		goto err;
--+
--+	limits = kzalloc(sizeof(*limits) * 4, GFP_KERNEL);
--+	if (!limits)
--+		goto err;
--+
--+	wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
--+				 BIT(NL80211_IFTYPE_ADHOC) |
--+				 BIT(NL80211_IFTYPE_AP);
--+
--+	if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MCHAN))
--+		combo->num_different_channels = 2;
--+	else
--+		combo->num_different_channels = 1;
--+
--+	if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MBSS)) {
--+		limits[i].max = 1;
--+		limits[i++].types = BIT(NL80211_IFTYPE_STATION);
--+		limits[i].max = 4;
--+		limits[i++].types = BIT(NL80211_IFTYPE_AP);
--+		max_iface_cnt = 5;
--+	} else {
--+		limits[i].max = 2;
--+		limits[i++].types = BIT(NL80211_IFTYPE_STATION) |
--+				    BIT(NL80211_IFTYPE_AP);
--+		max_iface_cnt = 2;
--+	}
--+
--+	if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_P2P)) {
--+		wiphy->interface_modes |= BIT(NL80211_IFTYPE_P2P_CLIENT) |
--+					  BIT(NL80211_IFTYPE_P2P_GO) |
--+					  BIT(NL80211_IFTYPE_P2P_DEVICE);
--+		limits[i].max = 1;
--+		limits[i++].types = BIT(NL80211_IFTYPE_P2P_CLIENT) |
--+				    BIT(NL80211_IFTYPE_P2P_GO);
--+		limits[i].max = 1;
--+		limits[i++].types = BIT(NL80211_IFTYPE_P2P_DEVICE);
--+		max_iface_cnt += 2;
--+	}
--+	combo->max_interfaces = max_iface_cnt;
--+	combo->limits = limits;
--+	combo->n_limits = i;
--+
--+	wiphy->iface_combinations = combo;
--+	wiphy->n_iface_combinations = 1;
--+	return 0;
--+
--+err:
--+	kfree(limits);
--+	kfree(combo);
--+	return -ENOMEM;
--+}
--+
-- static void brcmf_wiphy_pno_params(struct wiphy *wiphy)
-- {
-- 	/* scheduled scan settings */
--@@ -5745,7 +5757,6 @@ static void brcmf_wiphy_wowl_params(stru
-- static int brcmf_setup_wiphy(struct wiphy *wiphy, struct brcmf_if *ifp)
-- {
-- 	struct ieee80211_supported_band *band;
---	struct ieee80211_iface_combination ifc_combo;
-- 	__le32 bandlist[3];
-- 	u32 n_bands;
-- 	int err, i;
--@@ -5753,24 +5764,11 @@ static int brcmf_setup_wiphy(struct wiph
-- 	wiphy->max_scan_ssids = WL_NUM_SCAN_MAX;
-- 	wiphy->max_scan_ie_len = BRCMF_SCAN_IE_LEN_MAX;
-- 	wiphy->max_num_pmkids = WL_NUM_PMKIDS_MAX;
---	wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
---				 BIT(NL80211_IFTYPE_ADHOC) |
---				 BIT(NL80211_IFTYPE_AP) |
---				 BIT(NL80211_IFTYPE_P2P_CLIENT) |
---				 BIT(NL80211_IFTYPE_P2P_GO) |
---				 BIT(NL80211_IFTYPE_P2P_DEVICE);
---	/* need VSDB firmware feature for concurrent channels */
---	ifc_combo = brcmf_iface_combos[0];
---	if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MCHAN))
---		ifc_combo.num_different_channels = 2;
---	if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MBSS)) {
---		ifc_combo.n_limits = ARRAY_SIZE(brcmf_iface_limits_mbss),
---		ifc_combo.limits = brcmf_iface_limits_mbss;
---	}
---	wiphy->iface_combinations = kmemdup(&ifc_combo,
---					    sizeof(ifc_combo),
---					    GFP_KERNEL);
---	wiphy->n_iface_combinations = ARRAY_SIZE(brcmf_iface_combos);
--+
--+	err = brcmf_setup_ifmodes(wiphy, ifp);
--+	if (err)
--+		return err;
--+
-- 	wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
-- 	wiphy->cipher_suites = __wl_cipher_suites;
-- 	wiphy->n_cipher_suites = ARRAY_SIZE(__wl_cipher_suites);
--@@ -6035,6 +6033,8 @@ static void brcmf_free_wiphy(struct wiph
-- 	if (!wiphy)
-- 		return;
-- 
--+	if (wiphy->iface_combinations)
--+		kfree(wiphy->iface_combinations->limits);
-- 	kfree(wiphy->iface_combinations);
-- 	if (wiphy->bands[IEEE80211_BAND_2GHZ]) {
-- 		kfree(wiphy->bands[IEEE80211_BAND_2GHZ]->channels);
-diff --git a/package/kernel/mac80211/patches/389-0003-brcmfmac-rework-.get_station-callback.patch b/package/kernel/mac80211/patches/389-0003-brcmfmac-rework-.get_station-callback.patch
-deleted file mode 100644
-index 7bd0686..0000000
---- a/package/kernel/mac80211/patches/389-0003-brcmfmac-rework-.get_station-callback.patch
-+++ /dev/null
-@@ -1,326 +0,0 @@
--From: Arend van Spriel <arend@broadcom.com>
--Date: Thu, 11 Jun 2015 00:12:19 +0200
--Subject: [PATCH] brcmfmac: rework .get_station() callback
--
--The .get_station() cfg80211 callback is used in several scenarios. In
--managed mode it can obtain information about the access-point and its
--BSS parameters. In managed mode it can also obtain information about
--TDLS peers. In AP mode it can obtain information about connected
--clients.
--
--Reviewed-by: Hante Meuleman <meuleman@broadcom.com>
--Reviewed-by: Daniel (Deognyoun) Kim <dekim@broadcom.com>
--Reviewed-by: Franky (Zhenhui) Lin <frankyl@broadcom.com>
--Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
--Signed-off-by: Arend van Spriel <arend@broadcom.com>
--Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
-----
--
----- a/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c
--+++ b/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c
--@@ -2395,27 +2395,80 @@ brcmf_cfg80211_reconfigure_wep(struct br
-- 		brcmf_err("set wsec error (%d)\n", err);
-- }
-- 
--+static void brcmf_convert_sta_flags(u32 fw_sta_flags, struct station_info *si)
--+{
--+	struct nl80211_sta_flag_update *sfu;
--+
--+	brcmf_dbg(TRACE, "flags %08x\n", fw_sta_flags);
--+	si->filled |= BIT(NL80211_STA_INFO_STA_FLAGS);
--+	sfu = &si->sta_flags;
--+	sfu->mask = BIT(NL80211_STA_FLAG_WME) |
--+		    BIT(NL80211_STA_FLAG_AUTHENTICATED) |
--+		    BIT(NL80211_STA_FLAG_ASSOCIATED) |
--+		    BIT(NL80211_STA_FLAG_AUTHORIZED);
--+	if (fw_sta_flags & BRCMF_STA_WME)
--+		sfu->set |= BIT(NL80211_STA_FLAG_WME);
--+	if (fw_sta_flags & BRCMF_STA_AUTHE)
--+		sfu->set |= BIT(NL80211_STA_FLAG_AUTHENTICATED);
--+	if (fw_sta_flags & BRCMF_STA_ASSOC)
--+		sfu->set |= BIT(NL80211_STA_FLAG_ASSOCIATED);
--+	if (fw_sta_flags & BRCMF_STA_AUTHO)
--+		sfu->set |= BIT(NL80211_STA_FLAG_AUTHORIZED);
--+}
--+
--+static void brcmf_fill_bss_param(struct brcmf_if *ifp, struct station_info *si)
--+{
--+	struct {
--+		__le32 len;
--+		struct brcmf_bss_info_le bss_le;
--+	} *buf;
--+	u16 capability;
--+	int err;
--+
--+	buf = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL);
--+	if (!buf)
--+		return;
--+
--+	buf->len = cpu_to_le32(WL_BSS_INFO_MAX);
--+	err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_BSS_INFO, buf,
--+				     WL_BSS_INFO_MAX);
--+	if (err) {
--+		brcmf_err("Failed to get bss info (%d)\n", err);
--+		return;
--+	}
--+	si->filled |= BIT(NL80211_STA_INFO_BSS_PARAM);
--+	si->bss_param.beacon_interval = le16_to_cpu(buf->bss_le.beacon_period);
--+	si->bss_param.dtim_period = buf->bss_le.dtim_period;
--+	capability = le16_to_cpu(buf->bss_le.capability);
--+	if (capability & IEEE80211_HT_STBC_PARAM_DUAL_CTS_PROT)
--+		si->bss_param.flags |= BSS_PARAM_FLAGS_CTS_PROT;
--+	if (capability & WLAN_CAPABILITY_SHORT_PREAMBLE)
--+		si->bss_param.flags |= BSS_PARAM_FLAGS_SHORT_PREAMBLE;
--+	if (capability & WLAN_CAPABILITY_SHORT_SLOT_TIME)
--+		si->bss_param.flags |= BSS_PARAM_FLAGS_SHORT_SLOT_TIME;
--+}
--+
-- static s32
-- brcmf_cfg80211_get_station(struct wiphy *wiphy, struct net_device *ndev,
-- 			   const u8 *mac, struct station_info *sinfo)
-- {
-- 	struct brcmf_if *ifp = netdev_priv(ndev);
---	struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
---	struct brcmf_scb_val_le scb_val;
---	int rssi;
---	s32 rate;
-- 	s32 err = 0;
---	u8 *bssid = profile->bssid;
-- 	struct brcmf_sta_info_le sta_info_le;
---	u32 beacon_period;
---	u32 dtim_period;
--+	u32 sta_flags;
--+	u32 is_tdls_peer;
-- 
-- 	brcmf_dbg(TRACE, "Enter, MAC %pM\n", mac);
-- 	if (!check_vif_up(ifp->vif))
-- 		return -EIO;
-- 
---	if (brcmf_is_apmode(ifp->vif)) {
---		memcpy(&sta_info_le, mac, ETH_ALEN);
--+	memset(&sta_info_le, 0, sizeof(sta_info_le));
--+	memcpy(&sta_info_le, mac, ETH_ALEN);
--+	err = brcmf_fil_iovar_data_get(ifp, "tdls_sta_info",
--+				       &sta_info_le,
--+				       sizeof(sta_info_le));
--+	is_tdls_peer = !err;
--+	if (err) {
-- 		err = brcmf_fil_iovar_data_get(ifp, "sta_info",
-- 					       &sta_info_le,
-- 					       sizeof(sta_info_le));
--@@ -2423,73 +2476,48 @@ brcmf_cfg80211_get_station(struct wiphy
-- 			brcmf_err("GET STA INFO failed, %d\n", err);
-- 			goto done;
-- 		}
---		sinfo->filled = BIT(NL80211_STA_INFO_INACTIVE_TIME);
---		sinfo->inactive_time = le32_to_cpu(sta_info_le.idle) * 1000;
---		if (le32_to_cpu(sta_info_le.flags) & BRCMF_STA_ASSOC) {
---			sinfo->filled |= BIT(NL80211_STA_INFO_CONNECTED_TIME);
---			sinfo->connected_time = le32_to_cpu(sta_info_le.in);
---		}
---		brcmf_dbg(TRACE, "STA idle time : %d ms, connected time :%d sec\n",
---			  sinfo->inactive_time, sinfo->connected_time);
---	} else if (ifp->vif->wdev.iftype == NL80211_IFTYPE_STATION) {
---		if (memcmp(mac, bssid, ETH_ALEN)) {
---			brcmf_err("Wrong Mac address cfg_mac-%pM wl_bssid-%pM\n",
---				  mac, bssid);
---			err = -ENOENT;
---			goto done;
---		}
---		/* Report the current tx rate */
---		err = brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_RATE, &rate);
---		if (err) {
---			brcmf_err("Could not get rate (%d)\n", err);
---			goto done;
---		} else {
--+	}
--+	brcmf_dbg(TRACE, "version %d\n", le16_to_cpu(sta_info_le.ver));
--+	sinfo->filled = BIT(NL80211_STA_INFO_INACTIVE_TIME);
--+	sinfo->inactive_time = le32_to_cpu(sta_info_le.idle) * 1000;
--+	sta_flags = le32_to_cpu(sta_info_le.flags);
--+	brcmf_convert_sta_flags(sta_flags, sinfo);
--+	sinfo->sta_flags.mask |= BIT(NL80211_STA_FLAG_TDLS_PEER);
--+	if (is_tdls_peer)
--+		sinfo->sta_flags.set |= BIT(NL80211_STA_FLAG_TDLS_PEER);
--+	else
--+		sinfo->sta_flags.set &= ~BIT(NL80211_STA_FLAG_TDLS_PEER);
--+	if (sta_flags & BRCMF_STA_ASSOC) {
--+		sinfo->filled |= BIT(NL80211_STA_INFO_CONNECTED_TIME);
--+		sinfo->connected_time = le32_to_cpu(sta_info_le.in);
--+		brcmf_fill_bss_param(ifp, sinfo);
--+	}
--+	if (sta_flags & BRCMF_STA_SCBSTATS) {
--+		sinfo->filled |= BIT(NL80211_STA_INFO_TX_FAILED);
--+		sinfo->tx_failed = le32_to_cpu(sta_info_le.tx_failures);
--+		sinfo->filled |= BIT(NL80211_STA_INFO_TX_PACKETS);
--+		sinfo->tx_packets = le32_to_cpu(sta_info_le.tx_pkts);
--+		sinfo->tx_packets += le32_to_cpu(sta_info_le.tx_mcast_pkts);
--+		sinfo->filled |= BIT(NL80211_STA_INFO_RX_PACKETS);
--+		sinfo->rx_packets = le32_to_cpu(sta_info_le.rx_ucast_pkts);
--+		sinfo->rx_packets += le32_to_cpu(sta_info_le.rx_mcast_pkts);
--+		if (sinfo->tx_packets) {
-- 			sinfo->filled |= BIT(NL80211_STA_INFO_TX_BITRATE);
---			sinfo->txrate.legacy = rate * 5;
---			brcmf_dbg(CONN, "Rate %d Mbps\n", rate / 2);
--+			sinfo->txrate.legacy = le32_to_cpu(sta_info_le.tx_rate);
--+			sinfo->txrate.legacy /= 100;
-- 		}
---
---		if (test_bit(BRCMF_VIF_STATUS_CONNECTED,
---			     &ifp->vif->sme_state)) {
---			memset(&scb_val, 0, sizeof(scb_val));
---			err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_RSSI,
---						     &scb_val, sizeof(scb_val));
---			if (err) {
---				brcmf_err("Could not get rssi (%d)\n", err);
---				goto done;
---			} else {
---				rssi = le32_to_cpu(scb_val.val);
---				sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL);
---				sinfo->signal = rssi;
---				brcmf_dbg(CONN, "RSSI %d dBm\n", rssi);
---			}
---			err = brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_BCNPRD,
---						    &beacon_period);
---			if (err) {
---				brcmf_err("Could not get beacon period (%d)\n",
---					  err);
---				goto done;
---			} else {
---				sinfo->bss_param.beacon_interval =
---					beacon_period;
---				brcmf_dbg(CONN, "Beacon peroid %d\n",
---					  beacon_period);
---			}
---			err = brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_DTIMPRD,
---						    &dtim_period);
---			if (err) {
---				brcmf_err("Could not get DTIM period (%d)\n",
---					  err);
---				goto done;
---			} else {
---				sinfo->bss_param.dtim_period = dtim_period;
---				brcmf_dbg(CONN, "DTIM peroid %d\n",
---					  dtim_period);
---			}
---			sinfo->filled |= BIT(NL80211_STA_INFO_BSS_PARAM);
--+		if (sinfo->rx_packets) {
--+			sinfo->filled |= BIT(NL80211_STA_INFO_RX_BITRATE);
--+			sinfo->rxrate.legacy = le32_to_cpu(sta_info_le.rx_rate);
--+			sinfo->rxrate.legacy /= 100;
--+		}
--+		if (le16_to_cpu(sta_info_le.ver) >= 4) {
--+			sinfo->filled |= BIT(NL80211_STA_INFO_TX_BYTES);
--+			sinfo->tx_bytes = le64_to_cpu(sta_info_le.tx_tot_bytes);
--+			sinfo->filled |= BIT(NL80211_STA_INFO_RX_BYTES);
--+			sinfo->rx_bytes = le64_to_cpu(sta_info_le.rx_tot_bytes);
-- 		}
---	} else
---		err = -EPERM;
--+	}
-- done:
-- 	brcmf_dbg(TRACE, "Exit\n");
-- 	return err;
----- a/drivers/net/wireless/brcm80211/brcmfmac/fwil_types.h
--+++ b/drivers/net/wireless/brcm80211/brcmfmac/fwil_types.h
--@@ -32,7 +32,11 @@
-- #define	BRCMF_BSS_INFO_VERSION	109 /* curr ver of brcmf_bss_info_le struct */
-- #define BRCMF_BSS_RSSI_ON_CHANNEL	0x0002
-- 
---#define BRCMF_STA_ASSOC			0x10		/* Associated */
--+#define BRCMF_STA_WME              0x00000002      /* WMM association */
--+#define BRCMF_STA_AUTHE            0x00000008      /* Authenticated */
--+#define BRCMF_STA_ASSOC            0x00000010      /* Associated */
--+#define BRCMF_STA_AUTHO            0x00000020      /* Authorized */
--+#define BRCMF_STA_SCBSTATS         0x00004000      /* Per STA debug stats */
-- 
-- /* size of brcmf_scan_params not including variable length array */
-- #define BRCMF_SCAN_PARAMS_FIXED_SIZE	64
--@@ -113,6 +117,7 @@
-- #define BRCMF_WOWL_MAXPATTERNSIZE	128
-- 
-- #define BRCMF_COUNTRY_BUF_SZ		4
--+#define BRCMF_ANT_MAX			4
-- 
-- /* join preference types for join_pref iovar */
-- enum brcmf_join_pref_types {
--@@ -456,25 +461,61 @@ struct brcmf_channel_info_le {
-- };
-- 
-- struct brcmf_sta_info_le {
---	__le16	ver;		/* version of this struct */
---	__le16	len;		/* length in bytes of this structure */
---	__le16	cap;		/* sta's advertised capabilities */
---	__le32	flags;		/* flags defined below */
---	__le32	idle;		/* time since data pkt rx'd from sta */
---	u8	ea[ETH_ALEN];		/* Station address */
---	__le32	count;			/* # rates in this set */
---	u8	rates[BRCMF_MAXRATES_IN_SET];	/* rates in 500kbps units */
--+	__le16 ver;		/* version of this struct */
--+	__le16 len;		/* length in bytes of this structure */
--+	__le16 cap;		/* sta's advertised capabilities */
--+	__le32 flags;		/* flags defined below */
--+	__le32 idle;		/* time since data pkt rx'd from sta */
--+	u8 ea[ETH_ALEN];		/* Station address */
--+	__le32 count;			/* # rates in this set */
--+	u8 rates[BRCMF_MAXRATES_IN_SET];	/* rates in 500kbps units */
-- 						/* w/hi bit set if basic */
---	__le32	in;		/* seconds elapsed since associated */
---	__le32	listen_interval_inms; /* Min Listen interval in ms for STA */
---	__le32	tx_pkts;	/* # of packets transmitted */
---	__le32	tx_failures;	/* # of packets failed */
---	__le32	rx_ucast_pkts;	/* # of unicast packets received */
---	__le32	rx_mcast_pkts;	/* # of multicast packets received */
---	__le32	tx_rate;	/* Rate of last successful tx frame */
---	__le32	rx_rate;	/* Rate of last successful rx frame */
---	__le32	rx_decrypt_succeeds;	/* # of packet decrypted successfully */
---	__le32	rx_decrypt_failures;	/* # of packet decrypted failed */
--+	__le32 in;		/* seconds elapsed since associated */
--+	__le32 listen_interval_inms; /* Min Listen interval in ms for STA */
--+	__le32 tx_pkts;	/* # of packets transmitted */
--+	__le32 tx_failures;	/* # of packets failed */
--+	__le32 rx_ucast_pkts;	/* # of unicast packets received */
--+	__le32 rx_mcast_pkts;	/* # of multicast packets received */
--+	__le32 tx_rate;	/* Rate of last successful tx frame */
--+	__le32 rx_rate;	/* Rate of last successful rx frame */
--+	__le32 rx_decrypt_succeeds;	/* # of packet decrypted successfully */
--+	__le32 rx_decrypt_failures;	/* # of packet decrypted failed */
--+	__le32 tx_tot_pkts;    /* # of tx pkts (ucast + mcast) */
--+	__le32 rx_tot_pkts;    /* # of data packets recvd (uni + mcast) */
--+	__le32 tx_mcast_pkts;  /* # of mcast pkts txed */
--+	__le64 tx_tot_bytes;   /* data bytes txed (ucast + mcast) */
--+	__le64 rx_tot_bytes;   /* data bytes recvd (ucast + mcast) */
--+	__le64 tx_ucast_bytes; /* data bytes txed (ucast) */
--+	__le64 tx_mcast_bytes; /* # data bytes txed (mcast) */
--+	__le64 rx_ucast_bytes; /* data bytes recvd (ucast) */
--+	__le64 rx_mcast_bytes; /* data bytes recvd (mcast) */
--+	s8 rssi[BRCMF_ANT_MAX];   /* per antenna rssi */
--+	s8 nf[BRCMF_ANT_MAX];     /* per antenna noise floor */
--+	__le16 aid;                    /* association ID */
--+	__le16 ht_capabilities;        /* advertised ht caps */
--+	__le16 vht_flags;              /* converted vht flags */
--+	__le32 tx_pkts_retry_cnt;      /* # of frames where a retry was
--+					 * exhausted.
--+					 */
--+	__le32 tx_pkts_retry_exhausted; /* # of user frames where a retry
--+					 * was exhausted
--+					 */
--+	s8 rx_lastpkt_rssi[BRCMF_ANT_MAX]; /* Per antenna RSSI of last
--+					    * received data frame.
--+					    */
--+	/* TX WLAN retry/failure statistics:
--+	 * Separated for host requested frames and locally generated frames.
--+	 * Include unicast frame only where the retries/failures can be counted.
--+	 */
--+	__le32 tx_pkts_total;          /* # user frames sent successfully */
--+	__le32 tx_pkts_retries;        /* # user frames retries */
--+	__le32 tx_pkts_fw_total;       /* # FW generated sent successfully */
--+	__le32 tx_pkts_fw_retries;     /* # retries for FW generated frames */
--+	__le32 tx_pkts_fw_retry_exhausted;     /* # FW generated where a retry
--+						* was exhausted
--+						*/
--+	__le32 rx_pkts_retried;        /* # rx with retry bit set */
--+	__le32 tx_rate_fallback;       /* lowest fallback TX rate */
-- };
-- 
-- struct brcmf_chanspec_list {
-diff --git a/package/kernel/mac80211/patches/389-0004-brcmfmac-have-sdio-return-EIO-when-device-communicat.patch b/package/kernel/mac80211/patches/389-0004-brcmfmac-have-sdio-return-EIO-when-device-communicat.patch
-deleted file mode 100644
-index 302bc3e..0000000
---- a/package/kernel/mac80211/patches/389-0004-brcmfmac-have-sdio-return-EIO-when-device-communicat.patch
-+++ /dev/null
-@@ -1,56 +0,0 @@
--From: Arend van Spriel <arend@broadcom.com>
--Date: Thu, 11 Jun 2015 00:12:20 +0200
--Subject: [PATCH] brcmfmac: have sdio return -EIO when device communication
-- is not possible
--
--The bus interface functions txctl and rxctl may be used while the device
--can not be accessed, eg. upon driver .remove() callback. This patch will
--immediately return -EIO when this is the case which speeds up the module
--unload.
--
--Reviewed-by: Hante Meuleman <meuleman@broadcom.com>
--Reviewed-by: Franky (Zhenhui) Lin <frankyl@broadcom.com>
--Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
--Signed-off-by: Arend van Spriel <arend@broadcom.com>
--Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
-----
--
----- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
--+++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
--@@ -988,6 +988,7 @@ static void brcmf_sdiod_freezer_detach(s
-- 
-- static int brcmf_sdiod_remove(struct brcmf_sdio_dev *sdiodev)
-- {
--+	sdiodev->state = BRCMF_SDIOD_DOWN;
-- 	if (sdiodev->bus) {
-- 		brcmf_sdio_remove(sdiodev->bus);
-- 		sdiodev->bus = NULL;
----- a/drivers/net/wireless/brcm80211/brcmfmac/sdio.c
--+++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio.c
--@@ -2820,6 +2820,8 @@ static int brcmf_sdio_bus_txdata(struct
-- 	struct brcmf_sdio *bus = sdiodev->bus;
-- 
-- 	brcmf_dbg(TRACE, "Enter: pkt: data %p len %d\n", pkt->data, pkt->len);
--+	if (sdiodev->state != BRCMF_SDIOD_DATA)
--+		return -EIO;
-- 
-- 	/* Add space for the header */
-- 	skb_push(pkt, bus->tx_hdrlen);
--@@ -2948,6 +2950,8 @@ brcmf_sdio_bus_txctl(struct device *dev,
-- 	int ret;
-- 
-- 	brcmf_dbg(TRACE, "Enter\n");
--+	if (sdiodev->state != BRCMF_SDIOD_DATA)
--+		return -EIO;
-- 
-- 	/* Send from dpc */
-- 	bus->ctrl_frame_buf = msg;
--@@ -3238,6 +3242,8 @@ brcmf_sdio_bus_rxctl(struct device *dev,
-- 	struct brcmf_sdio *bus = sdiodev->bus;
-- 
-- 	brcmf_dbg(TRACE, "Enter\n");
--+	if (sdiodev->state != BRCMF_SDIOD_DATA)
--+		return -EIO;
-- 
-- 	/* Wait until control frame is available */
-- 	timeleft = brcmf_sdio_dcmd_resp_wait(bus, &bus->rxlen, &pending);
-diff --git a/package/kernel/mac80211/patches/389-0005-ath9k-make-DMA-stop-related-messages-debug-only.patch b/package/kernel/mac80211/patches/389-0005-ath9k-make-DMA-stop-related-messages-debug-only.patch
-deleted file mode 100644
-index 34af6d2..0000000
---- a/package/kernel/mac80211/patches/389-0005-ath9k-make-DMA-stop-related-messages-debug-only.patch
-+++ /dev/null
-@@ -1,74 +0,0 @@
--From: Felix Fietkau <nbd@openwrt.org>
--Date: Thu, 2 Jul 2015 13:35:05 +0200
--Subject: [PATCH] ath9k: make DMA stop related messages debug-only
--
--A long time ago, ath9k had issues during reset where the DMA engine
--would stay active and could potentially corrupt memory.
--To debug those issues, the driver would print warnings whenever they
--occur.
--
--Nowadays, these issues are gone and the primary cause of these messages
--is if the MAC is stuck during reset or busy processing a long
--transmission. This is fairly harmless, yet these messages continue to
--worry users.
--
--To reduce the number of bogus bug reports, turn these messages into
--debug messages and count their occurence in the "reset" debugfs file.
--
--Signed-off-by: Felix Fietkau <nbd@openwrt.org>
-----
--
----- a/drivers/net/wireless/ath/ath9k/debug.c
--+++ b/drivers/net/wireless/ath/ath9k/debug.c
--@@ -765,6 +765,8 @@ static int read_file_reset(struct seq_fi
-- 		[RESET_TYPE_BEACON_STUCK] = "Stuck Beacon",
-- 		[RESET_TYPE_MCI] = "MCI Reset",
-- 		[RESET_TYPE_CALIBRATION] = "Calibration error",
--+		[RESET_TX_DMA_ERROR] = "Tx DMA stop error",
--+		[RESET_RX_DMA_ERROR] = "Rx DMA stop error",
-- 	};
-- 	int i;
-- 
----- a/drivers/net/wireless/ath/ath9k/debug.h
--+++ b/drivers/net/wireless/ath/ath9k/debug.h
--@@ -50,6 +50,8 @@ enum ath_reset_type {
-- 	RESET_TYPE_BEACON_STUCK,
-- 	RESET_TYPE_MCI,
-- 	RESET_TYPE_CALIBRATION,
--+	RESET_TX_DMA_ERROR,
--+	RESET_RX_DMA_ERROR,
-- 	__RESET_TYPE_MAX
-- };
-- 
----- a/drivers/net/wireless/ath/ath9k/recv.c
--+++ b/drivers/net/wireless/ath/ath9k/recv.c
--@@ -496,10 +496,9 @@ bool ath_stoprecv(struct ath_softc *sc)
-- 
-- 	if (!(ah->ah_flags & AH_UNPLUGGED) &&
-- 	    unlikely(!stopped)) {
---		ath_err(ath9k_hw_common(sc->sc_ah),
---			"Could not stop RX, we could be "
---			"confusing the DMA engine when we start RX up\n");
---		ATH_DBG_WARN_ON_ONCE(!stopped);
--+		ath_dbg(ath9k_hw_common(sc->sc_ah), RESET,
--+			"Failed to stop Rx DMA\n");
--+		RESET_STAT_INC(sc, RESET_RX_DMA_ERROR);
-- 	}
-- 	return stopped && !reset;
-- }
----- a/drivers/net/wireless/ath/ath9k/xmit.c
--+++ b/drivers/net/wireless/ath/ath9k/xmit.c
--@@ -1896,8 +1896,11 @@ bool ath_drain_all_txq(struct ath_softc
-- 			npend |= BIT(i);
-- 	}
-- 
---	if (npend)
---		ath_err(common, "Failed to stop TX DMA, queues=0x%03x!\n", npend);
--+	if (npend) {
--+		RESET_STAT_INC(sc, RESET_TX_DMA_ERROR);
--+		ath_dbg(common, RESET,
--+			"Failed to stop TX DMA, queues=0x%03x!\n", npend);
--+	}
-- 
-- 	for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) {
-- 		if (!ATH_TXQ_SETUP(sc, i))
-diff --git a/package/kernel/mac80211/patches/389-0006-brcmfmac-free-ifp-for-non-netdev-interface-in-p2p-mo.patch b/package/kernel/mac80211/patches/389-0006-brcmfmac-free-ifp-for-non-netdev-interface-in-p2p-mo.patch
-deleted file mode 100644
-index 06f2dce..0000000
---- a/package/kernel/mac80211/patches/389-0006-brcmfmac-free-ifp-for-non-netdev-interface-in-p2p-mo.patch
-+++ /dev/null
-@@ -1,44 +0,0 @@
--From: Arend van Spriel <arend@broadcom.com>
--Date: Thu, 11 Jun 2015 00:12:21 +0200
--Subject: [PATCH] brcmfmac: free ifp for non-netdev interface in p2p module
--
--Making it more clear by freeing the ifp in same place where the
--vif object is freed.
--
--Reviewed-by: Hante Meuleman <meuleman@broadcom.com>
--Reviewed-by: Franky (Zhenhui) Lin <frankyl@broadcom.com>
--Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
--Signed-off-by: Arend van Spriel <arend@broadcom.com>
--Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
-----
--
----- a/drivers/net/wireless/brcm80211/brcmfmac/core.c
--+++ b/drivers/net/wireless/brcm80211/brcmfmac/core.c
--@@ -867,8 +867,6 @@ static void brcmf_del_if(struct brcmf_pu
-- 		}
-- 		/* unregister will take care of freeing it */
-- 		unregister_netdev(ifp->ndev);
---	} else {
---		kfree(ifp);
-- 	}
-- }
-- 
----- a/drivers/net/wireless/brcm80211/brcmfmac/p2p.c
--+++ b/drivers/net/wireless/brcm80211/brcmfmac/p2p.c
--@@ -2238,6 +2238,7 @@ static void brcmf_p2p_delete_p2pdev(stru
-- {
-- 	cfg80211_unregister_wdev(&vif->wdev);
-- 	p2p->bss_idx[P2PAPI_BSSCFG_DEVICE].vif = NULL;
--+	kfree(vif->ifp);
-- 	brcmf_free_vif(vif);
-- }
-- 
--@@ -2361,6 +2362,8 @@ int brcmf_p2p_del_vif(struct wiphy *wiph
-- 		break;
-- 
-- 	case NL80211_IFTYPE_P2P_DEVICE:
--+		brcmf_p2p_cancel_remain_on_channel(vif->ifp);
--+		brcmf_p2p_deinit_discovery(p2p);
-- 		brcmf_p2p_delete_p2pdev(p2p, vif);
-- 		return 0;
-- 	default:
-diff --git a/package/kernel/mac80211/patches/389-0007-brcmfmac-move-p2p-attach-detach-functions.patch b/package/kernel/mac80211/patches/389-0007-brcmfmac-move-p2p-attach-detach-functions.patch
-deleted file mode 100644
-index 0a6e093..0000000
---- a/package/kernel/mac80211/patches/389-0007-brcmfmac-move-p2p-attach-detach-functions.patch
-+++ /dev/null
-@@ -1,225 +0,0 @@
--From: Arend van Spriel <arend@broadcom.com>
--Date: Thu, 11 Jun 2015 00:12:22 +0200
--Subject: [PATCH] brcmfmac: move p2p attach/detach functions
--
--Moving two functions in p2p.c as is so next change will be
--easier to review.
--
--Reviewed-by: Hante Meuleman <meuleman@broadcom.com>
--Reviewed-by: Franky (Zhenhui) Lin <frankyl@broadcom.com>
--Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
--Signed-off-by: Arend van Spriel <arend@broadcom.com>
--Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
-----
--
----- a/drivers/net/wireless/brcm80211/brcmfmac/p2p.c
--+++ b/drivers/net/wireless/brcm80211/brcmfmac/p2p.c
--@@ -1908,105 +1908,6 @@ s32 brcmf_p2p_notify_rx_mgmt_p2p_probere
-- 
-- 
-- /**
--- * brcmf_p2p_attach() - attach for P2P.
--- *
--- * @cfg: driver private data for cfg80211 interface.
--- */
---s32 brcmf_p2p_attach(struct brcmf_cfg80211_info *cfg)
---{
---	struct brcmf_if *pri_ifp;
---	struct brcmf_if *p2p_ifp;
---	struct brcmf_cfg80211_vif *p2p_vif;
---	struct brcmf_p2p_info *p2p;
---	struct brcmf_pub *drvr;
---	s32 bssidx;
---	s32 err = 0;
---
---	p2p = &cfg->p2p;
---	p2p->cfg = cfg;
---
---	drvr = cfg->pub;
---
---	pri_ifp = drvr->iflist[0];
---	p2p_ifp = drvr->iflist[1];
---
---	p2p->bss_idx[P2PAPI_BSSCFG_PRIMARY].vif = pri_ifp->vif;
---
---	if (p2p_ifp) {
---		p2p_vif = brcmf_alloc_vif(cfg, NL80211_IFTYPE_P2P_DEVICE,
---					  false);
---		if (IS_ERR(p2p_vif)) {
---			brcmf_err("could not create discovery vif\n");
---			err = -ENOMEM;
---			goto exit;
---		}
---
---		p2p_vif->ifp = p2p_ifp;
---		p2p_ifp->vif = p2p_vif;
---		p2p_vif->wdev.netdev = p2p_ifp->ndev;
---		p2p_ifp->ndev->ieee80211_ptr = &p2p_vif->wdev;
---		SET_NETDEV_DEV(p2p_ifp->ndev, wiphy_dev(cfg->wiphy));
---
---		p2p->bss_idx[P2PAPI_BSSCFG_DEVICE].vif = p2p_vif;
---
---		brcmf_p2p_generate_bss_mac(p2p, NULL);
---		memcpy(p2p_ifp->mac_addr, p2p->dev_addr, ETH_ALEN);
---		brcmf_p2p_set_firmware(pri_ifp, p2p->dev_addr);
---
---		/* Initialize P2P Discovery in the firmware */
---		err = brcmf_fil_iovar_int_set(pri_ifp, "p2p_disc", 1);
---		if (err < 0) {
---			brcmf_err("set p2p_disc error\n");
---			brcmf_free_vif(p2p_vif);
---			goto exit;
---		}
---		/* obtain bsscfg index for P2P discovery */
---		err = brcmf_fil_iovar_int_get(pri_ifp, "p2p_dev", &bssidx);
---		if (err < 0) {
---			brcmf_err("retrieving discover bsscfg index failed\n");
---			brcmf_free_vif(p2p_vif);
---			goto exit;
---		}
---		/* Verify that firmware uses same bssidx as driver !! */
---		if (p2p_ifp->bssidx != bssidx) {
---			brcmf_err("Incorrect bssidx=%d, compared to p2p_ifp->bssidx=%d\n",
---				  bssidx, p2p_ifp->bssidx);
---			brcmf_free_vif(p2p_vif);
---			goto exit;
---		}
---
---		init_completion(&p2p->send_af_done);
---		INIT_WORK(&p2p->afx_hdl.afx_work, brcmf_p2p_afx_handler);
---		init_completion(&p2p->afx_hdl.act_frm_scan);
---		init_completion(&p2p->wait_next_af);
---	}
---exit:
---	return err;
---}
---
---
---/**
--- * brcmf_p2p_detach() - detach P2P.
--- *
--- * @p2p: P2P specific data.
--- */
---void brcmf_p2p_detach(struct brcmf_p2p_info *p2p)
---{
---	struct brcmf_cfg80211_vif *vif;
---
---	vif = p2p->bss_idx[P2PAPI_BSSCFG_DEVICE].vif;
---	if (vif != NULL) {
---		brcmf_p2p_cancel_remain_on_channel(vif->ifp);
---		brcmf_p2p_deinit_discovery(p2p);
---		/* remove discovery interface */
---		brcmf_free_vif(vif);
---		p2p->bss_idx[P2PAPI_BSSCFG_DEVICE].vif = NULL;
---	}
---	/* just set it all to zero */
---	memset(p2p, 0, sizeof(*p2p));
---}
---
---/**
--  * brcmf_p2p_get_current_chanspec() - Get current operation channel.
--  *
--  * @p2p: P2P specific data.
--@@ -2425,3 +2326,102 @@ void brcmf_p2p_stop_device(struct wiphy
-- 	clear_bit(BRCMF_VIF_STATUS_READY, &vif->sme_state);
-- 	mutex_unlock(&cfg->usr_sync);
-- }
--+
--+/**
--+ * brcmf_p2p_attach() - attach for P2P.
--+ *
--+ * @cfg: driver private data for cfg80211 interface.
--+ */
--+s32 brcmf_p2p_attach(struct brcmf_cfg80211_info *cfg)
--+{
--+	struct brcmf_if *pri_ifp;
--+	struct brcmf_if *p2p_ifp;
--+	struct brcmf_cfg80211_vif *p2p_vif;
--+	struct brcmf_p2p_info *p2p;
--+	struct brcmf_pub *drvr;
--+	s32 bssidx;
--+	s32 err = 0;
--+
--+	p2p = &cfg->p2p;
--+	p2p->cfg = cfg;
--+
--+	drvr = cfg->pub;
--+
--+	pri_ifp = drvr->iflist[0];
--+	p2p_ifp = drvr->iflist[1];
--+
--+	p2p->bss_idx[P2PAPI_BSSCFG_PRIMARY].vif = pri_ifp->vif;
--+
--+	if (p2p_ifp) {
--+		p2p_vif = brcmf_alloc_vif(cfg, NL80211_IFTYPE_P2P_DEVICE,
--+					  false);
--+		if (IS_ERR(p2p_vif)) {
--+			brcmf_err("could not create discovery vif\n");
--+			err = -ENOMEM;
--+			goto exit;
--+		}
--+
--+		p2p_vif->ifp = p2p_ifp;
--+		p2p_ifp->vif = p2p_vif;
--+		p2p_vif->wdev.netdev = p2p_ifp->ndev;
--+		p2p_ifp->ndev->ieee80211_ptr = &p2p_vif->wdev;
--+		SET_NETDEV_DEV(p2p_ifp->ndev, wiphy_dev(cfg->wiphy));
--+
--+		p2p->bss_idx[P2PAPI_BSSCFG_DEVICE].vif = p2p_vif;
--+
--+		brcmf_p2p_generate_bss_mac(p2p, NULL);
--+		memcpy(p2p_ifp->mac_addr, p2p->dev_addr, ETH_ALEN);
--+		brcmf_p2p_set_firmware(pri_ifp, p2p->dev_addr);
--+
--+		/* Initialize P2P Discovery in the firmware */
--+		err = brcmf_fil_iovar_int_set(pri_ifp, "p2p_disc", 1);
--+		if (err < 0) {
--+			brcmf_err("set p2p_disc error\n");
--+			brcmf_free_vif(p2p_vif);
--+			goto exit;
--+		}
--+		/* obtain bsscfg index for P2P discovery */
--+		err = brcmf_fil_iovar_int_get(pri_ifp, "p2p_dev", &bssidx);
--+		if (err < 0) {
--+			brcmf_err("retrieving discover bsscfg index failed\n");
--+			brcmf_free_vif(p2p_vif);
--+			goto exit;
--+		}
--+		/* Verify that firmware uses same bssidx as driver !! */
--+		if (p2p_ifp->bssidx != bssidx) {
--+			brcmf_err("Incorrect bssidx=%d, compared to p2p_ifp->bssidx=%d\n",
--+				  bssidx, p2p_ifp->bssidx);
--+			brcmf_free_vif(p2p_vif);
--+			goto exit;
--+		}
--+
--+		init_completion(&p2p->send_af_done);
--+		INIT_WORK(&p2p->afx_hdl.afx_work, brcmf_p2p_afx_handler);
--+		init_completion(&p2p->afx_hdl.act_frm_scan);
--+		init_completion(&p2p->wait_next_af);
--+	}
--+exit:
--+	return err;
--+}
--+
--+/**
--+ * brcmf_p2p_detach() - detach P2P.
--+ *
--+ * @p2p: P2P specific data.
--+ */
--+void brcmf_p2p_detach(struct brcmf_p2p_info *p2p)
--+{
--+	struct brcmf_cfg80211_vif *vif;
--+
--+	vif = p2p->bss_idx[P2PAPI_BSSCFG_DEVICE].vif;
--+	if (vif != NULL) {
--+		brcmf_p2p_cancel_remain_on_channel(vif->ifp);
--+		brcmf_p2p_deinit_discovery(p2p);
--+		/* remove discovery interface */
--+		brcmf_free_vif(vif);
--+		p2p->bss_idx[P2PAPI_BSSCFG_DEVICE].vif = NULL;
--+	}
--+	/* just set it all to zero */
--+	memset(p2p, 0, sizeof(*p2p));
--+}
--+
-diff --git a/package/kernel/mac80211/patches/389-0008-brcmfmac-assure-p2pdev-is-unregistered-upon-driver-u.patch b/package/kernel/mac80211/patches/389-0008-brcmfmac-assure-p2pdev-is-unregistered-upon-driver-u.patch
-deleted file mode 100644
-index 72e8eed..0000000
---- a/package/kernel/mac80211/patches/389-0008-brcmfmac-assure-p2pdev-is-unregistered-upon-driver-u.patch
-+++ /dev/null
-@@ -1,63 +0,0 @@
--From: Arend van Spriel <arend@broadcom.com>
--Date: Thu, 11 Jun 2015 00:12:23 +0200
--Subject: [PATCH] brcmfmac: assure p2pdev is unregistered upon driver
-- unload
--
--When unloading the driver with a p2pdev interface it resulted in
--a warning upon calling wiphy_unregister() and subsequently a crash
--in the driver. This patch assures the p2pdev is unregistered calling
--unregister_wdev() before doing the wiphy_unregister().
--
--Reviewed-by: Hante Meuleman <meuleman@broadcom.com>
--Reviewed-by: Franky (Zhenhui) Lin <frankyl@broadcom.com>
--Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
--Signed-off-by: Arend van Spriel <arend@broadcom.com>
--Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
-----
--
----- a/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c
--+++ b/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c
--@@ -6206,10 +6206,8 @@ void brcmf_cfg80211_detach(struct brcmf_
-- 	if (!cfg)
-- 		return;
-- 
---	WARN_ON(!list_empty(&cfg->vif_list));
---	wiphy_unregister(cfg->wiphy);
-- 	brcmf_btcoex_detach(cfg);
---	brcmf_p2p_detach(&cfg->p2p);
--+	wiphy_unregister(cfg->wiphy);
-- 	wl_deinit_priv(cfg);
-- 	brcmf_free_wiphy(cfg->wiphy);
-- }
----- a/drivers/net/wireless/brcm80211/brcmfmac/core.c
--+++ b/drivers/net/wireless/brcm80211/brcmfmac/core.c
--@@ -1098,6 +1098,7 @@ void brcmf_detach(struct device *dev)
-- 
-- 	/* stop firmware event handling */
-- 	brcmf_fweh_detach(drvr);
--+	brcmf_p2p_detach(&drvr->config->p2p);
-- 
-- 	brcmf_bus_change_state(bus_if, BRCMF_BUS_DOWN);
-- 
----- a/drivers/net/wireless/brcm80211/brcmfmac/p2p.c
--+++ b/drivers/net/wireless/brcm80211/brcmfmac/p2p.c
--@@ -16,6 +16,7 @@
-- #include <linux/slab.h>
-- #include <linux/netdevice.h>
-- #include <linux/etherdevice.h>
--+#include <linux/rtnetlink.h>
-- #include <net/cfg80211.h>
-- 
-- #include <brcmu_wifi.h>
--@@ -2418,8 +2419,9 @@ void brcmf_p2p_detach(struct brcmf_p2p_i
-- 		brcmf_p2p_cancel_remain_on_channel(vif->ifp);
-- 		brcmf_p2p_deinit_discovery(p2p);
-- 		/* remove discovery interface */
---		brcmf_free_vif(vif);
---		p2p->bss_idx[P2PAPI_BSSCFG_DEVICE].vif = NULL;
--+		rtnl_lock();
--+		brcmf_p2p_delete_p2pdev(p2p, vif);
--+		rtnl_unlock();
-- 	}
-- 	/* just set it all to zero */
-- 	memset(p2p, 0, sizeof(*p2p));
-diff --git a/package/kernel/mac80211/patches/390-0001-brcmfmac-fix-double-free-of-p2pdev-interface.patch b/package/kernel/mac80211/patches/390-0001-brcmfmac-fix-double-free-of-p2pdev-interface.patch
-deleted file mode 100644
-index 179c77e..0000000
---- a/package/kernel/mac80211/patches/390-0001-brcmfmac-fix-double-free-of-p2pdev-interface.patch
-+++ /dev/null
-@@ -1,27 +0,0 @@
--From: Arend van Spriel <arend@broadcom.com>
--Date: Mon, 15 Jun 2015 22:48:38 +0200
--Subject: [PATCH] brcmfmac: fix double free of p2pdev interface
--
--When freeing the driver ifp pointer it should also be removed from
--the driver interface list, which is what brcmf_remove_interface()
--does. Otherwise, the ifp pointer will be freed twice triggering
--a kernel oops.
--
--Fixes: f37d69a4babc ("brcmfmac: free ifp for non-netdev interface in p2p module")
--Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
--Reviewed-by: Hante Meuleman <meuleman@broadcom.com>
--Signed-off-by: Arend van Spriel <arend@broadcom.com>
--Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
-----
--
----- a/drivers/net/wireless/brcm80211/brcmfmac/p2p.c
--+++ b/drivers/net/wireless/brcm80211/brcmfmac/p2p.c
--@@ -2140,7 +2140,7 @@ static void brcmf_p2p_delete_p2pdev(stru
-- {
-- 	cfg80211_unregister_wdev(&vif->wdev);
-- 	p2p->bss_idx[P2PAPI_BSSCFG_DEVICE].vif = NULL;
---	kfree(vif->ifp);
--+	brcmf_remove_interface(vif->ifp->drvr, vif->ifp->bssidx);
-- 	brcmf_free_vif(vif);
-- }
-- 
-diff --git a/package/kernel/mac80211/patches/390-0002-brcmfmac-make-brcmf_p2p_detach-call-conditional.patch b/package/kernel/mac80211/patches/390-0002-brcmfmac-make-brcmf_p2p_detach-call-conditional.patch
-deleted file mode 100644
-index e4f88b5..0000000
---- a/package/kernel/mac80211/patches/390-0002-brcmfmac-make-brcmf_p2p_detach-call-conditional.patch
-+++ /dev/null
-@@ -1,29 +0,0 @@
--From: Arend van Spriel <arend@broadcom.com>
--Date: Mon, 15 Jun 2015 22:48:39 +0200
--Subject: [PATCH] brcmfmac: make brcmf_p2p_detach() call conditional
--
--During verification of error handling in brcmf_cfg80211_attach() a
--null pointer dereference occurred upon calling brcmf_p2p_detach()
--from brcmf_detach(). This should only be called when the
--brcmf_cfg80211_attach() has succeeded.
--
--Fixes: f7a40873d2fa ("brcmfmac: assure p2pdev is unregistered upon driver unload")
--Reviewed-by: Hante Meuleman <meuleman@broadcom.com>
--Reviewed-by: Franky (Zhenhui) Lin <frankyl@broadcom.com>
--Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
--Signed-off-by: Arend van Spriel <arend@broadcom.com>
--Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
-----
--
----- a/drivers/net/wireless/brcm80211/brcmfmac/core.c
--+++ b/drivers/net/wireless/brcm80211/brcmfmac/core.c
--@@ -1098,7 +1098,8 @@ void brcmf_detach(struct device *dev)
-- 
-- 	/* stop firmware event handling */
-- 	brcmf_fweh_detach(drvr);
---	brcmf_p2p_detach(&drvr->config->p2p);
--+	if (drvr->config)
--+		brcmf_p2p_detach(&drvr->config->p2p);
-- 
-- 	brcmf_bus_change_state(bus_if, BRCMF_BUS_DOWN);
-- 
-diff --git a/package/kernel/mac80211/patches/391-brcmfmac-set-wiphy-s-addresses-to-provide-valid-MACs.patch b/package/kernel/mac80211/patches/391-brcmfmac-set-wiphy-s-addresses-to-provide-valid-MACs.patch
-deleted file mode 100644
-index 0a81237..0000000
---- a/package/kernel/mac80211/patches/391-brcmfmac-set-wiphy-s-addresses-to-provide-valid-MACs.patch
-+++ /dev/null
-@@ -1,67 +0,0 @@
--From: Rafa? Mi?ecki <zajec5@gmail.com>
--Date: Thu, 9 Jul 2015 17:07:08 +0200
--Subject: [PATCH] brcmfmac: set wiphy's addresses to provide valid MACs
--
--Broadcom's firmware requires every BSS to use MAC address with unique
--last few bits. The amount of bits may depend on a particular firmware,
--it was verified to be 2 for BCM43602 one.
--If this condition won't be fulfilled firmware will reject such MAC:
--brcmfmac: _brcmf_set_mac_address: Setting cur_etheraddr failed, -52
--
--We don't want to simply set addr_mask as it would also disallow using
--locally administrated bit. Instead let's build a list of addresses
--manually enabling 0x2 bit for extra interfaces.
--
--Signed-off-by: Rafa? Mi?ecki <zajec5@gmail.com>
--Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
-----
--
----- a/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c
--+++ b/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c
--@@ -5784,6 +5784,7 @@ static void brcmf_wiphy_wowl_params(stru
-- 
-- static int brcmf_setup_wiphy(struct wiphy *wiphy, struct brcmf_if *ifp)
-- {
--+	struct brcmf_pub *drvr = ifp->drvr;
-- 	struct ieee80211_supported_band *band;
-- 	__le32 bandlist[3];
-- 	u32 n_bands;
--@@ -5797,6 +5798,19 @@ static int brcmf_setup_wiphy(struct wiph
-- 	if (err)
-- 		return err;
-- 
--+	for (i = 0; i < wiphy->iface_combinations->max_interfaces &&
--+	     i < ARRAY_SIZE(drvr->addresses); i++) {
--+		u8 *addr = drvr->addresses[i].addr;
--+
--+		memcpy(addr, drvr->mac, ETH_ALEN);
--+		if (i) {
--+			addr[0] |= BIT(1);
--+			addr[ETH_ALEN - 1] ^= i;
--+		}
--+	}
--+	wiphy->addresses = drvr->addresses;
--+	wiphy->n_addresses = i;
--+
-- 	wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
-- 	wiphy->cipher_suites = __wl_cipher_suites;
-- 	wiphy->n_cipher_suites = ARRAY_SIZE(__wl_cipher_suites);
----- a/drivers/net/wireless/brcm80211/brcmfmac/core.h
--+++ b/drivers/net/wireless/brcm80211/brcmfmac/core.h
--@@ -21,6 +21,7 @@
-- #ifndef BRCMFMAC_CORE_H
-- #define BRCMFMAC_CORE_H
-- 
--+#include <net/cfg80211.h>
-- #include "fweh.h"
-- 
-- #define TOE_TX_CSUM_OL		0x00000001
--@@ -118,6 +119,8 @@ struct brcmf_pub {
-- 	/* Multicast data packets sent to dongle */
-- 	unsigned long tx_multicast;
-- 
--+	struct mac_address addresses[BRCMF_MAX_IFS];
--+
-- 	struct brcmf_if *iflist[BRCMF_MAX_IFS];
-- 
-- 	struct mutex proto_block;
-diff --git a/package/kernel/mac80211/patches/392-brcmfmac-dhd_sdio.c-use-existing-atomic_or-primitive.patch b/package/kernel/mac80211/patches/392-brcmfmac-dhd_sdio.c-use-existing-atomic_or-primitive.patch
-deleted file mode 100644
-index e44f121..0000000
---- a/package/kernel/mac80211/patches/392-brcmfmac-dhd_sdio.c-use-existing-atomic_or-primitive.patch
-+++ /dev/null
-@@ -1,45 +0,0 @@
--From: Vineet Gupta <Vineet.Gupta1@synopsys.com>
--Date: Thu, 9 Jul 2015 13:43:18 +0530
--Subject: [PATCH] brcmfmac: dhd_sdio.c: use existing atomic_or primitive
--
--There's already a generic implementation so use that instead.
--
--Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
-----
--
----- a/drivers/net/wireless/brcm80211/brcmfmac/sdio.c
--+++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio.c
--@@ -2564,15 +2564,6 @@ static inline void brcmf_sdio_clrintr(st
-- 	}
-- }
-- 
---static void atomic_orr(int val, atomic_t *v)
---{
---	int old_val;
---
---	old_val = atomic_read(v);
---	while (atomic_cmpxchg(v, old_val, val | old_val) != old_val)
---		old_val = atomic_read(v);
---}
---
-- static int brcmf_sdio_intr_rstatus(struct brcmf_sdio *bus)
-- {
-- 	struct brcmf_core *buscore;
--@@ -2595,7 +2586,7 @@ static int brcmf_sdio_intr_rstatus(struc
-- 	if (val) {
-- 		brcmf_sdiod_regwl(bus->sdiodev, addr, val, &ret);
-- 		bus->sdcnt.f1regdata++;
---		atomic_orr(val, &bus->intstatus);
--+		atomic_or(val, &bus->intstatus);
-- 	}
-- 
-- 	return ret;
--@@ -2712,7 +2703,7 @@ static void brcmf_sdio_dpc(struct brcmf_
-- 
-- 	/* Keep still-pending events for next scheduling */
-- 	if (intstatus)
---		atomic_orr(intstatus, &bus->intstatus);
--+		atomic_or(intstatus, &bus->intstatus);
-- 
-- 	brcmf_sdio_clrintr(bus);
-- 
-diff --git a/package/kernel/mac80211/patches/393-0001-brcmfmac-check-all-combinations-when-setting-wiphy-s.patch b/package/kernel/mac80211/patches/393-0001-brcmfmac-check-all-combinations-when-setting-wiphy-s.patch
-deleted file mode 100644
-index 76ca143..0000000
---- a/package/kernel/mac80211/patches/393-0001-brcmfmac-check-all-combinations-when-setting-wiphy-s.patch
-+++ /dev/null
-@@ -1,46 +0,0 @@
--From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <zajec5@gmail.com>
--Date: Thu, 20 Aug 2015 00:16:42 +0200
--Subject: [PATCH] brcmfmac: check all combinations when setting wiphy's
-- addresses
--MIME-Version: 1.0
--Content-Type: text/plain; charset=UTF-8
--Content-Transfer-Encoding: 8bit
--
--Broadcom is working on better reflection of interface combinations. With
--upcoming patches we may have 1st combination supporting less interfaces
--than others.
--To don't run out of addresses check all combinations to find the one
--with the greatest max_interfaces value.
--
--Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
--Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
-----
--
----- a/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c
--+++ b/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c
--@@ -5785,7 +5785,9 @@ static void brcmf_wiphy_wowl_params(stru
-- static int brcmf_setup_wiphy(struct wiphy *wiphy, struct brcmf_if *ifp)
-- {
-- 	struct brcmf_pub *drvr = ifp->drvr;
--+	const struct ieee80211_iface_combination *combo;
-- 	struct ieee80211_supported_band *band;
--+	u16 max_interfaces = 0;
-- 	__le32 bandlist[3];
-- 	u32 n_bands;
-- 	int err, i;
--@@ -5798,8 +5800,13 @@ static int brcmf_setup_wiphy(struct wiph
-- 	if (err)
-- 		return err;
-- 
---	for (i = 0; i < wiphy->iface_combinations->max_interfaces &&
---	     i < ARRAY_SIZE(drvr->addresses); i++) {
--+	for (i = 0, combo = wiphy->iface_combinations;
--+	     i < wiphy->n_iface_combinations; i++, combo++) {
--+		max_interfaces = max(max_interfaces, combo->max_interfaces);
--+	}
--+
--+	for (i = 0; i < max_interfaces && i < ARRAY_SIZE(drvr->addresses);
--+	     i++) {
-- 		u8 *addr = drvr->addresses[i].addr;
-- 
-- 		memcpy(addr, drvr->mac, ETH_ALEN);
-diff --git a/package/kernel/mac80211/patches/393-0002-brcmfmac-correct-interface-combination-info.patch b/package/kernel/mac80211/patches/393-0002-brcmfmac-correct-interface-combination-info.patch
-deleted file mode 100644
-index c4a0720..0000000
---- a/package/kernel/mac80211/patches/393-0002-brcmfmac-correct-interface-combination-info.patch
-+++ /dev/null
-@@ -1,204 +0,0 @@
--From: Arend van Spriel <arend@broadcom.com>
--Date: Thu, 20 Aug 2015 22:06:03 +0200
--Subject: [PATCH] brcmfmac: correct interface combination info
--
--The interface combination provided by brcmfmac did not truly reflect
--the combinations supported by driver and/or firmware.
--
--Reviewed-by: Hante Meuleman <meuleman@broadcom.com>
--Reviewed-by: Franky (Zhenhui) Lin <frankyl@broadcom.com>
--Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
--Reviewed-by: Pontus Fuchs <pontusf@broadcom.com>
--Signed-off-by: Arend van Spriel <arend@broadcom.com>
--Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
-----
--
----- a/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c
--+++ b/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c
--@@ -5694,63 +5694,132 @@ brcmf_txrx_stypes[NUM_NL80211_IFTYPES] =
-- 	}
-- };
-- 
--+/**
--+ * brcmf_setup_ifmodes() - determine interface modes and combinations.
--+ *
--+ * @wiphy: wiphy object.
--+ * @ifp: interface object needed for feat module api.
--+ *
--+ * The interface modes and combinations are determined dynamically here
--+ * based on firmware functionality.
--+ *
--+ * no p2p and no mbss:
--+ *
--+ *	#STA <= 1, #AP <= 1, channels = 1, 2 total
--+ *
--+ * no p2p and mbss:
--+ *
--+ *	#STA <= 1, #AP <= 1, channels = 1, 2 total
--+ *	#AP <= 4, matching BI, channels = 1, 4 total
--+ *
--+ * p2p, no mchan, and mbss:
--+ *
--+ *	#STA <= 1, #P2P-DEV <= 1, #{P2P-CL, P2P-GO} <= 1, channels = 1, 3 total
--+ *	#STA <= 1, #P2P-DEV <= 1, #AP <= 1, #P2P-CL <= 1, channels = 1, 4 total
--+ *	#AP <= 4, matching BI, channels = 1, 4 total
--+ *
--+ * p2p, mchan, and mbss:
--+ *
--+ *	#STA <= 1, #P2P-DEV <= 1, #{P2P-CL, P2P-GO} <= 1, channels = 2, 3 total
--+ *	#STA <= 1, #P2P-DEV <= 1, #AP <= 1, #P2P-CL <= 1, channels = 1, 4 total
--+ *	#AP <= 4, matching BI, channels = 1, 4 total
--+ */
-- static int brcmf_setup_ifmodes(struct wiphy *wiphy, struct brcmf_if *ifp)
-- {
-- 	struct ieee80211_iface_combination *combo = NULL;
---	struct ieee80211_iface_limit *limits = NULL;
---	int i = 0, max_iface_cnt;
--+	struct ieee80211_iface_limit *c0_limits = NULL;
--+	struct ieee80211_iface_limit *p2p_limits = NULL;
--+	struct ieee80211_iface_limit *mbss_limits = NULL;
--+	bool mbss, p2p;
--+	int i, c, n_combos;
-- 
---	combo = kzalloc(sizeof(*combo), GFP_KERNEL);
--+	mbss = brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MBSS);
--+	p2p = brcmf_feat_is_enabled(ifp, BRCMF_FEAT_P2P);
--+
--+	n_combos = 1 + !!p2p + !!mbss;
--+	combo = kcalloc(n_combos, sizeof(*combo), GFP_KERNEL);
-- 	if (!combo)
-- 		goto err;
-- 
---	limits = kzalloc(sizeof(*limits) * 4, GFP_KERNEL);
---	if (!limits)
--+	c0_limits = kcalloc(p2p ? 3 : 2, sizeof(*c0_limits), GFP_KERNEL);
--+	if (!c0_limits)
-- 		goto err;
-- 
--+	if (p2p) {
--+		p2p_limits = kcalloc(4, sizeof(*p2p_limits), GFP_KERNEL);
--+		if (!p2p_limits)
--+			goto err;
--+	}
--+
--+	if (mbss) {
--+		mbss_limits = kcalloc(1, sizeof(*mbss_limits), GFP_KERNEL);
--+		if (!mbss_limits)
--+			goto err;
--+	}
--+
-- 	wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
-- 				 BIT(NL80211_IFTYPE_ADHOC) |
-- 				 BIT(NL80211_IFTYPE_AP);
-- 
---	if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MCHAN))
---		combo->num_different_channels = 2;
---	else
---		combo->num_different_channels = 1;
---
---	if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MBSS)) {
---		limits[i].max = 1;
---		limits[i++].types = BIT(NL80211_IFTYPE_STATION);
---		limits[i].max = 4;
---		limits[i++].types = BIT(NL80211_IFTYPE_AP);
---		max_iface_cnt = 5;
---	} else {
---		limits[i].max = 2;
---		limits[i++].types = BIT(NL80211_IFTYPE_STATION) |
---				    BIT(NL80211_IFTYPE_AP);
---		max_iface_cnt = 2;
---	}
---
---	if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_P2P)) {
--+	c = 0;
--+	i = 0;
--+	combo[c].num_different_channels = 1;
--+	c0_limits[i].max = 1;
--+	c0_limits[i++].types = BIT(NL80211_IFTYPE_STATION);
--+	if (p2p) {
--+		if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MCHAN))
--+			combo[c].num_different_channels = 2;
-- 		wiphy->interface_modes |= BIT(NL80211_IFTYPE_P2P_CLIENT) |
-- 					  BIT(NL80211_IFTYPE_P2P_GO) |
-- 					  BIT(NL80211_IFTYPE_P2P_DEVICE);
---		limits[i].max = 1;
---		limits[i++].types = BIT(NL80211_IFTYPE_P2P_CLIENT) |
---				    BIT(NL80211_IFTYPE_P2P_GO);
---		limits[i].max = 1;
---		limits[i++].types = BIT(NL80211_IFTYPE_P2P_DEVICE);
---		max_iface_cnt += 2;
---	}
---	combo->max_interfaces = max_iface_cnt;
---	combo->limits = limits;
---	combo->n_limits = i;
--+		c0_limits[i].max = 1;
--+		c0_limits[i++].types = BIT(NL80211_IFTYPE_P2P_DEVICE);
--+		c0_limits[i].max = 1;
--+		c0_limits[i++].types = BIT(NL80211_IFTYPE_P2P_CLIENT) |
--+				       BIT(NL80211_IFTYPE_P2P_GO);
--+	} else {
--+		c0_limits[i].max = 1;
--+		c0_limits[i++].types = BIT(NL80211_IFTYPE_AP);
--+	}
--+	combo[c].max_interfaces = i;
--+	combo[c].n_limits = i;
--+	combo[c].limits = c0_limits;
--+
--+	if (p2p) {
--+		c++;
--+		i = 0;
--+		combo[c].num_different_channels = 1;
--+		p2p_limits[i].max = 1;
--+		p2p_limits[i++].types = BIT(NL80211_IFTYPE_STATION);
--+		p2p_limits[i].max = 1;
--+		p2p_limits[i++].types = BIT(NL80211_IFTYPE_AP);
--+		p2p_limits[i].max = 1;
--+		p2p_limits[i++].types = BIT(NL80211_IFTYPE_P2P_CLIENT);
--+		p2p_limits[i].max = 1;
--+		p2p_limits[i++].types = BIT(NL80211_IFTYPE_P2P_DEVICE);
--+		combo[c].max_interfaces = i;
--+		combo[c].n_limits = i;
--+		combo[c].limits = p2p_limits;
--+	}
-- 
--+	if (mbss) {
--+		c++;
--+		combo[c].beacon_int_infra_match = true;
--+		combo[c].num_different_channels = 1;
--+		mbss_limits[0].max = 4;
--+		mbss_limits[0].types = BIT(NL80211_IFTYPE_AP);
--+		combo[c].max_interfaces = 4;
--+		combo[c].n_limits = 1;
--+		combo[c].limits = mbss_limits;
--+	}
--+	wiphy->n_iface_combinations = n_combos;
-- 	wiphy->iface_combinations = combo;
---	wiphy->n_iface_combinations = 1;
-- 	return 0;
-- 
-- err:
---	kfree(limits);
--+	kfree(c0_limits);
--+	kfree(p2p_limits);
--+	kfree(mbss_limits);
-- 	kfree(combo);
-- 	return -ENOMEM;
-- }
--@@ -6079,11 +6148,15 @@ static void brcmf_cfg80211_reg_notifier(
-- 
-- static void brcmf_free_wiphy(struct wiphy *wiphy)
-- {
--+	int i;
--+
-- 	if (!wiphy)
-- 		return;
-- 
---	if (wiphy->iface_combinations)
---		kfree(wiphy->iface_combinations->limits);
--+	if (wiphy->iface_combinations) {
--+		for (i = 0; i < wiphy->n_iface_combinations; i++)
--+			kfree(wiphy->iface_combinations[i].limits);
--+	}
-- 	kfree(wiphy->iface_combinations);
-- 	if (wiphy->bands[IEEE80211_BAND_2GHZ]) {
-- 		kfree(wiphy->bands[IEEE80211_BAND_2GHZ]->channels);
-diff --git a/package/kernel/mac80211/patches/393-0003-brcmfmac-add-debugfs-entry-for-msgbuf-statistics.patch b/package/kernel/mac80211/patches/393-0003-brcmfmac-add-debugfs-entry-for-msgbuf-statistics.patch
-deleted file mode 100644
-index 9768ef2..0000000
---- a/package/kernel/mac80211/patches/393-0003-brcmfmac-add-debugfs-entry-for-msgbuf-statistics.patch
-+++ /dev/null
-@@ -1,87 +0,0 @@
--From: Franky Lin <frankyl@broadcom.com>
--Date: Thu, 20 Aug 2015 22:06:04 +0200
--Subject: [PATCH] brcmfmac: add debugfs entry for msgbuf statistics
--
--Expose ring buffer read/write pointers and other useful statistics
--through debugfs.
--
--Reviewed-by: Arend Van Spriel <arend@broadcom.com>
--Reviewed-by: Hante Meuleman <meuleman@broadcom.com>
--Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
--Signed-off-by: Franky Lin <frankyl@broadcom.com>
--Signed-off-by: Arend van Spriel <arend@broadcom.com>
--Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
-----
--
----- a/drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c
--+++ b/drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c
--@@ -1360,6 +1360,60 @@ void brcmf_msgbuf_delete_flowring(struct
-- 	}
-- }
-- 
--+#ifdef DEBUG
--+static int brcmf_msgbuf_stats_read(struct seq_file *seq, void *data)
--+{
--+	struct brcmf_bus *bus_if = dev_get_drvdata(seq->private);
--+	struct brcmf_pub *drvr = bus_if->drvr;
--+	struct brcmf_msgbuf *msgbuf = (struct brcmf_msgbuf *)drvr->proto->pd;
--+	struct brcmf_commonring *commonring;
--+	u16 i;
--+	struct brcmf_flowring_ring *ring;
--+	struct brcmf_flowring_hash *hash;
--+
--+	commonring = msgbuf->commonrings[BRCMF_H2D_MSGRING_CONTROL_SUBMIT];
--+	seq_printf(seq, "h2d_ctl_submit: rp %4u, wp %4u, depth %4u\n",
--+		   commonring->r_ptr, commonring->w_ptr, commonring->depth);
--+	commonring = msgbuf->commonrings[BRCMF_H2D_MSGRING_RXPOST_SUBMIT];
--+	seq_printf(seq, "h2d_rx_submit:  rp %4u, wp %4u, depth %4u\n",
--+		   commonring->r_ptr, commonring->w_ptr, commonring->depth);
--+	commonring = msgbuf->commonrings[BRCMF_D2H_MSGRING_CONTROL_COMPLETE];
--+	seq_printf(seq, "d2h_ctl_cmplt:  rp %4u, wp %4u, depth %4u\n",
--+		   commonring->r_ptr, commonring->w_ptr, commonring->depth);
--+	commonring = msgbuf->commonrings[BRCMF_D2H_MSGRING_TX_COMPLETE];
--+	seq_printf(seq, "d2h_tx_cmplt:   rp %4u, wp %4u, depth %4u\n",
--+		   commonring->r_ptr, commonring->w_ptr, commonring->depth);
--+	commonring = msgbuf->commonrings[BRCMF_D2H_MSGRING_RX_COMPLETE];
--+	seq_printf(seq, "d2h_rx_cmplt:   rp %4u, wp %4u, depth %4u\n",
--+		   commonring->r_ptr, commonring->w_ptr, commonring->depth);
--+
--+	seq_printf(seq, "\nh2d_flowrings: depth %u\n",
--+		   BRCMF_H2D_TXFLOWRING_MAX_ITEM);
--+	seq_puts(seq, "Active flowrings:\n");
--+	hash = msgbuf->flow->hash;
--+	for (i = 0; i < msgbuf->flow->nrofrings; i++) {
--+		if (!msgbuf->flow->rings[i])
--+			continue;
--+		ring = msgbuf->flow->rings[i];
--+		if (ring->status != RING_OPEN)
--+			continue;
--+		commonring = msgbuf->flowrings[i];
--+		hash = &msgbuf->flow->hash[ring->hash_id];
--+		seq_printf(seq, "id %3u: rp %4u, wp %4u, qlen %4u, blocked %u\n"
--+				"        ifidx %u, fifo %u, da %pM\n",
--+				i, commonring->r_ptr, commonring->w_ptr,
--+				skb_queue_len(&ring->skblist), ring->blocked,
--+				hash->ifidx, hash->fifo, hash->mac);
--+	}
--+
--+	return 0;
--+}
--+#else
--+static int brcmf_msgbuf_stats_read(struct seq_file *seq, void *data)
--+{
--+	return 0;
--+}
--+#endif
-- 
-- int brcmf_proto_msgbuf_attach(struct brcmf_pub *drvr)
-- {
--@@ -1460,6 +1514,8 @@ int brcmf_proto_msgbuf_attach(struct brc
-- 	spin_lock_init(&msgbuf->flowring_work_lock);
-- 	INIT_LIST_HEAD(&msgbuf->work_queue);
-- 
--+	brcmf_debugfs_add_entry(drvr, "msgbuf_stats", brcmf_msgbuf_stats_read);
--+
-- 	return 0;
-- 
-- fail:
-diff --git a/package/kernel/mac80211/patches/393-0004-brcmfmac-make-use-of-cfg80211_check_combinations.patch b/package/kernel/mac80211/patches/393-0004-brcmfmac-make-use-of-cfg80211_check_combinations.patch
-deleted file mode 100644
-index 2b84cf9..0000000
---- a/package/kernel/mac80211/patches/393-0004-brcmfmac-make-use-of-cfg80211_check_combinations.patch
-+++ /dev/null
-@@ -1,83 +0,0 @@
--From: Arend van Spriel <arend@broadcom.com>
--Date: Thu, 20 Aug 2015 22:06:05 +0200
--Subject: [PATCH] brcmfmac: make use of cfg80211_check_combinations()
--
--Use cfg80211_check_combinations() so we can bail out early when an
--interface add or change results in an invalid combination.
--
--Reviewed-by: Hante Meuleman <meuleman@broadcom.com>
--Reviewed-by: Franky (Zhenhui) Lin <frankyl@broadcom.com>
--Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
--Signed-off-by: Arend van Spriel <arend@broadcom.com>
--Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
-----
--
----- a/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c
--+++ b/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c
--@@ -469,6 +469,36 @@ brcmf_find_wpsie(const u8 *parse, u32 le
-- 	return NULL;
-- }
-- 
--+static int brcmf_vif_change_validate(struct brcmf_cfg80211_info *cfg,
--+				     struct brcmf_cfg80211_vif *vif,
--+				     enum nl80211_iftype new_type)
--+{
--+	int iftype_num[NUM_NL80211_IFTYPES];
--+	struct brcmf_cfg80211_vif *pos;
--+
--+	memset(&iftype_num[0], 0, sizeof(iftype_num));
--+	list_for_each_entry(pos, &cfg->vif_list, list)
--+		if (pos == vif)
--+			iftype_num[new_type]++;
--+		else
--+			iftype_num[pos->wdev.iftype]++;
--+
--+	return cfg80211_check_combinations(cfg->wiphy, 1, 0, iftype_num);
--+}
--+
--+static int brcmf_vif_add_validate(struct brcmf_cfg80211_info *cfg,
--+				  enum nl80211_iftype new_type)
--+{
--+	int iftype_num[NUM_NL80211_IFTYPES];
--+	struct brcmf_cfg80211_vif *pos;
--+
--+	memset(&iftype_num[0], 0, sizeof(iftype_num));
--+	list_for_each_entry(pos, &cfg->vif_list, list)
--+		iftype_num[pos->wdev.iftype]++;
--+
--+	iftype_num[new_type]++;
--+	return cfg80211_check_combinations(cfg->wiphy, 1, 0, iftype_num);
--+}
-- 
-- static void convert_key_from_CPU(struct brcmf_wsec_key *key,
-- 				 struct brcmf_wsec_key_le *key_le)
--@@ -662,8 +692,14 @@ static struct wireless_dev *brcmf_cfg802
-- 						     struct vif_params *params)
-- {
-- 	struct wireless_dev *wdev;
--+	int err;
-- 
-- 	brcmf_dbg(TRACE, "enter: %s type %d\n", name, type);
--+	err = brcmf_vif_add_validate(wiphy_to_cfg(wiphy), type);
--+	if (err) {
--+		brcmf_err("iface validation failed: err=%d\n", err);
--+		return ERR_PTR(err);
--+	}
-- 	switch (type) {
-- 	case NL80211_IFTYPE_ADHOC:
-- 	case NL80211_IFTYPE_STATION:
--@@ -822,8 +858,12 @@ brcmf_cfg80211_change_iface(struct wiphy
-- 	s32 ap = 0;
-- 	s32 err = 0;
-- 
---	brcmf_dbg(TRACE, "Enter, ndev=%p, type=%d\n", ndev, type);
---
--+	brcmf_dbg(TRACE, "Enter, idx=%d, type=%d\n", ifp->bssidx, type);
--+	err = brcmf_vif_change_validate(wiphy_to_cfg(wiphy), vif, type);
--+	if (err) {
--+		brcmf_err("iface validation failed: err=%d\n", err);
--+		return err;
--+	}
-- 	switch (type) {
-- 	case NL80211_IFTYPE_MONITOR:
-- 	case NL80211_IFTYPE_WDS:
-diff --git a/package/kernel/mac80211/patches/393-0005-brcmfmac-block-the-correct-flowring-when-backup-queu.patch b/package/kernel/mac80211/patches/393-0005-brcmfmac-block-the-correct-flowring-when-backup-queu.patch
-deleted file mode 100644
-index 2d5f7b9..0000000
---- a/package/kernel/mac80211/patches/393-0005-brcmfmac-block-the-correct-flowring-when-backup-queu.patch
-+++ /dev/null
-@@ -1,48 +0,0 @@
--From: Franky Lin <frankyl@broadcom.com>
--Date: Thu, 20 Aug 2015 22:06:06 +0200
--Subject: [PATCH] brcmfmac: block the correct flowring when backup queue
-- overflow
--
--brcmf_flowring_block blocks the last active flowring under the same
--interface instead of the one provided by caller. This could lead to a
--dead lock of netif stop if there are more than one flowring under the
--interface and the traffic is high enough so brcmf_flowring_enqueue can
--not unblock the ring right away.
--
--Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
--Reviewed-by: Hante Meuleman <meuleman@broadcom.com>
--Signed-off-by: Franky Lin <frankyl@broadcom.com>
--Signed-off-by: Arend van Spriel <arend@broadcom.com>
--Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
-----
--
----- a/drivers/net/wireless/brcm80211/brcmfmac/flowring.c
--+++ b/drivers/net/wireless/brcm80211/brcmfmac/flowring.c
--@@ -194,11 +194,15 @@ static void brcmf_flowring_block(struct
-- 	spin_lock_irqsave(&flow->block_lock, flags);
-- 
-- 	ring = flow->rings[flowid];
--+	if (ring->blocked == blocked) {
--+		spin_unlock_irqrestore(&flow->block_lock, flags);
--+		return;
--+	}
-- 	ifidx = brcmf_flowring_ifidx_get(flow, flowid);
-- 
-- 	currently_blocked = false;
-- 	for (i = 0; i < flow->nrofrings; i++) {
---		if (flow->rings[i]) {
--+		if ((flow->rings[i]) && (i != flowid)) {
-- 			ring = flow->rings[i];
-- 			if ((ring->status == RING_OPEN) &&
-- 			    (brcmf_flowring_ifidx_get(flow, i) == ifidx)) {
--@@ -209,8 +213,8 @@ static void brcmf_flowring_block(struct
-- 			}
-- 		}
-- 	}
---	ring->blocked = blocked;
---	if (currently_blocked == blocked) {
--+	flow->rings[flowid]->blocked = blocked;
--+	if (currently_blocked) {
-- 		spin_unlock_irqrestore(&flow->block_lock, flags);
-- 		return;
-- 	}
-diff --git a/package/kernel/mac80211/patches/393-0006-brcmfmac-bump-highest-event-number-for-4339-firmware.patch b/package/kernel/mac80211/patches/393-0006-brcmfmac-bump-highest-event-number-for-4339-firmware.patch
-deleted file mode 100644
-index 7378401..0000000
---- a/package/kernel/mac80211/patches/393-0006-brcmfmac-bump-highest-event-number-for-4339-firmware.patch
-+++ /dev/null
-@@ -1,52 +0,0 @@
--From: Arend van Spriel <arend@broadcom.com>
--Date: Thu, 20 Aug 2015 22:06:07 +0200
--Subject: [PATCH] brcmfmac: bump highest event number for 4339 firmware
--
--The event mask length is determined by the highest event number
--that is specified in the driver. When this length is shorter than
--firmware expects setting event mask will fail and device becomes
--pretty useless. This issue was reported with bcm4339 firmware that
--was recently released.
--
--Reported-by: Pontus Fuchs <pontusf@broadcom.com>
--Reviewed-by: Hante Meuleman <meuleman@broadcom.com>
--Reviewed-by: Franky (Zhenhui) Lin <frankyl@broadcom.com>
--Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
--Reviewed-by: Pontus Fuchs <pontusf@broadcom.com>
--Signed-off-by: Arend van Spriel <arend@broadcom.com>
--Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
-----
--
----- a/drivers/net/wireless/brcm80211/brcmfmac/fweh.h
--+++ b/drivers/net/wireless/brcm80211/brcmfmac/fweh.h
--@@ -85,7 +85,6 @@ struct brcmf_event;
-- 	BRCMF_ENUM_DEF(IF, 54) \
-- 	BRCMF_ENUM_DEF(P2P_DISC_LISTEN_COMPLETE, 55) \
-- 	BRCMF_ENUM_DEF(RSSI, 56) \
---	BRCMF_ENUM_DEF(PFN_SCAN_COMPLETE, 57) \
-- 	BRCMF_ENUM_DEF(EXTLOG_MSG, 58) \
-- 	BRCMF_ENUM_DEF(ACTION_FRAME, 59) \
-- 	BRCMF_ENUM_DEF(ACTION_FRAME_COMPLETE, 60) \
--@@ -103,8 +102,7 @@ struct brcmf_event;
-- 	BRCMF_ENUM_DEF(FIFO_CREDIT_MAP, 74) \
-- 	BRCMF_ENUM_DEF(ACTION_FRAME_RX, 75) \
-- 	BRCMF_ENUM_DEF(TDLS_PEER_EVENT, 92) \
---	BRCMF_ENUM_DEF(BCMC_CREDIT_SUPPORT, 127) \
---	BRCMF_ENUM_DEF(PSTA_PRIMARY_INTF_IND, 128)
--+	BRCMF_ENUM_DEF(BCMC_CREDIT_SUPPORT, 127)
-- 
-- #define BRCMF_ENUM_DEF(id, val) \
-- 	BRCMF_E_##id = (val),
--@@ -112,7 +110,11 @@ struct brcmf_event;
-- /* firmware event codes sent by the dongle */
-- enum brcmf_fweh_event_code {
-- 	BRCMF_FWEH_EVENT_ENUM_DEFLIST
---	BRCMF_E_LAST
--+	/* this determines event mask length which must match
--+	 * minimum length check in device firmware so it is
--+	 * hard-coded here.
--+	 */
--+	BRCMF_E_LAST = 139
-- };
-- #undef BRCMF_ENUM_DEF
-- 
-diff --git a/package/kernel/mac80211/patches/394-0001-brcmfmac-consolidate-ifp-lookup-in-driver-core.patch b/package/kernel/mac80211/patches/394-0001-brcmfmac-consolidate-ifp-lookup-in-driver-core.patch
-deleted file mode 100644
-index 97444b3..0000000
---- a/package/kernel/mac80211/patches/394-0001-brcmfmac-consolidate-ifp-lookup-in-driver-core.patch
-+++ /dev/null
-@@ -1,138 +0,0 @@
--From: Arend van Spriel <arend@broadcom.com>
--Date: Wed, 26 Aug 2015 22:14:53 +0200
--Subject: [PATCH] brcmfmac: consolidate ifp lookup in driver core
--
--In rx path the firmware provide an interface index which is used to
--map to a struct brcmf_if instance. However, this involves some trick
--that is done in two places. This is changed by having driver core
--providing brcmf_get_ifp() function.
--
--Reviewed-by: Hante Meuleman <meuleman@broadcom.com>
--Reviewed-by: Franky (Zhenhui) Lin <frankyl@broadcom.com>
--Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
--Signed-off-by: Arend van Spriel <arend@broadcom.com>
-----
--
----- a/drivers/net/wireless/brcm80211/brcmfmac/bcdc.c
--+++ b/drivers/net/wireless/brcm80211/brcmfmac/bcdc.c
--@@ -276,6 +276,7 @@ brcmf_proto_bcdc_hdrpull(struct brcmf_pu
-- 			 struct sk_buff *pktbuf)
-- {
-- 	struct brcmf_proto_bcdc_header *h;
--+	struct brcmf_if *ifp;
-- 
-- 	brcmf_dbg(BCDC, "Enter\n");
-- 
--@@ -289,30 +290,21 @@ brcmf_proto_bcdc_hdrpull(struct brcmf_pu
-- 	trace_brcmf_bcdchdr(pktbuf->data);
-- 	h = (struct brcmf_proto_bcdc_header *)(pktbuf->data);
-- 
---	*ifidx = BCDC_GET_IF_IDX(h);
---	if (*ifidx >= BRCMF_MAX_IFS) {
---		brcmf_err("rx data ifnum out of range (%d)\n", *ifidx);
--+	ifp = brcmf_get_ifp(drvr, BCDC_GET_IF_IDX(h));
--+	if (IS_ERR_OR_NULL(ifp)) {
--+		brcmf_dbg(INFO, "no matching ifp found\n");
-- 		return -EBADE;
-- 	}
---	/* The ifidx is the idx to map to matching netdev/ifp. When receiving
---	 * events this is easy because it contains the bssidx which maps
---	 * 1-on-1 to the netdev/ifp. But for data frames the ifidx is rcvd.
---	 * bssidx 1 is used for p2p0 and no data can be received or
---	 * transmitted on it. Therefor bssidx is ifidx + 1 if ifidx > 0
---	 */
---	if (*ifidx)
---		(*ifidx)++;
---
-- 	if (((h->flags & BCDC_FLAG_VER_MASK) >> BCDC_FLAG_VER_SHIFT) !=
-- 	    BCDC_PROTO_VER) {
-- 		brcmf_err("%s: non-BCDC packet received, flags 0x%x\n",
---			  brcmf_ifname(drvr, *ifidx), h->flags);
--+			  brcmf_ifname(drvr, ifp->ifidx), h->flags);
-- 		return -EBADE;
-- 	}
-- 
-- 	if (h->flags & BCDC_FLAG_SUM_GOOD) {
-- 		brcmf_dbg(BCDC, "%s: BDC rcv, good checksum, flags 0x%x\n",
---			  brcmf_ifname(drvr, *ifidx), h->flags);
--+			  brcmf_ifname(drvr, ifp->ifidx), h->flags);
-- 		pktbuf->ip_summed = CHECKSUM_UNNECESSARY;
-- 	}
-- 
--@@ -320,12 +312,15 @@ brcmf_proto_bcdc_hdrpull(struct brcmf_pu
-- 
-- 	skb_pull(pktbuf, BCDC_HEADER_LEN);
-- 	if (do_fws)
---		brcmf_fws_hdrpull(drvr, *ifidx, h->data_offset << 2, pktbuf);
--+		brcmf_fws_hdrpull(drvr, ifp->ifidx, h->data_offset << 2,
--+				  pktbuf);
-- 	else
-- 		skb_pull(pktbuf, h->data_offset << 2);
-- 
-- 	if (pktbuf->len == 0)
-- 		return -ENODATA;
--+
--+	*ifidx = ifp->ifidx;
-- 	return 0;
-- }
-- 
----- a/drivers/net/wireless/brcm80211/brcmfmac/core.c
--+++ b/drivers/net/wireless/brcm80211/brcmfmac/core.c
--@@ -83,6 +83,25 @@ char *brcmf_ifname(struct brcmf_pub *drv
-- 	return "<if_none>";
-- }
-- 
--+struct brcmf_if *brcmf_get_ifp(struct brcmf_pub *drvr, int ifidx)
--+{
--+	if (ifidx < 0 || ifidx >= BRCMF_MAX_IFS) {
--+		brcmf_err("ifidx %d out of range\n", ifidx);
--+		return ERR_PTR(-ERANGE);
--+	}
--+
--+	/* The ifidx is the idx to map to matching netdev/ifp. When receiving
--+	 * events this is easy because it contains the bssidx which maps
--+	 * 1-on-1 to the netdev/ifp. But for data frames the ifidx is rcvd.
--+	 * bssidx 1 is used for p2p0 and no data can be received or
--+	 * transmitted on it. Therefor bssidx is ifidx + 1 if ifidx > 0
--+	 */
--+	if (ifidx)
--+		ifidx++;
--+
--+	return drvr->iflist[ifidx];
--+}
--+
-- static void _brcmf_set_multicast_list(struct work_struct *work)
-- {
-- 	struct brcmf_if *ifp;
----- a/drivers/net/wireless/brcm80211/brcmfmac/core.h
--+++ b/drivers/net/wireless/brcm80211/brcmfmac/core.h
--@@ -202,7 +202,7 @@ int brcmf_netdev_wait_pend8021x(struct b
-- 
-- /* Return pointer to interface name */
-- char *brcmf_ifname(struct brcmf_pub *drvr, int idx);
---
--+struct brcmf_if *brcmf_get_ifp(struct brcmf_pub *drvr, int ifidx);
-- int brcmf_net_attach(struct brcmf_if *ifp, bool rtnl_locked);
-- struct brcmf_if *brcmf_add_if(struct brcmf_pub *drvr, s32 bssidx, s32 ifidx,
-- 			      char *name, u8 *mac_addr);
----- a/drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c
--+++ b/drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c
--@@ -1081,16 +1081,8 @@ brcmf_msgbuf_rx_skb(struct brcmf_msgbuf
-- {
-- 	struct brcmf_if *ifp;
-- 
---	/* The ifidx is the idx to map to matching netdev/ifp. When receiving
---	 * events this is easy because it contains the bssidx which maps
---	 * 1-on-1 to the netdev/ifp. But for data frames the ifidx is rcvd.
---	 * bssidx 1 is used for p2p0 and no data can be received or
---	 * transmitted on it. Therefor bssidx is ifidx + 1 if ifidx > 0
---	 */
---	if (ifidx)
---		(ifidx)++;
---	ifp = msgbuf->drvr->iflist[ifidx];
---	if (!ifp || !ifp->ndev) {
--+	ifp = brcmf_get_ifp(msgbuf->drvr, ifidx);
--+	if (IS_ERR_OR_NULL(ifp) || !ifp->ndev) {
-- 		brcmf_err("Received pkt for invalid ifidx %d\n", ifidx);
-- 		brcmu_pkt_buf_free_skb(skb);
-- 		return;
-diff --git a/package/kernel/mac80211/patches/394-0002-brcmfmac-make-brcmf_proto_hdrpull-return-struct-brcm.patch b/package/kernel/mac80211/patches/394-0002-brcmfmac-make-brcmf_proto_hdrpull-return-struct-brcm.patch
-deleted file mode 100644
-index 632714c..0000000
---- a/package/kernel/mac80211/patches/394-0002-brcmfmac-make-brcmf_proto_hdrpull-return-struct-brcm.patch
-+++ /dev/null
-@@ -1,222 +0,0 @@
--From: Arend van Spriel <arend@broadcom.com>
--Date: Wed, 26 Aug 2015 22:14:54 +0200
--Subject: [PATCH] brcmfmac: make brcmf_proto_hdrpull() return struct
-- brcmf_if instance
--
--Avoid spreading the ifidx in the driver, but have it return the
--struct brcmf_if instance.
--
--Reviewed-by: Hante Meuleman <meuleman@broadcom.com>
--Reviewed-by: Franky (Zhenhui) Lin <frankyl@broadcom.com>
--Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
--Signed-off-by: Arend van Spriel <arend@broadcom.com>
-----
--
----- a/drivers/net/wireless/brcm80211/brcmfmac/bcdc.c
--+++ b/drivers/net/wireless/brcm80211/brcmfmac/bcdc.c
--@@ -272,11 +272,11 @@ brcmf_proto_bcdc_hdrpush(struct brcmf_pu
-- }
-- 
-- static int
---brcmf_proto_bcdc_hdrpull(struct brcmf_pub *drvr, bool do_fws, u8 *ifidx,
---			 struct sk_buff *pktbuf)
--+brcmf_proto_bcdc_hdrpull(struct brcmf_pub *drvr, bool do_fws,
--+			 struct sk_buff *pktbuf, struct brcmf_if **ifp)
-- {
-- 	struct brcmf_proto_bcdc_header *h;
---	struct brcmf_if *ifp;
--+	struct brcmf_if *tmp_if;
-- 
-- 	brcmf_dbg(BCDC, "Enter\n");
-- 
--@@ -290,21 +290,21 @@ brcmf_proto_bcdc_hdrpull(struct brcmf_pu
-- 	trace_brcmf_bcdchdr(pktbuf->data);
-- 	h = (struct brcmf_proto_bcdc_header *)(pktbuf->data);
-- 
---	ifp = brcmf_get_ifp(drvr, BCDC_GET_IF_IDX(h));
---	if (IS_ERR_OR_NULL(ifp)) {
--+	tmp_if = brcmf_get_ifp(drvr, BCDC_GET_IF_IDX(h));
--+	if (!tmp_if) {
-- 		brcmf_dbg(INFO, "no matching ifp found\n");
-- 		return -EBADE;
-- 	}
-- 	if (((h->flags & BCDC_FLAG_VER_MASK) >> BCDC_FLAG_VER_SHIFT) !=
-- 	    BCDC_PROTO_VER) {
-- 		brcmf_err("%s: non-BCDC packet received, flags 0x%x\n",
---			  brcmf_ifname(drvr, ifp->ifidx), h->flags);
--+			  brcmf_ifname(drvr, tmp_if->ifidx), h->flags);
-- 		return -EBADE;
-- 	}
-- 
-- 	if (h->flags & BCDC_FLAG_SUM_GOOD) {
-- 		brcmf_dbg(BCDC, "%s: BDC rcv, good checksum, flags 0x%x\n",
---			  brcmf_ifname(drvr, ifp->ifidx), h->flags);
--+			  brcmf_ifname(drvr, tmp_if->ifidx), h->flags);
-- 		pktbuf->ip_summed = CHECKSUM_UNNECESSARY;
-- 	}
-- 
--@@ -312,7 +312,7 @@ brcmf_proto_bcdc_hdrpull(struct brcmf_pu
-- 
-- 	skb_pull(pktbuf, BCDC_HEADER_LEN);
-- 	if (do_fws)
---		brcmf_fws_hdrpull(drvr, ifp->ifidx, h->data_offset << 2,
--+		brcmf_fws_hdrpull(drvr, tmp_if->ifidx, h->data_offset << 2,
-- 				  pktbuf);
-- 	else
-- 		skb_pull(pktbuf, h->data_offset << 2);
--@@ -320,7 +320,7 @@ brcmf_proto_bcdc_hdrpull(struct brcmf_pu
-- 	if (pktbuf->len == 0)
-- 		return -ENODATA;
-- 
---	*ifidx = ifp->ifidx;
--+	*ifp = tmp_if;
-- 	return 0;
-- }
-- 
----- a/drivers/net/wireless/brcm80211/brcmfmac/core.c
--+++ b/drivers/net/wireless/brcm80211/brcmfmac/core.c
--@@ -87,7 +87,7 @@ struct brcmf_if *brcmf_get_ifp(struct br
-- {
-- 	if (ifidx < 0 || ifidx >= BRCMF_MAX_IFS) {
-- 		brcmf_err("ifidx %d out of range\n", ifidx);
---		return ERR_PTR(-ERANGE);
--+		return NULL;
-- 	}
-- 
-- 	/* The ifidx is the idx to map to matching netdev/ifp. When receiving
--@@ -539,17 +539,15 @@ void brcmf_rx_frame(struct device *dev,
-- 	struct brcmf_bus *bus_if = dev_get_drvdata(dev);
-- 	struct brcmf_pub *drvr = bus_if->drvr;
-- 	struct brcmf_skb_reorder_data *rd;
---	u8 ifidx;
-- 	int ret;
-- 
-- 	brcmf_dbg(DATA, "Enter: %s: rxp=%p\n", dev_name(dev), skb);
-- 
-- 	/* process and remove protocol-specific header */
---	ret = brcmf_proto_hdrpull(drvr, true, &ifidx, skb);
---	ifp = drvr->iflist[ifidx];
--+	ret = brcmf_proto_hdrpull(drvr, true, skb, &ifp);
-- 
-- 	if (ret || !ifp || !ifp->ndev) {
---		if ((ret != -ENODATA) && ifp)
--+		if (ret != -ENODATA && ifp)
-- 			ifp->stats.rx_errors++;
-- 		brcmu_pkt_buf_free_skb(skb);
-- 		return;
--@@ -592,17 +590,17 @@ void brcmf_txcomplete(struct device *dev
-- {
-- 	struct brcmf_bus *bus_if = dev_get_drvdata(dev);
-- 	struct brcmf_pub *drvr = bus_if->drvr;
---	u8 ifidx;
--+	struct brcmf_if *ifp;
-- 
-- 	/* await txstatus signal for firmware if active */
-- 	if (brcmf_fws_fc_active(drvr->fws)) {
-- 		if (!success)
-- 			brcmf_fws_bustxfail(drvr->fws, txp);
-- 	} else {
---		if (brcmf_proto_hdrpull(drvr, false, &ifidx, txp))
--+		if (brcmf_proto_hdrpull(drvr, false, txp, &ifp))
-- 			brcmu_pkt_buf_free_skb(txp);
-- 		else
---			brcmf_txfinalize(drvr, txp, ifidx, success);
--+			brcmf_txfinalize(drvr, txp, ifp->ifidx, success);
-- 	}
-- }
-- 
----- a/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c
--+++ b/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c
--@@ -1448,7 +1448,7 @@ brcmf_fws_txs_process(struct brcmf_fws_i
-- 	struct sk_buff *skb;
-- 	struct brcmf_skbuff_cb *skcb;
-- 	struct brcmf_fws_mac_descriptor *entry = NULL;
---	u8 ifidx;
--+	struct brcmf_if *ifp;
-- 
-- 	brcmf_dbg(DATA, "flags %d\n", flags);
-- 
--@@ -1497,15 +1497,16 @@ brcmf_fws_txs_process(struct brcmf_fws_i
-- 	}
-- 	brcmf_fws_macdesc_return_req_credit(skb);
-- 
---	if (brcmf_proto_hdrpull(fws->drvr, false, &ifidx, skb)) {
--+	ret = brcmf_proto_hdrpull(fws->drvr, false, skb, &ifp);
--+	if (ret) {
-- 		brcmu_pkt_buf_free_skb(skb);
-- 		return -EINVAL;
-- 	}
-- 	if (!remove_from_hanger)
---		ret = brcmf_fws_txstatus_suppressed(fws, fifo, skb, ifidx,
--+		ret = brcmf_fws_txstatus_suppressed(fws, fifo, skb, ifp->ifidx,
-- 						    genbit, seq);
-- 	if (remove_from_hanger || ret)
---		brcmf_txfinalize(fws->drvr, skb, ifidx, true);
--+		brcmf_txfinalize(fws->drvr, skb, ifp->ifidx, true);
-- 
-- 	return 0;
-- }
--@@ -1848,7 +1849,7 @@ static int brcmf_fws_commit_skb(struct b
-- 		entry->transit_count--;
-- 		if (entry->suppressed)
-- 			entry->suppr_transit_count--;
---		brcmf_proto_hdrpull(fws->drvr, false, &ifidx, skb);
--+		(void)brcmf_proto_hdrpull(fws->drvr, false, skb, NULL);
-- 		goto rollback;
-- 	}
-- 
----- a/drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c
--+++ b/drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c
--@@ -522,7 +522,7 @@ static int brcmf_msgbuf_set_dcmd(struct
-- 
-- 
-- static int brcmf_msgbuf_hdrpull(struct brcmf_pub *drvr, bool do_fws,
---				u8 *ifidx, struct sk_buff *skb)
--+				struct sk_buff *skb, struct brcmf_if **ifp)
-- {
-- 	return -ENODEV;
-- }
--@@ -1082,7 +1082,7 @@ brcmf_msgbuf_rx_skb(struct brcmf_msgbuf
-- 	struct brcmf_if *ifp;
-- 
-- 	ifp = brcmf_get_ifp(msgbuf->drvr, ifidx);
---	if (IS_ERR_OR_NULL(ifp) || !ifp->ndev) {
--+	if (!ifp || !ifp->ndev) {
-- 		brcmf_err("Received pkt for invalid ifidx %d\n", ifidx);
-- 		brcmu_pkt_buf_free_skb(skb);
-- 		return;
----- a/drivers/net/wireless/brcm80211/brcmfmac/proto.h
--+++ b/drivers/net/wireless/brcm80211/brcmfmac/proto.h
--@@ -24,8 +24,8 @@ enum proto_addr_mode {
-- 
-- 
-- struct brcmf_proto {
---	int (*hdrpull)(struct brcmf_pub *drvr, bool do_fws, u8 *ifidx,
---		       struct sk_buff *skb);
--+	int (*hdrpull)(struct brcmf_pub *drvr, bool do_fws,
--+		       struct sk_buff *skb, struct brcmf_if **ifp);
-- 	int (*query_dcmd)(struct brcmf_pub *drvr, int ifidx, uint cmd,
-- 			  void *buf, uint len);
-- 	int (*set_dcmd)(struct brcmf_pub *drvr, int ifidx, uint cmd, void *buf,
--@@ -46,9 +46,19 @@ int brcmf_proto_attach(struct brcmf_pub
-- void brcmf_proto_detach(struct brcmf_pub *drvr);
-- 
-- static inline int brcmf_proto_hdrpull(struct brcmf_pub *drvr, bool do_fws,
---				      u8 *ifidx, struct sk_buff *skb)
--+				      struct sk_buff *skb,
--+				      struct brcmf_if **ifp)
-- {
---	return drvr->proto->hdrpull(drvr, do_fws, ifidx, skb);
--+	struct brcmf_if *tmp = NULL;
--+
--+	/* assure protocol is always called with
--+	 * non-null initialized pointer.
--+	 */
--+	if (ifp)
--+		*ifp = NULL;
--+	else
--+		ifp = &tmp;
--+	return drvr->proto->hdrpull(drvr, do_fws, skb, ifp);
-- }
-- static inline int brcmf_proto_query_dcmd(struct brcmf_pub *drvr, int ifidx,
-- 					 uint cmd, void *buf, uint len)
-diff --git a/package/kernel/mac80211/patches/394-0003-brcmfmac-change-parameters-for-brcmf_remove_interfac.patch b/package/kernel/mac80211/patches/394-0003-brcmfmac-change-parameters-for-brcmf_remove_interfac.patch
-deleted file mode 100644
-index 2d15a77..0000000
---- a/package/kernel/mac80211/patches/394-0003-brcmfmac-change-parameters-for-brcmf_remove_interfac.patch
-+++ /dev/null
-@@ -1,87 +0,0 @@
--From: Arend van Spriel <arend@broadcom.com>
--Date: Wed, 26 Aug 2015 22:14:55 +0200
--Subject: [PATCH] brcmfmac: change parameters for
-- brcmf_remove_interface()
--
--Just pass the interface to be removed, ie. the struct brcmf_if instance.
--
--Reviewed-by: Hante Meuleman <meuleman@broadcom.com>
--Reviewed-by: Franky (Zhenhui) Lin <frankyl@broadcom.com>
--Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
--Signed-off-by: Arend van Spriel <arend@broadcom.com>
-----
--
----- a/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c
--+++ b/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c
--@@ -4982,7 +4982,7 @@ brcmf_notify_connect_status_ap(struct br
-- 		brcmf_dbg(CONN, "AP mode link down\n");
-- 		complete(&cfg->vif_disabled);
-- 		if (ifp->vif->mbss)
---			brcmf_remove_interface(ifp->drvr, ifp->bssidx);
--+			brcmf_remove_interface(ifp);
-- 		return 0;
-- 	}
-- 
----- a/drivers/net/wireless/brcm80211/brcmfmac/core.c
--+++ b/drivers/net/wireless/brcm80211/brcmfmac/core.c
--@@ -887,12 +887,13 @@ static void brcmf_del_if(struct brcmf_pu
-- 	}
-- }
-- 
---void brcmf_remove_interface(struct brcmf_pub *drvr, u32 bssidx)
--+void brcmf_remove_interface(struct brcmf_if *ifp)
-- {
---	if (drvr->iflist[bssidx]) {
---		brcmf_fws_del_interface(drvr->iflist[bssidx]);
---		brcmf_del_if(drvr, bssidx);
---	}
--+	if (!ifp || WARN_ON(ifp->drvr->iflist[ifp->bssidx] != ifp))
--+		return;
--+
--+	brcmf_fws_del_interface(ifp);
--+	brcmf_del_if(ifp->drvr, ifp->bssidx);
-- }
-- 
-- int brcmf_get_next_free_bsscfgidx(struct brcmf_pub *drvr)
--@@ -1122,7 +1123,7 @@ void brcmf_detach(struct device *dev)
-- 
-- 	/* make sure primary interface removed last */
-- 	for (i = BRCMF_MAX_IFS-1; i > -1; i--)
---		brcmf_remove_interface(drvr, i);
--+		brcmf_remove_interface(drvr->iflist[i]);
-- 
-- 	brcmf_cfg80211_detach(drvr->config);
-- 
----- a/drivers/net/wireless/brcm80211/brcmfmac/core.h
--+++ b/drivers/net/wireless/brcm80211/brcmfmac/core.h
--@@ -206,7 +206,7 @@ struct brcmf_if *brcmf_get_ifp(struct br
-- int brcmf_net_attach(struct brcmf_if *ifp, bool rtnl_locked);
-- struct brcmf_if *brcmf_add_if(struct brcmf_pub *drvr, s32 bssidx, s32 ifidx,
-- 			      char *name, u8 *mac_addr);
---void brcmf_remove_interface(struct brcmf_pub *drvr, u32 bssidx);
--+void brcmf_remove_interface(struct brcmf_if *ifp);
-- int brcmf_get_next_free_bsscfgidx(struct brcmf_pub *drvr);
-- void brcmf_txflowblock_if(struct brcmf_if *ifp,
-- 			  enum brcmf_netif_stop_reason reason, bool state);
----- a/drivers/net/wireless/brcm80211/brcmfmac/fweh.c
--+++ b/drivers/net/wireless/brcm80211/brcmfmac/fweh.c
--@@ -222,7 +222,7 @@ static void brcmf_fweh_handle_if_event(s
-- 	err = brcmf_fweh_call_event_handler(ifp, emsg->event_code, emsg, data);
-- 
-- 	if (ifp && ifevent->action == BRCMF_E_IF_DEL)
---		brcmf_remove_interface(drvr, ifevent->bssidx);
--+		brcmf_remove_interface(ifp);
-- }
-- 
-- /**
----- a/drivers/net/wireless/brcm80211/brcmfmac/p2p.c
--+++ b/drivers/net/wireless/brcm80211/brcmfmac/p2p.c
--@@ -2140,7 +2140,7 @@ static void brcmf_p2p_delete_p2pdev(stru
-- {
-- 	cfg80211_unregister_wdev(&vif->wdev);
-- 	p2p->bss_idx[P2PAPI_BSSCFG_DEVICE].vif = NULL;
---	brcmf_remove_interface(vif->ifp->drvr, vif->ifp->bssidx);
--+	brcmf_remove_interface(vif->ifp);
-- 	brcmf_free_vif(vif);
-- }
-- 
-diff --git a/package/kernel/mac80211/patches/394-0004-brcmfmac-only-call-brcmf_cfg80211_detach-when-attach.patch b/package/kernel/mac80211/patches/394-0004-brcmfmac-only-call-brcmf_cfg80211_detach-when-attach.patch
-deleted file mode 100644
-index 2b61f4e..0000000
---- a/package/kernel/mac80211/patches/394-0004-brcmfmac-only-call-brcmf_cfg80211_detach-when-attach.patch
-+++ /dev/null
-@@ -1,92 +0,0 @@
--From: Arend van Spriel <arend@broadcom.com>
--Date: Wed, 26 Aug 2015 22:14:56 +0200
--Subject: [PATCH] brcmfmac: only call brcmf_cfg80211_detach() when attach
-- was successful
--
--In brcmf_bus_start() the function brcmf_cfg80211_attach() is called which
--may fail. If this happens we should not call brcmf_cfg80211_detach() in
--the failure path as it will result in NULL pointer dereference:
--
--  brcmf_fweh_activate_events: Set event_msgs error (-5)
--  brcmf_bus_start: failed: -5
--  brcmf_sdio_firmware_callback: dongle is not responding
--  BUG: unable to handle kernel NULL pointer dereference at 0000000000000068
--  IP: [<ffffffff811e8f08>] kernfs_find_ns+0x18/0xd0
--  PGD 0
--  Oops: 0000 [#1] SMP
--  Modules linked in: brcmfmac(O) brcmutil(O) cfg80211 auth_rpcgss
--  CPU: 1 PID: 45 Comm: kworker/1:1 Tainted: G           O
--  Hardware name: Dell Inc. Latitude E6410/07XJP9, BIOS A07 02/15/2011
--  Workqueue: events request_firmware_work_func
--  task: ffff880036c09ac0 ti: ffff880036dd4000 task.ti: ffff880036dd4000
--  RIP: 0010:[<ffffffff811e8f08>]  [<ffffffff811e8f08>] kernfs_find_ns+0x18/0xd0
--  RSP: 0018:ffff880036dd7a28  EFLAGS: 00010246
--  RAX: ffff880036c09ac0 RBX: 0000000000000000 RCX: 000000007fffffff
--  RDX: 0000000000000000 RSI: ffffffff816578b9 RDI: 0000000000000000
--  RBP: ffff880036dd7a48 R08: 0000000000000000 R09: ffff880036c0b340
--  R10: 00000000000002ec R11: ffff880036dd7b08 R12: ffffffff816578b9
--  R13: 0000000000000000 R14: ffffffff816578b9 R15: ffff8800c6c87000
--  FS:  0000000000000000(0000) GS:ffff88012bc40000(0000) knlGS:0000000000000000
--  CS:  0010 DS: 0000 ES: 0000 CR0: 000000008005003b
--  CR2: 0000000000000068 CR3: 0000000001a0b000 CR4: 00000000000006e0
--  Stack:
--   0000000000000000 ffffffff816578b9 0000000000000000 ffff8800c0d003c8
--   ffff880036dd7a78 ffffffff811e8ff5 0000000ffffffff1 ffffffff81a9b060
--   ffff8800c789f880 ffff8800c0d00000 ffff880036dd7a98 ffffffff811ebe0d
--  Call Trace:
--   [<ffffffff811e8ff5>] kernfs_find_and_get_ns+0x35/0x60
--   [<ffffffff811ebe0d>] sysfs_unmerge_group+0x1d/0x60
--   [<ffffffff81404ef2>] dpm_sysfs_remove+0x22/0x60
--   [<ffffffff813f9db9>] device_del+0x49/0x240
--   [<ffffffff815da768>] rfkill_unregister+0x58/0xc0
--   [<ffffffffa06bd91b>] wiphy_unregister+0xab/0x2f0 [cfg80211]
--   [<ffffffffa0742fe3>] brcmf_cfg80211_detach+0x23/0x50 [brcmfmac]
--   [<ffffffffa074d986>] brcmf_detach+0x86/0xe0 [brcmfmac]
--   [<ffffffffa0757de8>] brcmf_sdio_remove+0x48/0x120 [brcmfmac]
--   [<ffffffffa0758ed9>] brcmf_sdiod_remove+0x29/0xd0 [brcmfmac]
--   [<ffffffffa0759031>] brcmf_ops_sdio_remove+0xb1/0x110 [brcmfmac]
--   [<ffffffffa001c267>] sdio_bus_remove+0x37/0x100 [mmc_core]
--   [<ffffffff813fe026>] __device_release_driver+0x96/0x130
--   [<ffffffff813fe0e3>] device_release_driver+0x23/0x30
--   [<ffffffffa0754bc8>] brcmf_sdio_firmware_callback+0x2a8/0x5d0 [brcmfmac]
--   [<ffffffffa074deaf>] brcmf_fw_request_nvram_done+0x15f/0x5e0 [brcmfmac]
--   [<ffffffff8140142f>] ? devres_add+0x3f/0x50
--   [<ffffffff810642b5>] ? usermodehelper_read_unlock+0x15/0x20
--   [<ffffffff81400000>] ? platform_match+0x70/0xa0
--   [<ffffffff8140f400>] request_firmware_work_func+0x30/0x60
--   [<ffffffff8106828c>] process_one_work+0x14c/0x3d0
--   [<ffffffff8106862a>] worker_thread+0x11a/0x450
--   [<ffffffff81068510>] ? process_one_work+0x3d0/0x3d0
--   [<ffffffff8106d692>] kthread+0xd2/0xf0
--   [<ffffffff8106d5c0>] ? kthread_create_on_node+0x180/0x180
--   [<ffffffff815ed35f>] ret_from_fork+0x3f/0x70
--   [<ffffffff8106d5c0>] ? kthread_create_on_node+0x180/0x180
--  Code: e9 40 fe ff ff 48 89 d8 eb 87 66 0f 1f 84 00 00 00 00 00 66 66 66 66
--	90 55 48 89 e5 41 56 49 89 f6 41 55 49 89 d5 31 d2 41 54 53 <0f> b7
--	47 68 48 8b 5f 48 66 c1 e8 05 83 e0 01 4d 85 ed 0f b6 c8
--  RIP  [<ffffffff811e8f08>] kernfs_find_ns+0x18/0xd0
--   RSP <ffff880036dd7a28>
--  CR2: 0000000000000068
--  ---[ end trace 87d6ec0d3fe46740 ]---
--
--Reported-by: Daniel (Deognyoun) Kim <dekim@broadcom.com>
--Reviewed-by: Hante Meuleman <meuleman@broadcom.com>
--Reviewed-by: Franky (Zhenhui) Lin <frankyl@broadcom.com>
--Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
--Signed-off-by: Arend van Spriel <arend@broadcom.com>
-----
--
----- a/drivers/net/wireless/brcm80211/brcmfmac/core.c
--+++ b/drivers/net/wireless/brcm80211/brcmfmac/core.c
--@@ -1049,7 +1049,10 @@ int brcmf_bus_start(struct device *dev)
-- fail:
-- 	if (ret < 0) {
-- 		brcmf_err("failed: %d\n", ret);
---		brcmf_cfg80211_detach(drvr->config);
--+		if (drvr->config) {
--+			brcmf_cfg80211_detach(drvr->config);
--+			drvr->config = NULL;
--+		}
-- 		if (drvr->fws) {
-- 			brcmf_fws_del_interface(ifp);
-- 			brcmf_fws_deinit(drvr);
-diff --git a/package/kernel/mac80211/patches/394-0005-brcmfmac-correct-detection-of-p2pdev-interface-event.patch b/package/kernel/mac80211/patches/394-0005-brcmfmac-correct-detection-of-p2pdev-interface-event.patch
-deleted file mode 100644
-index 868b0a8..0000000
---- a/package/kernel/mac80211/patches/394-0005-brcmfmac-correct-detection-of-p2pdev-interface-event.patch
-+++ /dev/null
-@@ -1,105 +0,0 @@
--From: Arend van Spriel <arend@broadcom.com>
--Date: Wed, 26 Aug 2015 22:14:57 +0200
--Subject: [PATCH] brcmfmac: correct detection of p2pdev interface event
--
--The p2pdev interface is setup in firmware resulting in a interface
--event. This event has role and no-if flag. When role is p2p client
--and no-if flag is set it indicates that this is the p2pdev interface.
--This info is used in handling the event and adding interface in the
--driver.
--
--Reviewed-by: Hante Meuleman <meuleman@broadcom.com>
--Reviewed-by: Franky (Zhenhui) Lin <frankyl@broadcom.com>
--Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
--Signed-off-by: Arend van Spriel <arend@broadcom.com>
-----
--
----- a/drivers/net/wireless/brcm80211/brcmfmac/core.c
--+++ b/drivers/net/wireless/brcm80211/brcmfmac/core.c
--@@ -795,7 +795,7 @@ fail:
-- }
-- 
-- struct brcmf_if *brcmf_add_if(struct brcmf_pub *drvr, s32 bssidx, s32 ifidx,
---			      char *name, u8 *mac_addr)
--+			      bool is_p2pdev, char *name, u8 *mac_addr)
-- {
-- 	struct brcmf_if *ifp;
-- 	struct net_device *ndev;
--@@ -821,7 +821,7 @@ struct brcmf_if *brcmf_add_if(struct brc
-- 		}
-- 	}
-- 
---	if (!brcmf_p2p_enable && bssidx == 1) {
--+	if (!brcmf_p2p_enable && is_p2pdev) {
-- 		/* this is P2P_DEVICE interface */
-- 		brcmf_dbg(INFO, "allocate non-netdev interface\n");
-- 		ifp = kzalloc(sizeof(*ifp), GFP_KERNEL);
--@@ -999,12 +999,12 @@ int brcmf_bus_start(struct device *dev)
-- 	brcmf_dbg(TRACE, "\n");
-- 
-- 	/* add primary networking interface */
---	ifp = brcmf_add_if(drvr, 0, 0, "wlan%d", NULL);
--+	ifp = brcmf_add_if(drvr, 0, 0, false, "wlan%d", NULL);
-- 	if (IS_ERR(ifp))
-- 		return PTR_ERR(ifp);
-- 
-- 	if (brcmf_p2p_enable)
---		p2p_ifp = brcmf_add_if(drvr, 1, 0, "p2p%d", NULL);
--+		p2p_ifp = brcmf_add_if(drvr, 1, 0, false, "p2p%d", NULL);
-- 	else
-- 		p2p_ifp = NULL;
-- 	if (IS_ERR(p2p_ifp))
----- a/drivers/net/wireless/brcm80211/brcmfmac/core.h
--+++ b/drivers/net/wireless/brcm80211/brcmfmac/core.h
--@@ -205,7 +205,7 @@ char *brcmf_ifname(struct brcmf_pub *drv
-- struct brcmf_if *brcmf_get_ifp(struct brcmf_pub *drvr, int ifidx);
-- int brcmf_net_attach(struct brcmf_if *ifp, bool rtnl_locked);
-- struct brcmf_if *brcmf_add_if(struct brcmf_pub *drvr, s32 bssidx, s32 ifidx,
---			      char *name, u8 *mac_addr);
--+			      bool is_p2pdev, char *name, u8 *mac_addr);
-- void brcmf_remove_interface(struct brcmf_if *ifp);
-- int brcmf_get_next_free_bsscfgidx(struct brcmf_pub *drvr);
-- void brcmf_txflowblock_if(struct brcmf_if *ifp,
----- a/drivers/net/wireless/brcm80211/brcmfmac/fweh.c
--+++ b/drivers/net/wireless/brcm80211/brcmfmac/fweh.c
--@@ -179,6 +179,7 @@ static void brcmf_fweh_handle_if_event(s
-- {
-- 	struct brcmf_if_event *ifevent = data;
-- 	struct brcmf_if *ifp;
--+	bool is_p2pdev;
-- 	int err = 0;
-- 
-- 	brcmf_dbg(EVENT, "action: %u idx: %u bsscfg: %u flags: %u role: %u\n",
--@@ -186,18 +187,16 @@ static void brcmf_fweh_handle_if_event(s
-- 		  ifevent->flags, ifevent->role);
-- 
-- 	/* The P2P Device interface event must not be ignored
---	 * contrary to what firmware tells us. The only way to
---	 * distinguish the P2P Device is by looking at the ifidx
---	 * and bssidx received.
--+	 * contrary to what firmware tells us.
-- 	 */
---	if (!(ifevent->ifidx == 0 && ifevent->bssidx == 1) &&
---	    (ifevent->flags & BRCMF_E_IF_FLAG_NOIF)) {
--+	is_p2pdev = (ifevent->flags & BRCMF_E_IF_FLAG_NOIF) &&
--+		    ifevent->role == BRCMF_E_IF_ROLE_P2P_CLIENT;
--+	if (!is_p2pdev && (ifevent->flags & BRCMF_E_IF_FLAG_NOIF)) {
-- 		brcmf_dbg(EVENT, "event can be ignored\n");
-- 		return;
-- 	}
-- 	if (ifevent->ifidx >= BRCMF_MAX_IFS) {
---		brcmf_err("invalid interface index: %u\n",
---			  ifevent->ifidx);
--+		brcmf_err("invalid interface index: %u\n", ifevent->ifidx);
-- 		return;
-- 	}
-- 
--@@ -207,7 +206,7 @@ static void brcmf_fweh_handle_if_event(s
-- 		brcmf_dbg(EVENT, "adding %s (%pM)\n", emsg->ifname,
-- 			  emsg->addr);
-- 		ifp = brcmf_add_if(drvr, ifevent->bssidx, ifevent->ifidx,
---				   emsg->ifname, emsg->addr);
--+				   is_p2pdev, emsg->ifname, emsg->addr);
-- 		if (IS_ERR(ifp))
-- 			return;
-- 		brcmf_fws_add_interface(ifp);
-diff --git a/package/kernel/mac80211/patches/394-0006-brcmfmac-use-brcmf_get_ifp-to-map-ifidx-to-struct-br.patch b/package/kernel/mac80211/patches/394-0006-brcmfmac-use-brcmf_get_ifp-to-map-ifidx-to-struct-br.patch
-deleted file mode 100644
-index aebbfa6..0000000
---- a/package/kernel/mac80211/patches/394-0006-brcmfmac-use-brcmf_get_ifp-to-map-ifidx-to-struct-br.patch
-+++ /dev/null
-@@ -1,126 +0,0 @@
--From: Arend van Spriel <arend@broadcom.com>
--Date: Wed, 26 Aug 2015 22:14:58 +0200
--Subject: [PATCH] brcmfmac: use brcmf_get_ifp() to map ifidx to struct
-- brcmf_if instance
--
--The knowledge on how to map the interface index to a struct brcmf_if
--instance is in brcmf_get_ifp() so use that function when only the
--interface index is known instead of accessing brcmf_pub::iflist
--directly.
--
--Reviewed-by: Hante Meuleman <meuleman@broadcom.com>
--Reviewed-by: Franky (Zhenhui) Lin <frankyl@broadcom.com>
--Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
--Signed-off-by: Arend van Spriel <arend@broadcom.com>
-----
--
----- a/drivers/net/wireless/brcm80211/brcmfmac/btcoex.c
--+++ b/drivers/net/wireless/brcm80211/brcmfmac/btcoex.c
--@@ -149,7 +149,7 @@ static s32 brcmf_btcoex_params_read(stru
-- static void brcmf_btcoex_boost_wifi(struct brcmf_btcoex_info *btci,
-- 				    bool trump_sco)
-- {
---	struct brcmf_if *ifp = btci->cfg->pub->iflist[0];
--+	struct brcmf_if *ifp = brcmf_get_ifp(btci->cfg->pub, 0);
-- 
-- 	if (trump_sco && !btci->saved_regs_part2) {
-- 		/* this should reduce eSCO agressive
--@@ -468,7 +468,7 @@ int brcmf_btcoex_set_mode(struct brcmf_c
-- {
-- 	struct brcmf_cfg80211_info *cfg = wiphy_priv(vif->wdev.wiphy);
-- 	struct brcmf_btcoex_info *btci = cfg->btcoex;
---	struct brcmf_if *ifp = cfg->pub->iflist[0];
--+	struct brcmf_if *ifp = brcmf_get_ifp(cfg->pub, 0);
-- 
-- 	switch (mode) {
-- 	case BRCMF_BTCOEX_DISABLED:
----- a/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c
--+++ b/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c
--@@ -6212,7 +6212,7 @@ static void brcmf_free_wiphy(struct wiph
-- struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct brcmf_pub *drvr,
-- 						  struct device *busdev)
-- {
---	struct net_device *ndev = drvr->iflist[0]->ndev;
--+	struct net_device *ndev = brcmf_get_ifp(drvr, 0)->ndev;
-- 	struct brcmf_cfg80211_info *cfg;
-- 	struct wiphy *wiphy;
-- 	struct brcmf_cfg80211_vif *vif;
----- a/drivers/net/wireless/brcm80211/brcmfmac/feature.c
--+++ b/drivers/net/wireless/brcm80211/brcmfmac/feature.c
--@@ -121,7 +121,7 @@ static void brcmf_feat_iovar_int_set(str
-- 
-- void brcmf_feat_attach(struct brcmf_pub *drvr)
-- {
---	struct brcmf_if *ifp = drvr->iflist[0];
--+	struct brcmf_if *ifp = brcmf_get_ifp(drvr, 0);
-- 
-- 	brcmf_feat_iovar_int_get(ifp, BRCMF_FEAT_MCHAN, "mchan");
-- 	brcmf_feat_iovar_int_get(ifp, BRCMF_FEAT_PNO, "pfn");
----- a/drivers/net/wireless/brcm80211/brcmfmac/flowring.c
--+++ b/drivers/net/wireless/brcm80211/brcmfmac/flowring.c
--@@ -221,7 +221,7 @@ static void brcmf_flowring_block(struct
-- 
-- 	bus_if = dev_get_drvdata(flow->dev);
-- 	drvr = bus_if->drvr;
---	ifp = drvr->iflist[ifidx];
--+	ifp = brcmf_get_ifp(drvr, ifidx);
-- 	brcmf_txflowblock_if(ifp, BRCMF_NETIF_STOP_REASON_FLOW, blocked);
-- 
-- 	spin_unlock_irqrestore(&flow->block_lock, flags);
----- a/drivers/net/wireless/brcm80211/brcmfmac/fweh.c
--+++ b/drivers/net/wireless/brcm80211/brcmfmac/fweh.c
--@@ -334,7 +334,7 @@ void brcmf_fweh_attach(struct brcmf_pub
-- void brcmf_fweh_detach(struct brcmf_pub *drvr)
-- {
-- 	struct brcmf_fweh_info *fweh = &drvr->fweh;
---	struct brcmf_if *ifp = drvr->iflist[0];
--+	struct brcmf_if *ifp = brcmf_get_ifp(drvr, 0);
-- 	s8 eventmask[BRCMF_EVENTING_MASK_LEN];
-- 
-- 	if (ifp) {
----- a/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c
--+++ b/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c
--@@ -972,7 +972,7 @@ static void
-- brcmf_fws_flow_control_check(struct brcmf_fws_info *fws, struct pktq *pq,
-- 			     u8 if_id)
-- {
---	struct brcmf_if *ifp = fws->drvr->iflist[!if_id ? 0 : if_id + 1];
--+	struct brcmf_if *ifp = brcmf_get_ifp(fws->drvr, if_id);
-- 
-- 	if (WARN_ON(!ifp))
-- 		return;
--@@ -2118,6 +2118,7 @@ static int brcmf_debugfs_fws_stats_read(
-- int brcmf_fws_init(struct brcmf_pub *drvr)
-- {
-- 	struct brcmf_fws_info *fws;
--+	struct brcmf_if *ifp;
-- 	u32 tlv = BRCMF_FWS_FLAGS_RSSI_SIGNALS;
-- 	int rc;
-- 	u32 mode;
--@@ -2177,21 +2178,22 @@ int brcmf_fws_init(struct brcmf_pub *drv
-- 	 * continue. Set mode back to none indicating not enabled.
-- 	 */
-- 	fws->fw_signals = true;
---	if (brcmf_fil_iovar_int_set(drvr->iflist[0], "tlv", tlv)) {
--+	ifp = brcmf_get_ifp(drvr, 0);
--+	if (brcmf_fil_iovar_int_set(ifp, "tlv", tlv)) {
-- 		brcmf_err("failed to set bdcv2 tlv signaling\n");
-- 		fws->fcmode = BRCMF_FWS_FCMODE_NONE;
-- 		fws->fw_signals = false;
-- 	}
-- 
---	if (brcmf_fil_iovar_int_set(drvr->iflist[0], "ampdu_hostreorder", 1))
--+	if (brcmf_fil_iovar_int_set(ifp, "ampdu_hostreorder", 1))
-- 		brcmf_dbg(INFO, "enabling AMPDU host-reorder failed\n");
-- 
-- 	/* Enable seq number reuse, if supported */
---	if (brcmf_fil_iovar_int_get(drvr->iflist[0], "wlfc_mode", &mode) == 0) {
--+	if (brcmf_fil_iovar_int_get(ifp, "wlfc_mode", &mode) == 0) {
-- 		if (BRCMF_FWS_MODE_GET_REUSESEQ(mode)) {
-- 			mode = 0;
-- 			BRCMF_FWS_MODE_SET_REUSESEQ(mode, 1);
---			if (brcmf_fil_iovar_int_set(drvr->iflist[0],
--+			if (brcmf_fil_iovar_int_set(ifp,
-- 						    "wlfc_mode", mode) == 0) {
-- 				BRCMF_FWS_MODE_SET_REUSESEQ(fws->mode, 1);
-- 			}
-diff --git a/package/kernel/mac80211/patches/394-0007-brcmfmac-pass-struct-brcmf_if-instance-in-brcmf_txfi.patch b/package/kernel/mac80211/patches/394-0007-brcmfmac-pass-struct-brcmf_if-instance-in-brcmf_txfi.patch
-deleted file mode 100644
-index 23a7b6f..0000000
---- a/package/kernel/mac80211/patches/394-0007-brcmfmac-pass-struct-brcmf_if-instance-in-brcmf_txfi.patch
-+++ /dev/null
-@@ -1,122 +0,0 @@
--From: Arend van Spriel <arend@broadcom.com>
--Date: Wed, 26 Aug 2015 22:14:59 +0200
--Subject: [PATCH] brcmfmac: pass struct brcmf_if instance in
-- brcmf_txfinalize()
--
--Most call sites of brcmf_txfinalize already have struct brcmf_if
--instance so pass that to brcmf_txfinalize() as the function
--needs it anyway.
--
--Reviewed-by: Hante Meuleman <meuleman@broadcom.com>
--Reviewed-by: Franky (Zhenhui) Lin <frankyl@broadcom.com>
--Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
--Signed-off-by: Arend van Spriel <arend@broadcom.com>
-----
--
----- a/drivers/net/wireless/brcm80211/brcmfmac/core.c
--+++ b/drivers/net/wireless/brcm80211/brcmfmac/core.c
--@@ -560,17 +560,11 @@ void brcmf_rx_frame(struct device *dev,
-- 		brcmf_netif_rx(ifp, skb);
-- }
-- 
---void brcmf_txfinalize(struct brcmf_pub *drvr, struct sk_buff *txp, u8 ifidx,
---		      bool success)
--+void brcmf_txfinalize(struct brcmf_if *ifp, struct sk_buff *txp, bool success)
-- {
---	struct brcmf_if *ifp;
-- 	struct ethhdr *eh;
-- 	u16 type;
-- 
---	ifp = drvr->iflist[ifidx];
---	if (!ifp)
---		goto done;
---
-- 	eh = (struct ethhdr *)(txp->data);
-- 	type = ntohs(eh->h_proto);
-- 
--@@ -582,7 +576,7 @@ void brcmf_txfinalize(struct brcmf_pub *
-- 
-- 	if (!success)
-- 		ifp->stats.tx_errors++;
---done:
--+
-- 	brcmu_pkt_buf_free_skb(txp);
-- }
-- 
--@@ -600,7 +594,7 @@ void brcmf_txcomplete(struct device *dev
-- 		if (brcmf_proto_hdrpull(drvr, false, txp, &ifp))
-- 			brcmu_pkt_buf_free_skb(txp);
-- 		else
---			brcmf_txfinalize(drvr, txp, ifp->ifidx, success);
--+			brcmf_txfinalize(ifp, txp, success);
-- 	}
-- }
-- 
----- a/drivers/net/wireless/brcm80211/brcmfmac/core.h
--+++ b/drivers/net/wireless/brcm80211/brcmfmac/core.h
--@@ -210,8 +210,7 @@ void brcmf_remove_interface(struct brcmf
-- int brcmf_get_next_free_bsscfgidx(struct brcmf_pub *drvr);
-- void brcmf_txflowblock_if(struct brcmf_if *ifp,
-- 			  enum brcmf_netif_stop_reason reason, bool state);
---void brcmf_txfinalize(struct brcmf_pub *drvr, struct sk_buff *txp, u8 ifidx,
---		      bool success);
--+void brcmf_txfinalize(struct brcmf_if *ifp, struct sk_buff *txp, bool success);
-- void brcmf_netif_rx(struct brcmf_if *ifp, struct sk_buff *skb);
-- 
-- /* Sets dongle media info (drv_version, mac address). */
----- a/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c
--+++ b/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c
--@@ -1506,7 +1506,7 @@ brcmf_fws_txs_process(struct brcmf_fws_i
-- 		ret = brcmf_fws_txstatus_suppressed(fws, fifo, skb, ifp->ifidx,
-- 						    genbit, seq);
-- 	if (remove_from_hanger || ret)
---		brcmf_txfinalize(fws->drvr, skb, ifp->ifidx, true);
--+		brcmf_txfinalize(ifp, skb, true);
-- 
-- 	return 0;
-- }
--@@ -1905,7 +1905,7 @@ int brcmf_fws_process_skb(struct brcmf_i
-- 	if (fws->avoid_queueing) {
-- 		rc = brcmf_proto_txdata(drvr, ifp->ifidx, 0, skb);
-- 		if (rc < 0)
---			brcmf_txfinalize(drvr, skb, ifp->ifidx, false);
--+			brcmf_txfinalize(ifp, skb, false);
-- 		return rc;
-- 	}
-- 
--@@ -1929,7 +1929,7 @@ int brcmf_fws_process_skb(struct brcmf_i
-- 		brcmf_fws_schedule_deq(fws);
-- 	} else {
-- 		brcmf_err("drop skb: no hanger slot\n");
---		brcmf_txfinalize(drvr, skb, ifp->ifidx, false);
--+		brcmf_txfinalize(ifp, skb, false);
-- 		rc = -ENOMEM;
-- 	}
-- 	brcmf_fws_unlock(fws);
--@@ -2009,8 +2009,9 @@ static void brcmf_fws_dequeue_worker(str
-- 				ret = brcmf_proto_txdata(drvr, ifidx, 0, skb);
-- 				brcmf_fws_lock(fws);
-- 				if (ret < 0)
---					brcmf_txfinalize(drvr, skb, ifidx,
---							 false);
--+					brcmf_txfinalize(brcmf_get_ifp(drvr,
--+								       ifidx),
--+							 skb, false);
-- 				if (fws->bus_flow_blocked)
-- 					break;
-- 			}
----- a/drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c
--+++ b/drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c
--@@ -873,7 +873,11 @@ brcmf_msgbuf_process_txstatus(struct brc
-- 	commonring = msgbuf->flowrings[flowid];
-- 	atomic_dec(&commonring->outstanding_tx);
-- 
---	brcmf_txfinalize(msgbuf->drvr, skb, tx_status->msg.ifidx, true);
--+	/* Hante: i believe this was a bug as tx_status->msg.ifidx was used
--+	 * in brcmf_txfinalize as index in drvr->iflist. Can you confirm/deny?
--+	 */
--+	brcmf_txfinalize(brcmf_get_ifp(msgbuf->drvr, tx_status->msg.ifidx),
--+			 skb, true);
-- }
-- 
-- 
-diff --git a/package/kernel/mac80211/patches/394-0008-brcmfmac-add-mapping-for-interface-index-to-bsscfg-i.patch b/package/kernel/mac80211/patches/394-0008-brcmfmac-add-mapping-for-interface-index-to-bsscfg-i.patch
-deleted file mode 100644
-index 8ddc0a6..0000000
---- a/package/kernel/mac80211/patches/394-0008-brcmfmac-add-mapping-for-interface-index-to-bsscfg-i.patch
-+++ /dev/null
-@@ -1,92 +0,0 @@
--From: Arend van Spriel <arend@broadcom.com>
--Date: Wed, 26 Aug 2015 22:15:00 +0200
--Subject: [PATCH] brcmfmac: add mapping for interface index to bsscfg
-- index
--
--Because the P2P Device interface in firmware uses the same interface
--index as the primary interface we use the bsscfg index as index in the
--struct brcmf_pub::iflist. However, in the data path we get the interface
--index and not the bsscfg index. So we need a mapping of interface index
--to bsscfg index, which can be determined upon handle adding the interface.
--
--Reviewed-by: Hante Meuleman <meuleman@broadcom.com>
--Reviewed-by: Franky (Zhenhui) Lin <frankyl@broadcom.com>
--Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
--Signed-off-by: Arend van Spriel <arend@broadcom.com>
-----
--
----- a/drivers/net/wireless/brcm80211/brcmfmac/core.c
--+++ b/drivers/net/wireless/brcm80211/brcmfmac/core.c
--@@ -85,21 +85,20 @@ char *brcmf_ifname(struct brcmf_pub *drv
-- 
-- struct brcmf_if *brcmf_get_ifp(struct brcmf_pub *drvr, int ifidx)
-- {
--+	struct brcmf_if *ifp;
--+	s32 bssidx;
--+
-- 	if (ifidx < 0 || ifidx >= BRCMF_MAX_IFS) {
-- 		brcmf_err("ifidx %d out of range\n", ifidx);
-- 		return NULL;
-- 	}
-- 
---	/* The ifidx is the idx to map to matching netdev/ifp. When receiving
---	 * events this is easy because it contains the bssidx which maps
---	 * 1-on-1 to the netdev/ifp. But for data frames the ifidx is rcvd.
---	 * bssidx 1 is used for p2p0 and no data can be received or
---	 * transmitted on it. Therefor bssidx is ifidx + 1 if ifidx > 0
---	 */
---	if (ifidx)
---		ifidx++;
--+	ifp = NULL;
--+	bssidx = drvr->if2bss[ifidx];
--+	if (bssidx >= 0)
--+		ifp = drvr->iflist[bssidx];
-- 
---	return drvr->iflist[ifidx];
--+	return ifp;
-- }
-- 
-- static void _brcmf_set_multicast_list(struct work_struct *work)
--@@ -831,6 +830,8 @@ struct brcmf_if *brcmf_add_if(struct brc
-- 
-- 		ifp = netdev_priv(ndev);
-- 		ifp->ndev = ndev;
--+		/* store mapping ifidx to bssidx */
--+		drvr->if2bss[ifidx] = bssidx;
-- 	}
-- 
-- 	ifp->drvr = drvr;
--@@ -855,6 +856,7 @@ static void brcmf_del_if(struct brcmf_pu
-- 	struct brcmf_if *ifp;
-- 
-- 	ifp = drvr->iflist[bssidx];
--+	drvr->if2bss[ifp->ifidx] = -1;
-- 	drvr->iflist[bssidx] = NULL;
-- 	if (!ifp) {
-- 		brcmf_err("Null interface, idx=%d\n", bssidx);
--@@ -862,6 +864,7 @@ static void brcmf_del_if(struct brcmf_pu
-- 	}
-- 	brcmf_dbg(TRACE, "Enter, idx=%d, ifidx=%d\n", bssidx, ifp->ifidx);
-- 	if (ifp->ndev) {
--+		drvr->if2bss[ifp->ifidx] = -1;
-- 		if (bssidx == 0) {
-- 			if (ifp->ndev->netdev_ops == &brcmf_netdev_ops_pri) {
-- 				rtnl_lock();
--@@ -926,6 +929,7 @@ int brcmf_attach(struct device *dev)
-- 	if (!drvr)
-- 		return -ENOMEM;
-- 
--+	memset(drvr->if2bss, 0xFF, sizeof(drvr->if2bss));
-- 	mutex_init(&drvr->proto_block);
-- 
-- 	/* Link to bus module */
----- a/drivers/net/wireless/brcm80211/brcmfmac/core.h
--+++ b/drivers/net/wireless/brcm80211/brcmfmac/core.h
--@@ -122,6 +122,7 @@ struct brcmf_pub {
-- 	struct mac_address addresses[BRCMF_MAX_IFS];
-- 
-- 	struct brcmf_if *iflist[BRCMF_MAX_IFS];
--+	s32 if2bss[BRCMF_MAX_IFS];
-- 
-- 	struct mutex proto_block;
-- 	unsigned char proto_buf[BRCMF_DCMD_MAXLEN];
-diff --git a/package/kernel/mac80211/patches/394-0009-brcmfmac-add-dedicated-debug-level-for-firmware-cons.patch b/package/kernel/mac80211/patches/394-0009-brcmfmac-add-dedicated-debug-level-for-firmware-cons.patch
-deleted file mode 100644
-index a0a798b..0000000
---- a/package/kernel/mac80211/patches/394-0009-brcmfmac-add-dedicated-debug-level-for-firmware-cons.patch
-+++ /dev/null
-@@ -1,103 +0,0 @@
--From: Arend van Spriel <arend@broadcom.com>
--Date: Wed, 26 Aug 2015 22:15:01 +0200
--Subject: [PATCH] brcmfmac: add dedicated debug level for firmware
-- console logging
--
--Both PCIe and SDIO devices have the possibility to log the firmware
--console output in kernel log. For PCIe it is logged when PCIE debug
--level is enabled. For SDIO it is logged when user specifies a non-zero
--console interval through debugfs. This patch tries to make it a
--bit more consistent. The firmware console output is only logged when
--FWCON debug level is enabled.
--
--Reviewed-by: Hante Meuleman <meuleman@broadcom.com>
--Reviewed-by: Franky (Zhenhui) Lin <frankyl@broadcom.com>
--Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
--Reviewed-by: Pontus Fuchs <pontusf@broadcom.com>
--Signed-off-by: Arend van Spriel <arend@broadcom.com>
-----
--
----- a/drivers/net/wireless/brcm80211/brcmfmac/debug.h
--+++ b/drivers/net/wireless/brcm80211/brcmfmac/debug.h
--@@ -37,6 +37,7 @@
-- #define BRCMF_SDIO_VAL		0x00020000
-- #define BRCMF_MSGBUF_VAL	0x00040000
-- #define BRCMF_PCIE_VAL		0x00080000
--+#define BRCMF_FWCON_VAL		0x00100000
-- 
-- /* set default print format */
-- #undef pr_fmt
--@@ -78,6 +79,7 @@ do {								\
-- #define BRCMF_GLOM_ON()		(brcmf_msg_level & BRCMF_GLOM_VAL)
-- #define BRCMF_EVENT_ON()	(brcmf_msg_level & BRCMF_EVENT_VAL)
-- #define BRCMF_FIL_ON()		(brcmf_msg_level & BRCMF_FIL_VAL)
--+#define BRCMF_FWCON_ON()	(brcmf_msg_level & BRCMF_FWCON_VAL)
-- 
-- #else /* defined(DEBUG) || defined(CPTCFG_BRCM_TRACING) */
-- 
--@@ -90,6 +92,7 @@ do {								\
-- #define BRCMF_GLOM_ON()		0
-- #define BRCMF_EVENT_ON()	0
-- #define BRCMF_FIL_ON()		0
--+#define BRCMF_FWCON_ON()	0
-- 
-- #endif /* defined(DEBUG) || defined(CPTCFG_BRCM_TRACING) */
-- 
----- a/drivers/net/wireless/brcm80211/brcmfmac/pcie.c
--+++ b/drivers/net/wireless/brcm80211/brcmfmac/pcie.c
--@@ -644,7 +644,7 @@ static void brcmf_pcie_bus_console_init(
-- 	addr = console->base_addr + BRCMF_CONSOLE_BUFSIZE_OFFSET;
-- 	console->bufsize = brcmf_pcie_read_tcm32(devinfo, addr);
-- 
---	brcmf_dbg(PCIE, "Console: base %x, buf %x, size %d\n",
--+	brcmf_dbg(FWCON, "Console: base %x, buf %x, size %d\n",
-- 		  console->base_addr, console->buf_addr, console->bufsize);
-- }
-- 
--@@ -656,6 +656,9 @@ static void brcmf_pcie_bus_console_read(
-- 	u8 ch;
-- 	u32 newidx;
-- 
--+	if (!BRCMF_FWCON_ON())
--+		return;
--+
-- 	console = &devinfo->shared.console;
-- 	addr = console->base_addr + BRCMF_CONSOLE_WRITEIDX_OFFSET;
-- 	newidx = brcmf_pcie_read_tcm32(devinfo, addr);
--@@ -677,7 +680,7 @@ static void brcmf_pcie_bus_console_read(
-- 		}
-- 		if (ch == '\n') {
-- 			console->log_str[console->log_idx] = 0;
---			brcmf_dbg(PCIE, "CONSOLE: %s", console->log_str);
--+			pr_debug("CONSOLE: %s", console->log_str);
-- 			console->log_idx = 0;
-- 		}
-- 	}
----- a/drivers/net/wireless/brcm80211/brcmfmac/sdio.c
--+++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio.c
--@@ -123,6 +123,7 @@ struct rte_console {
-- 
-- #define BRCMF_FIRSTREAD	(1 << 6)
-- 
--+#define BRCMF_CONSOLE	10	/* watchdog interval to poll console */
-- 
-- /* SBSDIO_DEVICE_CTL */
-- 
--@@ -3204,6 +3205,8 @@ static void brcmf_sdio_debugfs_create(st
-- 	if (IS_ERR_OR_NULL(dentry))
-- 		return;
-- 
--+	bus->console_interval = BRCMF_CONSOLE;
--+
-- 	brcmf_debugfs_add_entry(drvr, "forensics", brcmf_sdio_forensic_read);
-- 	brcmf_debugfs_add_entry(drvr, "counters",
-- 				brcmf_debugfs_sdio_count_read);
--@@ -3613,7 +3616,7 @@ static void brcmf_sdio_bus_watchdog(stru
-- 	}
-- #ifdef DEBUG
-- 	/* Poll for console output periodically */
---	if (bus->sdiodev->state == BRCMF_SDIOD_DATA &&
--+	if (bus->sdiodev->state == BRCMF_SDIOD_DATA && BRCMF_FWCON_ON() &&
-- 	    bus->console_interval != 0) {
-- 		bus->console.count += BRCMF_WD_POLL_MS;
-- 		if (bus->console.count >= bus->console_interval) {
-diff --git a/package/kernel/mac80211/patches/394-0010-brcmfmac-remove-ifidx-parameter-from-brcmf_fws_txsta.patch b/package/kernel/mac80211/patches/394-0010-brcmfmac-remove-ifidx-parameter-from-brcmf_fws_txsta.patch
-deleted file mode 100644
-index 53e7ede..0000000
---- a/package/kernel/mac80211/patches/394-0010-brcmfmac-remove-ifidx-parameter-from-brcmf_fws_txsta.patch
-+++ /dev/null
-@@ -1,34 +0,0 @@
--From: Arend van Spriel <arend@broadcom.com>
--Date: Wed, 26 Aug 2015 22:15:02 +0200
--Subject: [PATCH] brcmfmac: remove ifidx parameter from
-- brcmf_fws_txstatus_suppressed()
--
--The brcmf_fws_txstatus_suppressed() function prototype specifies an
--ifidx parameter which is not used within the function implementation.
--
--Reviewed-by: Hante Meuleman <meuleman@broadcom.com>
--Reviewed-by: Franky (Zhenhui) Lin <frankyl@broadcom.com>
--Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
--Signed-off-by: Arend van Spriel <arend@broadcom.com>
-----
--
----- a/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c
--+++ b/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c
--@@ -1398,7 +1398,7 @@ done:
-- }
-- 
-- static int brcmf_fws_txstatus_suppressed(struct brcmf_fws_info *fws, int fifo,
---					 struct sk_buff *skb, u8 ifidx,
--+					 struct sk_buff *skb,
-- 					 u32 genbit, u16 seq)
-- {
-- 	struct brcmf_fws_mac_descriptor *entry = brcmf_skbcb(skb)->mac;
--@@ -1503,7 +1503,7 @@ brcmf_fws_txs_process(struct brcmf_fws_i
-- 		return -EINVAL;
-- 	}
-- 	if (!remove_from_hanger)
---		ret = brcmf_fws_txstatus_suppressed(fws, fifo, skb, ifp->ifidx,
--+		ret = brcmf_fws_txstatus_suppressed(fws, fifo, skb,
-- 						    genbit, seq);
-- 	if (remove_from_hanger || ret)
-- 		brcmf_txfinalize(ifp, skb, true);
-diff --git a/package/kernel/mac80211/patches/394-0011-brcmfmac-change-prototype-for-brcmf_fws_hdrpull.patch b/package/kernel/mac80211/patches/394-0011-brcmfmac-change-prototype-for-brcmf_fws_hdrpull.patch
-deleted file mode 100644
-index bb05235..0000000
---- a/package/kernel/mac80211/patches/394-0011-brcmfmac-change-prototype-for-brcmf_fws_hdrpull.patch
-+++ /dev/null
-@@ -1,97 +0,0 @@
--From: Arend van Spriel <arend@broadcom.com>
--Date: Wed, 26 Aug 2015 22:15:03 +0200
--Subject: [PATCH] brcmfmac: change prototype for brcmf_fws_hdrpull()
--
--Instead of passing ifidx and drvr just pass struct brcmf_if pointer
--which holds both parameters.
--
--Reviewed-by: Hante Meuleman <meuleman@broadcom.com>
--Reviewed-by: Franky (Zhenhui) Lin <frankyl@broadcom.com>
--Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
--Signed-off-by: Arend van Spriel <arend@broadcom.com>
-----
--
----- a/drivers/net/wireless/brcm80211/brcmfmac/bcdc.c
--+++ b/drivers/net/wireless/brcm80211/brcmfmac/bcdc.c
--@@ -312,8 +312,7 @@ brcmf_proto_bcdc_hdrpull(struct brcmf_pu
-- 
-- 	skb_pull(pktbuf, BCDC_HEADER_LEN);
-- 	if (do_fws)
---		brcmf_fws_hdrpull(drvr, tmp_if->ifidx, h->data_offset << 2,
---				  pktbuf);
--+		brcmf_fws_hdrpull(tmp_if, h->data_offset << 2, pktbuf);
-- 	else
-- 		skb_pull(pktbuf, h->data_offset << 2);
-- 
----- a/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c
--+++ b/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c
--@@ -1616,11 +1616,10 @@ static int brcmf_fws_notify_bcmc_credit_
-- 	return 0;
-- }
-- 
---int brcmf_fws_hdrpull(struct brcmf_pub *drvr, int ifidx, s16 signal_len,
---		      struct sk_buff *skb)
--+void brcmf_fws_hdrpull(struct brcmf_if *ifp, s16 siglen, struct sk_buff *skb)
-- {
-- 	struct brcmf_skb_reorder_data *rd;
---	struct brcmf_fws_info *fws = drvr->fws;
--+	struct brcmf_fws_info *fws = ifp->drvr->fws;
-- 	u8 *signal_data;
-- 	s16 data_len;
-- 	u8 type;
--@@ -1630,20 +1629,20 @@ int brcmf_fws_hdrpull(struct brcmf_pub *
-- 	s32 err;
-- 
-- 	brcmf_dbg(HDRS, "enter: ifidx %d, skblen %u, sig %d\n",
---		  ifidx, skb->len, signal_len);
--+		  ifp->ifidx, skb->len, siglen);
-- 
---	WARN_ON(signal_len > skb->len);
--+	WARN_ON(siglen > skb->len);
-- 
---	if (!signal_len)
---		return 0;
--+	if (!siglen)
--+		return;
-- 	/* if flow control disabled, skip to packet data and leave */
-- 	if ((!fws) || (!fws->fw_signals)) {
---		skb_pull(skb, signal_len);
---		return 0;
--+		skb_pull(skb, siglen);
--+		return;
-- 	}
-- 
-- 	fws->stats.header_pulls++;
---	data_len = signal_len;
--+	data_len = siglen;
-- 	signal_data = skb->data;
-- 
-- 	status = BRCMF_FWS_RET_OK_NOSCHEDULE;
--@@ -1731,14 +1730,12 @@ int brcmf_fws_hdrpull(struct brcmf_pub *
-- 	/* signalling processing result does
-- 	 * not affect the actual ethernet packet.
-- 	 */
---	skb_pull(skb, signal_len);
--+	skb_pull(skb, siglen);
-- 
-- 	/* this may be a signal-only packet
-- 	 */
-- 	if (skb->len == 0)
-- 		fws->stats.header_only_pkt++;
---
---	return 0;
-- }
-- 
-- static u8 brcmf_fws_precommit_skb(struct brcmf_fws_info *fws, int fifo,
----- a/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.h
--+++ b/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.h
--@@ -21,8 +21,7 @@
-- int brcmf_fws_init(struct brcmf_pub *drvr);
-- void brcmf_fws_deinit(struct brcmf_pub *drvr);
-- bool brcmf_fws_fc_active(struct brcmf_fws_info *fws);
---int brcmf_fws_hdrpull(struct brcmf_pub *drvr, int ifidx, s16 signal_len,
---		      struct sk_buff *skb);
--+void brcmf_fws_hdrpull(struct brcmf_if *ifp, s16 siglen, struct sk_buff *skb);
-- int brcmf_fws_process_skb(struct brcmf_if *ifp, struct sk_buff *skb);
-- 
-- void brcmf_fws_reset_interface(struct brcmf_if *ifp);
-diff --git a/package/kernel/mac80211/patches/394-0012-brcmfmac-introduce-brcmf_net_detach-function.patch b/package/kernel/mac80211/patches/394-0012-brcmfmac-introduce-brcmf_net_detach-function.patch
-deleted file mode 100644
-index ba92c67..0000000
---- a/package/kernel/mac80211/patches/394-0012-brcmfmac-introduce-brcmf_net_detach-function.patch
-+++ /dev/null
-@@ -1,99 +0,0 @@
--From: Arend van Spriel <arend@broadcom.com>
--Date: Wed, 26 Aug 2015 22:15:04 +0200
--Subject: [PATCH] brcmfmac: introduce brcmf_net_detach() function
--
--In case of error during brcmf_bus_start() the network interfaces were
--freed using free_netdev(). However, the interfaces may have additional
--memory allocated which is not freed. The netdev has destructor set to
--brcmf_cfg80211_free_netdev() which frees the additional memory if
--allocated and call free_netdev(). The brcmf_net_detach() either calls
--brcmf_cfg80211_free_netdev() directly or uses unregister_netdev() when
--struct net_device::reg_state indicates the netdev was registered.
--
--Reported-by: Daniel (Deognyoun) Kim <dekim@broadcom.com>
--Reviewed-by: Hante Meuleman <meuleman@broadcom.com>
--Reviewed-by: Franky (Zhenhui) Lin <frankyl@broadcom.com>
--Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
--Signed-off-by: Arend van Spriel <arend@broadcom.com>
-----
--
----- a/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c
--+++ b/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c
--@@ -4746,7 +4746,8 @@ void brcmf_cfg80211_free_netdev(struct n
-- 	ifp = netdev_priv(ndev);
-- 	vif = ifp->vif;
-- 
---	brcmf_free_vif(vif);
--+	if (vif)
--+		brcmf_free_vif(vif);
-- 	free_netdev(ndev);
-- }
-- 
----- a/drivers/net/wireless/brcm80211/brcmfmac/core.c
--+++ b/drivers/net/wireless/brcm80211/brcmfmac/core.c
--@@ -718,8 +718,6 @@ int brcmf_net_attach(struct brcmf_if *if
-- 	}
-- 
-- 	brcmf_dbg(INFO, "%s: Broadcom Dongle Host Driver\n", ndev->name);
---
---	ndev->destructor = brcmf_cfg80211_free_netdev;
-- 	return 0;
-- 
-- fail:
--@@ -729,6 +727,14 @@ fail:
-- 	return -EBADE;
-- }
-- 
--+static void brcmf_net_detach(struct net_device *ndev)
--+{
--+	if (ndev->reg_state == NETREG_REGISTERED)
--+		unregister_netdev(ndev);
--+	else
--+		brcmf_cfg80211_free_netdev(ndev);
--+}
--+
-- static int brcmf_net_p2p_open(struct net_device *ndev)
-- {
-- 	brcmf_dbg(TRACE, "Enter\n");
--@@ -805,8 +811,7 @@ struct brcmf_if *brcmf_add_if(struct brc
-- 			  ifp->ndev->name);
-- 		if (ifidx) {
-- 			netif_stop_queue(ifp->ndev);
---			unregister_netdev(ifp->ndev);
---			free_netdev(ifp->ndev);
--+			brcmf_net_detach(ifp->ndev);
-- 			drvr->iflist[bssidx] = NULL;
-- 		} else {
-- 			brcmf_err("ignore IF event\n");
--@@ -828,6 +833,7 @@ struct brcmf_if *brcmf_add_if(struct brc
-- 		if (!ndev)
-- 			return ERR_PTR(-ENOMEM);
-- 
--+		ndev->destructor = brcmf_cfg80211_free_netdev;
-- 		ifp = netdev_priv(ndev);
-- 		ifp->ndev = ndev;
-- 		/* store mapping ifidx to bssidx */
--@@ -879,8 +885,7 @@ static void brcmf_del_if(struct brcmf_pu
-- 			cancel_work_sync(&ifp->setmacaddr_work);
-- 			cancel_work_sync(&ifp->multicast_work);
-- 		}
---		/* unregister will take care of freeing it */
---		unregister_netdev(ifp->ndev);
--+		brcmf_net_detach(ifp->ndev);
-- 	}
-- }
-- 
--@@ -1056,11 +1061,11 @@ fail:
-- 			brcmf_fws_deinit(drvr);
-- 		}
-- 		if (drvr->iflist[0]) {
---			free_netdev(ifp->ndev);
--+			brcmf_net_detach(ifp->ndev);
-- 			drvr->iflist[0] = NULL;
-- 		}
-- 		if (p2p_ifp) {
---			free_netdev(p2p_ifp->ndev);
--+			brcmf_net_detach(p2p_ifp->ndev);
-- 			drvr->iflist[1] = NULL;
-- 		}
-- 		return ret;
-diff --git a/package/kernel/mac80211/patches/395-brcmfmac-Reset-PCIE-devices-after-recognition.patch b/package/kernel/mac80211/patches/395-brcmfmac-Reset-PCIE-devices-after-recognition.patch
-deleted file mode 100644
-index 5a7e447..0000000
---- a/package/kernel/mac80211/patches/395-brcmfmac-Reset-PCIE-devices-after-recognition.patch
-+++ /dev/null
-@@ -1,193 +0,0 @@
--From: Hante Meuleman <meuleman@broadcom.com>
--Date: Thu, 27 Aug 2015 16:14:06 +0200
--Subject: [PATCH] brcmfmac: Reset PCIE devices after recognition.
--
--When PCIE type devices are being FW reloaded without being properly
--reset then the device ends up in a locked state, requiring the
--device to be completely powered down. This patch adds a reset
--through watchdog at the moment the device (cores) has been
--recognized. This will solve warm reboot issues.
--
--Cc: Rafal Milecki <zajec5@gmail.com>
--Reviewed-by: Arend Van Spriel <arend@broadcom.com>
--Reviewed-by: Franky (Zhenhui) Lin <frankyl@broadcom.com>
--Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
--Signed-off-by: Hante Meuleman <meuleman@broadcom.com>
--Signed-off-by: Arend van Spriel <arend@broadcom.com>
-----
--
----- a/drivers/net/wireless/brcm80211/brcmfmac/chip.c
--+++ b/drivers/net/wireless/brcm80211/brcmfmac/chip.c
--@@ -101,6 +101,9 @@
-- /* ARM Cortex M3 core, ID 0x82a */
-- #define BCM4329_CORE_ARM_BASE		0x18002000
-- 
--+/* Max possibly supported memory size (limited by IO mapped memory) */
--+#define BRCMF_CHIP_MAX_MEMSIZE		(4 * 1024 * 1024)
--+
-- #define CORE_SB(base, field) \
-- 		(base + SBCONFIGOFF + offsetof(struct sbconfig, field))
-- #define	SBCOREREV(sbidh) \
--@@ -687,6 +690,12 @@ static int brcmf_chip_get_raminfo(struct
-- 		brcmf_err("RAM size is undetermined\n");
-- 		return -ENOMEM;
-- 	}
--+
--+	if (ci->pub.ramsize > BRCMF_CHIP_MAX_MEMSIZE) {
--+		brcmf_err("RAM size is incorrect\n");
--+		return -ENOMEM;
--+	}
--+
-- 	return 0;
-- }
-- 
--@@ -899,6 +908,15 @@ static int brcmf_chip_recognition(struct
-- 
-- 	/* assure chip is passive for core access */
-- 	brcmf_chip_set_passive(&ci->pub);
--+
--+	/* Call bus specific reset function now. Cores have been determined
--+	 * but further access may require a chip specific reset at this point.
--+	 */
--+	if (ci->ops->reset) {
--+		ci->ops->reset(ci->ctx, &ci->pub);
--+		brcmf_chip_set_passive(&ci->pub);
--+	}
--+
-- 	return brcmf_chip_get_raminfo(ci);
-- }
-- 
----- a/drivers/net/wireless/brcm80211/brcmfmac/chip.h
--+++ b/drivers/net/wireless/brcm80211/brcmfmac/chip.h
--@@ -73,6 +73,7 @@ struct brcmf_buscore_ops {
-- 	u32 (*read32)(void *ctx, u32 addr);
-- 	void (*write32)(void *ctx, u32 addr, u32 value);
-- 	int (*prepare)(void *ctx);
--+	int (*reset)(void *ctx, struct brcmf_chip *chip);
-- 	int (*setup)(void *ctx, struct brcmf_chip *chip);
-- 	void (*activate)(void *ctx, struct brcmf_chip *chip, u32 rstvec);
-- };
----- a/drivers/net/wireless/brcm80211/brcmfmac/pcie.c
--+++ b/drivers/net/wireless/brcm80211/brcmfmac/pcie.c
--@@ -74,6 +74,8 @@ enum brcmf_pcie_state {
-- #define BRCMF_PCIE_REG_INTMASK			0x94
-- #define BRCMF_PCIE_REG_SBMBX			0x98
-- 
--+#define BRCMF_PCIE_REG_LINK_STATUS_CTRL		0xBC
--+
-- #define BRCMF_PCIE_PCIE2REG_INTMASK		0x24
-- #define BRCMF_PCIE_PCIE2REG_MAILBOXINT		0x48
-- #define BRCMF_PCIE_PCIE2REG_MAILBOXMASK		0x4C
--@@ -466,6 +468,7 @@ brcmf_pcie_select_core(struct brcmf_pcie
-- 
-- static void brcmf_pcie_reset_device(struct brcmf_pciedev_info *devinfo)
-- {
--+	struct brcmf_core *core;
-- 	u16 cfg_offset[] = { BRCMF_PCIE_CFGREG_STATUS_CMD,
-- 			     BRCMF_PCIE_CFGREG_PM_CSR,
-- 			     BRCMF_PCIE_CFGREG_MSI_CAP,
--@@ -484,32 +487,38 @@ static void brcmf_pcie_reset_device(stru
-- 	if (!devinfo->ci)
-- 		return;
-- 
--+	/* Disable ASPM */
-- 	brcmf_pcie_select_core(devinfo, BCMA_CORE_PCIE2);
---	brcmf_pcie_write_reg32(devinfo, BRCMF_PCIE_PCIE2REG_CONFIGADDR,
---			       BRCMF_PCIE_CFGREG_LINK_STATUS_CTRL);
---	lsc = brcmf_pcie_read_reg32(devinfo, BRCMF_PCIE_PCIE2REG_CONFIGDATA);
--+	pci_read_config_dword(devinfo->pdev, BRCMF_PCIE_REG_LINK_STATUS_CTRL,
--+			      &lsc);
-- 	val = lsc & (~BRCMF_PCIE_LINK_STATUS_CTRL_ASPM_ENAB);
---	brcmf_pcie_write_reg32(devinfo, BRCMF_PCIE_PCIE2REG_CONFIGDATA, val);
--+	pci_write_config_dword(devinfo->pdev, BRCMF_PCIE_REG_LINK_STATUS_CTRL,
--+			       val);
-- 
--+	/* Watchdog reset */
-- 	brcmf_pcie_select_core(devinfo, BCMA_CORE_CHIPCOMMON);
-- 	WRITECC32(devinfo, watchdog, 4);
-- 	msleep(100);
-- 
--+	/* Restore ASPM */
-- 	brcmf_pcie_select_core(devinfo, BCMA_CORE_PCIE2);
---	brcmf_pcie_write_reg32(devinfo, BRCMF_PCIE_PCIE2REG_CONFIGADDR,
---			       BRCMF_PCIE_CFGREG_LINK_STATUS_CTRL);
---	brcmf_pcie_write_reg32(devinfo, BRCMF_PCIE_PCIE2REG_CONFIGDATA, lsc);
--+	pci_write_config_dword(devinfo->pdev, BRCMF_PCIE_REG_LINK_STATUS_CTRL,
--+			       lsc);
-- 
---	brcmf_pcie_select_core(devinfo, BCMA_CORE_PCIE2);
---	for (i = 0; i < ARRAY_SIZE(cfg_offset); i++) {
---		brcmf_pcie_write_reg32(devinfo, BRCMF_PCIE_PCIE2REG_CONFIGADDR,
---				       cfg_offset[i]);
---		val = brcmf_pcie_read_reg32(devinfo,
---					    BRCMF_PCIE_PCIE2REG_CONFIGDATA);
---		brcmf_dbg(PCIE, "config offset 0x%04x, value 0x%04x\n",
---			  cfg_offset[i], val);
---		brcmf_pcie_write_reg32(devinfo, BRCMF_PCIE_PCIE2REG_CONFIGDATA,
---				       val);
--+	core = brcmf_chip_get_core(devinfo->ci, BCMA_CORE_PCIE2);
--+	if (core->rev <= 13) {
--+		for (i = 0; i < ARRAY_SIZE(cfg_offset); i++) {
--+			brcmf_pcie_write_reg32(devinfo,
--+					       BRCMF_PCIE_PCIE2REG_CONFIGADDR,
--+					       cfg_offset[i]);
--+			val = brcmf_pcie_read_reg32(devinfo,
--+				BRCMF_PCIE_PCIE2REG_CONFIGDATA);
--+			brcmf_dbg(PCIE, "config offset 0x%04x, value 0x%04x\n",
--+				  cfg_offset[i], val);
--+			brcmf_pcie_write_reg32(devinfo,
--+					       BRCMF_PCIE_PCIE2REG_CONFIGDATA,
--+					       val);
--+		}
-- 	}
-- }
-- 
--@@ -519,8 +528,6 @@ static void brcmf_pcie_attach(struct brc
-- 	u32 config;
-- 
-- 	brcmf_pcie_select_core(devinfo, BCMA_CORE_PCIE2);
---	if (brcmf_pcie_read_reg32(devinfo, BRCMF_PCIE_PCIE2REG_INTMASK) != 0)
---		brcmf_pcie_reset_device(devinfo);
-- 	/* BAR1 window may not be sized properly */
-- 	brcmf_pcie_select_core(devinfo, BCMA_CORE_PCIE2);
-- 	brcmf_pcie_write_reg32(devinfo, BRCMF_PCIE_PCIE2REG_CONFIGADDR, 0x4e0);
--@@ -1636,6 +1643,23 @@ static int brcmf_pcie_buscoreprep(void *
-- }
-- 
-- 
--+static int brcmf_pcie_buscore_reset(void *ctx, struct brcmf_chip *chip)
--+{
--+	struct brcmf_pciedev_info *devinfo = (struct brcmf_pciedev_info *)ctx;
--+	u32 val;
--+
--+	devinfo->ci = chip;
--+	brcmf_pcie_reset_device(devinfo);
--+
--+	val = brcmf_pcie_read_reg32(devinfo, BRCMF_PCIE_PCIE2REG_MAILBOXINT);
--+	if (val != 0xffffffff)
--+		brcmf_pcie_write_reg32(devinfo, BRCMF_PCIE_PCIE2REG_MAILBOXINT,
--+				       val);
--+
--+	return 0;
--+}
--+
--+
-- static void brcmf_pcie_buscore_activate(void *ctx, struct brcmf_chip *chip,
-- 					u32 rstvec)
-- {
--@@ -1647,6 +1671,7 @@ static void brcmf_pcie_buscore_activate(
-- 
-- static const struct brcmf_buscore_ops brcmf_pcie_buscore_ops = {
-- 	.prepare = brcmf_pcie_buscoreprep,
--+	.reset = brcmf_pcie_buscore_reset,
-- 	.activate = brcmf_pcie_buscore_activate,
-- 	.read32 = brcmf_pcie_buscore_read32,
-- 	.write32 = brcmf_pcie_buscore_write32,
--@@ -1814,7 +1839,6 @@ brcmf_pcie_remove(struct pci_dev *pdev)
-- 		brcmf_pcie_intr_disable(devinfo);
-- 
-- 	brcmf_detach(&pdev->dev);
---	brcmf_pcie_reset_device(devinfo);
-- 
-- 	kfree(bus->bus_priv.pcie);
-- 	kfree(bus->msgbuf->flowrings);
-diff --git a/package/kernel/mac80211/patches/400-ath_move_debug_code.patch b/package/kernel/mac80211/patches/400-ath_move_debug_code.patch
-index 298f722..72e9a41 100644
---- a/package/kernel/mac80211/patches/400-ath_move_debug_code.patch
-+++ b/package/kernel/mac80211/patches/400-ath_move_debug_code.patch
-@@ -14,7 +14,7 @@
-  ccflags-y += -D__CHECK_ENDIAN__
- --- a/drivers/net/wireless/ath/ath.h
- +++ b/drivers/net/wireless/ath/ath.h
--@@ -316,13 +316,6 @@ void _ath_dbg(struct ath_common *common,
-+@@ -318,13 +318,6 @@ void _ath_dbg(struct ath_common *common,
-  #endif /* CPTCFG_ATH_DEBUG */
-  
-  /** Returns string describing opmode, or NULL if unknown mode. */
-diff --git a/package/kernel/mac80211/patches/402-ath_regd_optional.patch b/package/kernel/mac80211/patches/402-ath_regd_optional.patch
-index 2dac505..f918c18 100644
---- a/package/kernel/mac80211/patches/402-ath_regd_optional.patch
-+++ b/package/kernel/mac80211/patches/402-ath_regd_optional.patch
-@@ -59,7 +59,7 @@
-  	---help---
- --- a/.local-symbols
- +++ b/.local-symbols
--@@ -89,6 +89,7 @@ RTL8187_LEDS=
-+@@ -137,6 +137,7 @@ RTL8187_LEDS=
-  ATH_COMMON=
-  ATH_CARDS=
-  ATH_DEBUG=
-diff --git a/package/kernel/mac80211/patches/404-regd_no_assoc_hints.patch b/package/kernel/mac80211/patches/404-regd_no_assoc_hints.patch
-index 1476953..8b52ac3 100644
---- a/package/kernel/mac80211/patches/404-regd_no_assoc_hints.patch
-+++ b/package/kernel/mac80211/patches/404-regd_no_assoc_hints.patch
-@@ -1,6 +1,6 @@
- --- a/net/wireless/reg.c
- +++ b/net/wireless/reg.c
--@@ -2368,6 +2368,8 @@ void regulatory_hint_country_ie(struct w
-+@@ -2390,6 +2390,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;
--@@ -2571,6 +2573,7 @@ static void restore_regulatory_settings(
-+@@ -2596,6 +2598,7 @@ static void restore_regulatory_settings(
-  
-  void regulatory_hint_disconnect(void)
-  {
-diff --git a/package/kernel/mac80211/patches/410-ath9k_allow_adhoc_and_ap.patch b/package/kernel/mac80211/patches/410-ath9k_allow_adhoc_and_ap.patch
-index 93760f9..1a62484 100644
---- a/package/kernel/mac80211/patches/410-ath9k_allow_adhoc_and_ap.patch
-+++ b/package/kernel/mac80211/patches/410-ath9k_allow_adhoc_and_ap.patch
-@@ -1,6 +1,6 @@
- --- a/drivers/net/wireless/ath/ath9k/init.c
- +++ b/drivers/net/wireless/ath/ath9k/init.c
--@@ -715,6 +715,7 @@ static const struct ieee80211_iface_limi
-+@@ -722,6 +722,7 @@ static const struct ieee80211_iface_limi
-  				 BIT(NL80211_IFTYPE_AP) },
-  	{ .max = 1,	.types = BIT(NL80211_IFTYPE_P2P_CLIENT) |
-  				 BIT(NL80211_IFTYPE_P2P_GO) },
-diff --git a/package/kernel/mac80211/patches/440-ath5k_channel_bw_debugfs.patch b/package/kernel/mac80211/patches/440-ath5k_channel_bw_debugfs.patch
-index aa521d2..42d43a4 100644
---- a/package/kernel/mac80211/patches/440-ath5k_channel_bw_debugfs.patch
-+++ b/package/kernel/mac80211/patches/440-ath5k_channel_bw_debugfs.patch
-@@ -121,7 +121,7 @@ drivers/net/wireless/ath/ath5k/debug.c |   86 ++++++++++++++++++++++++++++++++
-  	debugfs_create_file("antenna", S_IWUSR | S_IRUSR, phydir, ah,
- --- a/drivers/net/wireless/ath/ath5k/ath5k.h
- +++ b/drivers/net/wireless/ath/ath5k/ath5k.h
--@@ -1371,6 +1371,7 @@ struct ath5k_hw {
-+@@ -1370,6 +1370,7 @@ struct ath5k_hw {
-  	u8			ah_coverage_class;
-  	bool			ah_ack_bitrate_high;
-  	u8			ah_bwmode;
-diff --git a/package/kernel/mac80211/patches/500-ath9k_eeprom_debugfs.patch b/package/kernel/mac80211/patches/500-ath9k_eeprom_debugfs.patch
-index c6f50be..a7f9d9f 100644
---- a/package/kernel/mac80211/patches/500-ath9k_eeprom_debugfs.patch
-+++ b/package/kernel/mac80211/patches/500-ath9k_eeprom_debugfs.patch
-@@ -1,6 +1,6 @@
- --- a/drivers/net/wireless/ath/ath9k/debug.c
- +++ b/drivers/net/wireless/ath/ath9k/debug.c
--@@ -1299,6 +1299,53 @@ void ath9k_deinit_debug(struct ath_softc
-+@@ -1301,6 +1301,53 @@ void ath9k_deinit_debug(struct ath_softc
-  	ath9k_cmn_spectral_deinit_debug(&sc->spec_priv);
-  }
-  
-@@ -54,7 +54,7 @@
-  int ath9k_init_debug(struct ath_hw *ah)
-  {
-  	struct ath_common *common = ath9k_hw_common(ah);
--@@ -1318,6 +1365,8 @@ int ath9k_init_debug(struct ath_hw *ah)
-+@@ -1320,6 +1367,8 @@ int ath9k_init_debug(struct ath_hw *ah)
-  	ath9k_tx99_init_debug(sc);
-  	ath9k_cmn_spectral_init_debug(&sc->spec_priv, sc->debug.debugfs_phy);
-  
-diff --git a/package/kernel/mac80211/patches/501-ath9k_ahb_init.patch b/package/kernel/mac80211/patches/501-ath9k_ahb_init.patch
-index 0bdcae4..b4e9762 100644
---- a/package/kernel/mac80211/patches/501-ath9k_ahb_init.patch
-+++ b/package/kernel/mac80211/patches/501-ath9k_ahb_init.patch
-@@ -1,6 +1,6 @@
- --- a/drivers/net/wireless/ath/ath9k/init.c
- +++ b/drivers/net/wireless/ath/ath9k/init.c
--@@ -1023,23 +1023,23 @@ static int __init ath9k_init(void)
-+@@ -1031,23 +1031,23 @@ static int __init ath9k_init(void)
-  {
-  	int error;
-  
-diff --git a/package/kernel/mac80211/patches/510-ath9k_intr_mitigation_tweak.patch b/package/kernel/mac80211/patches/510-ath9k_intr_mitigation_tweak.patch
-index ed2cfee..d2a3b96 100644
---- a/package/kernel/mac80211/patches/510-ath9k_intr_mitigation_tweak.patch
-+++ b/package/kernel/mac80211/patches/510-ath9k_intr_mitigation_tweak.patch
-@@ -1,6 +1,6 @@
- --- a/drivers/net/wireless/ath/ath9k/hw.c
- +++ b/drivers/net/wireless/ath/ath9k/hw.c
--@@ -389,13 +389,8 @@ static void ath9k_hw_init_config(struct
-+@@ -390,13 +390,8 @@ static void ath9k_hw_init_config(struct
-  
-  	ah->config.rx_intr_mitigation = true;
-  
-@@ -14,5 +14,5 @@
- +	ah->config.rimt_last = 250;
- +	ah->config.rimt_first = 500;
-  
-- 	/*
-- 	 * We need this for PCI devices only (Cardbus, PCI, miniPCI)
-+ 	if (AR_SREV_9462(ah) || AR_SREV_9565(ah))
-+ 		ah->config.pll_pwrsave = 7;
-diff --git a/package/kernel/mac80211/patches/511-ath9k_reduce_rxbuf.patch b/package/kernel/mac80211/patches/511-ath9k_reduce_rxbuf.patch
-index d4104f0..6766111 100644
---- a/package/kernel/mac80211/patches/511-ath9k_reduce_rxbuf.patch
-+++ b/package/kernel/mac80211/patches/511-ath9k_reduce_rxbuf.patch
-@@ -1,6 +1,6 @@
- --- a/drivers/net/wireless/ath/ath9k/ath9k.h
- +++ b/drivers/net/wireless/ath/ath9k/ath9k.h
--@@ -87,7 +87,7 @@ int ath_descdma_setup(struct ath_softc *
-+@@ -88,7 +88,7 @@ int ath_descdma_setup(struct ath_softc *
-  		(_l) &= ((_sz) - 1);		\
-  	} while (0)
-  
-diff --git a/package/kernel/mac80211/patches/512-ath9k_channelbw_debugfs.patch b/package/kernel/mac80211/patches/512-ath9k_channelbw_debugfs.patch
-index c0fbf5e..5ecf528 100644
---- a/package/kernel/mac80211/patches/512-ath9k_channelbw_debugfs.patch
-+++ b/package/kernel/mac80211/patches/512-ath9k_channelbw_debugfs.patch
-@@ -1,6 +1,6 @@
- --- a/drivers/net/wireless/ath/ath9k/debug.c
- +++ b/drivers/net/wireless/ath/ath9k/debug.c
--@@ -1346,6 +1346,52 @@ static const struct file_operations fops
-+@@ -1348,6 +1348,52 @@ static const struct file_operations fops
-  	.owner = THIS_MODULE
-  };
-  
-@@ -53,7 +53,7 @@
-  int ath9k_init_debug(struct ath_hw *ah)
-  {
-  	struct ath_common *common = ath9k_hw_common(ah);
--@@ -1367,6 +1413,8 @@ int ath9k_init_debug(struct ath_hw *ah)
-+@@ -1369,6 +1415,8 @@ int ath9k_init_debug(struct ath_hw *ah)
-  
-  	debugfs_create_file("eeprom", S_IRUSR, sc->debug.debugfs_phy, sc,
-  			    &fops_eeprom);
-diff --git a/package/kernel/mac80211/patches/513-ath9k_add_pci_ids.patch b/package/kernel/mac80211/patches/513-ath9k_add_pci_ids.patch
-index 40b5c81..c84d1bc 100644
---- a/package/kernel/mac80211/patches/513-ath9k_add_pci_ids.patch
-+++ b/package/kernel/mac80211/patches/513-ath9k_add_pci_ids.patch
-@@ -1,6 +1,6 @@
- --- a/drivers/net/wireless/ath/ath9k/hw.c
- +++ b/drivers/net/wireless/ath/ath9k/hw.c
--@@ -647,6 +647,7 @@ int ath9k_hw_init(struct ath_hw *ah)
-+@@ -651,6 +651,7 @@ int ath9k_hw_init(struct ath_hw *ah)
-  
-  	/* These are all the AR5008/AR9001/AR9002/AR9003 hardware family of chipsets */
-  	switch (ah->hw_version.devid) {
-diff --git a/package/kernel/mac80211/patches/522-mac80211_configure_antenna_gain.patch b/package/kernel/mac80211/patches/522-mac80211_configure_antenna_gain.patch
-index 0c50a0b..99bf7e8 100644
---- a/package/kernel/mac80211/patches/522-mac80211_configure_antenna_gain.patch
-+++ b/package/kernel/mac80211/patches/522-mac80211_configure_antenna_gain.patch
-@@ -18,7 +18,7 @@
-  				const u8 *addr);
- --- a/include/net/mac80211.h
- +++ b/include/net/mac80211.h
--@@ -1171,6 +1171,7 @@ enum ieee80211_smps_mode {
-+@@ -1252,6 +1252,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
--@@ -1192,6 +1193,7 @@ struct ieee80211_conf {
-+@@ -1273,6 +1274,7 @@ struct ieee80211_conf {
-  	u32 flags;
-  	int power_level, dynamic_ps_timeout;
-  	int max_sleep_period;
-@@ -36,7 +36,7 @@
-  	u8 ps_dtim_period;
- --- a/include/uapi/linux/nl80211.h
- +++ b/include/uapi/linux/nl80211.h
--@@ -1760,6 +1760,9 @@ enum nl80211_commands {
-+@@ -1761,6 +1761,9 @@ enum nl80211_commands {
-   * @NL80211_ATTR_REG_INDOOR: flag attribute, if set indicates that the device
-   *      is operating in an indoor environment.
-   *
-@@ -46,7 +46,7 @@
-   * @NUM_NL80211_ATTR: total number of nl80211_attrs available
-   * @NL80211_ATTR_MAX: highest attribute number currently defined
-   * @__NL80211_ATTR_AFTER_LAST: internal use
--@@ -2129,6 +2132,8 @@ enum nl80211_attrs {
-+@@ -2130,6 +2133,8 @@ enum nl80211_attrs {
-  
-  	NL80211_ATTR_REG_INDOOR,
-  
-@@ -57,7 +57,7 @@
-  	__NL80211_ATTR_AFTER_LAST,
- --- a/net/mac80211/cfg.c
- +++ b/net/mac80211/cfg.c
--@@ -2208,6 +2208,19 @@ static int ieee80211_get_tx_power(struct
-+@@ -2233,6 +2233,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)
-  {
--@@ -3771,6 +3784,7 @@ const struct cfg80211_ops mac80211_confi
-+@@ -3845,6 +3858,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
--@@ -1333,6 +1333,7 @@ struct ieee80211_local {
-+@@ -1318,6 +1318,7 @@ struct ieee80211_local {
-  	int dynamic_ps_forced_timeout;
-  
-  	int user_power_level; /* in dBm, for all interfaces */
-@@ -97,7 +97,7 @@
-  
- --- a/net/mac80211/main.c
- +++ b/net/mac80211/main.c
--@@ -98,7 +98,7 @@ static u32 ieee80211_hw_conf_chan(struct
-+@@ -95,7 +95,7 @@ static u32 ieee80211_hw_conf_chan(struct
-  	struct ieee80211_sub_if_data *sdata;
-  	struct cfg80211_chan_def chandef = {};
-  	u32 changed = 0;
-@@ -106,7 +106,7 @@
-  	u32 offchannel_flag;
-  
-  	offchannel_flag = local->hw.conf.flags & IEEE80211_CONF_OFFCHANNEL;
--@@ -155,6 +155,12 @@ static u32 ieee80211_hw_conf_chan(struct
-+@@ -152,6 +152,12 @@ static u32 ieee80211_hw_conf_chan(struct
-  	}
-  	rcu_read_unlock();
-  
-@@ -119,7 +119,7 @@
-  	if (local->hw.conf.power_level != power) {
-  		changed |= IEEE80211_CONF_CHANGE_POWER;
-  		local->hw.conf.power_level = power;
--@@ -578,6 +584,7 @@ struct ieee80211_hw *ieee80211_alloc_hw_
-+@@ -581,6 +587,7 @@ struct ieee80211_hw *ieee80211_alloc_hw_
-  					 IEEE80211_RADIOTAP_MCS_HAVE_BW;
-  	local->hw.radiotap_vht_details = IEEE80211_RADIOTAP_VHT_KNOWN_GI |
-  					 IEEE80211_RADIOTAP_VHT_KNOWN_BANDWIDTH;
-@@ -129,7 +129,7 @@
-  	local->user_power_level = IEEE80211_UNSET_POWER_LEVEL;
- --- a/net/wireless/nl80211.c
- +++ b/net/wireless/nl80211.c
--@@ -400,6 +400,7 @@ static const struct nla_policy nl80211_p
-+@@ -402,6 +402,7 @@ static const struct nla_policy nl80211_p
-  	[NL80211_ATTR_NETNS_FD] = { .type = NLA_U32 },
-  	[NL80211_ATTR_SCHED_SCAN_DELAY] = { .type = NLA_U32 },
-  	[NL80211_ATTR_REG_INDOOR] = { .type = NLA_FLAG },
-@@ -137,7 +137,7 @@
-  };
-  
-  /* policy for the key attributes */
--@@ -2206,6 +2207,20 @@ static int nl80211_set_wiphy(struct sk_b
-+@@ -2207,6 +2208,20 @@ static int nl80211_set_wiphy(struct sk_b
-  		if (result)
-  			return result;
-  	}
-diff --git a/package/kernel/mac80211/patches/530-ath9k_extra_leds.patch b/package/kernel/mac80211/patches/530-ath9k_extra_leds.patch
-index b0fb9fe..8aab45a 100644
---- a/package/kernel/mac80211/patches/530-ath9k_extra_leds.patch
-+++ b/package/kernel/mac80211/patches/530-ath9k_extra_leds.patch
-@@ -1,6 +1,6 @@
- --- a/drivers/net/wireless/ath/ath9k/ath9k.h
- +++ b/drivers/net/wireless/ath/ath9k/ath9k.h
--@@ -814,6 +814,9 @@ static inline int ath9k_dump_btcoex(stru
-+@@ -806,6 +806,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)
-  {
--@@ -953,6 +956,13 @@ void ath_ant_comb_scan(struct ath_softc
-+@@ -945,6 +948,13 @@ void ath_ant_comb_scan(struct ath_softc
-  
-  #define ATH9K_NUM_CHANCTX  2 /* supports 2 operating channels */
-  
-@@ -24,7 +24,7 @@
-  struct ath_softc {
-  	struct ieee80211_hw *hw;
-  	struct device *dev;
--@@ -1004,9 +1014,8 @@ struct ath_softc {
-+@@ -996,9 +1006,8 @@ struct ath_softc {
-  	spinlock_t chan_lock;
-  
-  #ifdef CPTCFG_MAC80211_LEDS
-@@ -165,7 +165,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
--@@ -935,7 +935,7 @@ int ath9k_init_device(u16 devid, struct
-+@@ -943,7 +943,7 @@ int ath9k_init_device(u16 devid, struct
-  
-  #ifdef CPTCFG_MAC80211_LEDS
-  	/* must be initialized before ieee80211_register_hw */
-@@ -176,7 +176,7 @@
-  #endif
- --- a/drivers/net/wireless/ath/ath9k/debug.c
- +++ b/drivers/net/wireless/ath/ath9k/debug.c
--@@ -1391,6 +1391,61 @@ static const struct file_operations fops
-+@@ -1393,6 +1393,61 @@ static const struct file_operations fops
-  	.llseek = default_llseek,
-  };
-  
-@@ -238,7 +238,7 @@
-  
-  int ath9k_init_debug(struct ath_hw *ah)
-  {
--@@ -1415,6 +1470,10 @@ int ath9k_init_debug(struct ath_hw *ah)
-+@@ -1417,6 +1472,10 @@ int ath9k_init_debug(struct ath_hw *ah)
-  			    &fops_eeprom);
-  	debugfs_create_file("chanbw", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy,
-  			    sc, &fops_chanbw);
-diff --git a/package/kernel/mac80211/patches/542-ath9k_debugfs_diag.patch b/package/kernel/mac80211/patches/542-ath9k_debugfs_diag.patch
-index 631a692..2b2c763 100644
---- a/package/kernel/mac80211/patches/542-ath9k_debugfs_diag.patch
-+++ b/package/kernel/mac80211/patches/542-ath9k_debugfs_diag.patch
-@@ -1,6 +1,6 @@
- --- a/drivers/net/wireless/ath/ath9k/debug.c
- +++ b/drivers/net/wireless/ath/ath9k/debug.c
--@@ -1447,6 +1447,50 @@ static const struct file_operations fops
-+@@ -1449,6 +1449,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);
--@@ -1474,6 +1518,8 @@ int ath9k_init_debug(struct ath_hw *ah)
-+@@ -1476,6 +1520,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
-@@ -62,7 +62,7 @@
-  	debugfs_create_devm_seqfile(sc->dev, "interrupt", sc->debug.debugfs_phy,
- --- a/drivers/net/wireless/ath/ath9k/hw.h
- +++ b/drivers/net/wireless/ath/ath9k/hw.h
--@@ -513,6 +513,12 @@ enum {
-+@@ -519,6 +519,12 @@ enum {
-  	ATH9K_RESET_COLD,
-  };
-  
-@@ -75,7 +75,7 @@
-  struct ath9k_hw_version {
-  	u32 magic;
-  	u16 devid;
--@@ -794,6 +800,8 @@ struct ath_hw {
-+@@ -804,6 +810,8 @@ struct ath_hw {
-  	u32 rfkill_polarity;
-  	u32 ah_flags;
-  
-@@ -84,7 +84,7 @@
-  	bool reset_power_on;
-  	bool htc_reset_init;
-  
--@@ -1055,6 +1063,7 @@ void ath9k_hw_check_nav(struct ath_hw *a
-+@@ -1066,6 +1074,7 @@ void ath9k_hw_check_nav(struct ath_hw *a
-  bool ath9k_hw_check_alive(struct ath_hw *ah);
-  
-  bool ath9k_hw_setpower(struct ath_hw *ah, enum ath9k_power_mode mode);
-@@ -94,7 +94,7 @@
-  struct ath_gen_timer *ath_gen_timer_alloc(struct ath_hw *ah,
- --- a/drivers/net/wireless/ath/ath9k/hw.c
- +++ b/drivers/net/wireless/ath/ath9k/hw.c
--@@ -1804,6 +1804,20 @@ u32 ath9k_hw_get_tsf_offset(struct times
-+@@ -1808,6 +1808,20 @@ u32 ath9k_hw_get_tsf_offset(struct times
-  }
-  EXPORT_SYMBOL(ath9k_hw_get_tsf_offset);
-  
-@@ -115,7 +115,7 @@
-  int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
-  		   struct ath9k_hw_cal_data *caldata, bool fastcc)
-  {
--@@ -2012,6 +2026,7 @@ int ath9k_hw_reset(struct ath_hw *ah, st
-+@@ -2016,6 +2030,7 @@ int ath9k_hw_reset(struct ath_hw *ah, st
-  		ar9003_hw_disable_phy_restart(ah);
-  
-  	ath9k_hw_apply_gpio_override(ah);
-diff --git a/package/kernel/mac80211/patches/543-ath9k_entropy_from_adc.patch b/package/kernel/mac80211/patches/543-ath9k_entropy_from_adc.patch
-index a8f1999..49b6367 100644
---- a/package/kernel/mac80211/patches/543-ath9k_entropy_from_adc.patch
-+++ b/package/kernel/mac80211/patches/543-ath9k_entropy_from_adc.patch
-@@ -1,6 +1,6 @@
- --- a/drivers/net/wireless/ath/ath9k/hw.h
- +++ b/drivers/net/wireless/ath/ath9k/hw.h
--@@ -710,6 +710,7 @@ struct ath_spec_scan {
-+@@ -720,6 +720,7 @@ struct ath_spec_scan {
-   * @config_pci_powersave:
-   * @calibrate: periodic calibration for NF, ANI, IQ, ADC gain, ADC-DC
-   *
-@@ -8,7 +8,7 @@
-   * @spectral_scan_config: set parameters for spectral scan and enable/disable it
-   * @spectral_scan_trigger: trigger a spectral scan run
-   * @spectral_scan_wait: wait for a spectral scan run to finish
--@@ -732,6 +733,7 @@ struct ath_hw_ops {
-+@@ -742,6 +743,7 @@ struct ath_hw_ops {
-  			struct ath_hw_antcomb_conf *antconf);
-  	void (*antdiv_comb_conf_set)(struct ath_hw *ah,
-  			struct ath_hw_antcomb_conf *antconf);
-@@ -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
--@@ -703,7 +703,8 @@ static void ath9k_init_txpower_limits(st
-+@@ -710,7 +710,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);
-  
-@@ -65,7 +65,7 @@
-  }
-  
-  static const struct ieee80211_iface_limit if_limits[] = {
--@@ -895,6 +896,18 @@ static void ath9k_set_hw_capab(struct at
-+@@ -903,6 +904,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)
-  {
--@@ -940,6 +953,8 @@ int ath9k_init_device(u16 devid, struct
-+@@ -948,6 +961,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/ar5008_phy.c
- +++ b/drivers/net/wireless/ath/ath9k/ar5008_phy.c
--@@ -1316,9 +1316,30 @@ void ar5008_hw_init_rate_txpower(struct
-+@@ -1327,9 +1327,30 @@ void ar5008_hw_init_rate_txpower(struct
-  	}
-  }
-  
-@@ -141,7 +141,7 @@
-  	static const u32 ar5416_cca_regs[6] = {
-  		AR_PHY_CCA,
-  		AR_PHY_CH1_CCA,
--@@ -1333,6 +1354,8 @@ int ar5008_hw_attach_phy_ops(struct ath_
-+@@ -1344,6 +1365,8 @@ int ar5008_hw_attach_phy_ops(struct ath_
-  	if (ret)
-  	    return ret;
-  
-diff --git a/package/kernel/mac80211/patches/544-ath9k-ar933x-usb-hang-workaround.patch b/package/kernel/mac80211/patches/544-ath9k-ar933x-usb-hang-workaround.patch
-index 240b898..6ca642a 100644
---- a/package/kernel/mac80211/patches/544-ath9k-ar933x-usb-hang-workaround.patch
-+++ b/package/kernel/mac80211/patches/544-ath9k-ar933x-usb-hang-workaround.patch
-@@ -1,6 +1,6 @@
- --- a/drivers/net/wireless/ath/ath9k/hw.c
- +++ b/drivers/net/wireless/ath/ath9k/hw.c
--@@ -245,6 +245,19 @@ void ath9k_hw_get_channel_centers(struct
-+@@ -246,6 +246,19 @@ void ath9k_hw_get_channel_centers(struct
-  		centers->synth_center + (extoff * HT40_CHANNEL_CENTER_SHIFT);
-  }
-  
-@@ -20,7 +20,7 @@
-  /******************/
-  /* Chip Revisions */
-  /******************/
--@@ -1382,6 +1395,9 @@ static bool ath9k_hw_set_reset(struct at
-+@@ -1386,6 +1399,9 @@ static bool ath9k_hw_set_reset(struct at
-  	if (AR_SREV_9100(ah))
-  		udelay(50);
-  
-@@ -30,7 +30,7 @@
-  	return true;
-  }
-  
--@@ -1481,6 +1497,9 @@ static bool ath9k_hw_chip_reset(struct a
-+@@ -1485,6 +1501,9 @@ static bool ath9k_hw_chip_reset(struct a
-  		ar9003_hw_internal_regulator_apply(ah);
-  	ath9k_hw_init_pll(ah, chan);
-  
-@@ -40,7 +40,7 @@
-  	return true;
-  }
-  
--@@ -1782,8 +1801,14 @@ static int ath9k_hw_do_fastcc(struct ath
-+@@ -1786,8 +1805,14 @@ static int ath9k_hw_do_fastcc(struct ath
-  	if (AR_SREV_9271(ah))
-  		ar9002_hw_load_ani_reg(ah, chan);
-  
-@@ -55,7 +55,7 @@
-  	return -EINVAL;
-  }
-  
--@@ -2037,6 +2062,9 @@ int ath9k_hw_reset(struct ath_hw *ah, st
-+@@ -2041,6 +2066,9 @@ int ath9k_hw_reset(struct ath_hw *ah, st
-  		ath9k_hw_set_radar_params(ah);
-  	}
-  
-diff --git a/package/kernel/mac80211/patches/545-ath9k_ani_ws_detect.patch b/package/kernel/mac80211/patches/545-ath9k_ani_ws_detect.patch
-index 9610372..bc0aca6 100644
---- a/package/kernel/mac80211/patches/545-ath9k_ani_ws_detect.patch
-+++ b/package/kernel/mac80211/patches/545-ath9k_ani_ws_detect.patch
-@@ -1,6 +1,6 @@
- --- a/drivers/net/wireless/ath/ath9k/ar5008_phy.c
- +++ b/drivers/net/wireless/ath/ath9k/ar5008_phy.c
--@@ -945,55 +945,6 @@ static bool ar5008_hw_ani_control_new(st
-+@@ -956,55 +956,6 @@ static bool ar5008_hw_ani_control_new(st
-  		 * on == 0 means more noise imm
-  		 */
-  		u32 on = param ? 1 : 0;
-diff --git a/package/kernel/mac80211/patches/600-0001-rt2x00-rt2800lib-move-rt2800_drv_data-declaration-in.patch b/package/kernel/mac80211/patches/600-0001-rt2x00-rt2800lib-move-rt2800_drv_data-declaration-in.patch
-index c0dc4fe..15863a6 100644
---- a/package/kernel/mac80211/patches/600-0001-rt2x00-rt2800lib-move-rt2800_drv_data-declaration-in.patch
-+++ b/package/kernel/mac80211/patches/600-0001-rt2x00-rt2800lib-move-rt2800_drv_data-declaration-in.patch
-@@ -20,32 +20,14 @@ Changes since v1: ---
-  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
--@@ -2960,17 +2960,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 @@
-+@@ -20,6 +20,20 @@
-  #ifndef RT2800LIB_H
-  #define RT2800LIB_H
-  
-++#include "rt2800.h"
-++
- +/* RT2800 driver data structure */
- +struct rt2800_drv_data {
- +	u8 calibration_bw20;
-@@ -55,8 +37,30 @@ Changes since v1: ---
- +	u8 txmixer_gain_24g;
- +	u8 txmixer_gain_5g;
- +	unsigned int tbtt_tick;
-++	DECLARE_BITMAP(sta_ids, STA_IDS_SIZE);
- +};
- +
-  struct rt2800_ops {
-  	void (*register_read)(struct rt2x00_dev *rt2x00dev,
-  			      const unsigned int offset, u32 *value);
-+--- a/drivers/net/wireless/rt2x00/rt2800.h
-++++ b/drivers/net/wireless/rt2x00/rt2800.h
-+@@ -2969,18 +2969,4 @@ enum rt2800_eeprom_word {
-+ #define WCID_END	222
-+ #define STA_IDS_SIZE	(WCID_END - WCID_START + 2)
-+ 
-+-/*
-+- * RT2800 driver data structure
-+- */
-+-struct rt2800_drv_data {
-+-	u8 calibration_bw20;
-+-	u8 calibration_bw40;
-+-	u8 bbp25;
-+-	u8 bbp26;
-+-	u8 txmixer_gain_24g;
-+-	u8 txmixer_gain_5g;
-+-	unsigned int tbtt_tick;
-+-	DECLARE_BITMAP(sta_ids, STA_IDS_SIZE);
-+-};
-+-
-+ #endif /* RT2800_H */
-diff --git a/package/kernel/mac80211/patches/600-0002-rt2x00-rt2800lib-introduce-RT2800_HAS_HIGH_SHARED_ME.patch b/package/kernel/mac80211/patches/600-0002-rt2x00-rt2800lib-introduce-RT2800_HAS_HIGH_SHARED_ME.patch
-index 6bad6ac..9165eec 100644
---- a/package/kernel/mac80211/patches/600-0002-rt2x00-rt2800lib-introduce-RT2800_HAS_HIGH_SHARED_ME.patch
-+++ b/package/kernel/mac80211/patches/600-0002-rt2x00-rt2800lib-introduce-RT2800_HAS_HIGH_SHARED_ME.patch
-@@ -24,7 +24,7 @@ Changes since v1:
- 
- --- a/drivers/net/wireless/rt2x00/rt2800lib.c
- +++ b/drivers/net/wireless/rt2x00/rt2800lib.c
--@@ -7747,6 +7747,7 @@ static int rt2800_probe_rt(struct rt2x00
-+@@ -7721,6 +7721,7 @@ static int rt2800_probe_rt(struct rt2x00
-  
-  int rt2800_probe_hw(struct rt2x00_dev *rt2x00dev)
-  {
-@@ -32,7 +32,7 @@ Changes since v1:
-  	int retval;
-  	u32 reg;
-  
--@@ -7754,6 +7755,9 @@ int rt2800_probe_hw(struct rt2x00_dev *r
-+@@ -7728,6 +7729,9 @@ int rt2800_probe_hw(struct rt2x00_dev *r
-  	if (retval)
-  		return retval;
-  
-@@ -44,9 +44,9 @@ Changes since v1:
-  	 */
- --- a/drivers/net/wireless/rt2x00/rt2800lib.h
- +++ b/drivers/net/wireless/rt2x00/rt2800lib.h
--@@ -20,6 +20,10 @@
-- #ifndef RT2800LIB_H
-- #define RT2800LIB_H
-+@@ -22,6 +22,10 @@
-+ 
-+ #include "rt2800.h"
-  
- +enum rt2800_flag {
- +	RT2800_HAS_HIGH_SHARED_MEM,
-@@ -55,16 +55,16 @@ Changes since v1:
-  /* RT2800 driver data structure */
-  struct rt2800_drv_data {
-  	u8 calibration_bw20;
--@@ -29,6 +33,8 @@ struct rt2800_drv_data {
-- 	u8 txmixer_gain_24g;
-+@@ -32,6 +36,8 @@ struct rt2800_drv_data {
-  	u8 txmixer_gain_5g;
-  	unsigned int tbtt_tick;
-+ 	DECLARE_BITMAP(sta_ids, STA_IDS_SIZE);
- +
- +	unsigned long rt2800_flags;
-  };
-  
-  struct rt2800_ops {
--@@ -61,6 +67,13 @@ struct rt2800_ops {
-+@@ -64,6 +70,13 @@ struct rt2800_ops {
-  	__le32 *(*drv_get_txwi)(struct queue_entry *entry);
-  };
-  
-diff --git a/package/kernel/mac80211/patches/600-0003-rt2x00-rt2800-serialize-shared-memory-access.patch b/package/kernel/mac80211/patches/600-0003-rt2x00-rt2800-serialize-shared-memory-access.patch
-index 9f8dfcc..5671515 100644
---- a/package/kernel/mac80211/patches/600-0003-rt2x00-rt2800-serialize-shared-memory-access.patch
-+++ b/package/kernel/mac80211/patches/600-0003-rt2x00-rt2800-serialize-shared-memory-access.patch
-@@ -175,7 +175,7 @@ Changes since v1: ---
-  
-  	/*
-  	 * Update WCID information
--@@ -1437,8 +1467,11 @@ int rt2800_config_pairwise_key(struct rt
-+@@ -1405,8 +1435,11 @@ int rt2800_config_pairwise_key(struct rt
-  		       sizeof(key_entry.rx_mic));
-  
-  		offset = PAIRWISE_KEY_ENTRY(key->hw_key_idx);
-@@ -187,7 +187,7 @@ Changes since v1: ---
-  	}
-  
-  	/*
--@@ -4908,14 +4941,19 @@ static int rt2800_init_registers(struct
-+@@ -4884,14 +4917,19 @@ static int rt2800_init_registers(struct
-  	/*
-  	 * ASIC will keep garbage value after boot, clear encryption keys.
-  	 */
-@@ -207,7 +207,7 @@ Changes since v1: ---
-  	}
-  
-  	/*
--@@ -5041,8 +5079,10 @@ static int rt2800_wait_bbp_ready(struct
-+@@ -5017,8 +5055,10 @@ static int rt2800_wait_bbp_ready(struct
-  	 * BBP was enabled after firmware was loaded,
-  	 * but we need to reactivate it now.
-  	 */
-@@ -218,7 +218,7 @@ Changes since v1: ---
-  	msleep(1);
-  
-  	for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
--@@ -6738,11 +6778,19 @@ int rt2800_enable_radio(struct rt2x00_de
-+@@ -6714,11 +6754,19 @@ int rt2800_enable_radio(struct rt2x00_de
-  	/*
-  	 * Send signal during boot time to initialize firmware.
-  	 */
-@@ -239,7 +239,7 @@ Changes since v1: ---
-  	msleep(1);
-  
-  	/*
--@@ -7751,6 +7799,8 @@ int rt2800_probe_hw(struct rt2x00_dev *r
-+@@ -7725,6 +7773,8 @@ int rt2800_probe_hw(struct rt2x00_dev *r
-  	int retval;
-  	u32 reg;
-  
-@@ -248,22 +248,22 @@ Changes since v1: ---
-  	retval = rt2800_probe_rt(rt2x00dev);
-  	if (retval)
-  		return retval;
--@@ -7830,8 +7880,11 @@ void rt2800_get_tkip_seq(struct ieee8021
-- 	u32 offset;
-+@@ -7808,8 +7858,11 @@ void rt2800_get_key_seq(struct ieee80211
-+ 		return;
-  
-- 	offset = MAC_IVEIV_ENTRY(hw_key_idx);
-+ 	offset = MAC_IVEIV_ENTRY(key->hw_key_idx);
- +
- +	rt2800_shared_mem_lock(rt2x00dev);
-  	rt2800_register_multiread(rt2x00dev, offset,
-  				      &iveiv_entry, sizeof(iveiv_entry));
- +	rt2800_shared_mem_unlock(rt2x00dev);
-  
-- 	memcpy(iv16, &iveiv_entry.iv[0], sizeof(*iv16));
-- 	memcpy(iv32, &iveiv_entry.iv[4], sizeof(*iv32));
-+ 	memcpy(&seq->tkip.iv16, &iveiv_entry.iv[0], 2);
-+ 	memcpy(&seq->tkip.iv32, &iveiv_entry.iv[4], 4);
- --- 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;
-+@@ -38,6 +38,11 @@ struct rt2800_drv_data {
-+ 	DECLARE_BITMAP(sta_ids, STA_IDS_SIZE);
-  
-  	unsigned long rt2800_flags;
- +
-@@ -274,7 +274,7 @@ Changes since v1: ---
-  };
-  
-  struct rt2800_ops {
--@@ -65,6 +70,10 @@ struct rt2800_ops {
-+@@ -68,6 +73,10 @@ struct rt2800_ops {
-  				  const u8 *data, const size_t len);
-  	int (*drv_init_registers)(struct rt2x00_dev *rt2x00dev);
-  	__le32 *(*drv_get_txwi)(struct queue_entry *entry);
-@@ -285,7 +285,7 @@ Changes since v1: ---
-  };
-  
-  static inline bool rt2800_has_high_shared_mem(struct rt2x00_dev *rt2x00dev)
--@@ -74,6 +83,29 @@ static inline bool rt2800_has_high_share
-+@@ -77,6 +86,29 @@ static inline bool rt2800_has_high_share
-  	return test_bit(RT2800_HAS_HIGH_SHARED_MEM, &drv_data->rt2800_flags);
-  }
-  
-@@ -486,7 +486,7 @@ Changes since v1: ---
-  /*
-   * Queue handlers.
-   */
--@@ -294,8 +315,10 @@ static int rt2800usb_write_firmware(stru
-+@@ -299,8 +320,10 @@ static int rt2800usb_write_firmware(stru
-  					      data + offset, length);
-  	}
-  
-@@ -497,7 +497,7 @@ Changes since v1: ---
-  
-  	/*
-  	 * Send firmware request to device to load firmware,
--@@ -310,7 +333,10 @@ static int rt2800usb_write_firmware(stru
-+@@ -315,7 +338,10 @@ static int rt2800usb_write_firmware(stru
-  	}
-  
-  	msleep(10);
-@@ -508,7 +508,7 @@ Changes since v1: ---
-  
-  	return 0;
-  }
--@@ -328,8 +354,10 @@ static int rt2800usb_init_registers(stru
-+@@ -333,8 +359,10 @@ static int rt2800usb_init_registers(stru
-  	if (rt2800_wait_csr_ready(rt2x00dev))
-  		return -EBUSY;
-  
-@@ -519,7 +519,7 @@ Changes since v1: ---
-  
-  	reg = 0;
-  	rt2x00_set_field32(&reg, MAC_SYS_CTRL_RESET_CSR, 1);
--@@ -859,6 +887,9 @@ static const struct rt2800_ops rt2800usb
-+@@ -863,6 +891,9 @@ static const struct rt2800_ops rt2800usb
-  	.drv_write_firmware	= rt2800usb_write_firmware,
-  	.drv_init_registers	= rt2800usb_init_registers,
-  	.drv_get_txwi		= rt2800usb_get_txwi,
-diff --git a/package/kernel/mac80211/patches/600-0005-rt2x00-rt2800lib-add-hw_beacon_count-field-to-struct.patch b/package/kernel/mac80211/patches/600-0005-rt2x00-rt2800lib-add-hw_beacon_count-field-to-struct.patch
-index e7eb630..d04998a 100644
---- a/package/kernel/mac80211/patches/600-0005-rt2x00-rt2800lib-add-hw_beacon_count-field-to-struct.patch
-+++ b/package/kernel/mac80211/patches/600-0005-rt2x00-rt2800lib-add-hw_beacon_count-field-to-struct.patch
-@@ -24,7 +24,7 @@ Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
- 
- --- a/drivers/net/wireless/rt2x00/rt2800lib.c
- +++ b/drivers/net/wireless/rt2x00/rt2800lib.c
--@@ -4638,6 +4638,7 @@ EXPORT_SYMBOL_GPL(rt2800_link_tuner);
-+@@ -4614,6 +4614,7 @@ EXPORT_SYMBOL_GPL(rt2800_link_tuner);
-   */
-  static int rt2800_init_registers(struct rt2x00_dev *rt2x00dev)
-  {
-@@ -32,7 +32,7 @@ Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
-  	u32 reg;
-  	u16 eeprom;
-  	unsigned int i;
--@@ -5003,7 +5004,7 @@ static int rt2800_init_registers(struct
-+@@ -4979,7 +4980,7 @@ static int rt2800_init_registers(struct
-  	/*
-  	 * Clear all beacons
-  	 */
-@@ -41,7 +41,7 @@ Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
-  		rt2800_clear_beacon_register(rt2x00dev, i);
-  
-  	if (rt2x00_is_usb(rt2x00dev)) {
--@@ -7852,6 +7853,8 @@ int rt2800_probe_hw(struct rt2x00_dev *r
-+@@ -7826,6 +7827,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);
-  
-@@ -52,11 +52,11 @@ Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
-  	 */
- --- a/drivers/net/wireless/rt2x00/rt2800lib.h
- +++ b/drivers/net/wireless/rt2x00/rt2800lib.h
--@@ -33,6 +33,7 @@ struct rt2800_drv_data {
-+@@ -35,6 +35,7 @@ struct rt2800_drv_data {
-  	u8 txmixer_gain_24g;
-  	u8 txmixer_gain_5g;
-  	unsigned int tbtt_tick;
- +	unsigned int hw_beacon_count;
-+ 	DECLARE_BITMAP(sta_ids, STA_IDS_SIZE);
-  
-  	unsigned long rt2800_flags;
-- 
-diff --git a/package/kernel/mac80211/patches/600-0006-rt2x00-rt2800lib-init-additional-beacon-offset-regis.patch b/package/kernel/mac80211/patches/600-0006-rt2x00-rt2800lib-init-additional-beacon-offset-regis.patch
-index b79b4be..f5231f0 100644
---- a/package/kernel/mac80211/patches/600-0006-rt2x00-rt2800lib-init-additional-beacon-offset-regis.patch
-+++ b/package/kernel/mac80211/patches/600-0006-rt2x00-rt2800lib-init-additional-beacon-offset-regis.patch
-@@ -34,7 +34,7 @@ Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
-   */
- --- a/drivers/net/wireless/rt2x00/rt2800lib.c
- +++ b/drivers/net/wireless/rt2x00/rt2800lib.c
--@@ -4650,6 +4650,30 @@ static int rt2800_init_registers(struct
-+@@ -4626,6 +4626,30 @@ static int rt2800_init_registers(struct
-  	if (ret)
-  		return ret;
-  
-diff --git a/package/kernel/mac80211/patches/600-0007-rt2x00-rt2800lib-fix-max-supported-beacon-count-for-.patch b/package/kernel/mac80211/patches/600-0007-rt2x00-rt2800lib-fix-max-supported-beacon-count-for-.patch
-index 180c5e3..4b21eae 100644
---- a/package/kernel/mac80211/patches/600-0007-rt2x00-rt2800lib-fix-max-supported-beacon-count-for-.patch
-+++ b/package/kernel/mac80211/patches/600-0007-rt2x00-rt2800lib-fix-max-supported-beacon-count-for-.patch
-@@ -10,7 +10,7 @@ Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
- 
- --- a/drivers/net/wireless/rt2x00/rt2800lib.c
- +++ b/drivers/net/wireless/rt2x00/rt2800lib.c
--@@ -7877,7 +7877,10 @@ int rt2800_probe_hw(struct rt2x00_dev *r
-+@@ -7851,7 +7851,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);
-  
-diff --git a/package/kernel/mac80211/patches/600-0009-rt2x00-rt2800lib-enable-support-for-RT3883.patch b/package/kernel/mac80211/patches/600-0009-rt2x00-rt2800lib-enable-support-for-RT3883.patch
-index 31aa34a..e77cd86 100644
---- a/package/kernel/mac80211/patches/600-0009-rt2x00-rt2800lib-enable-support-for-RT3883.patch
-+++ b/package/kernel/mac80211/patches/600-0009-rt2x00-rt2800lib-enable-support-for-RT3883.patch
-@@ -10,7 +10,7 @@ Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
- 
- --- a/drivers/net/wireless/rt2x00/rt2800lib.c
- +++ b/drivers/net/wireless/rt2x00/rt2800lib.c
--@@ -7847,6 +7847,7 @@ static int rt2800_probe_rt(struct rt2x00
-+@@ -7821,6 +7821,7 @@ static int rt2800_probe_rt(struct rt2x00
-  	case RT3390:
-  	case RT3572:
-  	case RT3593:
-diff --git a/package/kernel/mac80211/patches/600-0010-rt2x00-rt2800lib-add-rf_vals-for-RF3853.patch b/package/kernel/mac80211/patches/600-0010-rt2x00-rt2800lib-add-rf_vals-for-RF3853.patch
-index a90c590..780c1dd 100644
---- a/package/kernel/mac80211/patches/600-0010-rt2x00-rt2800lib-add-rf_vals-for-RF3853.patch
-+++ b/package/kernel/mac80211/patches/600-0010-rt2x00-rt2800lib-add-rf_vals-for-RF3853.patch
-@@ -31,7 +31,7 @@ Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
-  #define RF5370				0x5370
- --- a/drivers/net/wireless/rt2x00/rt2800lib.c
- +++ b/drivers/net/wireless/rt2x00/rt2800lib.c
--@@ -7465,6 +7465,66 @@ static const struct rf_channel rf_vals_3
-+@@ -7441,6 +7441,66 @@ static const struct rf_channel rf_vals_3
-  	{173, 0x61, 0, 9},
-  };
-  
-@@ -98,7 +98,7 @@ Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
-  static const struct rf_channel rf_vals_5592_xtal20[] = {
-  	/* Channel, N, K, mod, R */
-  	{1, 482, 4, 10, 3},
--@@ -7694,6 +7754,11 @@ static int rt2800_probe_hw_mode(struct r
-+@@ -7668,6 +7728,11 @@ static int rt2800_probe_hw_mode(struct r
-  		spec->channels = rf_vals_3x;
-  		break;
-  
-diff --git a/package/kernel/mac80211/patches/600-0011-rt2x00-rt2800lib-enable-VCO-calibration-for-RF3853.patch b/package/kernel/mac80211/patches/600-0011-rt2x00-rt2800lib-enable-VCO-calibration-for-RF3853.patch
-index ab2673b..858dece 100644
---- a/package/kernel/mac80211/patches/600-0011-rt2x00-rt2800lib-enable-VCO-calibration-for-RF3853.patch
-+++ b/package/kernel/mac80211/patches/600-0011-rt2x00-rt2800lib-enable-VCO-calibration-for-RF3853.patch
-@@ -10,7 +10,7 @@ Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
- 
- --- a/drivers/net/wireless/rt2x00/rt2800lib.c
- +++ b/drivers/net/wireless/rt2x00/rt2800lib.c
--@@ -4402,6 +4402,7 @@ void rt2800_vco_calibration(struct rt2x0
-+@@ -4378,6 +4378,7 @@ void rt2800_vco_calibration(struct rt2x0
-  	case RF3053:
-  	case RF3070:
-  	case RF3290:
-@@ -18,7 +18,7 @@ Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
-  	case RF5360:
-  	case RF5362:
-  	case RF5370:
--@@ -7873,6 +7874,7 @@ static int rt2800_probe_hw_mode(struct r
-+@@ -7847,6 +7848,7 @@ static int rt2800_probe_hw_mode(struct r
-  	case RF3053:
-  	case RF3070:
-  	case RF3290:
-diff --git a/package/kernel/mac80211/patches/600-0012-rt2x00-rt2800lib-add-channel-configuration-function-.patch b/package/kernel/mac80211/patches/600-0012-rt2x00-rt2800lib-add-channel-configuration-function-.patch
-index 05ed444..ed82e44 100644
---- a/package/kernel/mac80211/patches/600-0012-rt2x00-rt2800lib-add-channel-configuration-function-.patch
-+++ b/package/kernel/mac80211/patches/600-0012-rt2x00-rt2800lib-add-channel-configuration-function-.patch
-@@ -11,7 +11,7 @@ Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
- 
- --- a/drivers/net/wireless/rt2x00/rt2800lib.c
- +++ b/drivers/net/wireless/rt2x00/rt2800lib.c
--@@ -2649,6 +2649,211 @@ static void rt2800_config_channel_rf3053
-+@@ -2625,6 +2625,211 @@ static void rt2800_config_channel_rf3053
-  	}
-  }
-  
-@@ -223,7 +223,7 @@ Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
-  #define POWER_BOUND		0x27
-  #define POWER_BOUND_5G		0x2b
-  
--@@ -3261,6 +3466,9 @@ static void rt2800_config_channel(struct
-+@@ -3237,6 +3442,9 @@ static void rt2800_config_channel(struct
-  	case RF3322:
-  		rt2800_config_channel_rf3322(rt2x00dev, conf, rf, info);
-  		break;
-diff --git a/package/kernel/mac80211/patches/600-0013-rt2x00-rt2800lib-enable-RF3853-support.patch b/package/kernel/mac80211/patches/600-0013-rt2x00-rt2800lib-enable-RF3853-support.patch
-index 3b50775..33cbc4c 100644
---- a/package/kernel/mac80211/patches/600-0013-rt2x00-rt2800lib-enable-RF3853-support.patch
-+++ b/package/kernel/mac80211/patches/600-0013-rt2x00-rt2800lib-enable-RF3853-support.patch
-@@ -10,7 +10,7 @@ Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
- 
- --- a/drivers/net/wireless/rt2x00/rt2800lib.c
- +++ b/drivers/net/wireless/rt2x00/rt2800lib.c
--@@ -7430,6 +7430,7 @@ static int rt2800_init_eeprom(struct rt2
-+@@ -7406,6 +7406,7 @@ static int rt2800_init_eeprom(struct rt2
-  	case RF3290:
-  	case RF3320:
-  	case RF3322:
-diff --git a/package/kernel/mac80211/patches/600-0014-rt2x00-rt2800lib-add-MAC-register-initialization-for.patch b/package/kernel/mac80211/patches/600-0014-rt2x00-rt2800lib-add-MAC-register-initialization-for.patch
-index 4dfb068..c3a4798 100644
---- a/package/kernel/mac80211/patches/600-0014-rt2x00-rt2800lib-add-MAC-register-initialization-for.patch
-+++ b/package/kernel/mac80211/patches/600-0014-rt2x00-rt2800lib-add-MAC-register-initialization-for.patch
-@@ -35,7 +35,7 @@ Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
-  #define RX_FILTER_CFG			0x1400
- --- a/drivers/net/wireless/rt2x00/rt2800lib.c
- +++ b/drivers/net/wireless/rt2x00/rt2800lib.c
--@@ -5005,6 +5005,12 @@ static int rt2800_init_registers(struct
-+@@ -4981,6 +4981,12 @@ static int rt2800_init_registers(struct
-  			rt2800_register_write(rt2x00dev, TX_SW_CFG2,
-  					      0x00000000);
-  		}
-@@ -48,7 +48,7 @@ Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
-  	} else if (rt2x00_rt(rt2x00dev, RT5390) ||
-  		   rt2x00_rt(rt2x00dev, RT5392) ||
-  		   rt2x00_rt(rt2x00dev, RT5592)) {
--@@ -5035,9 +5041,11 @@ static int rt2800_init_registers(struct
-+@@ -5011,9 +5017,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);
-@@ -63,7 +63,7 @@ Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
-  		rt2x00_set_field32(&reg, MAX_LEN_CFG_MAX_PSDU, 2);
-  	else
-  		rt2x00_set_field32(&reg, MAX_LEN_CFG_MAX_PSDU, 1);
--@@ -5190,6 +5198,11 @@ static int rt2800_init_registers(struct
-+@@ -5166,6 +5174,11 @@ static int rt2800_init_registers(struct
-  	reg = rt2x00_rt(rt2x00dev, RT5592) ? 0x00000082 : 0x00000002;
-  	rt2800_register_write(rt2x00dev, TXOP_HLDR_ET, reg);
-  
-diff --git a/package/kernel/mac80211/patches/600-0016-rt2x00-rt2800lib-add-BBP-register-initialization-for.patch b/package/kernel/mac80211/patches/600-0016-rt2x00-rt2800lib-add-BBP-register-initialization-for.patch
-index 6663b78..e647777 100644
---- a/package/kernel/mac80211/patches/600-0016-rt2x00-rt2800lib-add-BBP-register-initialization-for.patch
-+++ b/package/kernel/mac80211/patches/600-0016-rt2x00-rt2800lib-add-BBP-register-initialization-for.patch
-@@ -11,7 +11,7 @@ Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
- 
- --- a/drivers/net/wireless/rt2x00/rt2800lib.c
- +++ b/drivers/net/wireless/rt2x00/rt2800lib.c
--@@ -5808,6 +5808,47 @@ static void rt2800_init_bbp_3593(struct
-+@@ -5784,6 +5784,47 @@ static void rt2800_init_bbp_3593(struct
-  		rt2800_bbp_write(rt2x00dev, 103, 0xc0);
-  }
-  
-@@ -59,7 +59,7 @@ Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
-  static void rt2800_init_bbp_53xx(struct rt2x00_dev *rt2x00dev)
-  {
-  	int ant, div_mode;
--@@ -6026,6 +6067,9 @@ static void rt2800_init_bbp(struct rt2x0
-+@@ -6002,6 +6043,9 @@ static void rt2800_init_bbp(struct rt2x0
-  	case RT3593:
-  		rt2800_init_bbp_3593(rt2x00dev);
-  		return;
-diff --git a/package/kernel/mac80211/patches/600-0017-rt2x00-rt2800lib-add-RFCSR-initialization-for-RT3883.patch b/package/kernel/mac80211/patches/600-0017-rt2x00-rt2800lib-add-RFCSR-initialization-for-RT3883.patch
-index 6e66f14..0fec3cd 100644
---- a/package/kernel/mac80211/patches/600-0017-rt2x00-rt2800lib-add-RFCSR-initialization-for-RT3883.patch
-+++ b/package/kernel/mac80211/patches/600-0017-rt2x00-rt2800lib-add-RFCSR-initialization-for-RT3883.patch
-@@ -21,7 +21,7 @@ Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
-  /*
- --- a/drivers/net/wireless/rt2x00/rt2800lib.c
- +++ b/drivers/net/wireless/rt2x00/rt2800lib.c
--@@ -6843,6 +6843,144 @@ static void rt2800_init_rfcsr_3593(struc
-+@@ -6819,6 +6819,144 @@ static void rt2800_init_rfcsr_3593(struc
-  	/* TODO: enable stream mode support */
-  }
-  
-@@ -166,7 +166,7 @@ Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
-  static void rt2800_init_rfcsr_5390(struct rt2x00_dev *rt2x00dev)
-  {
-  	rt2800_rf_init_calibration(rt2x00dev, 2);
--@@ -7074,6 +7212,9 @@ static void rt2800_init_rfcsr(struct rt2
-+@@ -7050,6 +7188,9 @@ static void rt2800_init_rfcsr(struct rt2
-  	case RT3390:
-  		rt2800_init_rfcsr_3390(rt2x00dev);
-  		break;
-diff --git a/package/kernel/mac80211/patches/600-0019-rt2x00-rt2800lib-force-rf-type-to-RF3853-on-RT3883.patch b/package/kernel/mac80211/patches/600-0019-rt2x00-rt2800lib-force-rf-type-to-RF3853-on-RT3883.patch
-index 9390f7e..c9d1e06 100644
---- a/package/kernel/mac80211/patches/600-0019-rt2x00-rt2800lib-force-rf-type-to-RF3853-on-RT3883.patch
-+++ b/package/kernel/mac80211/patches/600-0019-rt2x00-rt2800lib-force-rf-type-to-RF3853-on-RT3883.patch
-@@ -10,7 +10,7 @@ Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
- 
- --- a/drivers/net/wireless/rt2x00/rt2800lib.c
- +++ b/drivers/net/wireless/rt2x00/rt2800lib.c
--@@ -7611,6 +7611,8 @@ static int rt2800_init_eeprom(struct rt2
-+@@ -7587,6 +7587,8 @@ static int rt2800_init_eeprom(struct rt2
-  	    rt2x00_rt(rt2x00dev, RT5390) ||
-  	    rt2x00_rt(rt2x00dev, RT5392))
-  		rt2800_eeprom_read(rt2x00dev, EEPROM_CHIP_ID, &rf);
-diff --git a/package/kernel/mac80211/patches/600-0020-rt2x00-rt2800lib-add-channel-configuration-code-for-.patch b/package/kernel/mac80211/patches/600-0020-rt2x00-rt2800lib-add-channel-configuration-code-for-.patch
-index 1cba4f6..12b9c33 100644
---- a/package/kernel/mac80211/patches/600-0020-rt2x00-rt2800lib-add-channel-configuration-code-for-.patch
-+++ b/package/kernel/mac80211/patches/600-0020-rt2x00-rt2800lib-add-channel-configuration-code-for-.patch
-@@ -10,7 +10,7 @@ Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
- 
- --- 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
-+@@ -3405,6 +3405,36 @@ static char rt2800_txpower_to_dev(struct
-  		return clamp_t(char, txpower, MIN_A_TXPOWER, MAX_A_TXPOWER);
-  }
-  
-@@ -47,7 +47,7 @@ Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
-  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
-+@@ -3423,6 +3453,12 @@ static void rt2800_config_channel(struct
-  			rt2800_txpower_to_dev(rt2x00dev, rf->channel,
-  					      info->default_power3);
-  
-@@ -60,7 +60,7 @@ Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
-  	switch (rt2x00dev->chip.rf) {
-  	case RF2020:
-  	case RF3020:
--@@ -3530,6 +3566,15 @@ static void rt2800_config_channel(struct
-+@@ -3506,6 +3542,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);
-@@ -76,7 +76,7 @@ Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
-  	} else {
-  		rt2800_bbp_write(rt2x00dev, 62, 0x37 - rt2x00dev->lna_gain);
-  		rt2800_bbp_write(rt2x00dev, 63, 0x37 - rt2x00dev->lna_gain);
--@@ -3542,6 +3587,7 @@ static void rt2800_config_channel(struct
-+@@ -3518,6 +3563,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);
-@@ -84,7 +84,7 @@ Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
-  				rt2800_bbp_write(rt2x00dev, 75, 0x46);
-  			} else {
-  				if (rt2x00_rt(rt2x00dev, RT3593))
--@@ -3550,19 +3596,22 @@ static void rt2800_config_channel(struct
-+@@ -3526,19 +3572,22 @@ static void rt2800_config_channel(struct
-  					rt2800_bbp_write(rt2x00dev, 82, 0x84);
-  				rt2800_bbp_write(rt2x00dev, 75, 0x50);
-  			}
-@@ -110,7 +110,7 @@ Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
-  			rt2800_bbp_write(rt2x00dev, 83, 0x9a);
-  
-  		if (rt2x00_has_cap_external_lna_a(rt2x00dev))
--@@ -3684,6 +3733,23 @@ static void rt2800_config_channel(struct
-+@@ -3660,6 +3709,23 @@ static void rt2800_config_channel(struct
-  
-  		rt2800_bbp_write_with_rx_chain(rt2x00dev, 66, reg);
-  
-diff --git a/package/kernel/mac80211/patches/600-0021-rt2x00-rt2800lib-fix-txpower_to_dev-function-for-RT3.patch b/package/kernel/mac80211/patches/600-0021-rt2x00-rt2800lib-fix-txpower_to_dev-function-for-RT3.patch
-index 1773128..3f40b4e 100644
---- a/package/kernel/mac80211/patches/600-0021-rt2x00-rt2800lib-fix-txpower_to_dev-function-for-RT3.patch
-+++ b/package/kernel/mac80211/patches/600-0021-rt2x00-rt2800lib-fix-txpower_to_dev-function-for-RT3.patch
-@@ -10,7 +10,7 @@ Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
- 
- --- 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
-+@@ -3392,13 +3392,15 @@ static char rt2800_txpower_to_dev(struct
-  				  unsigned int channel,
-  				  char txpower)
-  {
-diff --git a/package/kernel/mac80211/patches/600-0022-rt2x00-rt2800lib-use-correct-txpower-calculation-fun.patch b/package/kernel/mac80211/patches/600-0022-rt2x00-rt2800lib-use-correct-txpower-calculation-fun.patch
-index 36f0a4c..52baeec 100644
---- a/package/kernel/mac80211/patches/600-0022-rt2x00-rt2800lib-use-correct-txpower-calculation-fun.patch
-+++ b/package/kernel/mac80211/patches/600-0022-rt2x00-rt2800lib-use-correct-txpower-calculation-fun.patch
-@@ -11,7 +11,7 @@ Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
- 
- --- a/drivers/net/wireless/rt2x00/rt2800lib.c
- +++ b/drivers/net/wireless/rt2x00/rt2800lib.c
--@@ -4635,7 +4635,8 @@ static void rt2800_config_txpower(struct
-+@@ -4611,7 +4611,8 @@ static void rt2800_config_txpower(struct
-  				  struct ieee80211_channel *chan,
-  				  int power_level)
-  {
-diff --git a/package/kernel/mac80211/patches/600-0023-rt2x00-rt2800lib-hardcode-txmixer-gain-values-to-zer.patch b/package/kernel/mac80211/patches/600-0023-rt2x00-rt2800lib-hardcode-txmixer-gain-values-to-zer.patch
-index 8119f97..b9dafc6 100644
---- a/package/kernel/mac80211/patches/600-0023-rt2x00-rt2800lib-hardcode-txmixer-gain-values-to-zer.patch
-+++ b/package/kernel/mac80211/patches/600-0023-rt2x00-rt2800lib-hardcode-txmixer-gain-values-to-zer.patch
-@@ -11,7 +11,7 @@ Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
- 
- --- a/drivers/net/wireless/rt2x00/rt2800lib.c
- +++ b/drivers/net/wireless/rt2x00/rt2800lib.c
--@@ -7493,7 +7493,8 @@ static u8 rt2800_get_txmixer_gain_24g(st
-+@@ -7469,7 +7469,8 @@ static u8 rt2800_get_txmixer_gain_24g(st
-  {
-  	u16 word;
-  
-@@ -21,7 +21,7 @@ Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
-  		return 0;
-  
-  	rt2800_eeprom_read(rt2x00dev, EEPROM_TXMIXER_GAIN_BG, &word);
--@@ -7507,7 +7508,8 @@ static u8 rt2800_get_txmixer_gain_5g(str
-+@@ -7483,7 +7484,8 @@ static u8 rt2800_get_txmixer_gain_5g(str
-  {
-  	u16 word;
-  
-diff --git a/package/kernel/mac80211/patches/600-0026-rt2x00-rt2800lib-use-correct-beacon-count-for-RT3883.patch b/package/kernel/mac80211/patches/600-0026-rt2x00-rt2800lib-use-correct-beacon-count-for-RT3883.patch
-index dfbdee7..f09f803 100644
---- a/package/kernel/mac80211/patches/600-0026-rt2x00-rt2800lib-use-correct-beacon-count-for-RT3883.patch
-+++ b/package/kernel/mac80211/patches/600-0026-rt2x00-rt2800lib-use-correct-beacon-count-for-RT3883.patch
-@@ -10,7 +10,7 @@ Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
- 
- --- 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
-+@@ -8402,7 +8402,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);
-  
-diff --git a/package/kernel/mac80211/patches/600-0027-rt2x00-rt2800lib-fix-antenna-configuration-for-RT388.patch b/package/kernel/mac80211/patches/600-0027-rt2x00-rt2800lib-fix-antenna-configuration-for-RT388.patch
-index 22f7110..f7d23fc 100644
---- a/package/kernel/mac80211/patches/600-0027-rt2x00-rt2800lib-fix-antenna-configuration-for-RT388.patch
-+++ b/package/kernel/mac80211/patches/600-0027-rt2x00-rt2800lib-fix-antenna-configuration-for-RT388.patch
-@@ -10,7 +10,7 @@ Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
- 
- --- 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
-+@@ -1937,7 +1937,8 @@ void rt2800_config_ant(struct rt2x00_dev
-  	rt2800_bbp_write(rt2x00dev, 3, r3);
-  	rt2800_bbp_write(rt2x00dev, 1, r1);
-  
-diff --git a/package/kernel/mac80211/patches/600-0028-rt2x00-rt2800lib-fix-LNA-gain-configuration-for-RT38.patch b/package/kernel/mac80211/patches/600-0028-rt2x00-rt2800lib-fix-LNA-gain-configuration-for-RT38.patch
-index 9945f38..4da750e 100644
---- a/package/kernel/mac80211/patches/600-0028-rt2x00-rt2800lib-fix-LNA-gain-configuration-for-RT38.patch
-+++ b/package/kernel/mac80211/patches/600-0028-rt2x00-rt2800lib-fix-LNA-gain-configuration-for-RT38.patch
-@@ -10,7 +10,7 @@ Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
- 
- --- 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
-+@@ -1960,7 +1960,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) {
-@@ -20,7 +20,7 @@ Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
-  			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
-+@@ -1970,7 +1971,8 @@ static void rt2800_config_lna_gain(struc
-  						      EEPROM_RSSI_BG2_LNA_A1);
-  		}
-  	} else {
-diff --git a/package/kernel/mac80211/patches/600-0029-rt2x00-rt2800lib-fix-VGC-setup-for-RT3883.patch b/package/kernel/mac80211/patches/600-0029-rt2x00-rt2800lib-fix-VGC-setup-for-RT3883.patch
-index beadea8..628b237 100644
---- a/package/kernel/mac80211/patches/600-0029-rt2x00-rt2800lib-fix-VGC-setup-for-RT3883.patch
-+++ b/package/kernel/mac80211/patches/600-0029-rt2x00-rt2800lib-fix-VGC-setup-for-RT3883.patch
-@@ -10,7 +10,7 @@ Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
- 
- --- a/drivers/net/wireless/rt2x00/rt2800lib.c
- +++ b/drivers/net/wireless/rt2x00/rt2800lib.c
--@@ -4835,7 +4835,8 @@ static u8 rt2800_get_default_vgc(struct
-+@@ -4811,7 +4811,8 @@ static u8 rt2800_get_default_vgc(struct
-  		else
-  			vgc = 0x2e + rt2x00dev->lna_gain;
-  	} else { /* 5GHZ band */
-@@ -20,7 +20,7 @@ Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
-  			vgc = 0x20 + (rt2x00dev->lna_gain * 5) / 3;
-  		else if (rt2x00_rt(rt2x00dev, RT5592))
-  			vgc = 0x24 + (2 * rt2x00dev->lna_gain);
--@@ -4855,7 +4856,8 @@ static inline void rt2800_set_vgc(struct
-+@@ -4831,7 +4832,8 @@ static inline void rt2800_set_vgc(struct
-  {
-  	if (qual->vgc_level != vgc_level) {
-  		if (rt2x00_rt(rt2x00dev, RT3572) ||
-@@ -30,7 +30,7 @@ Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
-  			rt2800_bbp_write_with_rx_chain(rt2x00dev, 66,
-  						       vgc_level);
-  		} else if (rt2x00_rt(rt2x00dev, RT5592)) {
--@@ -4902,6 +4904,11 @@ void rt2800_link_tuner(struct rt2x00_dev
-+@@ -4878,6 +4880,11 @@ void rt2800_link_tuner(struct rt2x00_dev
-  		}
-  		break;
-  
-diff --git a/package/kernel/mac80211/patches/600-0030-rt2x00-rt2800lib-fix-EEPROM-LNA-validation-for-RT388.patch b/package/kernel/mac80211/patches/600-0030-rt2x00-rt2800lib-fix-EEPROM-LNA-validation-for-RT388.patch
-index a6c0f58..216b8b6 100644
---- a/package/kernel/mac80211/patches/600-0030-rt2x00-rt2800lib-fix-EEPROM-LNA-validation-for-RT388.patch
-+++ b/package/kernel/mac80211/patches/600-0030-rt2x00-rt2800lib-fix-EEPROM-LNA-validation-for-RT388.patch
-@@ -10,7 +10,7 @@ Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
- 
- --- a/drivers/net/wireless/rt2x00/rt2800lib.c
- +++ b/drivers/net/wireless/rt2x00/rt2800lib.c
--@@ -7630,7 +7630,8 @@ static int rt2800_validate_eeprom(struct
-+@@ -7606,7 +7606,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);
-@@ -20,7 +20,7 @@ Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
-  		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,
--@@ -7650,7 +7651,8 @@ static int rt2800_validate_eeprom(struct
-+@@ -7626,7 +7627,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);
-@@ -30,7 +30,7 @@ Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
-  		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,
--@@ -7658,7 +7660,8 @@ static int rt2800_validate_eeprom(struct
-+@@ -7634,7 +7636,8 @@ static int rt2800_validate_eeprom(struct
-  	}
-  	rt2800_eeprom_write(rt2x00dev, EEPROM_RSSI_A2, word);
-  
-diff --git a/package/kernel/mac80211/patches/600-0031-rt2x00-rt2800lib-fix-txpower-compensation-for-RT3883.patch b/package/kernel/mac80211/patches/600-0031-rt2x00-rt2800lib-fix-txpower-compensation-for-RT3883.patch
-index 910f9ec..515086f 100644
---- a/package/kernel/mac80211/patches/600-0031-rt2x00-rt2800lib-fix-txpower-compensation-for-RT3883.patch
-+++ b/package/kernel/mac80211/patches/600-0031-rt2x00-rt2800lib-fix-txpower-compensation-for-RT3883.patch
-@@ -10,7 +10,7 @@ Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
- 
- --- a/drivers/net/wireless/rt2x00/rt2800lib.c
- +++ b/drivers/net/wireless/rt2x00/rt2800lib.c
--@@ -4005,6 +4005,9 @@ static u8 rt2800_compensate_txpower(stru
-+@@ -3981,6 +3981,9 @@ static u8 rt2800_compensate_txpower(stru
-  	if (rt2x00_rt(rt2x00dev, RT3593))
-  		return min_t(u8, txpower, 0xc);
-  
-diff --git a/package/kernel/mac80211/patches/600-0032-rt2x00-rt2800lib-enable-RT2800_HAS_HIGH_SHARED_MEM-f.patch b/package/kernel/mac80211/patches/600-0032-rt2x00-rt2800lib-enable-RT2800_HAS_HIGH_SHARED_MEM-f.patch
-index bcdfc67..77e3f1b 100644
---- a/package/kernel/mac80211/patches/600-0032-rt2x00-rt2800lib-enable-RT2800_HAS_HIGH_SHARED_MEM-f.patch
-+++ b/package/kernel/mac80211/patches/600-0032-rt2x00-rt2800lib-enable-RT2800_HAS_HIGH_SHARED_MEM-f.patch
-@@ -11,7 +11,7 @@ Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
- 
- --- a/drivers/net/wireless/rt2x00/rt2800lib.c
- +++ b/drivers/net/wireless/rt2x00/rt2800lib.c
--@@ -8441,7 +8441,8 @@ int rt2800_probe_hw(struct rt2x00_dev *r
-+@@ -8415,7 +8415,8 @@ int rt2800_probe_hw(struct rt2x00_dev *r
-  	if (retval)
-  		return retval;
-  
-diff --git a/package/kernel/mac80211/patches/603-rt2x00-introduce-rt2x00eeprom.patch b/package/kernel/mac80211/patches/603-rt2x00-introduce-rt2x00eeprom.patch
-index 8f650a2..44b629f 100644
---- a/package/kernel/mac80211/patches/603-rt2x00-introduce-rt2x00eeprom.patch
-+++ b/package/kernel/mac80211/patches/603-rt2x00-introduce-rt2x00eeprom.patch
-@@ -1,13 +1,13 @@
- --- a/.local-symbols
- +++ b/.local-symbols
--@@ -263,6 +263,7 @@ RT2X00_LIB_FIRMWARE=
-+@@ -312,6 +312,7 @@ RT2X00_LIB_FIRMWARE=
-  RT2X00_LIB_CRYPTO=
-  RT2X00_LIB_LEDS=
-  RT2X00_LIB_DEBUGFS=
- +RT2X00_LIB_EEPROM=
-  RT2X00_DEBUG=
-- RTL_CARDS=
-- RTL8192CE=
-+ WL_MEDIATEK=
-+ MT7601U=
- --- a/drivers/net/wireless/rt2x00/Kconfig
- +++ b/drivers/net/wireless/rt2x00/Kconfig
- @@ -69,6 +69,7 @@ config RT2800PCI
-@@ -48,7 +48,7 @@
-  obj-$(CPTCFG_RT2X00_LIB_MMIO)		+= rt2x00mmio.o
- --- a/drivers/net/wireless/rt2x00/rt2800lib.h
- +++ b/drivers/net/wireless/rt2x00/rt2800lib.h
--@@ -43,6 +43,8 @@ struct rt2800_drv_data {
-+@@ -46,6 +46,8 @@ struct rt2800_drv_data {
-  	} shmem_lock;
-  };
-  
-@@ -57,7 +57,7 @@
-  struct rt2800_ops {
-  	void (*register_read)(struct rt2x00_dev *rt2x00dev,
-  			      const unsigned int offset, u32 *value);
--@@ -176,6 +178,15 @@ static inline int rt2800_read_eeprom(str
-+@@ -179,6 +181,15 @@ static inline int rt2800_read_eeprom(str
-  {
-  	const struct rt2800_ops *rt2800ops = rt2x00dev->ops->drv;
-  
-diff --git a/package/kernel/mac80211/patches/608-add_platform_data_mac_addr.patch b/package/kernel/mac80211/patches/608-add_platform_data_mac_addr.patch
-index a35bd55..16a579d 100644
---- a/package/kernel/mac80211/patches/608-add_platform_data_mac_addr.patch
-+++ b/package/kernel/mac80211/patches/608-add_platform_data_mac_addr.patch
-@@ -41,7 +41,7 @@
-   * Interrupt context handlers.
- --- a/drivers/net/wireless/rt2x00/rt61pci.c
- +++ b/drivers/net/wireless/rt2x00/rt61pci.c
--@@ -2392,6 +2392,7 @@ static int rt61pci_validate_eeprom(struc
-+@@ -2390,6 +2390,7 @@ static int rt61pci_validate_eeprom(struc
-  	u32 reg;
-  	u16 word;
-  	u8 *mac;
-@@ -49,7 +49,7 @@
-  	s8 value;
-  
-  	rt2x00mmio_register_read(rt2x00dev, E2PROM_CSR, &reg);
--@@ -2412,7 +2413,11 @@ static int rt61pci_validate_eeprom(struc
-+@@ -2410,7 +2411,11 @@ static int rt61pci_validate_eeprom(struc
-  	/*
-  	 * Start validation of the data that has been read.
-  	 */
-diff --git a/package/kernel/mac80211/patches/610-rt2x00-fix-rt3352-ext-pa.patch b/package/kernel/mac80211/patches/610-rt2x00-fix-rt3352-ext-pa.patch
-index 067d2ea..39b1ccc 100644
---- a/package/kernel/mac80211/patches/610-rt2x00-fix-rt3352-ext-pa.patch
-+++ b/package/kernel/mac80211/patches/610-rt2x00-fix-rt3352-ext-pa.patch
-@@ -1,6 +1,6 @@
- --- a/drivers/net/wireless/rt2x00/rt2800lib.c
- +++ b/drivers/net/wireless/rt2x00/rt2800lib.c
--@@ -3552,11 +3552,18 @@ static void rt2800_config_channel(struct
-+@@ -3528,11 +3528,18 @@ static void rt2800_config_channel(struct
-  	/*
-  	 * Change BBP settings
-  	 */
-@@ -19,7 +19,7 @@
-  	} else if (rt2x00_rt(rt2x00dev, RT3593)) {
-  		if (rf->channel > 14) {
-  			/* Disable CCK Packet detection on 5GHz */
--@@ -6618,6 +6625,12 @@ static void rt2800_init_rfcsr_3290(struc
-+@@ -6594,6 +6601,12 @@ static void rt2800_init_rfcsr_3290(struc
-  
-  static void rt2800_init_rfcsr_3352(struct rt2x00_dev *rt2x00dev)
-  {
-@@ -32,7 +32,7 @@
-  	rt2800_rf_init_calibration(rt2x00dev, 30);
-  
-  	rt2800_rfcsr_write(rt2x00dev, 0, 0xf0);
--@@ -6653,15 +6666,30 @@ static void rt2800_init_rfcsr_3352(struc
-+@@ -6629,15 +6642,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);
-@@ -66,7 +66,7 @@
-  	rt2800_rfcsr_write(rt2x00dev, 43, 0xdb);
-  	rt2800_rfcsr_write(rt2x00dev, 44, 0xdb);
-  	rt2800_rfcsr_write(rt2x00dev, 45, 0xdb);
--@@ -6669,15 +6697,20 @@ static void rt2800_init_rfcsr_3352(struc
-+@@ -6645,15 +6673,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);
-@@ -96,7 +96,7 @@
-  	rt2800_rfcsr_write(rt2x00dev, 59, 0x00);
-  	rt2800_rfcsr_write(rt2x00dev, 60, 0x00);
-  	rt2800_rfcsr_write(rt2x00dev, 61, 0x00);
--@@ -7698,6 +7731,7 @@ static int rt2800_init_eeprom(struct rt2
-+@@ -7674,6 +7707,7 @@ static int rt2800_init_eeprom(struct rt2
-  	 * RT53xx: defined in "EEPROM_CHIP_ID" field
-  	 */
-  	if (rt2x00_rt(rt2x00dev, RT3290) ||
-@@ -104,7 +104,7 @@
-  	    rt2x00_rt(rt2x00dev, RT5390) ||
-  	    rt2x00_rt(rt2x00dev, RT5392))
-  		rt2800_eeprom_read(rt2x00dev, EEPROM_CHIP_ID, &rf);
--@@ -7793,7 +7827,8 @@ static int rt2800_init_eeprom(struct rt2
-+@@ -7769,7 +7803,8 @@ static int rt2800_init_eeprom(struct rt2
-  	/*
-  	 * Detect if this device has Bluetooth co-existence.
-  	 */
-@@ -114,7 +114,7 @@
-  		__set_bit(CAPABILITY_BT_COEXIST, &rt2x00dev->cap_flags);
-  
-  	/*
--@@ -7822,6 +7857,22 @@ static int rt2800_init_eeprom(struct rt2
-+@@ -7798,6 +7833,22 @@ static int rt2800_init_eeprom(struct rt2
-  					EIRP_MAX_TX_POWER_LIMIT)
-  		__set_bit(CAPABILITY_POWER_LIMIT, &rt2x00dev->cap_flags);
-  
-diff --git a/package/kernel/mac80211/patches/611-rt2x00-rf_vals-rt3352-xtal20.patch b/package/kernel/mac80211/patches/611-rt2x00-rf_vals-rt3352-xtal20.patch
-index 1dcca36..dcecba4 100644
---- a/package/kernel/mac80211/patches/611-rt2x00-rf_vals-rt3352-xtal20.patch
-+++ b/package/kernel/mac80211/patches/611-rt2x00-rf_vals-rt3352-xtal20.patch
-@@ -1,6 +1,6 @@
- --- a/drivers/net/wireless/rt2x00/rt2800lib.c
- +++ b/drivers/net/wireless/rt2x00/rt2800lib.c
--@@ -8209,6 +8209,27 @@ static const struct rf_channel rf_vals_5
-+@@ -8185,6 +8185,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;
--@@ -8297,7 +8318,10 @@ static int rt2800_probe_hw_mode(struct r
-+@@ -8271,7 +8292,10 @@ static int rt2800_probe_hw_mode(struct r
-  	case RF5390:
-  	case RF5392:
-  		spec->num_channels = 14;
-@@ -40,7 +40,7 @@
-  		break;
-  
-  	case RF3052:
--@@ -8481,6 +8505,19 @@ static int rt2800_probe_rt(struct rt2x00
-+@@ -8455,6 +8479,19 @@ static int rt2800_probe_rt(struct rt2x00
-  	return 0;
-  }
-  
-@@ -60,7 +60,7 @@
-  int rt2800_probe_hw(struct rt2x00_dev *rt2x00dev)
-  {
-  	struct rt2800_drv_data *drv_data = rt2x00dev->drv_data;
--@@ -8523,6 +8560,15 @@ int rt2800_probe_hw(struct rt2x00_dev *r
-+@@ -8497,6 +8534,15 @@ int rt2800_probe_hw(struct rt2x00_dev *r
-  	rt2800_register_write(rt2x00dev, GPIO_CTRL, reg);
-  
-  	/*
-diff --git a/package/kernel/mac80211/patches/615-rt2x00-fix_20mhz_clk.patch b/package/kernel/mac80211/patches/615-rt2x00-fix_20mhz_clk.patch
-index c779a17..9f11862 100644
---- a/package/kernel/mac80211/patches/615-rt2x00-fix_20mhz_clk.patch
-+++ b/package/kernel/mac80211/patches/615-rt2x00-fix_20mhz_clk.patch
-@@ -8,7 +8,7 @@
-  
-  #include "rt2x00.h"
-  #include "rt2800lib.h"
--@@ -8507,13 +8508,14 @@ static int rt2800_probe_rt(struct rt2x00
-+@@ -8481,13 +8482,14 @@ static int rt2800_probe_rt(struct rt2x00
-  
-  int rt2800_probe_clk(struct rt2x00_dev *rt2x00dev)
-  {
-diff --git a/package/kernel/mac80211/patches/616-rt2x00-support-rt5350.patch b/package/kernel/mac80211/patches/616-rt2x00-support-rt5350.patch
-index 840b3bc..9679d71 100644
---- a/package/kernel/mac80211/patches/616-rt2x00-support-rt5350.patch
-+++ b/package/kernel/mac80211/patches/616-rt2x00-support-rt5350.patch
-@@ -10,7 +10,7 @@
-  #define RF5370				0x5370
- --- a/drivers/net/wireless/rt2x00/rt2800lib.c
- +++ b/drivers/net/wireless/rt2x00/rt2800lib.c
--@@ -3038,6 +3038,13 @@ static void rt2800_config_channel_rf53xx
-+@@ -3014,6 +3014,13 @@ static void rt2800_config_channel_rf53xx
-  
-  				rt2800_rfcsr_write(rt2x00dev, 59,
-  						   r59_non_bt[idx]);
-@@ -24,7 +24,7 @@
-  			}
-  		}
-  	}
--@@ -3516,6 +3523,7 @@ static void rt2800_config_channel(struct
-+@@ -3492,6 +3499,7 @@ static void rt2800_config_channel(struct
-  		rt2800_config_channel_rf3853(rt2x00dev, conf, rf, info);
-  		break;
-  	case RF3070:
-@@ -32,7 +32,7 @@
-  	case RF5360:
-  	case RF5362:
-  	case RF5370:
--@@ -3534,6 +3542,7 @@ static void rt2800_config_channel(struct
-+@@ -3510,6 +3518,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, RF5362) ||
-  	    rt2x00_rf(rt2x00dev, RF5370) ||
--@@ -3812,7 +3821,8 @@ static void rt2800_config_channel(struct
-+@@ -3788,7 +3797,8 @@ static void rt2800_config_channel(struct
-  	/*
-  	 * Clear update flag
-  	 */
-@@ -50,7 +50,7 @@
-  		rt2800_bbp_read(rt2x00dev, 49, &bbp);
-  		rt2x00_set_field8(&bbp, BBP49_UPDATE_FLAG, 0);
-  		rt2800_bbp_write(rt2x00dev, 49, bbp);
--@@ -4698,6 +4708,7 @@ void rt2800_vco_calibration(struct rt2x0
-+@@ -4674,6 +4684,7 @@ void rt2800_vco_calibration(struct rt2x0
-  	case RF3070:
-  	case RF3290:
-  	case RF3853:
-@@ -58,7 +58,7 @@
-  	case RF5360:
-  	case RF5362:
-  	case RF5370:
--@@ -5111,6 +5122,8 @@ static int rt2800_init_registers(struct
-+@@ -5087,6 +5098,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);
--@@ -5766,9 +5779,13 @@ static void rt2800_init_bbp_3352(struct
-+@@ -5742,9 +5755,13 @@ static void rt2800_init_bbp_3352(struct
-  
-  	rt2800_bbp_write(rt2x00dev, 82, 0x62);
-  
-@@ -84,7 +84,7 @@
-  
-  	rt2800_bbp_write(rt2x00dev, 86, 0x38);
-  
--@@ -5782,9 +5799,13 @@ static void rt2800_init_bbp_3352(struct
-+@@ -5758,9 +5775,13 @@ static void rt2800_init_bbp_3352(struct
-  
-  	rt2800_bbp_write(rt2x00dev, 104, 0x92);
-  
-@@ -101,7 +101,7 @@
-  
-  	rt2800_bbp_write(rt2x00dev, 120, 0x50);
-  
--@@ -5809,6 +5830,13 @@ static void rt2800_init_bbp_3352(struct
-+@@ -5785,6 +5806,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)
--@@ -6150,6 +6178,7 @@ static void rt2800_init_bbp(struct rt2x0
-+@@ -6126,6 +6154,7 @@ static void rt2800_init_bbp(struct rt2x0
-  		rt2800_init_bbp_3290(rt2x00dev);
-  		break;
-  	case RT3352:
-@@ -123,7 +123,7 @@
-  		rt2800_init_bbp_3352(rt2x00dev);
-  		break;
-  	case RT3390:
--@@ -7101,6 +7130,76 @@ static void rt2800_init_rfcsr_3883(struc
-+@@ -7077,6 +7106,76 @@ static void rt2800_init_rfcsr_3883(struc
-  	rt2800_rfcsr_write(rt2x00dev, 20, rfcsr);
-  }
-  
-@@ -200,7 +200,7 @@
-  static void rt2800_init_rfcsr_5390(struct rt2x00_dev *rt2x00dev)
-  {
-  	rt2800_rf_init_calibration(rt2x00dev, 2);
--@@ -7341,6 +7440,9 @@ static void rt2800_init_rfcsr(struct rt2
-+@@ -7317,6 +7416,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;
--@@ -7600,6 +7702,12 @@ static int rt2800_validate_eeprom(struct
-+@@ -7576,6 +7678,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,7 +223,7 @@
-  	} else if (rt2x00_rt(rt2x00dev, RT2860) ||
-  		   rt2x00_rt(rt2x00dev, RT2872)) {
-  		/*
--@@ -7738,6 +7846,8 @@ static int rt2800_init_eeprom(struct rt2
-+@@ -7714,6 +7822,8 @@ static int rt2800_init_eeprom(struct rt2
-  		rt2800_eeprom_read(rt2x00dev, EEPROM_CHIP_ID, &rf);
-  	else if (rt2x00_rt(rt2x00dev, RT3883))
-  		rf = RF3853;
-@@ -232,7 +232,7 @@
-  	else
-  		rf = rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_RF_TYPE);
-  
--@@ -7757,6 +7867,7 @@ static int rt2800_init_eeprom(struct rt2
-+@@ -7733,6 +7843,7 @@ static int rt2800_init_eeprom(struct rt2
-  	case RF3320:
-  	case RF3322:
-  	case RF3853:
-@@ -240,7 +240,7 @@
-  	case RF5360:
-  	case RF5362:
-  	case RF5370:
--@@ -8312,6 +8423,7 @@ static int rt2800_probe_hw_mode(struct r
-+@@ -8286,6 +8397,7 @@ static int rt2800_probe_hw_mode(struct r
-  	case RF3290:
-  	case RF3320:
-  	case RF3322:
-@@ -248,7 +248,7 @@
-  	case RF5360:
-  	case RF5362:
-  	case RF5370:
--@@ -8451,6 +8563,7 @@ static int rt2800_probe_hw_mode(struct r
-+@@ -8425,6 +8537,7 @@ static int rt2800_probe_hw_mode(struct r
-  	case RF3070:
-  	case RF3290:
-  	case RF3853:
-@@ -256,7 +256,7 @@
-  	case RF5360:
-  	case RF5362:
-  	case RF5370:
--@@ -8491,6 +8604,7 @@ static int rt2800_probe_rt(struct rt2x00
-+@@ -8465,6 +8578,7 @@ static int rt2800_probe_rt(struct rt2x00
-  	case RT3572:
-  	case RT3593:
-  	case RT3883:
-diff --git a/package/kernel/mac80211/patches/619-rt2x00-change-led-polarity-from-OF.patch b/package/kernel/mac80211/patches/619-rt2x00-change-led-polarity-from-OF.patch
-index 13f2048..b085c5e 100644
---- a/package/kernel/mac80211/patches/619-rt2x00-change-led-polarity-from-OF.patch
-+++ b/package/kernel/mac80211/patches/619-rt2x00-change-led-polarity-from-OF.patch
-@@ -8,7 +8,7 @@
-  
-  #include "rt2x00.h"
-  #include "rt2800lib.h"
--@@ -7957,6 +7958,17 @@ static int rt2800_init_eeprom(struct rt2
-+@@ -7933,6 +7934,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/kernel/mac80211/patches/620-rt2x00-rt3352-rf-id.patch b/package/kernel/mac80211/patches/620-rt2x00-rt3352-rf-id.patch
-index aaa8367..259cb1f 100644
---- a/package/kernel/mac80211/patches/620-rt2x00-rt3352-rf-id.patch
-+++ b/package/kernel/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
--@@ -7841,10 +7841,11 @@ static int rt2800_init_eeprom(struct rt2
-+@@ -7817,10 +7817,11 @@ static int rt2800_init_eeprom(struct rt2
-  	 * RT53xx: defined in "EEPROM_CHIP_ID" field
-  	 */
-  	if (rt2x00_rt(rt2x00dev, RT3290) ||
-diff --git a/package/kernel/mac80211/patches/621-rt2x00-ht20_40_fix.patch b/package/kernel/mac80211/patches/621-rt2x00-ht20_40_fix.patch
-index bb2fc1c..77d63fe 100644
---- a/package/kernel/mac80211/patches/621-rt2x00-ht20_40_fix.patch
-+++ b/package/kernel/mac80211/patches/621-rt2x00-ht20_40_fix.patch
-@@ -11,7 +11,7 @@
-   * RFCSR 31:
- --- a/drivers/net/wireless/rt2x00/rt2800lib.c
- +++ b/drivers/net/wireless/rt2x00/rt2800lib.c
--@@ -3551,8 +3551,13 @@ static void rt2800_config_channel(struct
-+@@ -3527,8 +3527,13 @@ static void rt2800_config_channel(struct
-  	    rt2x00_rf(rt2x00dev, RF5390) ||
-  	    rt2x00_rf(rt2x00dev, RF5392)) {
-  		rt2800_rfcsr_read(rt2x00dev, 30, &rfcsr);
-diff --git a/package/kernel/mac80211/patches/801-libertas-configure-sysfs-links.patch b/package/kernel/mac80211/patches/801-libertas-configure-sysfs-links.patch
-index 9e29034..3b8b756 100644
---- a/package/kernel/mac80211/patches/801-libertas-configure-sysfs-links.patch
-+++ b/package/kernel/mac80211/patches/801-libertas-configure-sysfs-links.patch
-@@ -1,6 +1,6 @@
- --- a/drivers/net/wireless/libertas/cfg.c
- +++ b/drivers/net/wireless/libertas/cfg.c
--@@ -2084,6 +2084,8 @@ struct wireless_dev *lbs_cfg_alloc(struc
-+@@ -2083,6 +2083,8 @@ struct wireless_dev *lbs_cfg_alloc(struc
-  		goto err_wiphy_new;
-  	}
-  
-diff --git a/package/kernel/mac80211/patches/802-libertas-set-wireless-macaddr.patch b/package/kernel/mac80211/patches/802-libertas-set-wireless-macaddr.patch
-index 252fa81..dace56b 100644
---- a/package/kernel/mac80211/patches/802-libertas-set-wireless-macaddr.patch
-+++ b/package/kernel/mac80211/patches/802-libertas-set-wireless-macaddr.patch
-@@ -1,6 +1,6 @@
- --- a/drivers/net/wireless/libertas/cfg.c
- +++ b/drivers/net/wireless/libertas/cfg.c
--@@ -2174,6 +2174,8 @@ int lbs_cfg_register(struct lbs_private
-+@@ -2173,6 +2173,8 @@ int lbs_cfg_register(struct lbs_private
-  	wdev->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);
-  	wdev->wiphy->reg_notifier = lbs_reg_notifier;
-  
-diff --git a/package/kernel/mac80211/patches/820-b43-add-antenna-control.patch b/package/kernel/mac80211/patches/820-b43-add-antenna-control.patch
-index ac58dba..dd82ce5 100644
---- a/package/kernel/mac80211/patches/820-b43-add-antenna-control.patch
-+++ b/package/kernel/mac80211/patches/820-b43-add-antenna-control.patch
-@@ -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. */
--@@ -3302,8 +3302,8 @@ static int b43_chip_init(struct b43_wlde
-+@@ -3300,8 +3300,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);
--@@ -4003,7 +4003,6 @@ static int b43_op_config(struct ieee8021
-+@@ -4001,7 +4001,6 @@ static int b43_op_config(struct ieee8021
-  	struct b43_wldev *dev = wl->current_dev;
-  	struct b43_phy *phy = &dev->phy;
-  	struct ieee80211_conf *conf = &hw->conf;
-@@ -28,7 +28,7 @@
-  	int err = 0;
-  
-  	mutex_lock(&wl->mutex);
--@@ -4046,11 +4045,9 @@ static int b43_op_config(struct ieee8021
-+@@ -4044,11 +4043,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) {
--@@ -5213,6 +5210,47 @@ static int b43_op_get_survey(struct ieee
-+@@ -5209,6 +5206,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,
--@@ -5234,6 +5272,8 @@ static const struct ieee80211_ops b43_hw
-+@@ -5230,6 +5268,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.
--@@ -5542,6 +5582,8 @@ static int b43_one_core_attach(struct b4
-+@@ -5538,6 +5578,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;
--@@ -5632,6 +5674,9 @@ static struct b43_wl *b43_wireless_init(
-+@@ -5628,6 +5670,9 @@ static struct b43_wl *b43_wireless_init(
-  
-  	hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN;
-  
-diff --git a/package/kernel/mac80211/patches/861-brcmfmac-register-wiphy-s-during-module_init.patch b/package/kernel/mac80211/patches/861-brcmfmac-register-wiphy-s-during-module_init.patch
-index 685a5f9..f9799ce 100644
---- a/package/kernel/mac80211/patches/861-brcmfmac-register-wiphy-s-during-module_init.patch
-+++ b/package/kernel/mac80211/patches/861-brcmfmac-register-wiphy-s-during-module_init.patch
-@@ -13,7 +13,7 @@ Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
- 
- --- a/drivers/net/wireless/brcm80211/brcmfmac/core.c
- +++ b/drivers/net/wireless/brcm80211/brcmfmac/core.c
--@@ -1213,6 +1213,7 @@ static int __init brcmfmac_module_init(v
-+@@ -1189,6 +1189,7 @@ static int __init brcmfmac_module_init(v
-  #endif
-  	if (!schedule_work(&brcmf_driver_work))
-  		return -EBUSY;
-diff --git a/package/kernel/mac80211/patches/862-brcmfmac-workaround-bug-with-some-inconsistent-BSSes.patch b/package/kernel/mac80211/patches/862-brcmfmac-workaround-bug-with-some-inconsistent-BSSes.patch
-index 1cba2b3..5fdfa37 100644
---- a/package/kernel/mac80211/patches/862-brcmfmac-workaround-bug-with-some-inconsistent-BSSes.patch
-+++ b/package/kernel/mac80211/patches/862-brcmfmac-workaround-bug-with-some-inconsistent-BSSes.patch
-@@ -10,7 +10,7 @@ Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
- 
- --- a/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c
- +++ b/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c
--@@ -691,9 +691,37 @@ static struct wireless_dev *brcmf_cfg802
-+@@ -692,9 +692,37 @@ static struct wireless_dev *brcmf_cfg802
-  						     u32 *flags,
-  						     struct vif_params *params)
-  {
-diff --git a/package/kernel/mac80211/patches/900-wlcore-Add-support-for-DT-platform-data.patch b/package/kernel/mac80211/patches/900-wlcore-Add-support-for-DT-platform-data.patch
-deleted file mode 100644
-index 856dea8..0000000
---- a/package/kernel/mac80211/patches/900-wlcore-Add-support-for-DT-platform-data.patch
-+++ /dev/null
-@@ -1,139 +0,0 @@
--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/kernel/mac80211/patches/910-01-add-support-for-mt7620.patch b/package/kernel/mac80211/patches/910-01-add-support-for-mt7620.patch
-index 501910f..b0536ce 100644
---- a/package/kernel/mac80211/patches/910-01-add-support-for-mt7620.patch
-+++ b/package/kernel/mac80211/patches/910-01-add-support-for-mt7620.patch
-@@ -210,7 +210,7 @@
-  	case RT5592:
-  		*txwi_size = TXWI_DESC_SIZE_5WORDS;
-  		*rxwi_size = RXWI_DESC_SIZE_6WORDS;
--@@ -3326,6 +3399,312 @@ static void rt2800_config_channel_rf55xx
-+@@ -3302,6 +3375,312 @@ static void rt2800_config_channel_rf55xx
-  	rt2800_bbp_write(rt2x00dev, 196, (rf->channel <= 14) ? 0x19 : 0x7F);
-  }
-  
-@@ -258,6 +258,7 @@
- +	u32 mac_sys_ctrl, mac_status;
- +	u32 tx_pin = 0x00150F0F;
- +	struct hw_mode_spec *spec = &rt2x00dev->spec;
-++	struct rt2800_drv_data *drv_data = rt2x00dev->drv_data;
- +
- +	/* Frequeny plan setting */
- +	/*	
-@@ -383,7 +384,6 @@
- +		rfcsr &= (~0x4);
- +	rt2800_rfcsr_write(rt2x00dev, 28, rfcsr);
- +
--+	struct rt2800_drv_data *drv_data = rt2x00dev->drv_data;
- +	/*if (bScan == FALSE)*/
- +	if (conf_is_ht40(conf)) {
- +		txrx_agc_fc = rt2x00_get_field8(drv_data->calibration_bw40,
-@@ -523,7 +523,7 @@
-  static void rt2800_bbp_write_with_rx_chain(struct rt2x00_dev *rt2x00dev,
-  					   const unsigned int word,
-  					   const u8 value)
--@@ -3482,7 +3861,7 @@ static void rt2800_config_channel(struct
-+@@ -3458,7 +3837,7 @@ static void rt2800_config_channel(struct
-  				  struct channel_info *info)
-  {
-  	u32 reg;
-@@ -532,7 +532,7 @@
-  	u8 bbp, rfcsr;
-  
-  	info->default_power1 = rt2800_txpower_to_dev(rt2x00dev, rf->channel,
--@@ -3536,6 +3915,9 @@ static void rt2800_config_channel(struct
-+@@ -3512,6 +3891,9 @@ static void rt2800_config_channel(struct
-  	case RF5592:
-  		rt2800_config_channel_rf55xx(rt2x00dev, conf, rf, info);
-  		break;
-@@ -542,7 +542,7 @@
-  	default:
-  		rt2800_config_channel_rf2xxx(rt2x00dev, conf, rf, info);
-  	}
--@@ -3638,7 +4020,7 @@ static void rt2800_config_channel(struct
-+@@ -3614,7 +3996,7 @@ static void rt2800_config_channel(struct
-  		else if (rt2x00_rt(rt2x00dev, RT3593) ||
-  			 rt2x00_rt(rt2x00dev, RT3883))
-  			rt2800_bbp_write(rt2x00dev, 82, 0x82);
-@@ -551,7 +551,7 @@
-  			rt2800_bbp_write(rt2x00dev, 82, 0xf2);
-  
-  		if (rt2x00_rt(rt2x00dev, RT3593) ||
--@@ -3660,7 +4042,7 @@ static void rt2800_config_channel(struct
-+@@ -3636,7 +4018,7 @@ static void rt2800_config_channel(struct
-  	if (rt2x00_rt(rt2x00dev, RT3572))
-  		rt2800_rfcsr_write(rt2x00dev, 8, 0);
-  
-@@ -560,7 +560,7 @@
-  
-  	switch (rt2x00dev->default_ant.tx_chain_num) {
-  	case 3:
--@@ -3709,6 +4091,7 @@ static void rt2800_config_channel(struct
-+@@ -3685,6 +4067,7 @@ static void rt2800_config_channel(struct
-  
-  	rt2x00_set_field32(&tx_pin, TX_PIN_CFG_RFTR_EN, 1);
-  	rt2x00_set_field32(&tx_pin, TX_PIN_CFG_TRSW_EN, 1);
-@@ -568,7 +568,7 @@
-  
-  	rt2800_register_write(rt2x00dev, TX_PIN_CFG, tx_pin);
-  
--@@ -4725,6 +5108,14 @@ void rt2800_vco_calibration(struct rt2x0
-+@@ -4701,6 +5084,14 @@ void rt2800_vco_calibration(struct rt2x0
-  		rt2x00_set_field8(&rfcsr, RFCSR3_VCOCAL_EN, 1);
-  		rt2800_rfcsr_write(rt2x00dev, 3, rfcsr);
-  		break;
-@@ -583,7 +583,7 @@
-  	default:
-  		return;
-  	}
--@@ -5125,9 +5516,42 @@ static int rt2800_init_registers(struct
-+@@ -5101,9 +5492,42 @@ static int rt2800_init_registers(struct
-  	} else if (rt2x00_rt(rt2x00dev, RT5390) ||
-  		   rt2x00_rt(rt2x00dev, RT5392) ||
-  		   rt2x00_rt(rt2x00dev, RT5592)) {
-@@ -629,7 +629,7 @@
-  	} else if (rt2x00_rt(rt2x00dev, RT5350)) {
-  		rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000404);
-  	} else {
--@@ -6159,6 +6583,225 @@ static void rt2800_init_bbp_5592(struct
-+@@ -6135,6 +6559,225 @@ static void rt2800_init_bbp_5592(struct
-  		rt2800_bbp_write(rt2x00dev, 103, 0xc0);
-  }
-  
-@@ -855,7 +855,7 @@
-  static void rt2800_init_bbp(struct rt2x00_dev *rt2x00dev)
-  {
-  	unsigned int i;
--@@ -6201,7 +6844,10 @@ static void rt2800_init_bbp(struct rt2x0
-+@@ -6177,7 +6820,10 @@ static void rt2800_init_bbp(struct rt2x0
-  		return;
-  	case RT5390:
-  	case RT5392:
-@@ -867,7 +867,7 @@
-  		break;
-  	case RT5592:
-  		rt2800_init_bbp_5592(rt2x00dev);
--@@ -7415,6 +8061,295 @@ static void rt2800_init_rfcsr_5592(struc
-+@@ -7391,6 +8037,296 @@ static void rt2800_init_rfcsr_5592(struc
-  	rt2800_led_open_drain_enable(rt2x00dev);
-  }
-  
-@@ -875,6 +875,8 @@
- +{
- +	u16 freq;
- +	u8 rfvalue;
-++	struct hw_mode_spec *spec = &rt2x00dev->spec;
-++
- +	/* Initialize RF central register to default value */
- +	rt2800_rfcsr_write(rt2x00dev, 0, 0x02);
- +	rt2800_rfcsr_write(rt2x00dev, 1, 0x03);
-@@ -921,7 +923,6 @@
- +	rt2800_rfcsr_write(rt2x00dev, 42, 0x5B);
- +	rt2800_rfcsr_write(rt2x00dev, 43, 0x00);
- +
--+	struct hw_mode_spec *spec = &rt2x00dev->spec;
- +	rt2800_rfcsr_write(rt2x00dev, 11, 0x21);
- +	if (spec->clk_is_20mhz)
- +		rt2800_rfcsr_write(rt2x00dev, 13, 0x03);
-@@ -1163,7 +1164,7 @@
-  static void rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev)
-  {
-  	if (rt2800_is_305x_soc(rt2x00dev)) {
--@@ -7450,7 +8385,10 @@ static void rt2800_init_rfcsr(struct rt2
-+@@ -7426,7 +8362,10 @@ static void rt2800_init_rfcsr(struct rt2
-  		rt2800_init_rfcsr_5350(rt2x00dev);
-  		break;
-  	case RT5390:
-@@ -1175,7 +1176,7 @@
-  		break;
-  	case RT5392:
-  		rt2800_init_rfcsr_5392(rt2x00dev);
--@@ -7882,6 +8820,7 @@ static int rt2800_init_eeprom(struct rt2
-+@@ -7858,6 +8797,7 @@ static int rt2800_init_eeprom(struct rt2
-  	case RF5390:
-  	case RF5392:
-  	case RF5592:
-@@ -1183,7 +1184,7 @@
-  		break;
-  	default:
-  		rt2x00_err(rt2x00dev, "Invalid RF chipset 0x%04x detected\n",
--@@ -8448,6 +9387,7 @@ static int rt2800_probe_hw_mode(struct r
-+@@ -8422,6 +9362,7 @@ static int rt2800_probe_hw_mode(struct r
-  	case RF5372:
-  	case RF5390:
-  	case RF5392:
-@@ -1191,7 +1192,7 @@
-  		spec->num_channels = 14;
-  		if (spec->clk_is_20mhz)
-  			spec->channels = rf_vals_xtal20mhz_3x;
--@@ -8588,6 +9528,7 @@ static int rt2800_probe_hw_mode(struct r
-+@@ -8562,6 +9503,7 @@ static int rt2800_probe_hw_mode(struct r
-  	case RF5372:
-  	case RF5390:
-  	case RF5392:
-diff --git a/package/kernel/mac80211/patches/920-ath10k_allow_fallback_to_board_bin_on_empty_otp_stream.patch b/package/kernel/mac80211/patches/920-ath10k_allow_fallback_to_board_bin_on_empty_otp_stream.patch
-deleted file mode 100644
-index 4c04d4f..0000000
---- a/package/kernel/mac80211/patches/920-ath10k_allow_fallback_to_board_bin_on_empty_otp_stream.patch
-+++ /dev/null
-@@ -1,20 +0,0 @@
----- a/drivers/net/wireless/ath/ath10k/core.c
--+++ b/drivers/net/wireless/ath/ath10k/core.c
--@@ -387,9 +387,14 @@ static int ath10k_download_and_run_otp(s
-- 
-- 	ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot otp execute result %d\n", result);
-- 
---	if (!skip_otp && result != 0) {
---		ath10k_err(ar, "otp calibration failed: %d", result);
---		return -EINVAL;
--+	if (!skip_otp) {
--+		if (result == 2) {
--+			ath10k_warn(ar, "otp stream is empty, using board.bin contents");
--+			return 0;
--+		} else if (result != 0) {
--+			ath10k_err(ar, "otp calibration failed: %d", result);
--+			return -EINVAL;
--+		}
-- 	}
-- 
-- 	return 0;
-diff --git a/package/kernel/mac80211/patches/921-ath10k_init_devices_synchronously.patch b/package/kernel/mac80211/patches/921-ath10k_init_devices_synchronously.patch
-index eed3814..93196e1 100644
---- a/package/kernel/mac80211/patches/921-ath10k_init_devices_synchronously.patch
-+++ b/package/kernel/mac80211/patches/921-ath10k_init_devices_synchronously.patch
-@@ -14,7 +14,7 @@ Signed-off-by: Sven Eckelmann <sven@open-mesh.com>
- 
- --- a/drivers/net/wireless/ath/ath10k/core.c
- +++ b/drivers/net/wireless/ath/ath10k/core.c
--@@ -1323,6 +1323,16 @@ int ath10k_core_register(struct ath10k *
-+@@ -1520,6 +1520,16 @@ int ath10k_core_register(struct ath10k *
-  	ar->chip_id = chip_id;
-  	queue_work(ar->workqueue, &ar->register_work);
-  
-diff --git a/package/kernel/mac80211/patches/930-ath10k_add_tpt_led_trigger.patch b/package/kernel/mac80211/patches/930-ath10k_add_tpt_led_trigger.patch
-index 8003f86..34910a0 100644
---- a/package/kernel/mac80211/patches/930-ath10k_add_tpt_led_trigger.patch
-+++ b/package/kernel/mac80211/patches/930-ath10k_add_tpt_led_trigger.patch
-@@ -1,6 +1,6 @@
- --- a/drivers/net/wireless/ath/ath10k/mac.c
- +++ b/drivers/net/wireless/ath/ath10k/mac.c
--@@ -5416,6 +5416,21 @@ struct ath10k_vif *ath10k_get_arvif(stru
-+@@ -6804,6 +6804,21 @@ struct ath10k_vif *ath10k_get_arvif(stru
-  	return arvif_iter.arvif;
-  }
-  
-@@ -22,7 +22,7 @@
-  int ath10k_mac_register(struct ath10k *ar)
-  {
-  	static const u32 cipher_suites[] = {
--@@ -5590,6 +5605,12 @@ int ath10k_mac_register(struct ath10k *a
-+@@ -7025,6 +7040,12 @@ int ath10k_mac_register(struct ath10k *a
-  	ar->hw->wiphy->cipher_suites = cipher_suites;
-  	ar->hw->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);
-  
-diff --git a/package/kernel/mac80211/patches/940-mwl8k_init_devices_synchronously.patch b/package/kernel/mac80211/patches/940-mwl8k_init_devices_synchronously.patch
-new file mode 100644
-index 0000000..75d8212
---- /dev/null
-+++ b/package/kernel/mac80211/patches/940-mwl8k_init_devices_synchronously.patch
-@@ -0,0 +1,20 @@
-+--- a/drivers/net/wireless/mwl8k.c
-++++ b/drivers/net/wireless/mwl8k.c
-+@@ -6261,6 +6261,8 @@ static int mwl8k_probe(struct pci_dev *p
-+ 
-+ 	priv->running_bsses = 0;
-+ 
-++	wait_for_completion(&priv->firmware_loading_complete);
-++
-+ 	return rc;
-+ 
-+ err_stop_firmware:
-+@@ -6294,8 +6296,6 @@ static void mwl8k_remove(struct pci_dev
-+ 		return;
-+ 	priv = hw->priv;
-+ 
-+-	wait_for_completion(&priv->firmware_loading_complete);
-+-
-+ 	if (priv->fw_state == FW_STATE_ERROR) {
-+ 		mwl8k_hw_reset(priv);
-+ 		goto unmap;

+ 1 - 1
patches/openwrt/0022-hostapd-work-around-unconditional-libopenssl-build-dependency.patch

@@ -8,7 +8,7 @@ not only wpad-mesh. Fix this by applying the same workaround as in
 ustream-ssl.
 ustream-ssl.
 
 
 diff --git a/package/network/services/hostapd/Makefile b/package/network/services/hostapd/Makefile
 diff --git a/package/network/services/hostapd/Makefile b/package/network/services/hostapd/Makefile
-index c16cb11..c39b6b4 100644
+index 3dff7b4..d86bb43 100644
 --- a/package/network/services/hostapd/Makefile
 --- a/package/network/services/hostapd/Makefile
 +++ b/package/network/services/hostapd/Makefile
 +++ b/package/network/services/hostapd/Makefile
 @@ -177,7 +177,7 @@ endef
 @@ -177,7 +177,7 @@ endef