From 46d2b929c768ad4f0817f9132cddb71eaf1f40c4 Mon Sep 17 00:00:00 2001
From: Felix Fietkau <nbd@openwrt.org>
Date: Sat, 27 Aug 2011 21:57:07 +0000
Subject: mac80211: update to wireless-testing 2011-08-26

SVN-Revision: 28093
---
 package/mac80211/Makefile                          |   8 +-
 .../mac80211/patches/000-disable_ethernet.patch    |  12 +
 package/mac80211/patches/001-disable_b44.patch     |   2 +-
 package/mac80211/patches/002-disable_rfkill.patch  |   2 +-
 .../mac80211/patches/005-disable_ssb_build.patch   |  17 +-
 .../mac80211/patches/006-disable_bcma_build.patch  |  20 +-
 .../mac80211/patches/007-remove_misc_drivers.patch |   6 +-
 package/mac80211/patches/010-no_pcmcia.patch       |   2 +-
 package/mac80211/patches/011-no_sdio.patch         |   2 +-
 .../mac80211/patches/013-disable_b43_nphy.patch    |   2 +-
 .../patches/015-remove-rt2x00-options.patch        |   4 +-
 package/mac80211/patches/017-remove_ath9k_rc.patch |   2 +-
 .../patches/018-revert_printk_va_format.patch      |   4 +-
 .../patches/019-remove_ath5k_pci_option.patch      |   2 +-
 .../mac80211/patches/022-atomic64_backport.patch   |   8 +-
 .../mac80211/patches/110-disable_usb_compat.patch  |   2 +-
 package/mac80211/patches/300-pending_work.patch    | 792 ++-------------------
 package/mac80211/patches/310-ibss_ht.patch         |  20 +-
 .../mac80211/patches/400-ath_move_debug_code.patch |  11 +
 .../patches/410-ath9k_allow_adhoc_and_ap.patch     |   4 +-
 .../patches/510-ath9k_intr_mitigation_tweak.patch  |   2 +-
 .../patches/530-mac80211_cur_txpower.patch         |   2 +-
 .../mac80211/patches/531-ath9k_cur_txpower.patch   |   4 +-
 .../patches/540-ath9k_sw_retry_reduce.patch        |  61 --
 .../mac80211/patches/540-ath9k_txkeyidx_u8.patch   |  56 ++
 .../patches/541-ath9k_aggr_queue_cleanup.patch     |  34 +-
 .../mac80211/patches/542-ath9k_limit_qlen.patch    | 176 -----
 .../mac80211/patches/542-ath9k_move_seqno.patch    | 207 ++++++
 .../patches/543-ath9k_move_seqno_alloc.patch       | 119 ++++
 .../patches/544-ath9k_defer_buffer_setup.patch     | 264 +++++++
 .../mac80211/patches/550-ath9k_limit_qlen.patch    | 152 ++++
 .../patches/551-ath9k_sw_retry_reduce.patch        |  61 ++
 .../patches/560-mac80211_defer_bar_tx.patch        |  90 +++
 ...t2x00-add-CONFIG_RT2X00_LIB_EEPROM-option.patch |   2 +-
 .../700-mwl8k-missing-pci-id-for-WNR854T.patch     |   2 +-
 .../patches/800-b43-gpio-mask-module-option.patch  |  19 +-
 package/mac80211/patches/810-b43_no_pio.patch      |   2 +-
 37 files changed, 1114 insertions(+), 1061 deletions(-)
 create mode 100644 package/mac80211/patches/000-disable_ethernet.patch
 create mode 100644 package/mac80211/patches/400-ath_move_debug_code.patch
 delete mode 100644 package/mac80211/patches/540-ath9k_sw_retry_reduce.patch
 create mode 100644 package/mac80211/patches/540-ath9k_txkeyidx_u8.patch
 delete mode 100644 package/mac80211/patches/542-ath9k_limit_qlen.patch
 create mode 100644 package/mac80211/patches/542-ath9k_move_seqno.patch
 create mode 100644 package/mac80211/patches/543-ath9k_move_seqno_alloc.patch
 create mode 100644 package/mac80211/patches/544-ath9k_defer_buffer_setup.patch
 create mode 100644 package/mac80211/patches/550-ath9k_limit_qlen.patch
 create mode 100644 package/mac80211/patches/551-ath9k_sw_retry_reduce.patch
 create mode 100644 package/mac80211/patches/560-mac80211_defer_bar_tx.patch

(limited to 'package/mac80211')

diff --git a/package/mac80211/Makefile b/package/mac80211/Makefile
index 2faae577d3..d4bbff495f 100644
--- a/package/mac80211/Makefile
+++ b/package/mac80211/Makefile
@@ -10,10 +10,10 @@ include $(INCLUDE_DIR)/kernel.mk
 
 PKG_NAME:=mac80211
 
-PKG_VERSION:=2011-08-10
-PKG_RELEASE:=2
+PKG_VERSION:=2011-08-26
+PKG_RELEASE:=1
 PKG_SOURCE_URL:=http://mirror2.openwrt.org/sources
-PKG_MD5SUM:=fb2ee04eaafbdf4117c475ba78f8f5b9
+PKG_MD5SUM:=37218b56e8a30b351662087d68948825
 
 PKG_SOURCE:=compat-wireless-$(PKG_VERSION).tar.bz2
 PKG_BUILD_DIR:=$(KERNEL_BUILD_DIR)/compat-wireless-$(PKG_VERSION)
@@ -1155,7 +1155,7 @@ MAKE_OPTS:= \
 	CONFIG_LIBERTAS=$(if $(CONFIG_PACKAGE_kmod-libertas-sd)$(CONFIG_PACKAGE_kmod-libertas-usb),m) \
 	CONFIG_LIBERTAS_CS= \
 	CONFIG_LIBERTAS_SPI= \
-	CONFIG_LIBERTAS_SDIO=$(if $(CONFIG_PACKAGE_kmod-libertas-sd),m) \
+	CONFIG_COMPAT_LIBERTAS_SDIO=$(if $(CONFIG_PACKAGE_kmod-libertas-sd),m) \
 	CONFIG_LIBERTAS_THINFIRM= \
 	CONFIG_LIBERTAS_USB=$(if $(CONFIG_PACKAGE_kmod-libertas-usb),m) \
 	CONFIG_IPW2100=$(if $(CONFIG_PACKAGE_kmod-net-ipw2100),m) \
diff --git a/package/mac80211/patches/000-disable_ethernet.patch b/package/mac80211/patches/000-disable_ethernet.patch
new file mode 100644
index 0000000000..f89fa53290
--- /dev/null
+++ b/package/mac80211/patches/000-disable_ethernet.patch
@@ -0,0 +1,12 @@
+--- a/Makefile
++++ b/Makefile
+@@ -29,9 +29,6 @@ obj-$(CONFIG_COMPAT_WIRELESS_MODULES) +=
+ 
+ obj-$(CONFIG_COMPAT_NET_USB_MODULES) += drivers/net/usb/
+ 
+-obj-$(CONFIG_COMPAT_NETWORK_MODULES) += drivers/net/ethernet/atheros/
+-obj-$(CONFIG_COMPAT_NETWORK_MODULES) += drivers/net/ethernet/broadcom/
+-
+ obj-$(CONFIG_COMPAT_VAR_MODULES) += drivers/ssb/
+ obj-$(CONFIG_COMPAT_VAR_MODULES) += drivers/bcma/
+ obj-$(CONFIG_COMPAT_VAR_MODULES) += drivers/misc/eeprom/
diff --git a/package/mac80211/patches/001-disable_b44.patch b/package/mac80211/patches/001-disable_b44.patch
index 547a453eac..a4008bf1ad 100644
--- a/package/mac80211/patches/001-disable_b44.patch
+++ b/package/mac80211/patches/001-disable_b44.patch
@@ -1,6 +1,6 @@
 --- a/config.mk
 +++ b/config.mk
-@@ -339,8 +339,8 @@ CONFIG_B43_BCMA_PIO=y
+@@ -340,8 +340,8 @@ CONFIG_B43_BCMA_PIO=y
  
  CONFIG_P54_PCI=m
  
diff --git a/package/mac80211/patches/002-disable_rfkill.patch b/package/mac80211/patches/002-disable_rfkill.patch
index 887b9956f8..61e8b966b7 100644
--- a/package/mac80211/patches/002-disable_rfkill.patch
+++ b/package/mac80211/patches/002-disable_rfkill.patch
@@ -9,7 +9,7 @@
  
  ifeq ($(CONFIG_MAC80211),y)
  $(error "ERROR: you have MAC80211 compiled into the kernel, CONFIG_MAC80211=y, as such you cannot replace its mac80211 driver. You need this set to CONFIG_MAC80211=m. If you are using Fedora upgrade your kernel as later version should this set as modular. For further information on Fedora see https://bugzilla.redhat.com/show_bug.cgi?id=470143. If you are using your own kernel recompile it and make mac80211 modular")
-@@ -649,10 +649,10 @@ endif #CONFIG_COMPAT_KERNEL_2_6_27
+@@ -642,10 +642,10 @@ endif #CONFIG_COMPAT_KERNEL_2_6_27
  # We need the backported rfkill module on kernel < 2.6.31.
  # In more recent kernel versions use the in kernel rfkill module.
  ifdef CONFIG_COMPAT_KERNEL_2_6_31
diff --git a/package/mac80211/patches/005-disable_ssb_build.patch b/package/mac80211/patches/005-disable_ssb_build.patch
index 04bf827d72..d5578d173f 100644
--- a/package/mac80211/patches/005-disable_ssb_build.patch
+++ b/package/mac80211/patches/005-disable_ssb_build.patch
@@ -1,14 +1,13 @@
 --- a/Makefile
 +++ b/Makefile
-@@ -30,7 +30,7 @@ obj-$(CONFIG_COMPAT_WIRELESS_MODULES) +=
+@@ -29,7 +29,6 @@ obj-$(CONFIG_COMPAT_WIRELESS_MODULES) +=
+ 
  obj-$(CONFIG_COMPAT_NET_USB_MODULES) += drivers/net/usb/
  
- obj-$(CONFIG_COMPAT_NETWORK_MODULES) += drivers/net/
--obj-$(CONFIG_COMPAT_VAR_MODULES) +=  drivers/ssb/ drivers/bcma/ drivers/misc/eeprom/
-+obj-$(CONFIG_COMPAT_VAR_MODULES) +=  drivers/bcma/ drivers/misc/eeprom/
+-obj-$(CONFIG_COMPAT_VAR_MODULES) += drivers/ssb/
+ obj-$(CONFIG_COMPAT_VAR_MODULES) += drivers/bcma/
+ obj-$(CONFIG_COMPAT_VAR_MODULES) += drivers/misc/eeprom/
  
- ifeq ($(CONFIG_STAGING_EXCLUDE_BUILD),)
- obj-$(CONFIG_COMPAT_STAGING) += drivers/staging/ath6kl/
 --- a/config.mk
 +++ b/config.mk
 @@ -9,7 +9,6 @@ ifeq ($(wildcard $(KLIB_BUILD)/.config),
@@ -19,7 +18,7 @@
  else
  include $(KLIB_BUILD)/.config
  endif
-@@ -315,7 +314,8 @@ CONFIG_IPW2200_QOS=y
+@@ -316,7 +315,8 @@ CONFIG_IPW2200_QOS=y
  # % echo 1 > /sys/bus/pci/drivers/ipw2200/*/rtap_iface
  endif #CONFIG_WIRELESS_EXT
  
@@ -29,7 +28,7 @@
  # Sonics Silicon Backplane
  CONFIG_SSB_SPROM=y
  
-@@ -328,7 +328,7 @@ endif #CONFIG_PCMCIA
+@@ -329,7 +329,7 @@ endif #CONFIG_PCMCIA
  # CONFIG_SSB_DEBUG=y
  CONFIG_SSB_DRIVER_PCICORE=y
  CONFIG_B43_SSB=y
@@ -38,7 +37,7 @@
  
  CONFIG_BCMA=m
  CONFIG_BCMA_BLOCKIO=y
-@@ -537,7 +537,6 @@ endif #CONFIG_SPI_MASTER end of SPI driv
+@@ -538,7 +538,6 @@ endif #CONFIG_SPI_MASTER end of SPI driv
  
  ifdef CONFIG_MMC
  
diff --git a/package/mac80211/patches/006-disable_bcma_build.patch b/package/mac80211/patches/006-disable_bcma_build.patch
index 93d00cd259..17eff65383 100644
--- a/package/mac80211/patches/006-disable_bcma_build.patch
+++ b/package/mac80211/patches/006-disable_bcma_build.patch
@@ -1,17 +1,16 @@
 --- a/Makefile
 +++ b/Makefile
-@@ -30,7 +30,7 @@ obj-$(CONFIG_COMPAT_WIRELESS_MODULES) +=
+@@ -29,7 +29,6 @@ obj-$(CONFIG_COMPAT_WIRELESS_MODULES) +=
+ 
  obj-$(CONFIG_COMPAT_NET_USB_MODULES) += drivers/net/usb/
  
- obj-$(CONFIG_COMPAT_NETWORK_MODULES) += drivers/net/
--obj-$(CONFIG_COMPAT_VAR_MODULES) +=  drivers/bcma/ drivers/misc/eeprom/
-+obj-$(CONFIG_COMPAT_VAR_MODULES) +=  drivers/misc/eeprom/
+-obj-$(CONFIG_COMPAT_VAR_MODULES) += drivers/bcma/
+ obj-$(CONFIG_COMPAT_VAR_MODULES) += drivers/misc/eeprom/
  
  ifeq ($(CONFIG_STAGING_EXCLUDE_BUILD),)
- obj-$(CONFIG_COMPAT_STAGING) += drivers/staging/ath6kl/
 --- a/config.mk
 +++ b/config.mk
-@@ -330,9 +330,9 @@ CONFIG_SSB_DRIVER_PCICORE=y
+@@ -331,12 +331,12 @@ CONFIG_SSB_DRIVER_PCICORE=y
  CONFIG_B43_SSB=y
  endif #__CONFIG_SSB
  
@@ -22,5 +21,10 @@
 +# CONFIG_BCMA_BLOCKIO=y
 +# CONFIG_BCMA_HOST_PCI=y
  # CONFIG_BCMA_DEBUG=y
- CONFIG_B43_BCMA=y
- CONFIG_B43_BCMA_PIO=y
+-CONFIG_B43_BCMA=y
+-CONFIG_B43_BCMA_PIO=y
++# CONFIG_B43_BCMA=y
++# CONFIG_B43_BCMA_PIO=y
+ 
+ CONFIG_P54_PCI=m
+ 
diff --git a/package/mac80211/patches/007-remove_misc_drivers.patch b/package/mac80211/patches/007-remove_misc_drivers.patch
index cdf9e03252..103eb7b60a 100644
--- a/package/mac80211/patches/007-remove_misc_drivers.patch
+++ b/package/mac80211/patches/007-remove_misc_drivers.patch
@@ -1,6 +1,6 @@
 --- a/config.mk
 +++ b/config.mk
-@@ -212,7 +212,7 @@ $(warning "WARNING: CONFIG_CFG80211_WEXT
+@@ -213,7 +213,7 @@ $(warning "WARNING: CONFIG_CFG80211_WEXT
  endif #CONFIG_WIRELESS_EXT
  
  ifdef CONFIG_STAGING
@@ -9,7 +9,7 @@
  endif #CONFIG_STAGING
  
  # mac80211 test driver
-@@ -367,13 +367,13 @@ endif #CONFIG_CRC_ITU_T
+@@ -368,13 +368,13 @@ endif #CONFIG_CRC_ITU_T
  CONFIG_MWL8K=m
  
  # Ethernet drivers go here
@@ -28,7 +28,7 @@
  endif #CONFIG_COMPAT_KERNEL_2_6_27
  
  ifdef CONFIG_WIRELESS_EXT
-@@ -434,21 +434,21 @@ endif #CONFIG_COMPAT_KERNEL_2_6_29
+@@ -435,21 +435,21 @@ endif #CONFIG_COMPAT_KERNEL_2_6_29
  # Note: this depends on CONFIG_USB_NET_RNDIS_HOST and CONFIG_USB_NET_CDCETHER
  # it also requires new RNDIS_HOST and CDC_ETHER modules which we add
  ifdef CONFIG_COMPAT_KERNEL_2_6_29
diff --git a/package/mac80211/patches/010-no_pcmcia.patch b/package/mac80211/patches/010-no_pcmcia.patch
index f6b89d86bc..d6246b782a 100644
--- a/package/mac80211/patches/010-no_pcmcia.patch
+++ b/package/mac80211/patches/010-no_pcmcia.patch
@@ -9,7 +9,7 @@
  else
  include $(KLIB_BUILD)/.config
  endif
-@@ -247,7 +247,7 @@ CONFIG_B43=m
+@@ -248,7 +248,7 @@ CONFIG_B43=m
  CONFIG_B43_HWRNG=y
  CONFIG_B43_PCI_AUTOSELECT=y
  ifdef CONFIG_PCMCIA
diff --git a/package/mac80211/patches/011-no_sdio.patch b/package/mac80211/patches/011-no_sdio.patch
index bb6be23667..366488a4ad 100644
--- a/package/mac80211/patches/011-no_sdio.patch
+++ b/package/mac80211/patches/011-no_sdio.patch
@@ -1,6 +1,6 @@
 --- a/config.mk
 +++ b/config.mk
-@@ -520,7 +520,7 @@ endif #CONFIG_SPI_MASTER end of SPI driv
+@@ -521,7 +521,7 @@ endif #CONFIG_SPI_MASTER end of SPI driv
  
  ifdef CONFIG_MMC
  
diff --git a/package/mac80211/patches/013-disable_b43_nphy.patch b/package/mac80211/patches/013-disable_b43_nphy.patch
index ebbf912934..8baaaca7c4 100644
--- a/package/mac80211/patches/013-disable_b43_nphy.patch
+++ b/package/mac80211/patches/013-disable_b43_nphy.patch
@@ -1,6 +1,6 @@
 --- a/config.mk
 +++ b/config.mk
-@@ -253,7 +253,7 @@ ifdef CONFIG_MAC80211_LEDS
+@@ -254,7 +254,7 @@ ifdef CONFIG_MAC80211_LEDS
  CONFIG_B43_LEDS=y
  endif #CONFIG_MAC80211_LEDS
  CONFIG_B43_PHY_LP=y
diff --git a/package/mac80211/patches/015-remove-rt2x00-options.patch b/package/mac80211/patches/015-remove-rt2x00-options.patch
index 3bed5b2a50..e449c23ef8 100644
--- a/package/mac80211/patches/015-remove-rt2x00-options.patch
+++ b/package/mac80211/patches/015-remove-rt2x00-options.patch
@@ -1,6 +1,6 @@
 --- a/config.mk
 +++ b/config.mk
-@@ -329,7 +329,7 @@ CONFIG_RTL8180=m
+@@ -330,7 +330,7 @@ CONFIG_RTL8180=m
  
  CONFIG_ADM8211=m
  
@@ -9,7 +9,7 @@
  CONFIG_RT2400PCI=m
  CONFIG_RT2500PCI=m
  ifdef CONFIG_CRC_CCITT
-@@ -469,7 +469,7 @@ CONFIG_RT2800USB_RT35XX=y
+@@ -470,7 +470,7 @@ CONFIG_RT2800USB_RT35XX=y
  # CONFIG_RT2800USB_RT53XX=y
  CONFIG_RT2800USB_UNKNOWN=y
  endif #CONFIG_CRC_CCITT
diff --git a/package/mac80211/patches/017-remove_ath9k_rc.patch b/package/mac80211/patches/017-remove_ath9k_rc.patch
index d275283166..f3415564dd 100644
--- a/package/mac80211/patches/017-remove_ath9k_rc.patch
+++ b/package/mac80211/patches/017-remove_ath9k_rc.patch
@@ -1,6 +1,6 @@
 --- a/config.mk
 +++ b/config.mk
-@@ -219,7 +219,7 @@ CONFIG_ATH9K_COMMON=m
+@@ -220,7 +220,7 @@ CONFIG_ATH9K_COMMON=m
  # as default once we get minstrel properly tested and blessed by
  # our systems engineering team. CCK rates also need to be used
  # for long range considerations.
diff --git a/package/mac80211/patches/018-revert_printk_va_format.patch b/package/mac80211/patches/018-revert_printk_va_format.patch
index 8b7e6443cd..6aff41ae09 100644
--- a/package/mac80211/patches/018-revert_printk_va_format.patch
+++ b/package/mac80211/patches/018-revert_printk_va_format.patch
@@ -1,6 +1,6 @@
 --- a/drivers/net/wireless/b43/main.c
 +++ b/drivers/net/wireless/b43/main.c
-@@ -334,83 +334,59 @@ static int b43_ratelimit(struct b43_wl *
+@@ -337,83 +337,59 @@ static int b43_ratelimit(struct b43_wl *
  
  void b43info(struct b43_wl *wl, const char *fmt, ...)
  {
@@ -98,7 +98,7 @@
  
 --- a/drivers/net/wireless/b43legacy/main.c
 +++ b/drivers/net/wireless/b43legacy/main.c
-@@ -180,75 +180,52 @@ static int b43legacy_ratelimit(struct b4
+@@ -179,75 +179,52 @@ static int b43legacy_ratelimit(struct b4
  
  void b43legacyinfo(struct b43legacy_wl *wl, const char *fmt, ...)
  {
diff --git a/package/mac80211/patches/019-remove_ath5k_pci_option.patch b/package/mac80211/patches/019-remove_ath5k_pci_option.patch
index 07e30549c4..9de0418562 100644
--- a/package/mac80211/patches/019-remove_ath5k_pci_option.patch
+++ b/package/mac80211/patches/019-remove_ath5k_pci_option.patch
@@ -1,6 +1,6 @@
 --- a/config.mk
 +++ b/config.mk
-@@ -224,7 +224,7 @@ CONFIG_ATH9K_COMMON=m
+@@ -225,7 +225,7 @@ CONFIG_ATH9K_COMMON=m
  # PCI Drivers
  ifdef CONFIG_PCI
  
diff --git a/package/mac80211/patches/022-atomic64_backport.patch b/package/mac80211/patches/022-atomic64_backport.patch
index 17df9c9b53..ab77f76ad0 100644
--- a/package/mac80211/patches/022-atomic64_backport.patch
+++ b/package/mac80211/patches/022-atomic64_backport.patch
@@ -1,8 +1,8 @@
 --- a/compat/Makefile
 +++ b/compat/Makefile
-@@ -34,3 +34,8 @@ compat-$(CONFIG_COMPAT_KERNEL_2_6_39) +=
- 	compat-2.6.39.o \
- 	kstrtox.o
+@@ -38,3 +38,8 @@ compat-$(CONFIG_COMPAT_KERNEL_3_1) += \
+ 	cordic.o \
+ 	crc8.o
  
 +ifndef CONFIG_64BIT
 +ifndef CONFIG_GENERIC_ATOMIC64
@@ -70,7 +70,7 @@
 +
 --- a/include/linux/compat-3.1.h
 +++ b/include/linux/compat-3.1.h
-@@ -36,6 +36,18 @@
+@@ -19,6 +19,18 @@
  	.prod_id = { NULL, NULL, (v3), NULL }, \
  	.prod_id_hash = { 0, 0, (vh3), 0 }, }
  
diff --git a/package/mac80211/patches/110-disable_usb_compat.patch b/package/mac80211/patches/110-disable_usb_compat.patch
index dda96999a8..7678e3bbbc 100644
--- a/package/mac80211/patches/110-disable_usb_compat.patch
+++ b/package/mac80211/patches/110-disable_usb_compat.patch
@@ -33,7 +33,7 @@
  #endif
 --- a/config.mk
 +++ b/config.mk
-@@ -455,7 +455,7 @@ endif #CONFIG_COMPAT_KERNEL_2_6_29
+@@ -456,7 +456,7 @@ endif #CONFIG_COMPAT_KERNEL_2_6_29
  # This activates a threading fix for usb urb.
  # this is mainline commit: b3e670443b7fb8a2d29831b62b44a039c283e351
  # This fix will be included in some stable releases.
diff --git a/package/mac80211/patches/300-pending_work.patch b/package/mac80211/patches/300-pending_work.patch
index 2b457197c5..01df8f7456 100644
--- a/package/mac80211/patches/300-pending_work.patch
+++ b/package/mac80211/patches/300-pending_work.patch
@@ -1,104 +1,3 @@
---- a/drivers/net/wireless/b43/main.c
-+++ b/drivers/net/wireless/b43/main.c
-@@ -320,6 +320,10 @@ static void b43_wireless_core_exit(struc
- static int b43_wireless_core_init(struct b43_wldev *dev);
- static struct b43_wldev * b43_wireless_core_stop(struct b43_wldev *dev);
- static int b43_wireless_core_start(struct b43_wldev *dev);
-+static void b43_op_bss_info_changed(struct ieee80211_hw *hw,
-+				    struct ieee80211_vif *vif,
-+				    struct ieee80211_bss_conf *conf,
-+				    u32 changed);
- 
- static int b43_ratelimit(struct b43_wl *wl)
- {
-@@ -3754,14 +3758,24 @@ static int b43_op_config(struct ieee8021
- 	struct ieee80211_conf *conf = &hw->conf;
- 	int antenna;
- 	int err = 0;
-+	bool reload_bss = false;
- 
- 	mutex_lock(&wl->mutex);
- 
-+	dev = wl->current_dev;
-+
- 	/* Switch the band (if necessary). This might change the active core. */
- 	err = b43_switch_band(wl, conf->channel);
- 	if (err)
- 		goto out_unlock_mutex;
--	dev = wl->current_dev;
-+
-+	/* Need to reload all settings if the core changed */
-+	if (dev != wl->current_dev) {
-+		dev = wl->current_dev;
-+		changed = ~0;
-+		reload_bss = true;
-+	}
-+
- 	phy = &dev->phy;
- 
- 	if (conf_is_ht(conf))
-@@ -3822,6 +3836,9 @@ out_mac_enable:
- out_unlock_mutex:
- 	mutex_unlock(&wl->mutex);
- 
-+	if (wl->vif && reload_bss)
-+		b43_op_bss_info_changed(hw, wl->vif, &wl->vif->bss_conf, ~0);
-+
- 	return err;
- }
- 
-@@ -3910,7 +3927,8 @@ static void b43_op_bss_info_changed(stru
- 	if (changed & BSS_CHANGED_BEACON_INT &&
- 	    (b43_is_mode(wl, NL80211_IFTYPE_AP) ||
- 	     b43_is_mode(wl, NL80211_IFTYPE_MESH_POINT) ||
--	     b43_is_mode(wl, NL80211_IFTYPE_ADHOC)))
-+	     b43_is_mode(wl, NL80211_IFTYPE_ADHOC)) &&
-+	    conf->beacon_int)
- 		b43_set_beacon_int(dev, conf->beacon_int);
- 
- 	if (changed & BSS_CHANGED_BASIC_RATES)
-@@ -4691,6 +4709,9 @@ static int b43_op_add_interface(struct i
-  out_mutex_unlock:
- 	mutex_unlock(&wl->mutex);
- 
-+	if (err == 0)
-+		b43_op_bss_info_changed(hw, vif, &vif->bss_conf, ~0);
-+
- 	return err;
- }
- 
-@@ -4761,6 +4782,9 @@ static int b43_op_start(struct ieee80211
-  out_mutex_unlock:
- 	mutex_unlock(&wl->mutex);
- 
-+	/* reload configuration */
-+	b43_op_config(hw, ~0);
-+
- 	return err;
- }
- 
-@@ -4917,10 +4941,18 @@ out:
- 	if (err)
- 		wl->current_dev = NULL; /* Failed to init the dev. */
- 	mutex_unlock(&wl->mutex);
--	if (err)
-+
-+	if (err) {
- 		b43err(wl, "Controller restart FAILED\n");
--	else
--		b43info(wl, "Controller restarted\n");
-+		return;
-+	}
-+
-+	/* reload configuration */
-+	b43_op_config(wl->hw, ~0);
-+	if (wl->vif)
-+		b43_op_bss_info_changed(wl->hw, wl->vif, &wl->vif->bss_conf, ~0);
-+
-+	b43info(wl, "Controller restarted\n");
- }
- 
- static int b43_setup_bands(struct b43_wldev *dev,
 --- a/net/mac80211/agg-rx.c
 +++ b/net/mac80211/agg-rx.c
 @@ -184,6 +184,8 @@ static void ieee80211_send_addba_resp(st
@@ -282,7 +181,7 @@
  			break;
 --- a/net/mac80211/rx.c
 +++ b/net/mac80211/rx.c
-@@ -2147,7 +2147,8 @@ ieee80211_rx_h_action(struct ieee80211_r
+@@ -2160,7 +2160,8 @@ ieee80211_rx_h_action(struct ieee80211_r
  		 */
  		if (sdata->vif.type != NL80211_IFTYPE_STATION &&
  		    sdata->vif.type != NL80211_IFTYPE_AP_VLAN &&
@@ -292,7 +191,7 @@
  			break;
  
  		/* verify action_code is present */
-@@ -2345,13 +2346,14 @@ ieee80211_rx_h_mgmt(struct ieee80211_rx_
+@@ -2375,13 +2376,14 @@ ieee80211_rx_h_mgmt(struct ieee80211_rx_
  
  	if (!ieee80211_vif_is_mesh(&sdata->vif) &&
  	    sdata->vif.type != NL80211_IFTYPE_ADHOC &&
@@ -309,7 +208,7 @@
  		break;
  	case cpu_to_le16(IEEE80211_STYPE_DEAUTH):
  	case cpu_to_le16(IEEE80211_STYPE_DISASSOC):
-@@ -2692,10 +2694,16 @@ static int prepare_for_handlers(struct i
+@@ -2724,10 +2726,16 @@ static int prepare_for_handlers(struct i
  		}
  		break;
  	case NL80211_IFTYPE_WDS:
@@ -346,636 +245,65 @@
  	WLAN_STA_CLEAR_PS_FILT	= 1<<9,
  	WLAN_STA_MFP		= 1<<10,
  	WLAN_STA_BLOCK_BA	= 1<<11,
---- a/drivers/net/wireless/ath/ath9k/xmit.c
-+++ b/drivers/net/wireless/ath/ath9k/xmit.c
-@@ -551,7 +551,8 @@ static void ath_tx_complete_aggr(struct 
- 		if (clear_filter)
- 			tid->ac->clear_ps_filter = true;
- 		list_splice(&bf_pending, &tid->buf_q);
--		ath_tx_queue_tid(txq, tid);
-+		if (!an->sleeping)
-+			ath_tx_queue_tid(txq, tid);
- 		spin_unlock_bh(&txq->axq_lock);
- 	}
- 
-@@ -643,8 +644,10 @@ static u32 ath_lookup_rate(struct ath_so
-  * meet the minimum required mpdudensity.
-  */
- static int ath_compute_num_delims(struct ath_softc *sc, struct ath_atx_tid *tid,
--				  struct ath_buf *bf, u16 frmlen)
-+				  struct ath_buf *bf, u16 frmlen,
-+				  bool first_subfrm)
- {
-+#define FIRST_DESC_NDELIMS 60
- 	struct sk_buff *skb = bf->bf_mpdu;
- 	struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
- 	u32 nsymbits, nsymbols;
-@@ -667,6 +670,13 @@ static int ath_compute_num_delims(struct
- 		ndelim += ATH_AGGR_ENCRYPTDELIM;
- 
- 	/*
-+	 * Add delimiter when using RTS/CTS with aggregation
-+	 * and non enterprise AR9003 card
-+	 */
-+	if (first_subfrm)
-+		ndelim = max(ndelim, FIRST_DESC_NDELIMS);
-+
-+	/*
- 	 * Convert desired mpdu density from microeconds to bytes based
- 	 * on highest rate in rate series (i.e. first rate) to determine
- 	 * required minimum length for subframe. Take into account
-@@ -755,7 +765,6 @@ static enum ATH_AGGR_STATUS ath_tx_form_
- 			status = ATH_AGGR_LIMITED;
- 			break;
- 		}
--		nframes++;
- 
- 		/* add padding for previous frame to aggregation length */
- 		al += bpad + al_delta;
-@@ -764,9 +773,11 @@ static enum ATH_AGGR_STATUS ath_tx_form_
- 		 * Get the delimiters needed to meet the MPDU
- 		 * density for this node.
- 		 */
--		ndelim = ath_compute_num_delims(sc, tid, bf_first, fi->framelen);
-+		ndelim = ath_compute_num_delims(sc, tid, bf_first, fi->framelen,
-+						!nframes);
- 		bpad = PADBYTES(al_delta) + (ndelim << 2);
- 
-+		nframes++;
- 		bf->bf_next = NULL;
- 		ath9k_hw_set_desc_link(sc->sc_ah, bf->bf_desc, 0);
- 
-@@ -1413,7 +1424,8 @@ static void ath_tx_send_ampdu(struct ath
- 		 */
- 		TX_STAT_INC(txctl->txq->axq_qnum, a_queued_sw);
- 		list_add_tail(&bf->list, &tid->buf_q);
--		ath_tx_queue_tid(txctl->txq, tid);
-+		if (!txctl->an || !txctl->an->sleeping)
-+			ath_tx_queue_tid(txctl->txq, tid);
- 		return;
- 	}
- 
-@@ -1572,9 +1584,9 @@ u8 ath_txchainmask_reduction(struct ath_
- {
- 	struct ath_hw *ah = sc->sc_ah;
- 	struct ath9k_channel *curchan = ah->curchan;
--	if ((sc->sc_flags & SC_OP_ENABLE_APM) &&
--			(curchan->channelFlags & CHANNEL_5GHZ) &&
--			(chainmask == 0x7) && (rate < 0x90))
-+	if ((ah->caps.hw_caps & ATH9K_HW_CAP_APM) &&
-+	    (curchan->channelFlags & CHANNEL_5GHZ) &&
-+	    (chainmask == 0x7) && (rate < 0x90))
- 		return 0x3;
- 	else
- 		return chainmask;
---- a/include/net/cfg80211.h
-+++ b/include/net/cfg80211.h
-@@ -421,6 +421,7 @@ struct station_parameters {
-  * @STATION_INFO_RX_BITRATE: @rxrate fields are filled
-  * @STATION_INFO_BSS_PARAM: @bss_param filled
-  * @STATION_INFO_CONNECTED_TIME: @connected_time filled
-+ * @STATION_INFO_ASSOC_REQ_IES: @assoc_req_ies filled
-  */
- enum station_info_flags {
- 	STATION_INFO_INACTIVE_TIME	= 1<<0,
-@@ -439,7 +440,8 @@ enum station_info_flags {
- 	STATION_INFO_SIGNAL_AVG		= 1<<13,
- 	STATION_INFO_RX_BITRATE		= 1<<14,
- 	STATION_INFO_BSS_PARAM          = 1<<15,
--	STATION_INFO_CONNECTED_TIME	= 1<<16
-+	STATION_INFO_CONNECTED_TIME	= 1<<16,
-+	STATION_INFO_ASSOC_REQ_IES	= 1<<17
- };
- 
- /**
---- a/net/wireless/nl80211.c
-+++ b/net/wireless/nl80211.c
-@@ -2236,7 +2236,7 @@ static int nl80211_send_station(struct s
- 	}
- 	nla_nest_end(msg, sinfoattr);
- 
--	if (sinfo->assoc_req_ies)
-+	if (sinfo->filled & STATION_INFO_ASSOC_REQ_IES)
- 		NLA_PUT(msg, NL80211_ATTR_IE, sinfo->assoc_req_ies_len,
- 			sinfo->assoc_req_ies);
- 
---- a/drivers/net/wireless/ath/ath9k/ar9003_mac.c
-+++ b/drivers/net/wireless/ath/ath9k/ar9003_mac.c
-@@ -415,36 +415,12 @@ static void ar9003_hw_set11n_ratescenari
- static void ar9003_hw_set11n_aggr_first(struct ath_hw *ah, void *ds,
- 					u32 aggrLen)
- {
--#define FIRST_DESC_NDELIMS 60
- 	struct ar9003_txc *ads = (struct ar9003_txc *) ds;
- 
- 	ads->ctl12 |= (AR_IsAggr | AR_MoreAggr);
- 
--	if (ah->ent_mode & AR_ENT_OTP_MPSD) {
--		u32 ctl17, ndelim;
--		/*
--		 * Add delimiter when using RTS/CTS with aggregation
--		 * and non enterprise AR9003 card
--		 */
--		ctl17 = ads->ctl17;
--		ndelim = MS(ctl17, AR_PadDelim);
--
--		if (ndelim < FIRST_DESC_NDELIMS) {
--			aggrLen += (FIRST_DESC_NDELIMS - ndelim) * 4;
--			ndelim = FIRST_DESC_NDELIMS;
--		}
--
--		ctl17 &= ~AR_AggrLen;
--		ctl17 |= SM(aggrLen, AR_AggrLen);
--
--		ctl17 &= ~AR_PadDelim;
--		ctl17 |= SM(ndelim, AR_PadDelim);
--
--		ads->ctl17 = ctl17;
--	} else {
--		ads->ctl17 &= ~AR_AggrLen;
--		ads->ctl17 |= SM(aggrLen, AR_AggrLen);
--	}
-+	ads->ctl17 &= ~AR_AggrLen;
-+	ads->ctl17 |= SM(aggrLen, AR_AggrLen);
- }
- 
- static void ar9003_hw_set11n_aggr_middle(struct ath_hw *ah, void *ds,
---- a/drivers/net/wireless/ath/ath9k/main.c
-+++ b/drivers/net/wireless/ath/ath9k/main.c
-@@ -565,7 +565,6 @@ set_timer:
- static void ath_node_attach(struct ath_softc *sc, struct ieee80211_sta *sta)
- {
- 	struct ath_node *an;
--	struct ath_hw *ah = sc->sc_ah;
- 	an = (struct ath_node *)sta->drv_priv;
- 
- #ifdef CONFIG_ATH9K_DEBUGFS
-@@ -574,9 +573,6 @@ static void ath_node_attach(struct ath_s
- 	spin_unlock(&sc->nodes_lock);
- 	an->sta = sta;
- #endif
--	if ((ah->caps.hw_caps) & ATH9K_HW_CAP_APM)
--		sc->sc_flags |= SC_OP_ENABLE_APM;
--
- 	if (sc->sc_flags & SC_OP_TXAGGR) {
- 		ath_tx_node_init(sc, an);
- 		an->maxampdu = 1 << (IEEE80211_HT_MAX_AMPDU_FACTOR +
-@@ -826,11 +822,9 @@ irqreturn_t ath_isr(int irq, void *dev)
- 	if (status & ATH9K_INT_TXURN)
- 		ath9k_hw_updatetxtriglevel(ah, true);
- 
--	if (ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) {
--		if (status & ATH9K_INT_RXEOL) {
--			ah->imask &= ~(ATH9K_INT_RXEOL | ATH9K_INT_RXORN);
--			ath9k_hw_set_interrupts(ah, ah->imask);
--		}
-+	if (status & ATH9K_INT_RXEOL) {
-+		ah->imask &= ~(ATH9K_INT_RXEOL | ATH9K_INT_RXORN);
-+		ath9k_hw_set_interrupts(ah, ah->imask);
- 	}
- 
- 	if (status & ATH9K_INT_MIB) {
-@@ -1680,6 +1674,7 @@ static int ath9k_config(struct ieee80211
- 
- 	if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
- 		struct ieee80211_channel *curchan = hw->conf.channel;
-+		struct ath9k_channel old_chan;
- 		int pos = curchan->hw_value;
- 		int old_pos = -1;
- 		unsigned long flags;
-@@ -1696,15 +1691,25 @@ static int ath9k_config(struct ieee80211
- 			"Set channel: %d MHz type: %d\n",
- 			curchan->center_freq, conf->channel_type);
- 
--		ath9k_cmn_update_ichannel(&sc->sc_ah->channels[pos],
--					  curchan, conf->channel_type);
--
- 		/* update survey stats for the old channel before switching */
- 		spin_lock_irqsave(&common->cc_lock, flags);
- 		ath_update_survey_stats(sc);
- 		spin_unlock_irqrestore(&common->cc_lock, flags);
- 
- 		/*
-+		 * Preserve the current channel values, before updating
-+		 * the same channel
-+		 */
-+		if (old_pos == pos) {
-+			memcpy(&old_chan, &sc->sc_ah->channels[pos],
-+				sizeof(struct ath9k_channel));
-+			ah->curchan = &old_chan;
-+		}
-+
-+		ath9k_cmn_update_ichannel(&sc->sc_ah->channels[pos],
-+					  curchan, conf->channel_type);
-+
-+		/*
- 		 * If the operating channel changes, change the survey in-use flags
- 		 * along with it.
- 		 * Reset the survey data for the new channel, unless we're switching
---- a/drivers/net/wireless/ath/ath9k/recv.c
-+++ b/drivers/net/wireless/ath/ath9k/recv.c
-@@ -761,7 +761,7 @@ static struct ath_buf *ath_get_next_rx_b
- 	 * on.  All this is necessary because of our use of
- 	 * a self-linked list to avoid rx overruns.
- 	 */
--	ret = ath9k_hw_rxprocdesc(ah, ds, rs, 0);
-+	ret = ath9k_hw_rxprocdesc(ah, ds, rs);
- 	if (ret == -EINPROGRESS) {
- 		struct ath_rx_status trs;
- 		struct ath_buf *tbf;
-@@ -787,7 +787,7 @@ static struct ath_buf *ath_get_next_rx_b
- 		 */
- 
- 		tds = tbf->bf_desc;
--		ret = ath9k_hw_rxprocdesc(ah, tds, &trs, 0);
-+		ret = ath9k_hw_rxprocdesc(ah, tds, &trs);
- 		if (ret == -EINPROGRESS)
- 			return NULL;
- 	}
-@@ -1978,5 +1978,10 @@ requeue:
- 
- 	spin_unlock_bh(&sc->rx.rxbuflock);
- 
-+	if (!(ah->imask & ATH9K_INT_RXEOL)) {
-+		ah->imask |= (ATH9K_INT_RXEOL | ATH9K_INT_RXORN);
-+		ath9k_hw_set_interrupts(ah, ah->imask);
-+	}
-+
- 	return 0;
- }
---- a/drivers/net/wireless/ath/ath9k/mac.c
-+++ b/drivers/net/wireless/ath/ath9k/mac.c
-@@ -345,21 +345,8 @@ int ath9k_hw_setuptxqueue(struct ath_hw 
- 	}
- 	memset(qi, 0, sizeof(struct ath9k_tx_queue_info));
- 	qi->tqi_type = type;
--	if (qinfo == NULL) {
--		qi->tqi_qflags =
--			TXQ_FLAG_TXOKINT_ENABLE
--			| TXQ_FLAG_TXERRINT_ENABLE
--			| TXQ_FLAG_TXDESCINT_ENABLE | TXQ_FLAG_TXURNINT_ENABLE;
--		qi->tqi_aifs = INIT_AIFS;
--		qi->tqi_cwmin = ATH9K_TXQ_USEDEFAULT;
--		qi->tqi_cwmax = INIT_CWMAX;
--		qi->tqi_shretry = INIT_SH_RETRY;
--		qi->tqi_lgretry = INIT_LG_RETRY;
--		qi->tqi_physCompBuf = 0;
--	} else {
--		qi->tqi_physCompBuf = qinfo->tqi_physCompBuf;
--		(void) ath9k_hw_set_txq_props(ah, q, qinfo);
--	}
-+	qi->tqi_physCompBuf = qinfo->tqi_physCompBuf;
-+	(void) ath9k_hw_set_txq_props(ah, q, qinfo);
- 
- 	return q;
- }
-@@ -564,7 +551,7 @@ bool ath9k_hw_resettxqueue(struct ath_hw
- EXPORT_SYMBOL(ath9k_hw_resettxqueue);
- 
- int ath9k_hw_rxprocdesc(struct ath_hw *ah, struct ath_desc *ds,
--			struct ath_rx_status *rs, u64 tsf)
-+			struct ath_rx_status *rs)
- {
- 	struct ar5416_desc ads;
- 	struct ar5416_desc *adsp = AR5416DESC(ds);
---- a/drivers/net/wireless/ath/ath9k/mac.h
-+++ b/drivers/net/wireless/ath/ath9k/mac.h
-@@ -687,7 +687,7 @@ int ath9k_hw_setuptxqueue(struct ath_hw 
- bool ath9k_hw_releasetxqueue(struct ath_hw *ah, u32 q);
- bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q);
- int ath9k_hw_rxprocdesc(struct ath_hw *ah, struct ath_desc *ds,
--			struct ath_rx_status *rs, u64 tsf);
-+			struct ath_rx_status *rs);
- void ath9k_hw_setuprxdesc(struct ath_hw *ah, struct ath_desc *ds,
- 			  u32 size, u32 flags);
- bool ath9k_hw_setrxabort(struct ath_hw *ah, bool set);
---- a/drivers/net/wireless/ath/ath9k/ar9003_calib.c
-+++ b/drivers/net/wireless/ath/ath9k/ar9003_calib.c
-@@ -839,20 +839,8 @@ static bool ar9003_hw_init_cal(struct at
- 			       struct ath9k_channel *chan)
- {
- 	struct ath_common *common = ath9k_hw_common(ah);
--	struct ath9k_hw_capabilities *pCap = &ah->caps;
--	int val;
- 	bool txiqcal_done = false;
- 
--	val = REG_READ(ah, AR_ENT_OTP);
--	ath_dbg(common, ATH_DBG_CALIBRATE, "ath9k: AR_ENT_OTP 0x%x\n", val);
--
--	/* Configure rx/tx chains before running AGC/TxiQ cals */
--	if (val & AR_ENT_OTP_CHAIN2_DISABLE)
--		ar9003_hw_set_chain_masks(ah, 0x3, 0x3);
--	else
--		ar9003_hw_set_chain_masks(ah, pCap->rx_chainmask,
--					  pCap->tx_chainmask);
--
- 	/* Do Tx IQ Calibration */
- 	REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_1,
- 		      AR_PHY_TX_IQCAL_CONTROL_1_IQCORR_I_Q_COFF_DELPT,
-@@ -887,9 +875,6 @@ static bool ar9003_hw_init_cal(struct at
- 	if (txiqcal_done)
- 		ar9003_hw_tx_iq_cal_post_proc(ah);
- 
--	/* Revert chainmasks to their original values before NF cal */
--	ar9003_hw_set_chain_masks(ah, ah->rxchainmask, ah->txchainmask);
--
- 	ath9k_hw_start_nfcal(ah, true);
- 
- 	/* Initialize list pointers */
 --- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c
 +++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
-@@ -540,7 +540,7 @@ static void ar9003_hw_init_bb(struct ath
- 	udelay(synthDelay + BASE_ACTIVATE_DELAY);
- }
- 
--void ar9003_hw_set_chain_masks(struct ath_hw *ah, u8 rx, u8 tx)
-+static void ar9003_hw_set_chain_masks(struct ath_hw *ah, u8 rx, u8 tx)
- {
- 	switch (rx) {
- 	case 0x5:
---- a/drivers/net/wireless/ath/ath9k/ar9003_phy.h
-+++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.h
-@@ -1124,6 +1124,4 @@
- #define AR_PHY_CL_TAB_CL_GAIN_MOD		0x1f
- #define AR_PHY_CL_TAB_CL_GAIN_MOD_S		0
- 
--void ar9003_hw_set_chain_masks(struct ath_hw *ah, u8 rx, u8 tx);
--
- #endif  /* AR9003_PHY_H */
---- a/drivers/net/wireless/ath/ath9k/ath9k.h
-+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
-@@ -558,8 +558,7 @@ struct ath_ant_comb {
- #define SC_OP_BT_PRIORITY_DETECTED   BIT(12)
- #define SC_OP_BT_SCAN		     BIT(13)
- #define SC_OP_ANI_RUN		     BIT(14)
--#define SC_OP_ENABLE_APM	     BIT(15)
--#define SC_OP_PRIM_STA_VIF	     BIT(16)
-+#define SC_OP_PRIM_STA_VIF	     BIT(15)
- 
- /* Powersave flags */
- #define PS_WAIT_FOR_BEACON        BIT(0)
-@@ -664,7 +663,6 @@ extern int led_blink;
- extern bool is_ath9k_unloaded;
- 
- irqreturn_t ath_isr(int irq, void *dev);
--void ath9k_init_crypto(struct ath_softc *sc);
- int ath9k_init_device(u16 devid, struct ath_softc *sc,
- 		    const struct ath_bus_ops *bus_ops);
- void ath9k_deinit_device(struct ath_softc *sc);
---- a/drivers/net/wireless/ath/ath9k/common.c
-+++ b/drivers/net/wireless/ath/ath9k/common.c
-@@ -169,6 +169,32 @@ void ath9k_cmn_update_txpow(struct ath_h
- }
- EXPORT_SYMBOL(ath9k_cmn_update_txpow);
- 
-+void ath9k_cmn_init_crypto(struct ath_hw *ah)
-+{
-+	struct ath_common *common = ath9k_hw_common(ah);
-+	int i = 0;
-+
-+	/* Get the hardware key cache size. */
-+	common->keymax = AR_KEYTABLE_SIZE;
-+
-+	/*
-+	 * Check whether the separate key cache entries
-+	 * are required to handle both tx+rx MIC keys.
-+	 * With split mic keys the number of stations is limited
-+	 * to 27 otherwise 59.
-+	 */
-+	if (ah->misc_mode & AR_PCU_MIC_NEW_LOC_ENA)
-+		common->crypt_caps |= ATH_CRYPT_CAP_MIC_COMBINED;
-+
-+	/*
-+	 * Reset the key cache since some parts do not
-+	 * reset the contents on initial power up.
-+	 */
-+	for (i = 0; i < common->keymax; i++)
-+		ath_hw_keyreset(common, (u16) i);
-+}
-+EXPORT_SYMBOL(ath9k_cmn_init_crypto);
-+
- static int __init ath9k_cmn_init(void)
- {
- 	return 0;
---- a/drivers/net/wireless/ath/ath9k/common.h
-+++ b/drivers/net/wireless/ath/ath9k/common.h
-@@ -62,3 +62,4 @@ void ath9k_cmn_btcoex_bt_stomp(struct at
- 				  enum ath_stomp_type stomp_type);
- void ath9k_cmn_update_txpow(struct ath_hw *ah, u16 cur_txpow,
- 			    u16 new_txpow, u16 *txpower);
-+void ath9k_cmn_init_crypto(struct ath_hw *ah);
---- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c
-+++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c
-@@ -572,25 +572,6 @@ err:
- 	return -EINVAL;
- }
- 
--static void ath9k_init_crypto(struct ath9k_htc_priv *priv)
--{
--	struct ath_common *common = ath9k_hw_common(priv->ah);
--	int i = 0;
--
--	/* Get the hardware key cache size. */
--	common->keymax = AR_KEYTABLE_SIZE;
--
--	if (priv->ah->misc_mode & AR_PCU_MIC_NEW_LOC_ENA)
--		common->crypt_caps |= ATH_CRYPT_CAP_MIC_COMBINED;
--
--	/*
--	 * Reset the key cache since some parts do not
--	 * reset the contents on initial power up.
--	 */
--	for (i = 0; i < common->keymax; i++)
--		ath_hw_keyreset(common, (u16) i);
--}
--
- static void ath9k_init_channels_rates(struct ath9k_htc_priv *priv)
- {
- 	if (priv->ah->caps.hw_caps & ATH9K_HW_CAP_2GHZ) {
-@@ -720,7 +701,7 @@ static int ath9k_init_priv(struct ath9k_
- 	for (i = 0; i < ATH9K_HTC_MAX_BCN_VIF; i++)
- 		priv->cur_beacon_conf.bslot[i] = NULL;
- 
--	ath9k_init_crypto(priv);
-+	ath9k_cmn_init_crypto(ah);
- 	ath9k_init_channels_rates(priv);
- 	ath9k_init_misc(priv);
- 
---- a/drivers/net/wireless/ath/ath9k/init.c
-+++ b/drivers/net/wireless/ath/ath9k/init.c
-@@ -404,31 +404,6 @@ fail:
- 	return error;
- }
- 
--void ath9k_init_crypto(struct ath_softc *sc)
--{
--	struct ath_common *common = ath9k_hw_common(sc->sc_ah);
--	int i = 0;
--
--	/* Get the hardware key cache size. */
--	common->keymax = AR_KEYTABLE_SIZE;
--
--	/*
--	 * Reset the key cache since some parts do not
--	 * reset the contents on initial power up.
--	 */
--	for (i = 0; i < common->keymax; i++)
--		ath_hw_keyreset(common, (u16) i);
--
--	/*
--	 * Check whether the separate key cache entries
--	 * are required to handle both tx+rx MIC keys.
--	 * With split mic keys the number of stations is limited
--	 * to 27 otherwise 59.
--	 */
--	if (sc->sc_ah->misc_mode & AR_PCU_MIC_NEW_LOC_ENA)
--		common->crypt_caps |= ATH_CRYPT_CAP_MIC_COMBINED;
--}
--
- static int ath9k_init_btcoex(struct ath_softc *sc)
- {
- 	struct ath_txq *txq;
-@@ -630,7 +605,7 @@ static int ath9k_init_softc(u16 devid, s
- 	if (ret)
- 		goto err_btcoex;
- 
--	ath9k_init_crypto(sc);
-+	ath9k_cmn_init_crypto(sc->sc_ah);
- 	ath9k_init_misc(sc);
- 
- 	return 0;
---- a/drivers/net/wireless/ath/ath9k/pci.c
-+++ b/drivers/net/wireless/ath/ath9k/pci.c
-@@ -129,7 +129,7 @@ static void ath_pci_aspm_init(struct ath
- 		return;
- 
- 	parent = pdev->bus->self;
--	if (WARN_ON(!parent))
-+	if (!parent)
- 		return;
- 
- 	pos = pci_pcie_cap(parent);
-@@ -338,7 +338,7 @@ static int ath_pci_resume(struct device 
- 	   * semi-random values after suspend/resume.
- 	   */
- 	ath9k_ps_wakeup(sc);
--	ath9k_init_crypto(sc);
-+	ath9k_cmn_init_crypto(sc->sc_ah);
- 	ath9k_ps_restore(sc);
- 
- 	sc->ps_idle = true;
---- a/drivers/net/wireless/ath/ath9k/calib.c
-+++ b/drivers/net/wireless/ath/ath9k/calib.c
-@@ -82,7 +82,6 @@ static void ath9k_hw_update_nfcal_hist_b
- 					      int16_t *nfarray)
- {
- 	struct ath_common *common = ath9k_hw_common(ah);
--	struct ieee80211_conf *conf = &common->hw->conf;
- 	struct ath_nf_limits *limit;
- 	struct ath9k_nfcal_hist *h;
- 	bool high_nf_mid = false;
-@@ -94,7 +93,7 @@ static void ath9k_hw_update_nfcal_hist_b
- 
- 	for (i = 0; i < NUM_NF_READINGS; i++) {
- 		if (!(chainmask & (1 << i)) ||
--		    ((i >= AR5416_MAX_CHAINS) && !conf_is_ht40(conf)))
-+		    ((i >= AR5416_MAX_CHAINS) && !IS_CHAN_HT40(ah->curchan)))
- 			continue;
- 
- 		h[i].nfCalBuffer[h[i].currIndex] = nfarray[i];
---- a/drivers/net/wireless/ath/ath9k/debug.c
-+++ b/drivers/net/wireless/ath/ath9k/debug.c
-@@ -1163,6 +1163,59 @@ static const struct file_operations fops
- 	.llseek = default_llseek,/* read accesses f_pos */
- };
+@@ -671,7 +671,7 @@ static int ar9003_hw_process_ini(struct 
+ 		REG_WRITE_ARRAY(&ah->iniModesAdditional,
+ 				modesIndex, regWrites);
+ 
+-	if (AR_SREV_9300(ah))
++	if (AR_SREV_9330(ah))
+ 		REG_WRITE_ARRAY(&ah->iniModesAdditional, 1, regWrites);
+ 
+ 	if (AR_SREV_9340(ah) && !ah->is_clk_25mhz)
+--- a/drivers/net/wireless/ath/ath9k/hw.c
++++ b/drivers/net/wireless/ath/ath9k/hw.c
+@@ -997,8 +997,14 @@ void ath9k_hw_init_global_settings(struc
+ 		slottime = 21;
+ 		sifstime = 64;
+ 	} else {
+-		eifs = REG_READ(ah, AR_D_GBL_IFS_EIFS)/common->clockrate;
+-		reg = REG_READ(ah, AR_USEC);
++		if (AR_SREV_9287(ah) && AR_SREV_9287_13_OR_LATER(ah)) {
++			eifs = AR_D_GBL_IFS_EIFS_ASYNC_FIFO;
++			reg = AR_USEC_ASYNC_FIFO;
++		} else {
++			eifs = REG_READ(ah, AR_D_GBL_IFS_EIFS)/
++				common->clockrate;
++			reg = REG_READ(ah, AR_USEC);
++		}
+ 		rx_lat = MS(reg, AR_USEC_RX_LAT);
+ 		tx_lat = MS(reg, AR_USEC_TX_LAT);
+ 
+--- a/drivers/net/wireless/ath/ath9k/reg.h
++++ b/drivers/net/wireless/ath/ath9k/reg.h
+@@ -619,6 +619,7 @@
+ #define AR_D_GBL_IFS_EIFS         0x10b0
+ #define AR_D_GBL_IFS_EIFS_M       0x0000FFFF
+ #define AR_D_GBL_IFS_EIFS_RESV0   0xFFFF0000
++#define AR_D_GBL_IFS_EIFS_ASYNC_FIFO 363
+ 
+ #define AR_D_GBL_IFS_MISC        0x10f0
+ #define AR_D_GBL_IFS_MISC_LFSR_SLICE_SEL        0x00000007
+@@ -1503,6 +1504,7 @@ enum {
+ #define AR_USEC_TX_LAT_S     14
+ #define AR_USEC_RX_LAT       0x1F800000
+ #define AR_USEC_RX_LAT_S     23
++#define AR_USEC_ASYNC_FIFO   0x12E00074
+ 
+ #define AR_RESET_TSF        0x8020
+ #define AR_RESET_TSF_ONCE   0x01000000
+--- a/drivers/net/wireless/ath/ath9k/xmit.c
++++ b/drivers/net/wireless/ath/ath9k/xmit.c
+@@ -582,7 +582,10 @@ static bool ath_lookup_legacy(struct ath
+ 	tx_info = IEEE80211_SKB_CB(skb);
+ 	rates = tx_info->control.rates;
  
-+static ssize_t read_file_dump_nfcal(struct file *file, char __user *user_buf,
-+				    size_t count, loff_t *ppos)
-+{
-+	struct ath_softc *sc = file->private_data;
-+	struct ath_hw *ah = sc->sc_ah;
-+	struct ath9k_nfcal_hist *h = sc->caldata.nfCalHist;
-+	struct ath_common *common = ath9k_hw_common(ah);
-+	struct ieee80211_conf *conf = &common->hw->conf;
-+	u32 len = 0, size = 1500;
-+	u32 i, j;
-+	ssize_t retval = 0;
-+	char *buf;
-+	u8 chainmask = (ah->rxchainmask << 3) | ah->rxchainmask;
-+	u8 nread;
-+
-+	buf = kzalloc(size, GFP_KERNEL);
-+	if (!buf)
-+		return -ENOMEM;
-+
-+	len += snprintf(buf + len, size - len,
-+			"Channel Noise Floor : %d\n", ah->noise);
-+	len += snprintf(buf + len, size - len,
-+			"Chain | privNF | # Readings | NF Readings\n");
-+	for (i = 0; i < NUM_NF_READINGS; i++) {
-+		if (!(chainmask & (1 << i)) ||
-+		    ((i >= AR5416_MAX_CHAINS) && !conf_is_ht40(conf)))
-+			continue;
-+
-+		nread = AR_PHY_CCA_FILTERWINDOW_LENGTH - h[i].invalidNFcount;
-+		len += snprintf(buf + len, size - len, " %d\t %d\t %d\t\t",
-+				i, h[i].privNF, nread);
-+		for (j = 0; j < nread; j++)
-+			len += snprintf(buf + len, size - len,
-+					" %d", h[i].nfCalBuffer[j]);
-+		len += snprintf(buf + len, size - len, "\n");
-+	}
-+
-+	if (len > size)
-+		len = size;
-+
-+	retval = simple_read_from_buffer(user_buf, count, ppos, buf, len);
-+	kfree(buf);
-+
-+	return retval;
-+}
-+
-+static const struct file_operations fops_dump_nfcal = {
-+	.read = read_file_dump_nfcal,
-+	.open = ath9k_debugfs_open,
-+	.owner = THIS_MODULE,
-+	.llseek = default_llseek,
-+};
+-	for (i = 3; i >= 0; i--) {
++	for (i = 0; i < 4; i++) {
++		if (!rates[i].count || rates[i].idx < 0)
++			break;
 +
- static ssize_t read_file_base_eeprom(struct file *file, char __user *user_buf,
- 				     size_t count, loff_t *ppos)
- {
-@@ -1262,6 +1315,8 @@ int ath9k_init_debug(struct ath_hw *ah)
- 			    &ah->config.cwm_ignore_extcca);
- 	debugfs_create_file("regdump", S_IRUSR, sc->debug.debugfs_phy, sc,
- 			    &fops_regdump);
-+	debugfs_create_file("dump_nfcal", S_IRUSR, sc->debug.debugfs_phy, sc,
-+			    &fops_dump_nfcal);
- 	debugfs_create_file("base_eeprom", S_IRUSR, sc->debug.debugfs_phy, sc,
- 			    &fops_base_eeprom);
- 	debugfs_create_file("modal_eeprom", S_IRUSR, sc->debug.debugfs_phy, sc,
---- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
-+++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
-@@ -69,7 +69,7 @@ static int ar9003_hw_power_interpolate(i
- static const struct ar9300_eeprom ar9300_default = {
- 	.eepromVersion = 2,
- 	.templateVersion = 2,
--	.macAddr = {1, 2, 3, 4, 5, 6},
-+	.macAddr = {0, 2, 3, 4, 5, 6},
- 	.custData = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 		     0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
- 	.baseEepHeader = {
---- a/drivers/net/wireless/ath/ath9k/eeprom_4k.c
-+++ b/drivers/net/wireless/ath/ath9k/eeprom_4k.c
-@@ -349,10 +349,7 @@ static u32 ath9k_hw_4k_get_eeprom(struct
- 	case EEP_ANT_DIV_CTL1:
- 		return pModal->antdiv_ctl1;
- 	case EEP_TXGAIN_TYPE:
--		if (ver_minor >= AR5416_EEP_MINOR_VER_19)
--			return pBase->txGainType;
--		else
--			return AR5416_EEP_TXGAIN_ORIGINAL;
-+		return pBase->txGainType;
- 	default:
- 		return 0;
+ 		if (!(rates[i].flags & IEEE80211_TX_RC_MCS))
+ 			return true;
  	}
diff --git a/package/mac80211/patches/310-ibss_ht.patch b/package/mac80211/patches/310-ibss_ht.patch
index 0a770d22d3..eb1c8fce8b 100644
--- a/package/mac80211/patches/310-ibss_ht.patch
+++ b/package/mac80211/patches/310-ibss_ht.patch
@@ -1,6 +1,6 @@
 --- a/include/net/cfg80211.h
 +++ b/include/net/cfg80211.h
-@@ -1045,6 +1045,7 @@ struct cfg80211_ibss_params {
+@@ -1085,6 +1085,7 @@ struct cfg80211_ibss_params {
  	u8 *ssid;
  	u8 *bssid;
  	struct ieee80211_channel *channel;
@@ -8,7 +8,7 @@
  	u8 *ie;
  	u8 ssid_len, ie_len;
  	u16 beacon_interval;
-@@ -2478,6 +2479,12 @@ struct cfg80211_bss *cfg80211_get_bss(st
+@@ -2584,6 +2585,12 @@ struct cfg80211_bss *cfg80211_get_bss(st
  				      const u8 *bssid,
  				      const u8 *ssid, size_t ssid_len,
  				      u16 capa_mask, u16 capa_val);
@@ -23,7 +23,7 @@
  		  struct ieee80211_channel *channel,
 --- a/net/wireless/nl80211.c
 +++ b/net/wireless/nl80211.c
-@@ -4351,13 +4351,41 @@ static int nl80211_join_ibss(struct sk_b
+@@ -4470,13 +4470,41 @@ static int nl80211_join_ibss(struct sk_b
  		ibss.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
  	}
  
@@ -169,7 +169,7 @@
  
  	unsigned long ibss_join_req;
  	/* probe response/beacon for IBSS */
-@@ -1151,6 +1152,7 @@ void ieee80211_ibss_notify_scan_complete
+@@ -1089,6 +1090,7 @@ void ieee80211_ibss_notify_scan_complete
  void ieee80211_ibss_setup_sdata(struct ieee80211_sub_if_data *sdata);
  struct sta_info *ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata,
  					u8 *bssid, u8 *addr, u32 supp_rates,
@@ -177,7 +177,7 @@
  					gfp_t gfp);
  int ieee80211_ibss_join(struct ieee80211_sub_if_data *sdata,
  			struct cfg80211_ibss_params *params);
-@@ -1405,6 +1407,12 @@ void ieee80211_recalc_smps(struct ieee80
+@@ -1343,6 +1345,12 @@ void ieee80211_recalc_smps(struct ieee80
  size_t ieee80211_ie_split(const u8 *ies, size_t ielen,
  			  const u8 *ids, int n_ids, size_t offset);
  size_t ieee80211_ie_split_vendor(const u8 *ies, size_t ielen, size_t offset);
@@ -190,7 +190,7 @@
  
  /* internal work items */
  void ieee80211_work_init(struct ieee80211_local *local);
-@@ -1433,6 +1441,8 @@ ieee80211_get_channel_mode(struct ieee80
+@@ -1371,6 +1379,8 @@ ieee80211_get_channel_mode(struct ieee80
  bool ieee80211_set_channel_type(struct ieee80211_local *local,
  				struct ieee80211_sub_if_data *sdata,
  				enum nl80211_channel_type chantype);
@@ -201,7 +201,7 @@
  #define debug_noinline noinline
 --- a/net/mac80211/util.c
 +++ b/net/mac80211/util.c
-@@ -1008,23 +1008,8 @@ int ieee80211_build_preq_ies(struct ieee
+@@ -841,23 +841,8 @@ int ieee80211_build_preq_ies(struct ieee
  		offset = noffset;
  	}
  
@@ -227,7 +227,7 @@
  
  	/*
  	 * If adding more here, adjust code in main.c
-@@ -1548,3 +1533,100 @@ void ieee80211_disable_rssi_reports(stru
+@@ -1381,3 +1366,100 @@ void ieee80211_disable_rssi_reports(stru
  	_ieee80211_enable_rssi_reports(sdata, 0, 0);
  }
  EXPORT_SYMBOL(ieee80211_disable_rssi_reports);
@@ -687,7 +687,7 @@
  	if (params->ie) {
 --- a/net/mac80211/rx.c
 +++ b/net/mac80211/rx.c
-@@ -2148,7 +2148,8 @@ ieee80211_rx_h_action(struct ieee80211_r
+@@ -2161,7 +2161,8 @@ ieee80211_rx_h_action(struct ieee80211_r
  		if (sdata->vif.type != NL80211_IFTYPE_STATION &&
  		    sdata->vif.type != NL80211_IFTYPE_AP_VLAN &&
  		    sdata->vif.type != NL80211_IFTYPE_AP &&
@@ -697,7 +697,7 @@
  			break;
  
  		/* verify action_code is present */
-@@ -2666,7 +2667,8 @@ static int prepare_for_handlers(struct i
+@@ -2696,7 +2697,8 @@ static int prepare_for_handlers(struct i
  			else
  				rate_idx = status->rate_idx;
  			rx->sta = ieee80211_ibss_add_sta(sdata, bssid,
diff --git a/package/mac80211/patches/400-ath_move_debug_code.patch b/package/mac80211/patches/400-ath_move_debug_code.patch
new file mode 100644
index 0000000000..2584298836
--- /dev/null
+++ b/package/mac80211/patches/400-ath_move_debug_code.patch
@@ -0,0 +1,11 @@
+--- a/drivers/net/wireless/ath/Makefile
++++ b/drivers/net/wireless/ath/Makefile
+@@ -8,6 +8,5 @@ obj-$(CONFIG_ATH_COMMON)	+= ath.o
+ ath-objs :=	main.o \
+ 		regd.o \
+ 		hw.o \
+-		key.o
+-
+-ath-$(CONFIG_ATH_DEBUG) += debug.o
++		key.o \
++		debug.o
diff --git a/package/mac80211/patches/410-ath9k_allow_adhoc_and_ap.patch b/package/mac80211/patches/410-ath9k_allow_adhoc_and_ap.patch
index 4fb85ab208..13f11bba92 100644
--- a/package/mac80211/patches/410-ath9k_allow_adhoc_and_ap.patch
+++ b/package/mac80211/patches/410-ath9k_allow_adhoc_and_ap.patch
@@ -1,6 +1,6 @@
 --- a/drivers/net/wireless/ath/ath9k/main.c
 +++ b/drivers/net/wireless/ath/ath9k/main.c
-@@ -1493,15 +1493,6 @@ static int ath9k_add_interface(struct ie
+@@ -1491,15 +1491,6 @@ static int ath9k_add_interface(struct ie
  		}
  	}
  
@@ -16,7 +16,7 @@
  	ath_dbg(common, ATH_DBG_CONFIG,
  		"Attach a VIF of type: %d\n", vif->type);
  
-@@ -1527,15 +1518,6 @@ static int ath9k_change_interface(struct
+@@ -1525,15 +1516,6 @@ static int ath9k_change_interface(struct
  	mutex_lock(&sc->mutex);
  	ath9k_ps_wakeup(sc);
  
diff --git a/package/mac80211/patches/510-ath9k_intr_mitigation_tweak.patch b/package/mac80211/patches/510-ath9k_intr_mitigation_tweak.patch
index 834e1a2aeb..e2bfde443a 100644
--- a/package/mac80211/patches/510-ath9k_intr_mitigation_tweak.patch
+++ b/package/mac80211/patches/510-ath9k_intr_mitigation_tweak.patch
@@ -1,6 +1,6 @@
 --- a/drivers/net/wireless/ath/ath9k/hw.c
 +++ b/drivers/net/wireless/ath/ath9k/hw.c
-@@ -1664,8 +1664,8 @@ int ath9k_hw_reset(struct ath_hw *ah, st
+@@ -1671,8 +1671,8 @@ int ath9k_hw_reset(struct ath_hw *ah, st
  	REG_WRITE(ah, AR_OBS, 8);
  
  	if (ah->config.rx_intr_mitigation) {
diff --git a/package/mac80211/patches/530-mac80211_cur_txpower.patch b/package/mac80211/patches/530-mac80211_cur_txpower.patch
index 5e99c03ba0..a8a042b7ee 100644
--- a/package/mac80211/patches/530-mac80211_cur_txpower.patch
+++ b/package/mac80211/patches/530-mac80211_cur_txpower.patch
@@ -11,7 +11,7 @@
  	u16 listen_interval;
 --- a/net/mac80211/cfg.c
 +++ b/net/mac80211/cfg.c
-@@ -1532,7 +1532,7 @@ static int ieee80211_get_tx_power(struct
+@@ -1551,7 +1551,7 @@ static int ieee80211_get_tx_power(struct
  {
  	struct ieee80211_local *local = wiphy_priv(wiphy);
  
diff --git a/package/mac80211/patches/531-ath9k_cur_txpower.patch b/package/mac80211/patches/531-ath9k_cur_txpower.patch
index 26085c1301..f0de43eb47 100644
--- a/package/mac80211/patches/531-ath9k_cur_txpower.patch
+++ b/package/mac80211/patches/531-ath9k_cur_txpower.patch
@@ -1,6 +1,6 @@
 --- a/drivers/net/wireless/ath/ath9k/main.c
 +++ b/drivers/net/wireless/ath/ath9k/main.c
-@@ -1736,6 +1736,8 @@ static int ath9k_config(struct ieee80211
+@@ -1734,6 +1734,8 @@ static int ath9k_config(struct ieee80211
  			return -EINVAL;
  		}
  
@@ -9,7 +9,7 @@
  		/*
  		 * The most recent snapshot of channel->noisefloor for the old
  		 * channel is only available after the hardware reset. Copy it to
-@@ -1753,6 +1755,7 @@ static int ath9k_config(struct ieee80211
+@@ -1751,6 +1753,7 @@ static int ath9k_config(struct ieee80211
  		ath9k_cmn_update_txpow(ah, sc->curtxpow,
  				       sc->config.txpowlimit, &sc->curtxpow);
  		ath9k_ps_restore(sc);
diff --git a/package/mac80211/patches/540-ath9k_sw_retry_reduce.patch b/package/mac80211/patches/540-ath9k_sw_retry_reduce.patch
deleted file mode 100644
index d34b85140a..0000000000
--- a/package/mac80211/patches/540-ath9k_sw_retry_reduce.patch
+++ /dev/null
@@ -1,61 +0,0 @@
---- a/drivers/net/wireless/ath/ath9k/xmit.c
-+++ b/drivers/net/wireless/ath/ath9k/xmit.c
-@@ -248,13 +248,16 @@ static void ath_tid_drain(struct ath_sof
- }
- 
- static void ath_tx_set_retry(struct ath_softc *sc, struct ath_txq *txq,
--			     struct sk_buff *skb)
-+			     struct sk_buff *skb, int count)
- {
- 	struct ath_frame_info *fi = get_frame_info(skb);
- 	struct ieee80211_hdr *hdr;
-+	int prev = fi->retries;
- 
- 	TX_STAT_INC(txq->axq_qnum, a_retries);
--	if (fi->retries++ > 0)
-+	fi->retries += count;
-+
-+	if (prev > 0)
- 		return;
- 
- 	hdr = (struct ieee80211_hdr *)skb->data;
-@@ -359,6 +362,7 @@ static void ath_tx_complete_aggr(struct 
- 	int nframes;
- 	u8 tidno;
- 	bool clear_filter;
-+	int i, retries;
- 
- 	skb = bf->bf_mpdu;
- 	hdr = (struct ieee80211_hdr *)skb->data;
-@@ -367,6 +371,10 @@ static void ath_tx_complete_aggr(struct 
- 
- 	memcpy(rates, tx_info->control.rates, sizeof(rates));
- 
-+	retries = ts->ts_longretry + 1;
-+	for (i = 0; i < ts->ts_rateindex; i++)
-+		retries += rates[i].count;
-+
- 	rcu_read_lock();
- 
- 	sta = ieee80211_find_sta_by_ifaddr(hw, hdr->addr1, hdr->addr2);
-@@ -451,7 +459,8 @@ static void ath_tx_complete_aggr(struct 
- 			} else if (fi->retries < ATH_MAX_SW_RETRIES) {
- 				if (!(ts->ts_status & ATH9K_TXERR_FILT) ||
- 				    !an->sleeping)
--					ath_tx_set_retry(sc, txq, bf->bf_mpdu);
-+					ath_tx_set_retry(sc, txq, bf->bf_mpdu,
-+							 retries);
- 
- 				clear_filter = true;
- 				txpending = 1;
---- a/drivers/net/wireless/ath/ath9k/ath9k.h
-+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
-@@ -538,7 +538,7 @@ struct ath_ant_comb {
- #define DEFAULT_CACHELINE       32
- #define ATH_REGCLASSIDS_MAX     10
- #define ATH_CABQ_READY_TIME     80      /* % of beacon interval */
--#define ATH_MAX_SW_RETRIES      10
-+#define ATH_MAX_SW_RETRIES      20
- #define ATH_CHAN_MAX            255
- 
- #define ATH_TXPOWER_MAX         100     /* .5 dBm units */
diff --git a/package/mac80211/patches/540-ath9k_txkeyidx_u8.patch b/package/mac80211/patches/540-ath9k_txkeyidx_u8.patch
new file mode 100644
index 0000000000..2b59533df2
--- /dev/null
+++ b/package/mac80211/patches/540-ath9k_txkeyidx_u8.patch
@@ -0,0 +1,56 @@
+--- a/drivers/net/wireless/ath/ath9k/ar9002_mac.c
++++ b/drivers/net/wireless/ath/ath9k/ar9002_mac.c
+@@ -273,7 +273,7 @@ static int ar9002_hw_proc_txdesc(struct 
+ 
+ static void ar9002_hw_set11n_txdesc(struct ath_hw *ah, void *ds,
+ 				    u32 pktLen, enum ath9k_pkt_type type,
+-				    u32 txPower, u32 keyIx,
++				    u32 txPower, u8 keyIx,
+ 				    enum ath9k_key_type keyType, u32 flags)
+ {
+ 	struct ar5416_desc *ads = AR5416DESC(ds);
+--- a/drivers/net/wireless/ath/ath9k/ath9k.h
++++ b/drivers/net/wireless/ath/ath9k/ath9k.h
+@@ -207,8 +207,8 @@ struct ath_atx_ac {
+ 
+ struct ath_frame_info {
+ 	int framelen;
+-	u32 keyix;
+ 	enum ath9k_key_type keytype;
++	u8 keyix;
+ 	u8 retries;
+ 	u16 seqno;
+ };
+--- a/drivers/net/wireless/ath/ath9k/hw.h
++++ b/drivers/net/wireless/ath/ath9k/hw.h
+@@ -623,7 +623,7 @@ struct ath_hw_ops {
+ 			   struct ath_tx_status *ts);
+ 	void (*set11n_txdesc)(struct ath_hw *ah, void *ds,
+ 			      u32 pktLen, enum ath9k_pkt_type type,
+-			      u32 txPower, u32 keyIx,
++			      u32 txPower, u8 keyIx,
+ 			      enum ath9k_key_type keyType,
+ 			      u32 flags);
+ 	void (*set11n_ratescenario)(struct ath_hw *ah, void *ds,
+--- a/drivers/net/wireless/ath/ath9k/mac.h
++++ b/drivers/net/wireless/ath/ath9k/mac.h
+@@ -194,7 +194,7 @@ struct ath_htc_rx_status {
+ #define ATH9K_RX_DECRYPT_BUSY     0x40
+ 
+ #define ATH9K_RXKEYIX_INVALID	((u8)-1)
+-#define ATH9K_TXKEYIX_INVALID	((u32)-1)
++#define ATH9K_TXKEYIX_INVALID	((u8)-1)
+ 
+ enum ath9k_phyerr {
+ 	ATH9K_PHYERR_UNDERRUN             = 0,  /* Transmit underrun */
+--- a/drivers/net/wireless/ath/ath9k/ar9003_mac.c
++++ b/drivers/net/wireless/ath/ath9k/ar9003_mac.c
+@@ -312,7 +312,7 @@ static int ar9003_hw_proc_txdesc(struct 
+ 
+ static void ar9003_hw_set11n_txdesc(struct ath_hw *ah, void *ds,
+ 		u32 pktlen, enum ath9k_pkt_type type, u32 txpower,
+-		u32 keyIx, enum ath9k_key_type keyType, u32 flags)
++		u8 keyIx, enum ath9k_key_type keyType, u32 flags)
+ {
+ 	struct ar9003_txc *ads = (struct ar9003_txc *) ds;
+ 
diff --git a/package/mac80211/patches/541-ath9k_aggr_queue_cleanup.patch b/package/mac80211/patches/541-ath9k_aggr_queue_cleanup.patch
index e196cedfab..27c144fba1 100644
--- a/package/mac80211/patches/541-ath9k_aggr_queue_cleanup.patch
+++ b/package/mac80211/patches/541-ath9k_aggr_queue_cleanup.patch
@@ -6,8 +6,8 @@
  struct ath_frame_info {
 +	struct ath_buf *bf;
  	int framelen;
- 	u32 keyix;
  	enum ath9k_key_type keytype;
+ 	u8 keyix;
 @@ -235,7 +236,7 @@ struct ath_buf {
  
  struct ath_atx_tid {
@@ -92,7 +92,7 @@
  		if (fi->retries)
  			ath_tx_update_baw(sc, tid, fi->seqno);
  
-@@ -352,7 +353,8 @@ static void ath_tx_complete_aggr(struct 
+@@ -349,7 +350,8 @@ static void ath_tx_complete_aggr(struct 
  	struct ieee80211_tx_info *tx_info;
  	struct ath_atx_tid *tid = NULL;
  	struct ath_buf *bf_next, *bf_last = bf->bf_lastbf;
@@ -102,7 +102,7 @@
  	u16 seq_st = 0, acked_cnt = 0, txfail_cnt = 0;
  	u32 ba[WME_BA_BMP_SIZE >> 5];
  	int isaggr, txfail, txpending, sendbar = 0, needreset = 0, nbad = 0;
-@@ -430,8 +432,7 @@ static void ath_tx_complete_aggr(struct 
+@@ -422,8 +424,7 @@ static void ath_tx_complete_aggr(struct 
  		}
  	}
  
@@ -112,7 +112,7 @@
  
  	ath_tx_count_frames(sc, bf, ts, txok, &nframes, &nbad);
  	while (bf) {
-@@ -476,10 +477,10 @@ static void ath_tx_complete_aggr(struct 
+@@ -467,10 +468,10 @@ static void ath_tx_complete_aggr(struct 
  		 * Make sure the last desc is reclaimed if it
  		 * not a holding desc.
  		 */
@@ -126,7 +126,7 @@
  
  		if (!txpending || (tid->state & AGGR_CLEANUP)) {
  			/*
-@@ -530,7 +531,7 @@ static void ath_tx_complete_aggr(struct 
+@@ -521,7 +522,7 @@ static void ath_tx_complete_aggr(struct 
  
  					ath9k_hw_cleartxdesc(sc->sc_ah,
  							     tbf->bf_desc);
@@ -135,7 +135,7 @@
  				} else {
  					/*
  					 * Clear descriptor status words for
-@@ -545,21 +546,21 @@ static void ath_tx_complete_aggr(struct 
+@@ -536,21 +537,21 @@ static void ath_tx_complete_aggr(struct 
  			 * Put this buffer to the temporary pending
  			 * queue to retain ordering
  			 */
@@ -160,7 +160,7 @@
  		if (!an->sleeping)
  			ath_tx_queue_tid(txq, tid);
  		spin_unlock_bh(&txq->axq_lock);
-@@ -730,19 +731,22 @@ static enum ATH_AGGR_STATUS ath_tx_form_
+@@ -743,19 +744,22 @@ static enum ATH_AGGR_STATUS ath_tx_form_
  					     int *aggr_len)
  {
  #define PADBYTES(_len) ((4 - ((_len) % 4)) % 4)
@@ -188,7 +188,7 @@
  
  		/* do not step over block-ack window */
  		if (!BAW_WITHIN(tid->seq_start, tid->baw_size, fi->seqno)) {
-@@ -794,7 +798,9 @@ static enum ATH_AGGR_STATUS ath_tx_form_
+@@ -808,7 +812,9 @@ static enum ATH_AGGR_STATUS ath_tx_form_
  		if (!fi->retries)
  			ath_tx_addto_baw(sc, tid, fi->seqno);
  		ath9k_hw_set11n_aggr_middle(sc->sc_ah, bf->bf_desc, ndelim);
@@ -199,7 +199,7 @@
  		if (bf_prev) {
  			bf_prev->bf_next = bf;
  			ath9k_hw_set_desc_link(sc->sc_ah, bf_prev->bf_desc,
-@@ -802,7 +808,7 @@ static enum ATH_AGGR_STATUS ath_tx_form_
+@@ -816,7 +822,7 @@ static enum ATH_AGGR_STATUS ath_tx_form_
  		}
  		bf_prev = bf;
  
@@ -208,7 +208,7 @@
  
  	*aggr_len = al;
  
-@@ -820,7 +826,7 @@ static void ath_tx_sched_aggr(struct ath
+@@ -834,7 +840,7 @@ static void ath_tx_sched_aggr(struct ath
  	int aggr_len;
  
  	do {
@@ -217,7 +217,7 @@
  			return;
  
  		INIT_LIST_HEAD(&bf_q);
-@@ -941,7 +947,7 @@ bool ath_tx_aggr_sleep(struct ath_softc 
+@@ -955,7 +961,7 @@ bool ath_tx_aggr_sleep(struct ath_softc 
  
  		spin_lock_bh(&txq->axq_lock);
  
@@ -226,7 +226,7 @@
  			buffered = true;
  
  		tid->sched = false;
-@@ -974,7 +980,7 @@ void ath_tx_aggr_wakeup(struct ath_softc
+@@ -988,7 +994,7 @@ void ath_tx_aggr_wakeup(struct ath_softc
  		spin_lock_bh(&txq->axq_lock);
  		ac->clear_ps_filter = true;
  
@@ -235,7 +235,7 @@
  			ath_tx_queue_tid(txq, tid);
  			ath_txq_schedule(sc, txq);
  		}
-@@ -1318,7 +1324,7 @@ void ath_txq_schedule(struct ath_softc *
+@@ -1332,7 +1338,7 @@ void ath_txq_schedule(struct ath_softc *
  			 * add tid to round-robin queue if more frames
  			 * are pending for the tid
  			 */
@@ -244,7 +244,7 @@
  				ath_tx_queue_tid(txq, tid);
  
  			if (tid == last_tid ||
-@@ -1424,7 +1430,7 @@ static void ath_tx_send_ampdu(struct ath
+@@ -1438,7 +1444,7 @@ static void ath_tx_send_ampdu(struct ath
  	 * - seqno is not within block-ack window
  	 * - h/w queue depth exceeds low water mark
  	 */
@@ -253,7 +253,7 @@
  	    !BAW_WITHIN(tid->seq_start, tid->baw_size, fi->seqno) ||
  	    txctl->txq->axq_ampdu_depth >= ATH_AGGR_MIN_QDEPTH) {
  		/*
-@@ -1432,7 +1438,7 @@ static void ath_tx_send_ampdu(struct ath
+@@ -1446,7 +1452,7 @@ static void ath_tx_send_ampdu(struct ath
  		 * for aggregation.
  		 */
  		TX_STAT_INC(txctl->txq->axq_qnum, a_queued_sw);
@@ -262,7 +262,7 @@
  		if (!txctl->an || !txctl->an->sleeping)
  			ath_tx_queue_tid(txctl->txq, tid);
  		return;
-@@ -1763,6 +1769,7 @@ static struct ath_buf *ath_tx_setup_buff
+@@ -1777,6 +1783,7 @@ static struct ath_buf *ath_tx_setup_buff
  			    bf->bf_buf_addr,
  			    txq->axq_qnum);
  
@@ -270,7 +270,7 @@
  
  	return bf;
  }
-@@ -2380,7 +2387,7 @@ void ath_tx_node_init(struct ath_softc *
+@@ -2394,7 +2401,7 @@ void ath_tx_node_init(struct ath_softc *
  		tid->sched     = false;
  		tid->paused    = false;
  		tid->state &= ~AGGR_CLEANUP;
diff --git a/package/mac80211/patches/542-ath9k_limit_qlen.patch b/package/mac80211/patches/542-ath9k_limit_qlen.patch
deleted file mode 100644
index f05db0a7c0..0000000000
--- a/package/mac80211/patches/542-ath9k_limit_qlen.patch
+++ /dev/null
@@ -1,176 +0,0 @@
---- a/drivers/net/wireless/ath/ath9k/ath9k.h
-+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
-@@ -240,6 +240,7 @@ struct ath_atx_tid {
- 	struct ath_node *an;
- 	struct ath_atx_ac *ac;
- 	unsigned long tx_buf[BITS_TO_LONGS(ATH_TID_MAX_BUFS)];
-+	int buf_pending;
- 	u16 seq_start;
- 	u16 seq_next;
- 	u16 baw_size;
-@@ -286,6 +287,9 @@ struct ath_tx_control {
-  *  (axq_qnum).
-  */
- struct ath_tx {
-+	u32 qlen_single;
-+	u32 qlen_aggr;
-+
- 	u16 seq_no;
- 	u32 txqsetup;
- 	spinlock_t txbuflock;
---- a/drivers/net/wireless/ath/ath9k/debug.c
-+++ b/drivers/net/wireless/ath/ath9k/debug.c
-@@ -1341,6 +1341,10 @@ int ath9k_init_debug(struct ath_hw *ah)
- 			    sc, &fops_wiphy);
- 	debugfs_create_file("xmit", S_IRUSR, sc->debug.debugfs_phy, sc,
- 			    &fops_xmit);
-+	debugfs_create_u32("qlen_single", S_IRUSR | S_IWUSR,
-+			   sc->debug.debugfs_phy, &sc->tx.qlen_single);
-+	debugfs_create_u32("qlen_aggr", S_IRUSR | S_IWUSR,
-+			   sc->debug.debugfs_phy, &sc->tx.qlen_aggr);
- 	debugfs_create_file("stations", S_IRUSR, sc->debug.debugfs_phy, sc,
- 			    &fops_stations);
- 	debugfs_create_file("misc", S_IRUSR, sc->debug.debugfs_phy, sc,
---- a/drivers/net/wireless/ath/ath9k/xmit.c
-+++ b/drivers/net/wireless/ath/ath9k/xmit.c
-@@ -340,6 +340,14 @@ static void ath_tx_count_frames(struct a
- 	}
- }
- 
-+static struct ath_atx_tid *ath_get_tid(struct ath_node *an, struct sk_buff *skb)
-+{
-+	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
-+	u8 tidno;
-+
-+	tidno = ieee80211_get_qos_ctl(hdr)[0] & IEEE80211_QOS_CTL_TID_MASK;
-+	return ATH_AN_2_TID(an, tidno);
-+}
- 
- static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
- 				 struct ath_buf *bf, struct list_head *bf_q,
-@@ -435,6 +443,8 @@ static void ath_tx_complete_aggr(struct 
- 	__skb_queue_head_init(&bf_pending);
- 
- 	ath_tx_count_frames(sc, bf, ts, txok, &nframes, &nbad);
-+	tid->buf_pending -= nframes;
-+
- 	while (bf) {
- 		txfail = txpending = sendbar = 0;
- 		bf_next = bf->bf_next;
-@@ -799,6 +809,7 @@ static enum ATH_AGGR_STATUS ath_tx_form_
- 			ath_tx_addto_baw(sc, tid, fi->seqno);
- 		ath9k_hw_set11n_aggr_middle(sc->sc_ah, bf->bf_desc, ndelim);
- 
-+		tid->buf_pending++;
- 		__skb_unlink(skb, &tid->buf_q);
- 		list_add_tail(&bf->list, bf_q);
- 		if (bf_prev) {
-@@ -1451,6 +1462,8 @@ static void ath_tx_send_ampdu(struct ath
- 	if (!fi->retries)
- 		ath_tx_addto_baw(sc, tid, fi->seqno);
- 
-+	tid->buf_pending++;
-+
- 	/* Queue to h/w without aggregation */
- 	TX_STAT_INC(txctl->txq->axq_qnum, a_queued_hw);
- 	bf->bf_lastbf = bf;
-@@ -1515,7 +1528,6 @@ static void setup_frame_info(struct ieee
- 	struct ath_atx_tid *tid;
- 	enum ath9k_key_type keytype;
- 	u16 seqno = 0;
--	u8 tidno;
- 
- 	keytype = ath9k_cmn_get_hw_crypto_keytype(skb);
- 
-@@ -1526,13 +1538,11 @@ static void setup_frame_info(struct ieee
- 	if (an && ieee80211_is_data_qos(hdr->frame_control) &&
- 		conf_is_ht(&hw->conf) && (sc->sc_flags & SC_OP_TXAGGR)) {
- 
--		tidno = ieee80211_get_qos_ctl(hdr)[0] & IEEE80211_QOS_CTL_TID_MASK;
--
- 		/*
- 		 * Override seqno set by upper layer with the one
- 		 * in tx aggregation state.
- 		 */
--		tid = ATH_AN_2_TID(an, tidno);
-+		tid = ath_get_tid(an, skb);
- 		seqno = tid->seq_next;
- 		hdr->seq_ctrl = cpu_to_le16(seqno << IEEE80211_SEQ_SEQ_SHIFT);
- 		INCR(tid->seq_next, IEEE80211_SEQ_MAX);
-@@ -1776,24 +1786,14 @@ static struct ath_buf *ath_tx_setup_buff
- 
- /* FIXME: tx power */
- static void ath_tx_start_dma(struct ath_softc *sc, struct ath_buf *bf,
--			     struct ath_tx_control *txctl)
-+			     struct ath_tx_control *txctl,
-+			     struct ath_atx_tid *tid)
- {
- 	struct sk_buff *skb = bf->bf_mpdu;
- 	struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
--	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
- 	struct list_head bf_head;
--	struct ath_atx_tid *tid = NULL;
--	u8 tidno;
- 
- 	spin_lock_bh(&txctl->txq->axq_lock);
--	if ((sc->sc_flags & SC_OP_TXAGGR) && txctl->an &&
--		ieee80211_is_data_qos(hdr->frame_control)) {
--		tidno = ieee80211_get_qos_ctl(hdr)[0] &
--			IEEE80211_QOS_CTL_TID_MASK;
--		tid = ATH_AN_2_TID(txctl->an, tidno);
--
--		WARN_ON(tid->ac->txq != txctl->txq);
--	}
- 
- 	if ((tx_info->flags & IEEE80211_TX_CTL_AMPDU) && tid) {
- 		/*
-@@ -1833,6 +1833,7 @@ int ath_tx_start(struct ieee80211_hw *hw
- 	struct ieee80211_vif *vif = info->control.vif;
- 	struct ath_softc *sc = hw->priv;
- 	struct ath_txq *txq = txctl->txq;
-+	struct ath_atx_tid *tid = NULL;
- 	struct ath_buf *bf;
- 	int padpos, padsize;
- 	int frmlen = skb->len + FCS_LEN;
-@@ -1866,6 +1867,7 @@ int ath_tx_start(struct ieee80211_hw *hw
- 
- 		skb_push(skb, padsize);
- 		memmove(skb->data, skb->data + padsize, padpos);
-+		hdr = (struct ieee80211_hdr *) skb->data;
- 	}
- 
- 	if ((vif && vif->type != NL80211_IFTYPE_AP &&
-@@ -1875,6 +1877,24 @@ int ath_tx_start(struct ieee80211_hw *hw
- 
- 	setup_frame_info(hw, skb, frmlen);
- 
-+	if ((sc->sc_flags & SC_OP_TXAGGR) && txctl->an &&
-+	    ieee80211_is_data_qos(hdr->frame_control)) {
-+		tid = ath_get_tid(txctl->an, skb);
-+
-+		WARN_ON(tid->ac->txq != txq);
-+	}
-+
-+	if ((info->flags & IEEE80211_TX_CTL_AMPDU) && tid) {
-+		if (sc->tx.qlen_aggr > 0 && skb_queue_len(&tid->buf_q) +
-+		    tid->buf_pending >= sc->tx.qlen_aggr)
-+			return -ENOMEM;
-+	} else {
-+		if (sc->tx.qlen_single > 0 &&
-+		    txq->axq_depth - txq->axq_ampdu_depth >=
-+		      sc->tx.qlen_single)
-+			return -ENOMEM;
-+	}
-+
- 	/*
- 	 * At this point, the vif, hw_key and sta pointers in the tx control
- 	 * info are no longer valid (overwritten by the ath_frame_info data.
-@@ -1893,7 +1913,7 @@ int ath_tx_start(struct ieee80211_hw *hw
- 	}
- 	spin_unlock_bh(&txq->axq_lock);
- 
--	ath_tx_start_dma(sc, bf, txctl);
-+	ath_tx_start_dma(sc, bf, txctl, tid);
- 
- 	return 0;
- }
diff --git a/package/mac80211/patches/542-ath9k_move_seqno.patch b/package/mac80211/patches/542-ath9k_move_seqno.patch
new file mode 100644
index 0000000000..c0d293a803
--- /dev/null
+++ b/package/mac80211/patches/542-ath9k_move_seqno.patch
@@ -0,0 +1,207 @@
+--- a/drivers/net/wireless/ath/ath9k/ath9k.h
++++ b/drivers/net/wireless/ath/ath9k/ath9k.h
+@@ -211,12 +211,12 @@ struct ath_frame_info {
+ 	enum ath9k_key_type keytype;
+ 	u8 keyix;
+ 	u8 retries;
+-	u16 seqno;
+ };
+ 
+ struct ath_buf_state {
+ 	u8 bf_type;
+ 	u8 bfs_paprd;
++	u16 seqno;
+ 	unsigned long bfs_paprd_timestamp;
+ };
+ 
+--- a/drivers/net/wireless/ath/ath9k/xmit.c
++++ b/drivers/net/wireless/ath/ath9k/xmit.c
+@@ -168,7 +168,7 @@ static void ath_tx_flush_tid(struct ath_
+ 
+ 		spin_unlock_bh(&txq->axq_lock);
+ 		if (fi->retries) {
+-			ath_tx_update_baw(sc, tid, fi->seqno);
++			ath_tx_update_baw(sc, tid, bf->bf_state.seqno);
+ 			ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, 0, 1);
+ 		} else {
+ 			ath_tx_send_normal(sc, txq, NULL, &bf_head);
+@@ -237,7 +237,7 @@ static void ath_tid_drain(struct ath_sof
+ 		list_add_tail(&bf->list, &bf_head);
+ 
+ 		if (fi->retries)
+-			ath_tx_update_baw(sc, tid, fi->seqno);
++			ath_tx_update_baw(sc, tid, bf->bf_state.seqno);
+ 
+ 		spin_unlock(&txq->axq_lock);
+ 		ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, 0, 0);
+@@ -327,7 +327,7 @@ static void ath_tx_count_frames(struct a
+ 
+ 	while (bf) {
+ 		fi = get_frame_info(bf->bf_mpdu);
+-		ba_index = ATH_BA_INDEX(seq_st, fi->seqno);
++		ba_index = ATH_BA_INDEX(seq_st, bf->bf_state.seqno);
+ 
+ 		(*nframes)++;
+ 		if (!txok || (isaggr && !ATH_BA_ISSET(ba, ba_index)))
+@@ -428,6 +428,8 @@ static void ath_tx_complete_aggr(struct 
+ 
+ 	ath_tx_count_frames(sc, bf, ts, txok, &nframes, &nbad);
+ 	while (bf) {
++		u16 seqno = bf->bf_state.seqno;
++
+ 		txfail = txpending = sendbar = 0;
+ 		bf_next = bf->bf_next;
+ 
+@@ -435,7 +437,7 @@ static void ath_tx_complete_aggr(struct 
+ 		tx_info = IEEE80211_SKB_CB(skb);
+ 		fi = get_frame_info(skb);
+ 
+-		if (ATH_BA_ISSET(ba, ATH_BA_INDEX(seq_st, fi->seqno))) {
++		if (ATH_BA_ISSET(ba, ATH_BA_INDEX(seq_st, seqno))) {
+ 			/* transmit completion, subframe is
+ 			 * acked by block ack */
+ 			acked_cnt++;
+@@ -479,7 +481,7 @@ static void ath_tx_complete_aggr(struct 
+ 			 * block-ack window
+ 			 */
+ 			spin_lock_bh(&txq->axq_lock);
+-			ath_tx_update_baw(sc, tid, fi->seqno);
++			ath_tx_update_baw(sc, tid, seqno);
+ 			spin_unlock_bh(&txq->axq_lock);
+ 
+ 			if (rc_update && (acked_cnt == 1 || txfail_cnt == 1)) {
+@@ -507,7 +509,7 @@ static void ath_tx_complete_aggr(struct 
+ 					 */
+ 					if (!tbf) {
+ 						spin_lock_bh(&txq->axq_lock);
+-						ath_tx_update_baw(sc, tid, fi->seqno);
++						ath_tx_update_baw(sc, tid, seqno);
+ 						spin_unlock_bh(&txq->axq_lock);
+ 
+ 						bf->bf_state.bf_type |=
+@@ -752,17 +754,19 @@ static enum ATH_AGGR_STATUS ath_tx_form_
+ 	struct ieee80211_tx_info *tx_info;
+ 	struct ath_frame_info *fi;
+ 	struct sk_buff *skb;
++	u16 seqno;
+ 
+ 	do {
+ 		skb = skb_peek(&tid->buf_q);
+ 		fi = get_frame_info(skb);
+ 		bf = fi->bf;
++		seqno = bf->bf_state.seqno;
+ 
+ 		if (!bf_first)
+ 			bf_first = bf;
+ 
+ 		/* do not step over block-ack window */
+-		if (!BAW_WITHIN(tid->seq_start, tid->baw_size, fi->seqno)) {
++		if (!BAW_WITHIN(tid->seq_start, tid->baw_size, seqno)) {
+ 			status = ATH_AGGR_BAW_CLOSED;
+ 			break;
+ 		}
+@@ -810,7 +814,7 @@ static enum ATH_AGGR_STATUS ath_tx_form_
+ 
+ 		/* link buffers of this frame to the aggregate */
+ 		if (!fi->retries)
+-			ath_tx_addto_baw(sc, tid, fi->seqno);
++			ath_tx_addto_baw(sc, tid, seqno);
+ 		ath9k_hw_set11n_aggr_middle(sc->sc_ah, bf->bf_desc, ndelim);
+ 
+ 		__skb_unlink(skb, &tid->buf_q);
+@@ -1434,6 +1438,7 @@ static void ath_tx_send_ampdu(struct ath
+ {
+ 	struct ath_frame_info *fi = get_frame_info(bf->bf_mpdu);
+ 	struct list_head bf_head;
++	u16 seqno = bf->bf_state.seqno;
+ 
+ 	bf->bf_state.bf_type |= BUF_AMPDU;
+ 
+@@ -1445,7 +1450,7 @@ static void ath_tx_send_ampdu(struct ath
+ 	 * - h/w queue depth exceeds low water mark
+ 	 */
+ 	if (!skb_queue_empty(&tid->buf_q) || tid->paused ||
+-	    !BAW_WITHIN(tid->seq_start, tid->baw_size, fi->seqno) ||
++	    !BAW_WITHIN(tid->seq_start, tid->baw_size, seqno) ||
+ 	    txctl->txq->axq_ampdu_depth >= ATH_AGGR_MIN_QDEPTH) {
+ 		/*
+ 		 * Add this frame to software queue for scheduling later
+@@ -1463,7 +1468,7 @@ static void ath_tx_send_ampdu(struct ath
+ 
+ 	/* Add sub-frame to BAW */
+ 	if (!fi->retries)
+-		ath_tx_addto_baw(sc, tid, fi->seqno);
++		ath_tx_addto_baw(sc, tid, seqno);
+ 
+ 	/* Queue to h/w without aggregation */
+ 	TX_STAT_INC(txctl->txq->axq_qnum, a_queued_hw);
+@@ -1519,39 +1524,19 @@ static enum ath9k_pkt_type get_hw_packet
+ static void setup_frame_info(struct ieee80211_hw *hw, struct sk_buff *skb,
+ 			     int framelen)
+ {
+-	struct ath_softc *sc = hw->priv;
+ 	struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
+ 	struct ieee80211_sta *sta = tx_info->control.sta;
+ 	struct ieee80211_key_conf *hw_key = tx_info->control.hw_key;
+-	struct ieee80211_hdr *hdr;
++	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
+ 	struct ath_frame_info *fi = get_frame_info(skb);
+ 	struct ath_node *an = NULL;
+-	struct ath_atx_tid *tid;
+ 	enum ath9k_key_type keytype;
+-	u16 seqno = 0;
+-	u8 tidno;
+ 
+ 	keytype = ath9k_cmn_get_hw_crypto_keytype(skb);
+ 
+ 	if (sta)
+ 		an = (struct ath_node *) sta->drv_priv;
+ 
+-	hdr = (struct ieee80211_hdr *)skb->data;
+-	if (an && ieee80211_is_data_qos(hdr->frame_control) &&
+-		conf_is_ht(&hw->conf) && (sc->sc_flags & SC_OP_TXAGGR)) {
+-
+-		tidno = ieee80211_get_qos_ctl(hdr)[0] & IEEE80211_QOS_CTL_TID_MASK;
+-
+-		/*
+-		 * Override seqno set by upper layer with the one
+-		 * in tx aggregation state.
+-		 */
+-		tid = ATH_AN_2_TID(an, tidno);
+-		seqno = tid->seq_next;
+-		hdr->seq_ctrl = cpu_to_le16(seqno << IEEE80211_SEQ_SEQ_SHIFT);
+-		INCR(tid->seq_next, IEEE80211_SEQ_MAX);
+-	}
+-
+ 	memset(fi, 0, sizeof(*fi));
+ 	if (hw_key)
+ 		fi->keyix = hw_key->hw_key_idx;
+@@ -1561,7 +1546,6 @@ static void setup_frame_info(struct ieee
+ 		fi->keyix = ATH9K_TXKEYIX_INVALID;
+ 	fi->keytype = keytype;
+ 	fi->framelen = framelen;
+-	fi->seqno = seqno;
+ }
+ 
+ static int setup_tx_flags(struct sk_buff *skb)
+@@ -1797,6 +1781,7 @@ static void ath_tx_start_dma(struct ath_
+ 	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
+ 	struct list_head bf_head;
+ 	struct ath_atx_tid *tid = NULL;
++	u16 seqno;
+ 	u8 tidno;
+ 
+ 	spin_lock_bh(&txctl->txq->axq_lock);
+@@ -1806,6 +1791,12 @@ static void ath_tx_start_dma(struct ath_
+ 			IEEE80211_QOS_CTL_TID_MASK;
+ 		tid = ATH_AN_2_TID(txctl->an, tidno);
+ 
++		seqno = tid->seq_next;
++		hdr->seq_ctrl = cpu_to_le16(tid->seq_next << IEEE80211_SEQ_SEQ_SHIFT);
++		INCR(tid->seq_next, IEEE80211_SEQ_MAX);
++
++		bf->bf_state.seqno = seqno;
++
+ 		WARN_ON(tid->ac->txq != txctl->txq);
+ 	}
+ 
diff --git a/package/mac80211/patches/543-ath9k_move_seqno_alloc.patch b/package/mac80211/patches/543-ath9k_move_seqno_alloc.patch
new file mode 100644
index 0000000000..8de5fd27ab
--- /dev/null
+++ b/package/mac80211/patches/543-ath9k_move_seqno_alloc.patch
@@ -0,0 +1,119 @@
+--- a/drivers/net/wireless/ath/ath9k/xmit.c
++++ b/drivers/net/wireless/ath/ath9k/xmit.c
+@@ -1717,17 +1717,19 @@ static void ath_buf_set_rate(struct ath_
+ 
+ }
+ 
+-static struct ath_buf *ath_tx_setup_buffer(struct ieee80211_hw *hw,
++static struct ath_buf *ath_tx_setup_buffer(struct ath_softc *sc,
+ 					   struct ath_txq *txq,
++					   struct ath_atx_tid *tid,
+ 					   struct sk_buff *skb)
+ {
+-	struct ath_softc *sc = hw->priv;
+ 	struct ath_hw *ah = sc->sc_ah;
+ 	struct ath_common *common = ath9k_hw_common(sc->sc_ah);
+ 	struct ath_frame_info *fi = get_frame_info(skb);
++	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
+ 	struct ath_buf *bf;
+ 	struct ath_desc *ds;
+ 	int frm_type;
++	u16 seqno;
+ 
+ 	bf = ath_tx_get_buffer(sc);
+ 	if (!bf) {
+@@ -1737,6 +1739,13 @@ static struct ath_buf *ath_tx_setup_buff
+ 
+ 	ATH_TXBUF_RESET(bf);
+ 
++	if (tid) {
++		seqno = tid->seq_next;
++		hdr->seq_ctrl = cpu_to_le16(tid->seq_next << IEEE80211_SEQ_SEQ_SHIFT);
++		INCR(tid->seq_next, IEEE80211_SEQ_MAX);
++		bf->bf_state.seqno = seqno;
++	}
++
+ 	bf->bf_flags = setup_tx_flags(skb);
+ 	bf->bf_mpdu = skb;
+ 
+@@ -1773,15 +1782,15 @@ static struct ath_buf *ath_tx_setup_buff
+ }
+ 
+ /* FIXME: tx power */
+-static void ath_tx_start_dma(struct ath_softc *sc, struct ath_buf *bf,
++static int ath_tx_start_dma(struct ath_softc *sc, struct sk_buff *skb,
+ 			     struct ath_tx_control *txctl)
+ {
+-	struct sk_buff *skb = bf->bf_mpdu;
+ 	struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
+ 	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
+ 	struct list_head bf_head;
+ 	struct ath_atx_tid *tid = NULL;
+-	u16 seqno;
++	struct ath_buf *bf;
++	int ret = 0;
+ 	u8 tidno;
+ 
+ 	spin_lock_bh(&txctl->txq->axq_lock);
+@@ -1791,15 +1800,15 @@ static void ath_tx_start_dma(struct ath_
+ 			IEEE80211_QOS_CTL_TID_MASK;
+ 		tid = ATH_AN_2_TID(txctl->an, tidno);
+ 
+-		seqno = tid->seq_next;
+-		hdr->seq_ctrl = cpu_to_le16(tid->seq_next << IEEE80211_SEQ_SEQ_SHIFT);
+-		INCR(tid->seq_next, IEEE80211_SEQ_MAX);
+-
+-		bf->bf_state.seqno = seqno;
+-
+ 		WARN_ON(tid->ac->txq != txctl->txq);
+ 	}
+ 
++	bf = ath_tx_setup_buffer(sc, txctl->txq, tid, skb);
++	if (unlikely(!bf)) {
++		ret = -ENOMEM;
++		goto out;
++	}
++
+ 	if ((tx_info->flags & IEEE80211_TX_CTL_AMPDU) && tid) {
+ 		/*
+ 		 * Try aggregation if it's a unicast data frame
+@@ -1825,7 +1834,9 @@ static void ath_tx_start_dma(struct ath_
+ 		ath_tx_send_normal(sc, txctl->txq, tid, &bf_head);
+ 	}
+ 
++out:
+ 	spin_unlock_bh(&txctl->txq->axq_lock);
++	return ret;
+ }
+ 
+ /* Upon failure caller should free skb */
+@@ -1838,7 +1849,6 @@ int ath_tx_start(struct ieee80211_hw *hw
+ 	struct ieee80211_vif *vif = info->control.vif;
+ 	struct ath_softc *sc = hw->priv;
+ 	struct ath_txq *txq = txctl->txq;
+-	struct ath_buf *bf;
+ 	int padpos, padsize;
+ 	int frmlen = skb->len + FCS_LEN;
+ 	int q;
+@@ -1885,10 +1895,6 @@ int ath_tx_start(struct ieee80211_hw *hw
+ 	 * info are no longer valid (overwritten by the ath_frame_info data.
+ 	 */
+ 
+-	bf = ath_tx_setup_buffer(hw, txctl->txq, skb);
+-	if (unlikely(!bf))
+-		return -ENOMEM;
+-
+ 	q = skb_get_queue_mapping(skb);
+ 	spin_lock_bh(&txq->axq_lock);
+ 	if (txq == sc->tx.txq_map[q] &&
+@@ -1898,9 +1904,7 @@ int ath_tx_start(struct ieee80211_hw *hw
+ 	}
+ 	spin_unlock_bh(&txq->axq_lock);
+ 
+-	ath_tx_start_dma(sc, bf, txctl);
+-
+-	return 0;
++	return ath_tx_start_dma(sc, skb, txctl);
+ }
+ 
+ /*****************/
diff --git a/package/mac80211/patches/544-ath9k_defer_buffer_setup.patch b/package/mac80211/patches/544-ath9k_defer_buffer_setup.patch
new file mode 100644
index 0000000000..d91ced0c5e
--- /dev/null
+++ b/package/mac80211/patches/544-ath9k_defer_buffer_setup.patch
@@ -0,0 +1,264 @@
+--- a/drivers/net/wireless/ath/ath9k/xmit.c
++++ b/drivers/net/wireless/ath/ath9k/xmit.c
+@@ -48,8 +48,9 @@ static u16 bits_per_symbol[][2] = {
+ #define IS_HT_RATE(_rate)     ((_rate) & 0x80)
+ 
+ static void ath_tx_send_normal(struct ath_softc *sc, struct ath_txq *txq,
+-			       struct ath_atx_tid *tid,
+-			       struct list_head *bf_head);
++			       struct ath_atx_tid *tid, struct sk_buff *skb);
++static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb,
++			    int tx_flags, struct ath_txq *txq);
+ static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf,
+ 				struct ath_txq *txq, struct list_head *bf_q,
+ 				struct ath_tx_status *ts, int txok, int sendbar);
+@@ -61,6 +62,10 @@ static void ath_tx_rc_status(struct ath_
+ 			     int txok, bool update_rc);
+ static void ath_tx_update_baw(struct ath_softc *sc, struct ath_atx_tid *tid,
+ 			      int seqno);
++static struct ath_buf *ath_tx_setup_buffer(struct ath_softc *sc,
++					   struct ath_txq *txq,
++					   struct ath_atx_tid *tid,
++					   struct sk_buff *skb);
+ 
+ enum {
+ 	MCS_HT20,
+@@ -164,14 +169,13 @@ static void ath_tx_flush_tid(struct ath_
+ 		fi = get_frame_info(skb);
+ 		bf = fi->bf;
+ 
+-		list_add_tail(&bf->list, &bf_head);
+-
+ 		spin_unlock_bh(&txq->axq_lock);
+-		if (fi->retries) {
++		if (bf && fi->retries) {
++			list_add_tail(&bf->list, &bf_head);
+ 			ath_tx_update_baw(sc, tid, bf->bf_state.seqno);
+ 			ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, 0, 1);
+ 		} else {
+-			ath_tx_send_normal(sc, txq, NULL, &bf_head);
++			ath_tx_send_normal(sc, txq, NULL, skb);
+ 		}
+ 		spin_lock_bh(&txq->axq_lock);
+ 	}
+@@ -234,6 +238,13 @@ static void ath_tid_drain(struct ath_sof
+ 		fi = get_frame_info(skb);
+ 		bf = fi->bf;
+ 
++		if (!bf) {
++			spin_unlock(&txq->axq_lock);
++			ath_tx_complete(sc, skb, ATH_TX_ERROR, txq);
++			spin_lock(&txq->axq_lock);
++			continue;
++		}
++
+ 		list_add_tail(&bf->list, &bf_head);
+ 
+ 		if (fi->retries)
+@@ -760,8 +771,14 @@ static enum ATH_AGGR_STATUS ath_tx_form_
+ 		skb = skb_peek(&tid->buf_q);
+ 		fi = get_frame_info(skb);
+ 		bf = fi->bf;
+-		seqno = bf->bf_state.seqno;
++		if (!fi->bf)
++			bf = ath_tx_setup_buffer(sc, txq, tid, skb);
+ 
++		if (!bf)
++			continue;
++
++		bf->bf_state.bf_type |= BUF_AMPDU;
++		seqno = bf->bf_state.seqno;
+ 		if (!bf_first)
+ 			bf_first = bf;
+ 
+@@ -1434,13 +1451,11 @@ static void ath_tx_txqaddbuf(struct ath_
+ }
+ 
+ static void ath_tx_send_ampdu(struct ath_softc *sc, struct ath_atx_tid *tid,
+-			      struct ath_buf *bf, struct ath_tx_control *txctl)
++			      struct sk_buff *skb, struct ath_tx_control *txctl)
+ {
+-	struct ath_frame_info *fi = get_frame_info(bf->bf_mpdu);
++	struct ath_frame_info *fi = get_frame_info(skb);
+ 	struct list_head bf_head;
+-	u16 seqno = bf->bf_state.seqno;
+-
+-	bf->bf_state.bf_type |= BUF_AMPDU;
++	struct ath_buf *bf;
+ 
+ 	/*
+ 	 * Do not queue to h/w when any of the following conditions is true:
+@@ -1450,25 +1465,29 @@ static void ath_tx_send_ampdu(struct ath
+ 	 * - h/w queue depth exceeds low water mark
+ 	 */
+ 	if (!skb_queue_empty(&tid->buf_q) || tid->paused ||
+-	    !BAW_WITHIN(tid->seq_start, tid->baw_size, seqno) ||
++	    !BAW_WITHIN(tid->seq_start, tid->baw_size, tid->seq_next) ||
+ 	    txctl->txq->axq_ampdu_depth >= ATH_AGGR_MIN_QDEPTH) {
+ 		/*
+ 		 * Add this frame to software queue for scheduling later
+ 		 * for aggregation.
+ 		 */
+ 		TX_STAT_INC(txctl->txq->axq_qnum, a_queued_sw);
+-		__skb_queue_tail(&tid->buf_q, bf->bf_mpdu);
++		__skb_queue_tail(&tid->buf_q, skb);
+ 		if (!txctl->an || !txctl->an->sleeping)
+ 			ath_tx_queue_tid(txctl->txq, tid);
+ 		return;
+ 	}
+ 
++	bf = ath_tx_setup_buffer(sc, txctl->txq, tid, skb);
++	if (!bf)
++		return;
++
++	bf->bf_state.bf_type |= BUF_AMPDU;
+ 	INIT_LIST_HEAD(&bf_head);
+ 	list_add(&bf->list, &bf_head);
+ 
+ 	/* Add sub-frame to BAW */
+-	if (!fi->retries)
+-		ath_tx_addto_baw(sc, tid, seqno);
++	ath_tx_addto_baw(sc, tid, bf->bf_state.seqno);
+ 
+ 	/* Queue to h/w without aggregation */
+ 	TX_STAT_INC(txctl->txq->axq_qnum, a_queued_hw);
+@@ -1478,13 +1497,21 @@ static void ath_tx_send_ampdu(struct ath
+ }
+ 
+ static void ath_tx_send_normal(struct ath_softc *sc, struct ath_txq *txq,
+-			       struct ath_atx_tid *tid,
+-			       struct list_head *bf_head)
++			       struct ath_atx_tid *tid, struct sk_buff *skb)
+ {
+-	struct ath_frame_info *fi;
++	struct ath_frame_info *fi = get_frame_info(skb);
++	struct list_head bf_head;
+ 	struct ath_buf *bf;
+ 
+-	bf = list_first_entry(bf_head, struct ath_buf, list);
++	bf = fi->bf;
++	if (!bf)
++		bf = ath_tx_setup_buffer(sc, txq, tid, skb);
++
++	if (!bf)
++		return;
++
++	INIT_LIST_HEAD(&bf_head);
++	list_add_tail(&bf->list, &bf_head);
+ 	bf->bf_state.bf_type &= ~BUF_AMPDU;
+ 
+ 	/* update starting sequence number for subsequent ADDBA request */
+@@ -1492,9 +1519,8 @@ static void ath_tx_send_normal(struct at
+ 		INCR(tid->seq_start, IEEE80211_SEQ_MAX);
+ 
+ 	bf->bf_lastbf = bf;
+-	fi = get_frame_info(bf->bf_mpdu);
+ 	ath_buf_set_rate(sc, bf, fi->framelen);
+-	ath_tx_txqaddbuf(sc, txq, bf_head, false);
++	ath_tx_txqaddbuf(sc, txq, &bf_head, false);
+ 	TX_STAT_INC(txq->axq_qnum, queued);
+ }
+ 
+@@ -1717,6 +1743,10 @@ static void ath_buf_set_rate(struct ath_
+ 
+ }
+ 
++/*
++ * Assign a descriptor (and sequence number if necessary,
++ * and map buffer for DMA. Frees skb on error
++ */
+ static struct ath_buf *ath_tx_setup_buffer(struct ath_softc *sc,
+ 					   struct ath_txq *txq,
+ 					   struct ath_atx_tid *tid,
+@@ -1734,7 +1764,7 @@ static struct ath_buf *ath_tx_setup_buff
+ 	bf = ath_tx_get_buffer(sc);
+ 	if (!bf) {
+ 		ath_dbg(common, ATH_DBG_XMIT, "TX buffers are full\n");
+-		return NULL;
++		goto error;
+ 	}
+ 
+ 	ATH_TXBUF_RESET(bf);
+@@ -1757,7 +1787,7 @@ static struct ath_buf *ath_tx_setup_buff
+ 		ath_err(ath9k_hw_common(sc->sc_ah),
+ 			"dma_mapping_error() on TX\n");
+ 		ath_tx_return_buffer(sc, bf);
+-		return NULL;
++		goto error;
+ 	}
+ 
+ 	frm_type = get_hw_packet_type(skb);
+@@ -1779,18 +1809,20 @@ static struct ath_buf *ath_tx_setup_buff
+ 	fi->bf = bf;
+ 
+ 	return bf;
++
++error:
++	dev_kfree_skb_any(skb);
++	return NULL;
+ }
+ 
+ /* FIXME: tx power */
+-static int ath_tx_start_dma(struct ath_softc *sc, struct sk_buff *skb,
++static void ath_tx_start_dma(struct ath_softc *sc, struct sk_buff *skb,
+ 			     struct ath_tx_control *txctl)
+ {
+ 	struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
+ 	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
+-	struct list_head bf_head;
+ 	struct ath_atx_tid *tid = NULL;
+ 	struct ath_buf *bf;
+-	int ret = 0;
+ 	u8 tidno;
+ 
+ 	spin_lock_bh(&txctl->txq->axq_lock);
+@@ -1803,21 +1835,16 @@ static int ath_tx_start_dma(struct ath_s
+ 		WARN_ON(tid->ac->txq != txctl->txq);
+ 	}
+ 
+-	bf = ath_tx_setup_buffer(sc, txctl->txq, tid, skb);
+-	if (unlikely(!bf)) {
+-		ret = -ENOMEM;
+-		goto out;
+-	}
+-
+ 	if ((tx_info->flags & IEEE80211_TX_CTL_AMPDU) && tid) {
+ 		/*
+ 		 * Try aggregation if it's a unicast data frame
+ 		 * and the destination is HT capable.
+ 		 */
+-		ath_tx_send_ampdu(sc, tid, bf, txctl);
++		ath_tx_send_ampdu(sc, tid, skb, txctl);
+ 	} else {
+-		INIT_LIST_HEAD(&bf_head);
+-		list_add_tail(&bf->list, &bf_head);
++		bf = ath_tx_setup_buffer(sc, txctl->txq, tid, skb);
++		if (!bf)
++			goto out;
+ 
+ 		bf->bf_state.bfs_paprd = txctl->paprd;
+ 
+@@ -1831,12 +1858,11 @@ static int ath_tx_start_dma(struct ath_s
+ 		if (tx_info->flags & IEEE80211_TX_CTL_CLEAR_PS_FILT)
+ 			ath9k_hw_set_clrdmask(sc->sc_ah, bf->bf_desc, true);
+ 
+-		ath_tx_send_normal(sc, txctl->txq, tid, &bf_head);
++		ath_tx_send_normal(sc, txctl->txq, tid, skb);
+ 	}
+ 
+ out:
+ 	spin_unlock_bh(&txctl->txq->axq_lock);
+-	return ret;
+ }
+ 
+ /* Upon failure caller should free skb */
+@@ -1904,7 +1930,8 @@ int ath_tx_start(struct ieee80211_hw *hw
+ 	}
+ 	spin_unlock_bh(&txq->axq_lock);
+ 
+-	return ath_tx_start_dma(sc, skb, txctl);
++	ath_tx_start_dma(sc, skb, txctl);
++	return 0;
+ }
+ 
+ /*****************/
diff --git a/package/mac80211/patches/550-ath9k_limit_qlen.patch b/package/mac80211/patches/550-ath9k_limit_qlen.patch
new file mode 100644
index 0000000000..9e144f39c5
--- /dev/null
+++ b/package/mac80211/patches/550-ath9k_limit_qlen.patch
@@ -0,0 +1,152 @@
+--- a/drivers/net/wireless/ath/ath9k/ath9k.h
++++ b/drivers/net/wireless/ath/ath9k/ath9k.h
+@@ -240,6 +240,7 @@ struct ath_atx_tid {
+ 	struct ath_node *an;
+ 	struct ath_atx_ac *ac;
+ 	unsigned long tx_buf[BITS_TO_LONGS(ATH_TID_MAX_BUFS)];
++	int buf_pending;
+ 	u16 seq_start;
+ 	u16 seq_next;
+ 	u16 baw_size;
+@@ -286,6 +287,9 @@ struct ath_tx_control {
+  *  (axq_qnum).
+  */
+ struct ath_tx {
++	u32 qlen_single;
++	u32 qlen_aggr;
++
+ 	u16 seq_no;
+ 	u32 txqsetup;
+ 	spinlock_t txbuflock;
+--- a/drivers/net/wireless/ath/ath9k/debug.c
++++ b/drivers/net/wireless/ath/ath9k/debug.c
+@@ -1341,6 +1341,10 @@ int ath9k_init_debug(struct ath_hw *ah)
+ 			    sc, &fops_wiphy);
+ 	debugfs_create_file("xmit", S_IRUSR, sc->debug.debugfs_phy, sc,
+ 			    &fops_xmit);
++	debugfs_create_u32("qlen_single", S_IRUSR | S_IWUSR,
++			   sc->debug.debugfs_phy, &sc->tx.qlen_single);
++	debugfs_create_u32("qlen_aggr", S_IRUSR | S_IWUSR,
++			   sc->debug.debugfs_phy, &sc->tx.qlen_aggr);
+ 	debugfs_create_file("stations", S_IRUSR, sc->debug.debugfs_phy, sc,
+ 			    &fops_stations);
+ 	debugfs_create_file("misc", S_IRUSR, sc->debug.debugfs_phy, sc,
+--- a/drivers/net/wireless/ath/ath9k/xmit.c
++++ b/drivers/net/wireless/ath/ath9k/xmit.c
+@@ -348,6 +348,14 @@ static void ath_tx_count_frames(struct a
+ 	}
+ }
+ 
++static struct ath_atx_tid *ath_get_tid(struct ath_node *an, struct sk_buff *skb)
++{
++	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
++	u8 tidno;
++
++	tidno = ieee80211_get_qos_ctl(hdr)[0] & IEEE80211_QOS_CTL_TID_MASK;
++	return ATH_AN_2_TID(an, tidno);
++}
+ 
+ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
+ 				 struct ath_buf *bf, struct list_head *bf_q,
+@@ -438,6 +446,8 @@ static void ath_tx_complete_aggr(struct 
+ 	__skb_queue_head_init(&bf_pending);
+ 
+ 	ath_tx_count_frames(sc, bf, ts, txok, &nframes, &nbad);
++	tid->buf_pending -= nframes;
++
+ 	while (bf) {
+ 		u16 seqno = bf->bf_state.seqno;
+ 
+@@ -834,6 +844,7 @@ static enum ATH_AGGR_STATUS ath_tx_form_
+ 			ath_tx_addto_baw(sc, tid, seqno);
+ 		ath9k_hw_set11n_aggr_middle(sc->sc_ah, bf->bf_desc, ndelim);
+ 
++		tid->buf_pending++;
+ 		__skb_unlink(skb, &tid->buf_q);
+ 		list_add_tail(&bf->list, bf_q);
+ 		if (bf_prev) {
+@@ -1489,6 +1500,8 @@ static void ath_tx_send_ampdu(struct ath
+ 	/* Add sub-frame to BAW */
+ 	ath_tx_addto_baw(sc, tid, bf->bf_state.seqno);
+ 
++	tid->buf_pending++;
++
+ 	/* Queue to h/w without aggregation */
+ 	TX_STAT_INC(txctl->txq->axq_qnum, a_queued_hw);
+ 	bf->bf_lastbf = bf;
+@@ -1817,23 +1830,13 @@ error:
+ 
+ /* FIXME: tx power */
+ static void ath_tx_start_dma(struct ath_softc *sc, struct sk_buff *skb,
+-			     struct ath_tx_control *txctl)
++			     struct ath_tx_control *txctl,
++			     struct ath_atx_tid *tid)
+ {
+ 	struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
+-	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
+-	struct ath_atx_tid *tid = NULL;
+ 	struct ath_buf *bf;
+-	u8 tidno;
+ 
+ 	spin_lock_bh(&txctl->txq->axq_lock);
+-	if ((sc->sc_flags & SC_OP_TXAGGR) && txctl->an &&
+-		ieee80211_is_data_qos(hdr->frame_control)) {
+-		tidno = ieee80211_get_qos_ctl(hdr)[0] &
+-			IEEE80211_QOS_CTL_TID_MASK;
+-		tid = ATH_AN_2_TID(txctl->an, tidno);
+-
+-		WARN_ON(tid->ac->txq != txctl->txq);
+-	}
+ 
+ 	if ((tx_info->flags & IEEE80211_TX_CTL_AMPDU) && tid) {
+ 		/*
+@@ -1875,6 +1878,7 @@ int ath_tx_start(struct ieee80211_hw *hw
+ 	struct ieee80211_vif *vif = info->control.vif;
+ 	struct ath_softc *sc = hw->priv;
+ 	struct ath_txq *txq = txctl->txq;
++	struct ath_atx_tid *tid = NULL;
+ 	int padpos, padsize;
+ 	int frmlen = skb->len + FCS_LEN;
+ 	int q;
+@@ -1907,6 +1911,7 @@ int ath_tx_start(struct ieee80211_hw *hw
+ 
+ 		skb_push(skb, padsize);
+ 		memmove(skb->data, skb->data + padsize, padpos);
++		hdr = (struct ieee80211_hdr *) skb->data;
+ 	}
+ 
+ 	if ((vif && vif->type != NL80211_IFTYPE_AP &&
+@@ -1916,6 +1921,24 @@ int ath_tx_start(struct ieee80211_hw *hw
+ 
+ 	setup_frame_info(hw, skb, frmlen);
+ 
++	if ((sc->sc_flags & SC_OP_TXAGGR) && txctl->an &&
++	    ieee80211_is_data_qos(hdr->frame_control)) {
++		tid = ath_get_tid(txctl->an, skb);
++
++		WARN_ON(tid->ac->txq != txq);
++	}
++
++	if ((info->flags & IEEE80211_TX_CTL_AMPDU) && tid) {
++		if (sc->tx.qlen_aggr > 0 && skb_queue_len(&tid->buf_q) +
++		    tid->buf_pending >= sc->tx.qlen_aggr)
++			return -ENOMEM;
++	} else {
++		if (sc->tx.qlen_single > 0 &&
++		    txq->axq_depth - txq->axq_ampdu_depth >=
++		      sc->tx.qlen_single)
++			return -ENOMEM;
++	}
++
+ 	/*
+ 	 * At this point, the vif, hw_key and sta pointers in the tx control
+ 	 * info are no longer valid (overwritten by the ath_frame_info data.
+@@ -1930,7 +1953,7 @@ int ath_tx_start(struct ieee80211_hw *hw
+ 	}
+ 	spin_unlock_bh(&txq->axq_lock);
+ 
+-	ath_tx_start_dma(sc, skb, txctl);
++	ath_tx_start_dma(sc, skb, txctl, tid);
+ 	return 0;
+ }
+ 
diff --git a/package/mac80211/patches/551-ath9k_sw_retry_reduce.patch b/package/mac80211/patches/551-ath9k_sw_retry_reduce.patch
new file mode 100644
index 0000000000..3bc6edd66f
--- /dev/null
+++ b/package/mac80211/patches/551-ath9k_sw_retry_reduce.patch
@@ -0,0 +1,61 @@
+--- a/drivers/net/wireless/ath/ath9k/xmit.c
++++ b/drivers/net/wireless/ath/ath9k/xmit.c
+@@ -260,13 +260,16 @@ static void ath_tid_drain(struct ath_sof
+ }
+ 
+ static void ath_tx_set_retry(struct ath_softc *sc, struct ath_txq *txq,
+-			     struct sk_buff *skb)
++			     struct sk_buff *skb, int count)
+ {
+ 	struct ath_frame_info *fi = get_frame_info(skb);
+ 	struct ieee80211_hdr *hdr;
++	int prev = fi->retries;
+ 
+ 	TX_STAT_INC(txq->axq_qnum, a_retries);
+-	if (fi->retries++ > 0)
++	fi->retries += count;
++
++	if (prev > 0)
+ 		return;
+ 
+ 	hdr = (struct ieee80211_hdr *)skb->data;
+@@ -380,6 +383,7 @@ static void ath_tx_complete_aggr(struct 
+ 	int nframes;
+ 	u8 tidno;
+ 	bool clear_filter;
++	int i, retries;
+ 
+ 	skb = bf->bf_mpdu;
+ 	hdr = (struct ieee80211_hdr *)skb->data;
+@@ -388,6 +392,10 @@ static void ath_tx_complete_aggr(struct 
+ 
+ 	memcpy(rates, tx_info->control.rates, sizeof(rates));
+ 
++	retries = ts->ts_longretry + 1;
++	for (i = 0; i < ts->ts_rateindex; i++)
++		retries += rates[i].count;
++
+ 	rcu_read_lock();
+ 
+ 	sta = ieee80211_find_sta_by_ifaddr(hw, hdr->addr1, hdr->addr2);
+@@ -475,7 +483,8 @@ static void ath_tx_complete_aggr(struct 
+ 			} else if (fi->retries < ATH_MAX_SW_RETRIES) {
+ 				if (!(ts->ts_status & ATH9K_TXERR_FILT) ||
+ 				    !an->sleeping)
+-					ath_tx_set_retry(sc, txq, bf->bf_mpdu);
++					ath_tx_set_retry(sc, txq, bf->bf_mpdu,
++							 retries);
+ 
+ 				clear_filter = true;
+ 				txpending = 1;
+--- a/drivers/net/wireless/ath/ath9k/ath9k.h
++++ b/drivers/net/wireless/ath/ath9k/ath9k.h
+@@ -543,7 +543,7 @@ struct ath_ant_comb {
+ #define DEFAULT_CACHELINE       32
+ #define ATH_REGCLASSIDS_MAX     10
+ #define ATH_CABQ_READY_TIME     80      /* % of beacon interval */
+-#define ATH_MAX_SW_RETRIES      10
++#define ATH_MAX_SW_RETRIES      20
+ #define ATH_CHAN_MAX            255
+ 
+ #define ATH_TXPOWER_MAX         100     /* .5 dBm units */
diff --git a/package/mac80211/patches/560-mac80211_defer_bar_tx.patch b/package/mac80211/patches/560-mac80211_defer_bar_tx.patch
new file mode 100644
index 0000000000..9bf89183e8
--- /dev/null
+++ b/package/mac80211/patches/560-mac80211_defer_bar_tx.patch
@@ -0,0 +1,90 @@
+--- a/net/mac80211/sta_info.h
++++ b/net/mac80211/sta_info.h
+@@ -84,6 +84,8 @@ enum ieee80211_sta_info_flags {
+  * @stop_initiator: initiator of a session stop
+  * @tx_stop: TX DelBA frame when stopping
+  * @buf_size: reorder buffer size at receiver
++ * @failed_bar_ssn: ssn of the last failed BAR tx attempt
++ * @bar_pending: BAR needs to be re-sent
+  *
+  * This structure's lifetime is managed by RCU, assignments to
+  * the array holding it must hold the aggregation mutex.
+@@ -104,6 +106,9 @@ struct tid_ampdu_tx {
+ 	u8 stop_initiator;
+ 	bool tx_stop;
+ 	u8 buf_size;
++
++	u16 failed_bar_ssn;
++	bool bar_pending;
+ };
+ 
+ /**
+--- a/net/mac80211/status.c
++++ b/net/mac80211/status.c
+@@ -127,12 +127,32 @@ static void ieee80211_handle_filtered_fr
+ 	dev_kfree_skb(skb);
+ }
+ 
++static void ieee80211_check_pending_bar(struct sta_info *sta, u8 *addr, u8 tid)
++{
++	struct tid_ampdu_tx *tid_tx;
++
++	tid_tx = rcu_dereference(sta->ampdu_mlme.tid_tx[tid]);
++	if (!tid_tx || !tid_tx->bar_pending)
++		return;
++
++	tid_tx->bar_pending = false;
++	ieee80211_send_bar(sta->sdata, addr, tid, tid_tx->failed_bar_ssn);
++}
++
+ static void ieee80211_frame_acked(struct sta_info *sta, struct sk_buff *skb)
+ {
+ 	struct ieee80211_mgmt *mgmt = (void *) skb->data;
+ 	struct ieee80211_local *local = sta->local;
+ 	struct ieee80211_sub_if_data *sdata = sta->sdata;
+ 
++	if (ieee80211_is_data_qos(mgmt->frame_control)) {
++		struct ieee80211_hdr *hdr = (void *) skb->data;
++		u8 *qc = ieee80211_get_qos_ctl(hdr);
++		u16 tid = qc[0] & 0xf;
++
++		ieee80211_check_pending_bar(sta, hdr->addr1, tid);
++	}
++
+ 	if (ieee80211_is_action(mgmt->frame_control) &&
+ 	    sdata->vif.type == NL80211_IFTYPE_STATION &&
+ 	    mgmt->u.action.category == WLAN_CATEGORY_HT &&
+@@ -161,6 +181,18 @@ static void ieee80211_frame_acked(struct
+ 	}
+ }
+ 
++static void ieee80211_set_bar_pending(struct sta_info *sta, u8 tid, u16 ssn)
++{
++	struct tid_ampdu_tx *tid_tx;
++
++	tid_tx = rcu_dereference(sta->ampdu_mlme.tid_tx[tid]);
++	if (!tid_tx)
++		return;
++
++	tid_tx->failed_bar_ssn = ssn;
++	tid_tx->bar_pending = true;
++}
++
+ /*
+  * Use a static threshold for now, best value to be determined
+  * by testing ...
+@@ -254,10 +286,13 @@ void ieee80211_tx_status(struct ieee8021
+ 			 */
+ 			bar = (struct ieee80211_bar *) skb->data;
+ 			if (!(bar->control & IEEE80211_BAR_CTRL_MULTI_TID)) {
++				u16 ssn = le16_to_cpu(bar->start_seq_num);
++
+ 				tid = (bar->control &
+ 				       IEEE80211_BAR_CTRL_TID_INFO_MASK) >>
+ 				      IEEE80211_BAR_CTRL_TID_INFO_SHIFT;
+-				ieee80211_stop_tx_ba_session(&sta->sta, tid);
++
++				ieee80211_set_bar_pending(sta, tid, ssn);
+ 			}
+ 		}
+ 
diff --git a/package/mac80211/patches/604-rt2x00-add-CONFIG_RT2X00_LIB_EEPROM-option.patch b/package/mac80211/patches/604-rt2x00-add-CONFIG_RT2X00_LIB_EEPROM-option.patch
index 9e30620fda..f607ea17b2 100644
--- a/package/mac80211/patches/604-rt2x00-add-CONFIG_RT2X00_LIB_EEPROM-option.patch
+++ b/package/mac80211/patches/604-rt2x00-add-CONFIG_RT2X00_LIB_EEPROM-option.patch
@@ -1,6 +1,6 @@
 --- a/config.mk
 +++ b/config.mk
-@@ -581,6 +581,7 @@ CONFIG_RT2X00=y
+@@ -574,6 +574,7 @@ CONFIG_RT2X00=y
  CONFIG_RT2X00_LIB=m
  CONFIG_RT2800_LIB=m
  CONFIG_RT2X00_LIB_FIRMWARE=y
diff --git a/package/mac80211/patches/700-mwl8k-missing-pci-id-for-WNR854T.patch b/package/mac80211/patches/700-mwl8k-missing-pci-id-for-WNR854T.patch
index c95e2a5161..9bc8a33990 100644
--- a/package/mac80211/patches/700-mwl8k-missing-pci-id-for-WNR854T.patch
+++ b/package/mac80211/patches/700-mwl8k-missing-pci-id-for-WNR854T.patch
@@ -1,6 +1,6 @@
 --- a/drivers/net/wireless/mwl8k.c
 +++ b/drivers/net/wireless/mwl8k.c
-@@ -5195,6 +5195,7 @@ MODULE_FIRMWARE("mwl8k/fmimage_8366.fw")
+@@ -5192,6 +5192,7 @@ MODULE_FIRMWARE("mwl8k/fmimage_8366.fw")
  MODULE_FIRMWARE(MWL8K_8366_AP_FW(MWL8K_8366_AP_FW_API));
  
  static DEFINE_PCI_DEVICE_TABLE(mwl8k_pci_id_table) = {
diff --git a/package/mac80211/patches/800-b43-gpio-mask-module-option.patch b/package/mac80211/patches/800-b43-gpio-mask-module-option.patch
index d61e11af85..a9958829f8 100644
--- a/package/mac80211/patches/800-b43-gpio-mask-module-option.patch
+++ b/package/mac80211/patches/800-b43-gpio-mask-module-option.patch
@@ -1,6 +1,6 @@
 --- a/drivers/net/wireless/b43/b43.h
 +++ b/drivers/net/wireless/b43/b43.h
-@@ -746,6 +746,7 @@ struct b43_wldev {
+@@ -751,6 +751,7 @@ struct b43_wldev {
  	bool qos_enabled;		/* TRUE, if QoS is used. */
  	bool hwcrypto_enabled;		/* TRUE, if HW crypto acceleration is enabled. */
  	bool use_pio;			/* TRUE if next init should use PIO */
@@ -10,7 +10,7 @@
  	struct b43_phy phy;
 --- a/drivers/net/wireless/b43/main.c
 +++ b/drivers/net/wireless/b43/main.c
-@@ -75,6 +75,11 @@ MODULE_FIRMWARE("b43/ucode16_mimo.fw");
+@@ -74,6 +74,11 @@ MODULE_FIRMWARE("b43/ucode16_mimo.fw");
  MODULE_FIRMWARE("b43/ucode5.fw");
  MODULE_FIRMWARE("b43/ucode9.fw");
  
@@ -22,7 +22,7 @@
  static int modparam_bad_frames_preempt;
  module_param_named(bad_frames_preempt, modparam_bad_frames_preempt, int, 0444);
  MODULE_PARM_DESC(bad_frames_preempt,
-@@ -2671,10 +2676,10 @@ static int b43_gpio_init(struct b43_wlde
+@@ -2676,10 +2681,10 @@ static int b43_gpio_init(struct b43_wlde
  		    & ~B43_MACCTL_GPOUTSMSK);
  
  	b43_write16(dev, B43_MMIO_GPIO_MASK, b43_read16(dev, B43_MMIO_GPIO_MASK)
@@ -35,16 +35,3 @@
  	if (dev->dev->chip_id == 0x4301) {
  		mask |= 0x0060;
  		set |= 0x0060;
-@@ -5441,10 +5446,10 @@ static void b43_print_driverinfo(void)
- 	feat_sdio = "S";
- #endif
- 	printk(KERN_INFO "Broadcom 43xx driver loaded "
--	       "[ Features: %s%s%s%s%s, Firmware-ID: "
-+	       "[ Features: %s%s%s%s%s, GPIO LED Mask: 0x%04x, Firmware-ID: "
- 	       B43_SUPPORTED_FIRMWARE_ID " ]\n",
- 	       feat_pci, feat_pcmcia, feat_nphy,
--	       feat_leds, feat_sdio);
-+	       feat_leds, feat_sdio, modparam_gpiomask);
- }
- 
- static int __init b43_init(void)
diff --git a/package/mac80211/patches/810-b43_no_pio.patch b/package/mac80211/patches/810-b43_no_pio.patch
index 1d0382cd20..33c986534c 100644
--- a/package/mac80211/patches/810-b43_no_pio.patch
+++ b/package/mac80211/patches/810-b43_no_pio.patch
@@ -11,7 +11,7 @@
  b43-$(CONFIG_B43_PCMCIA)	+= pcmcia.o
 --- a/drivers/net/wireless/b43/main.c
 +++ b/drivers/net/wireless/b43/main.c
-@@ -1884,9 +1884,11 @@ static void b43_do_interrupt_thread(stru
+@@ -1883,9 +1883,11 @@ static void b43_do_interrupt_thread(stru
  			       dma_reason[4], dma_reason[5]);
  			b43err(dev->wl, "This device does not support DMA "
  			       "on your system. It will now be switched to PIO.\n");
-- 
cgit v1.2.3