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)
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) \
--- /dev/null
+--- 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/
--- 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
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
--- 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),
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
# 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
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
--- 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
+
--- 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
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
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
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
--- 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
--- 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
--- a/config.mk
+++ b/config.mk
-@@ -329,7 +329,7 @@ CONFIG_RTL8180=m
+@@ -330,7 +330,7 @@ CONFIG_RTL8180=m
CONFIG_ADM8211=m
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
--- 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.
--- 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, ...)
{
--- 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, ...)
{
--- 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
--- 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
+
--- 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 }, }
#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.
---- 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;
}
--- 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;
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);
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,
--- /dev/null
+--- 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
--- 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
}
}
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);
--- 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) {
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);
--- 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;
}
/*
* 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);
+++ /dev/null
---- 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 */
--- /dev/null
+--- 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;
+
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 {
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;
+++ /dev/null
---- 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;
- }
--- /dev/null
+--- 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);
+ }
+
--- /dev/null
+--- 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);
+ }
+
+ /*****************/
--- /dev/null
+--- 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;
+ }
+
+ /*****************/
--- /dev/null
+--- 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;
+ }
+
--- /dev/null
+--- 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 */
--- /dev/null
+--- 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);
+ }
+ }
+
--- 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
--- 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) = {
--- 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 */
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");
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)
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");