mac80211: update to wireless-testing 2011-08-26
authorFelix Fietkau <nbd@openwrt.org>
Sat, 27 Aug 2011 21:57:07 +0000 (21:57 +0000)
committerFelix Fietkau <nbd@openwrt.org>
Sat, 27 Aug 2011 21:57:07 +0000 (21:57 +0000)
SVN-Revision: 28093

37 files changed:
package/mac80211/Makefile
package/mac80211/patches/000-disable_ethernet.patch [new file with mode: 0644]
package/mac80211/patches/001-disable_b44.patch
package/mac80211/patches/002-disable_rfkill.patch
package/mac80211/patches/005-disable_ssb_build.patch
package/mac80211/patches/006-disable_bcma_build.patch
package/mac80211/patches/007-remove_misc_drivers.patch
package/mac80211/patches/010-no_pcmcia.patch
package/mac80211/patches/011-no_sdio.patch
package/mac80211/patches/013-disable_b43_nphy.patch
package/mac80211/patches/015-remove-rt2x00-options.patch
package/mac80211/patches/017-remove_ath9k_rc.patch
package/mac80211/patches/018-revert_printk_va_format.patch
package/mac80211/patches/019-remove_ath5k_pci_option.patch
package/mac80211/patches/022-atomic64_backport.patch
package/mac80211/patches/110-disable_usb_compat.patch
package/mac80211/patches/300-pending_work.patch
package/mac80211/patches/310-ibss_ht.patch
package/mac80211/patches/400-ath_move_debug_code.patch [new file with mode: 0644]
package/mac80211/patches/410-ath9k_allow_adhoc_and_ap.patch
package/mac80211/patches/510-ath9k_intr_mitigation_tweak.patch
package/mac80211/patches/530-mac80211_cur_txpower.patch
package/mac80211/patches/531-ath9k_cur_txpower.patch
package/mac80211/patches/540-ath9k_sw_retry_reduce.patch [deleted file]
package/mac80211/patches/540-ath9k_txkeyidx_u8.patch [new file with mode: 0644]
package/mac80211/patches/541-ath9k_aggr_queue_cleanup.patch
package/mac80211/patches/542-ath9k_limit_qlen.patch [deleted file]
package/mac80211/patches/542-ath9k_move_seqno.patch [new file with mode: 0644]
package/mac80211/patches/543-ath9k_move_seqno_alloc.patch [new file with mode: 0644]
package/mac80211/patches/544-ath9k_defer_buffer_setup.patch [new file with mode: 0644]
package/mac80211/patches/550-ath9k_limit_qlen.patch [new file with mode: 0644]
package/mac80211/patches/551-ath9k_sw_retry_reduce.patch [new file with mode: 0644]
package/mac80211/patches/560-mac80211_defer_bar_tx.patch [new file with mode: 0644]
package/mac80211/patches/604-rt2x00-add-CONFIG_RT2X00_LIB_EEPROM-option.patch
package/mac80211/patches/700-mwl8k-missing-pci-id-for-WNR854T.patch
package/mac80211/patches/800-b43-gpio-mask-module-option.patch
package/mac80211/patches/810-b43_no_pio.patch

index 2faae57..d4bbff4 100644 (file)
@@ -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 (file)
index 0000000..f89fa53
--- /dev/null
@@ -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/
index 547a453..a4008bf 100644 (file)
@@ -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
  
index 887b995..61e8b96 100644 (file)
@@ -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
index 04bf827..d5578d1 100644 (file)
@@ -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
  
index 93d00cd..17eff65 100644 (file)
@@ -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
  
 +# 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
index cdf9e03..103eb7b 100644 (file)
@@ -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
index f6b89d8..d6246b7 100644 (file)
@@ -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
index bb6be23..366488a 100644 (file)
@@ -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
  
index ebbf912..8baaaca 100644 (file)
@@ -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
index 3bed5b2..e449c23 100644 (file)
@@ -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
index d275283..f341556 100644 (file)
@@ -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.
index 8b7e644..6aff41a 100644 (file)
@@ -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, ...)
  {
index 07e3054..9de0418 100644 (file)
@@ -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
  
index 17df9c9..ab77f76 100644 (file)
@@ -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 }, }
  
index dda9699..7678e3b 100644 (file)
@@ -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.
index 2b45719..01df8f7 100644 (file)
@@ -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
                        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 &&
                        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 &&
                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:
        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;
        }
index 0a770d2..eb1c8fc 100644 (file)
@@ -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]);
        }
  
  
        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,
                                        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);
  
  /* 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);
  #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;
        }
  
  
        /*
         * 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);
        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 &&
                        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 (file)
index 0000000..2584298
--- /dev/null
@@ -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
index 4fb85ab..13f11bb 100644 (file)
@@ -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);
  
index 834e1a2..e2bfde4 100644 (file)
@@ -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) {
index 5e99c03..a8a042b 100644 (file)
@@ -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);
  
index 26085c1..f0de43e 100644 (file)
@@ -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 (file)
index d34b851..0000000
+++ /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 (file)
index 0000000..2b59533
--- /dev/null
@@ -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;
index e196ced..27c144f 100644 (file)
@@ -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;
        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 
                }
        }
  
  
        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.
                 */
  
                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);
                                } 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
                         */
                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)
  
                /* 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);
                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;
  
  
        *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 {
                        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);
  
                        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;
  
                        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
                         */
                                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
         */
            !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);
                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);
  
  
        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 (file)
index f05db0a..0000000
+++ /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 (file)
index 0000000..c0d293a
--- /dev/null
@@ -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 (file)
index 0000000..8de5fd2
--- /dev/null
@@ -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 (file)
index 0000000..d91ced0
--- /dev/null
@@ -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 (file)
index 0000000..9e144f3
--- /dev/null
@@ -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 (file)
index 0000000..3bc6edd
--- /dev/null
@@ -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 (file)
index 0000000..9bf8918
--- /dev/null
@@ -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);
+                       }
+               }
index 9e30620..f607ea1 100644 (file)
@@ -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
index c95e2a5..9bc8a33 100644 (file)
@@ -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) = {
index d61e11a..a995882 100644 (file)
@@ -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)
        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)
index 1d0382c..33c9865 100644 (file)
@@ -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");