aboutsummaryrefslogtreecommitdiffstats
path: root/package
diff options
context:
space:
mode:
authorFelix Fietkau <nbd@openwrt.org>2011-03-13 18:38:37 +0000
committerFelix Fietkau <nbd@openwrt.org>2011-03-13 18:38:37 +0000
commit66a6f82ee3704c72b3c6ea268ac71eed883722a5 (patch)
tree5572c7175f7b0854994964a55c03050c4471ef8a /package
parenta08bd03fadb1950c149a03978e3abab7786cdcc5 (diff)
downloadupstream-66a6f82ee3704c72b3c6ea268ac71eed883722a5.tar.gz
upstream-66a6f82ee3704c72b3c6ea268ac71eed883722a5.tar.bz2
upstream-66a6f82ee3704c72b3c6ea268ac71eed883722a5.zip
mac80211: update to wireless-testing 2011-03-11
SVN-Revision: 26128
Diffstat (limited to 'package')
-rw-r--r--package/mac80211/Makefile4
-rw-r--r--package/mac80211/patches/030-backport_93c86_eeprom.patch6
-rw-r--r--package/mac80211/patches/050-fix_missing_include.patch10
-rw-r--r--package/mac80211/patches/300-ath9k_gpio_settings.patch4
-rw-r--r--package/mac80211/patches/310-pending_work.patch366
-rw-r--r--package/mac80211/patches/401-ath9k-dont-register-leds-on-ar9100.patch14
-rw-r--r--package/mac80211/patches/407-ath9k-override-mac-address-from-platform-data.patch6
-rw-r--r--package/mac80211/patches/409-ath9k_platform_settings.patch8
-rw-r--r--package/mac80211/patches/500-ath9k_eeprom_debugfs.patch6
-rw-r--r--package/mac80211/patches/510-ath9k_intr_mitigation_tweak.patch (renamed from package/mac80211/patches/520-ath9k_intr_mitigation_tweak.patch)0
-rw-r--r--package/mac80211/patches/510-ath9k_led_cleanup.patch303
-rw-r--r--package/mac80211/patches/520-mac80211_drv_tim_override.patch (renamed from package/mac80211/patches/530-mac80211_drv_tim_override.patch)2
-rw-r--r--package/mac80211/patches/521-ath9k_fix_ap_ps_buffering.patch (renamed from package/mac80211/patches/531-ath9k_fix_ap_ps_buffering.patch)12
-rw-r--r--package/mac80211/patches/522-ath9k_remove_pending_frames_workaround.patch (renamed from package/mac80211/patches/532-ath9k_remove_pending_frames_workaround.patch)2
-rw-r--r--package/mac80211/patches/530-mac80211_redirect_vlan_eap_frames.patch (renamed from package/mac80211/patches/580-mac80211_redirect_vlan_eap_frames.patch)0
-rw-r--r--package/mac80211/patches/540-mac80211_add_rx_rate.patch232
-rw-r--r--package/mac80211/patches/550-ath9k_no_vif_promisc_handling.patch13
-rw-r--r--package/mac80211/patches/560-mac80211_minstrel_ht_sampling_fix.patch50
-rw-r--r--package/mac80211/patches/570-ath9k_fix_reg_bit_macros.patch14
-rw-r--r--package/mac80211/patches/571-ath9k_fix_dma_stop.patch72
-rw-r--r--package/mac80211/patches/572-ath9k_fix_tx_flush.patch141
-rw-r--r--package/mac80211/patches/573-ath9k_beacon_stop.patch143
-rw-r--r--package/mac80211/patches/581-mac80211_chantype_change_fix.patch12
-rw-r--r--package/mac80211/patches/590-ath9k_tid_cleanup_send_bar.patch11
-rw-r--r--package/mac80211/patches/700-mwl8k-missing-pci-id-for-WNR854T.patch2
-rw-r--r--package/mac80211/patches/710-p54_rssi_crash_fix.patch18
-rw-r--r--package/mac80211/patches/720-mac80211-print-restart-warning.patch14
-rw-r--r--package/mac80211/patches/721-mac80211-fix-scan-race.patch141
28 files changed, 396 insertions, 1210 deletions
diff --git a/package/mac80211/Makefile b/package/mac80211/Makefile
index c78a6cb0af..46293696c3 100644
--- a/package/mac80211/Makefile
+++ b/package/mac80211/Makefile
@@ -10,10 +10,10 @@ include $(INCLUDE_DIR)/kernel.mk
PKG_NAME:=mac80211
-PKG_VERSION:=2011-02-25
+PKG_VERSION:=2011-03-11
PKG_RELEASE:=1
PKG_SOURCE_URL:=http://mirror2.openwrt.org/sources
-PKG_MD5SUM:=c0242cc152a157902ff60fe05d1773b2
+PKG_MD5SUM:=123b9220fa2b016979b7b3874f349643
PKG_SOURCE:=compat-wireless-$(PKG_VERSION).tar.bz2
PKG_BUILD_DIR:=$(KERNEL_BUILD_DIR)/compat-wireless-$(PKG_VERSION)
diff --git a/package/mac80211/patches/030-backport_93c86_eeprom.patch b/package/mac80211/patches/030-backport_93c86_eeprom.patch
index 0415e5f1fc..30ff85ed05 100644
--- a/package/mac80211/patches/030-backport_93c86_eeprom.patch
+++ b/package/mac80211/patches/030-backport_93c86_eeprom.patch
@@ -1,8 +1,8 @@
--- a/include/linux/compat-2.6.36.h
+++ b/include/linux/compat-2.6.36.h
-@@ -102,6 +102,8 @@ int no_printk(const char *s, ...) { retu
- #define alloc_workqueue(name, flags, max_active) __create_workqueue(name, flags, max_active, 0)
- #endif
+@@ -104,6 +104,8 @@ int no_printk(const char *s, ...) { retu
+
+ #define PCI_EEPROM_WIDTH_93C86 8
+#define PCI_EEPROM_WIDTH_93C86 8
+
diff --git a/package/mac80211/patches/050-fix_missing_include.patch b/package/mac80211/patches/050-fix_missing_include.patch
deleted file mode 100644
index 458ff4d864..0000000000
--- a/package/mac80211/patches/050-fix_missing_include.patch
+++ /dev/null
@@ -1,10 +0,0 @@
---- a/compat/compat-2.6.39.c
-+++ b/compat/compat-2.6.39.c
-@@ -10,6 +10,7 @@
-
- #include <linux/compat.h>
- #include <linux/tty.h>
-+#include <linux/sched.h>
-
- /*
- * Termios Helper Methods
diff --git a/package/mac80211/patches/300-ath9k_gpio_settings.patch b/package/mac80211/patches/300-ath9k_gpio_settings.patch
index e38b572e5a..af2057759e 100644
--- a/package/mac80211/patches/300-ath9k_gpio_settings.patch
+++ b/package/mac80211/patches/300-ath9k_gpio_settings.patch
@@ -1,7 +1,7 @@
--- a/drivers/net/wireless/ath/ath9k/debug.c
+++ b/drivers/net/wireless/ath/ath9k/debug.c
-@@ -1091,6 +1091,12 @@ int ath9k_init_debug(struct ath_hw *ah)
- sc->debug.debugfs_phy, &ah->config.cwm_ignore_extcca))
+@@ -1145,6 +1145,12 @@ int ath9k_init_debug(struct ath_hw *ah)
+ sc, &fops_regdump))
goto err;
+ debugfs_create_u32("gpio_mask", S_IRUSR | S_IWUSR,
diff --git a/package/mac80211/patches/310-pending_work.patch b/package/mac80211/patches/310-pending_work.patch
new file mode 100644
index 0000000000..57dcecaf10
--- /dev/null
+++ b/package/mac80211/patches/310-pending_work.patch
@@ -0,0 +1,366 @@
+--- a/drivers/net/wireless/ath/ath9k/ath9k.h
++++ b/drivers/net/wireless/ath/ath9k/ath9k.h
+@@ -189,7 +189,6 @@ struct ath_txq {
+ u32 axq_ampdu_depth;
+ bool stopped;
+ bool axq_tx_inprogress;
+- bool txq_flush_inprogress;
+ struct list_head axq_acq;
+ struct list_head txq_fifo[ATH_TXFIFO_DEPTH];
+ struct list_head txq_fifo_pending;
+--- a/drivers/net/wireless/ath/ath9k/beacon.c
++++ b/drivers/net/wireless/ath/ath9k/beacon.c
+@@ -373,6 +373,7 @@ void ath_beacon_tasklet(unsigned long da
+ ath_dbg(common, ATH_DBG_BSTUCK,
+ "missed %u consecutive beacons\n",
+ sc->beacon.bmisscnt);
++ ath9k_hw_stop_dma_queue(ah, sc->beacon.beaconq);
+ ath9k_hw_bstuck_nfcal(ah);
+ } else if (sc->beacon.bmisscnt >= BSTUCK_THRESH) {
+ ath_dbg(common, ATH_DBG_BSTUCK,
+@@ -450,16 +451,6 @@ void ath_beacon_tasklet(unsigned long da
+ sc->beacon.updateslot = OK;
+ }
+ if (bfaddr != 0) {
+- /*
+- * Stop any current dma and put the new frame(s) on the queue.
+- * This should never fail since we check above that no frames
+- * are still pending on the queue.
+- */
+- if (!ath9k_hw_stoptxdma(ah, sc->beacon.beaconq)) {
+- ath_err(common, "beacon queue %u did not stop?\n",
+- sc->beacon.beaconq);
+- }
+-
+ /* NB: cabq traffic should already be queued and primed */
+ ath9k_hw_puttxbuf(ah, sc->beacon.beaconq, bfaddr);
+ ath9k_hw_txstart(ah, sc->beacon.beaconq);
+@@ -780,7 +771,7 @@ void ath9k_set_beaconing_status(struct a
+ ah->imask &= ~ATH9K_INT_SWBA;
+ ath9k_hw_set_interrupts(ah, ah->imask);
+ tasklet_kill(&sc->bcon_tasklet);
+- ath9k_hw_stoptxdma(ah, sc->beacon.beaconq);
++ ath9k_hw_stop_dma_queue(ah, sc->beacon.beaconq);
+ }
+ ath9k_ps_restore(sc);
+ }
+--- a/drivers/net/wireless/ath/ath9k/hw.h
++++ b/drivers/net/wireless/ath/ath9k/hw.h
+@@ -95,9 +95,9 @@
+ #define REG_READ_FIELD(_a, _r, _f) \
+ (((REG_READ(_a, _r) & _f) >> _f##_S))
+ #define REG_SET_BIT(_a, _r, _f) \
+- REG_WRITE(_a, _r, REG_READ(_a, _r) | _f)
++ REG_WRITE(_a, _r, REG_READ(_a, _r) | (_f))
+ #define REG_CLR_BIT(_a, _r, _f) \
+- REG_WRITE(_a, _r, REG_READ(_a, _r) & ~_f)
++ REG_WRITE(_a, _r, REG_READ(_a, _r) & ~(_f))
+
+ #define DO_DELAY(x) do { \
+ if ((++(x) % 64) == 0) \
+--- a/drivers/net/wireless/ath/ath9k/mac.c
++++ b/drivers/net/wireless/ath/ath9k/mac.c
+@@ -143,84 +143,59 @@ bool ath9k_hw_updatetxtriglevel(struct a
+ }
+ EXPORT_SYMBOL(ath9k_hw_updatetxtriglevel);
+
+-bool ath9k_hw_stoptxdma(struct ath_hw *ah, u32 q)
++void ath9k_hw_abort_tx_dma(struct ath_hw *ah)
+ {
+-#define ATH9K_TX_STOP_DMA_TIMEOUT 4000 /* usec */
+-#define ATH9K_TIME_QUANTUM 100 /* usec */
+- struct ath_common *common = ath9k_hw_common(ah);
+- struct ath9k_hw_capabilities *pCap = &ah->caps;
+- struct ath9k_tx_queue_info *qi;
+- u32 tsfLow, j, wait;
+- u32 wait_time = ATH9K_TX_STOP_DMA_TIMEOUT / ATH9K_TIME_QUANTUM;
++ int i, q;
+
+- if (q >= pCap->total_queues) {
+- ath_dbg(common, ATH_DBG_QUEUE,
+- "Stopping TX DMA, invalid queue: %u\n", q);
+- return false;
+- }
++ REG_WRITE(ah, AR_Q_TXD, AR_Q_TXD_M);
+
+- qi = &ah->txq[q];
+- if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
+- ath_dbg(common, ATH_DBG_QUEUE,
+- "Stopping TX DMA, inactive queue: %u\n", q);
+- return false;
+- }
++ REG_SET_BIT(ah, AR_PCU_MISC, AR_PCU_FORCE_QUIET_COLL | AR_PCU_CLEAR_VMF);
++ REG_SET_BIT(ah, AR_DIAG_SW, AR_DIAG_FORCE_CH_IDLE_HIGH);
++ REG_SET_BIT(ah, AR_D_GBL_IFS_MISC, AR_D_GBL_IFS_MISC_IGNORE_BACKOFF);
+
+- REG_WRITE(ah, AR_Q_TXD, 1 << q);
++ for (q = 0; q < AR_NUM_QCU; q++) {
++ for (i = 0; i < 1000; i++) {
++ if (i)
++ udelay(5);
+
+- for (wait = wait_time; wait != 0; wait--) {
+- if (ath9k_hw_numtxpending(ah, q) == 0)
+- break;
+- udelay(ATH9K_TIME_QUANTUM);
++ if (!ath9k_hw_numtxpending(ah, q))
++ break;
++ }
+ }
+
+- if (ath9k_hw_numtxpending(ah, q)) {
+- ath_dbg(common, ATH_DBG_QUEUE,
+- "%s: Num of pending TX Frames %d on Q %d\n",
+- __func__, ath9k_hw_numtxpending(ah, q), q);
+-
+- for (j = 0; j < 2; j++) {
+- tsfLow = REG_READ(ah, AR_TSF_L32);
+- REG_WRITE(ah, AR_QUIET2,
+- SM(10, AR_QUIET2_QUIET_DUR));
+- REG_WRITE(ah, AR_QUIET_PERIOD, 100);
+- REG_WRITE(ah, AR_NEXT_QUIET_TIMER, tsfLow >> 10);
+- REG_SET_BIT(ah, AR_TIMER_MODE,
+- AR_QUIET_TIMER_EN);
+-
+- if ((REG_READ(ah, AR_TSF_L32) >> 10) == (tsfLow >> 10))
+- break;
++ REG_CLR_BIT(ah, AR_PCU_MISC, AR_PCU_FORCE_QUIET_COLL | AR_PCU_CLEAR_VMF);
++ REG_CLR_BIT(ah, AR_DIAG_SW, AR_DIAG_FORCE_CH_IDLE_HIGH);
++ REG_CLR_BIT(ah, AR_D_GBL_IFS_MISC, AR_D_GBL_IFS_MISC_IGNORE_BACKOFF);
+
+- ath_dbg(common, ATH_DBG_QUEUE,
+- "TSF has moved while trying to set quiet time TSF: 0x%08x\n",
+- tsfLow);
+- }
++ REG_WRITE(ah, AR_Q_TXD, 0);
++}
++EXPORT_SYMBOL(ath9k_hw_abort_tx_dma);
+
+- REG_SET_BIT(ah, AR_DIAG_SW, AR_DIAG_FORCE_CH_IDLE_HIGH);
++bool ath9k_hw_stop_dma_queue(struct ath_hw *ah, u32 q)
++{
++#define ATH9K_TX_STOP_DMA_TIMEOUT 1000 /* usec */
++#define ATH9K_TIME_QUANTUM 100 /* usec */
++ int wait_time = ATH9K_TX_STOP_DMA_TIMEOUT / ATH9K_TIME_QUANTUM;
++ int wait;
+
+- udelay(200);
+- REG_CLR_BIT(ah, AR_TIMER_MODE, AR_QUIET_TIMER_EN);
++ REG_WRITE(ah, AR_Q_TXD, 1 << q);
+
+- wait = wait_time;
+- while (ath9k_hw_numtxpending(ah, q)) {
+- if ((--wait) == 0) {
+- ath_err(common,
+- "Failed to stop TX DMA in 100 msec after killing last frame\n");
+- break;
+- }
++ for (wait = wait_time; wait != 0; wait--) {
++ if (wait != wait_time)
+ udelay(ATH9K_TIME_QUANTUM);
+- }
+
+- REG_CLR_BIT(ah, AR_DIAG_SW, AR_DIAG_FORCE_CH_IDLE_HIGH);
++ if (ath9k_hw_numtxpending(ah, q) == 0)
++ break;
+ }
+
+ REG_WRITE(ah, AR_Q_TXD, 0);
++
+ return wait != 0;
+
+ #undef ATH9K_TX_STOP_DMA_TIMEOUT
+ #undef ATH9K_TIME_QUANTUM
+ }
+-EXPORT_SYMBOL(ath9k_hw_stoptxdma);
++EXPORT_SYMBOL(ath9k_hw_stop_dma_queue);
+
+ void ath9k_hw_gettxintrtxqs(struct ath_hw *ah, u32 *txqs)
+ {
+--- a/drivers/net/wireless/ath/ath9k/mac.h
++++ b/drivers/net/wireless/ath/ath9k/mac.h
+@@ -676,7 +676,8 @@ void ath9k_hw_txstart(struct ath_hw *ah,
+ void ath9k_hw_cleartxdesc(struct ath_hw *ah, void *ds);
+ u32 ath9k_hw_numtxpending(struct ath_hw *ah, u32 q);
+ bool ath9k_hw_updatetxtriglevel(struct ath_hw *ah, bool bIncTrigLevel);
+-bool ath9k_hw_stoptxdma(struct ath_hw *ah, u32 q);
++bool ath9k_hw_stop_dma_queue(struct ath_hw *ah, u32 q);
++void ath9k_hw_abort_tx_dma(struct ath_hw *ah);
+ void ath9k_hw_gettxintrtxqs(struct ath_hw *ah, u32 *txqs);
+ bool ath9k_hw_set_txq_props(struct ath_hw *ah, int q,
+ const struct ath9k_tx_queue_info *qinfo);
+--- a/drivers/net/wireless/ath/ath9k/main.c
++++ b/drivers/net/wireless/ath/ath9k/main.c
+@@ -2128,56 +2128,42 @@ static void ath9k_set_coverage_class(str
+
+ static void ath9k_flush(struct ieee80211_hw *hw, bool drop)
+ {
+-#define ATH_FLUSH_TIMEOUT 60 /* ms */
+ struct ath_softc *sc = hw->priv;
+- struct ath_txq *txq = NULL;
+- struct ath_hw *ah = sc->sc_ah;
+- struct ath_common *common = ath9k_hw_common(ah);
+- int i, j, npend = 0;
++ int timeout = 200; /* ms */
++ int i, j;
+
++ ath9k_ps_wakeup(sc);
+ mutex_lock(&sc->mutex);
+
+ cancel_delayed_work_sync(&sc->tx_complete_work);
+
+- for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) {
+- if (!ATH_TXQ_SETUP(sc, i))
+- continue;
+- txq = &sc->tx.txq[i];
+-
+- if (!drop) {
+- for (j = 0; j < ATH_FLUSH_TIMEOUT; j++) {
+- if (!ath9k_has_pending_frames(sc, txq))
+- break;
+- usleep_range(1000, 2000);
+- }
+- }
++ if (drop)
++ timeout = 1;
++
++ for (j = 0; j < timeout; j++) {
++ int npend = 0;
++
++ if (j)
++ usleep_range(1000, 2000);
+
+- if (drop || ath9k_has_pending_frames(sc, txq)) {
+- ath_dbg(common, ATH_DBG_QUEUE, "Drop frames from hw queue:%d\n",
+- txq->axq_qnum);
+- spin_lock_bh(&txq->axq_lock);
+- txq->txq_flush_inprogress = true;
+- spin_unlock_bh(&txq->axq_lock);
+-
+- ath9k_ps_wakeup(sc);
+- ath9k_hw_stoptxdma(ah, txq->axq_qnum);
+- npend = ath9k_hw_numtxpending(ah, txq->axq_qnum);
+- ath9k_ps_restore(sc);
+- if (npend)
+- break;
++ for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) {
++ if (!ATH_TXQ_SETUP(sc, i))
++ continue;
+
+- ath_draintxq(sc, txq, false);
+- txq->txq_flush_inprogress = false;
++ npend += ath9k_has_pending_frames(sc, &sc->tx.txq[i]);
+ }
++
++ if (!npend)
++ goto out;
+ }
+
+- if (npend) {
++ if (!ath_drain_all_txq(sc, false))
+ ath_reset(sc, false);
+- txq->txq_flush_inprogress = false;
+- }
+
++out:
+ ieee80211_queue_delayed_work(hw, &sc->tx_complete_work, 0);
+ mutex_unlock(&sc->mutex);
++ ath9k_ps_restore(sc);
+ }
+
+ struct ieee80211_ops ath9k_ops = {
+--- a/drivers/net/wireless/ath/ath9k/xmit.c
++++ b/drivers/net/wireless/ath/ath9k/xmit.c
+@@ -166,7 +166,7 @@ static void ath_tx_flush_tid(struct ath_
+ fi = get_frame_info(bf->bf_mpdu);
+ if (fi->retries) {
+ ath_tx_update_baw(sc, tid, fi->seqno);
+- ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, 0, 0);
++ ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, 0, 1);
+ } else {
+ ath_tx_send_normal(sc, txq, NULL, &bf_head);
+ }
+@@ -1194,16 +1194,14 @@ bool ath_drain_all_txq(struct ath_softc
+ if (sc->sc_flags & SC_OP_INVALID)
+ return true;
+
+- /* Stop beacon queue */
+- ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq);
++ ath9k_hw_abort_tx_dma(ah);
+
+- /* Stop data queues */
++ /* Check if any queue remains active */
+ for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) {
+- if (ATH_TXQ_SETUP(sc, i)) {
+- txq = &sc->tx.txq[i];
+- ath9k_hw_stoptxdma(ah, txq->axq_qnum);
+- npend += ath9k_hw_numtxpending(ah, txq->axq_qnum);
+- }
++ if (!ATH_TXQ_SETUP(sc, i))
++ continue;
++
++ npend += ath9k_hw_numtxpending(ah, sc->tx.txq[i].axq_qnum);
+ }
+
+ if (npend)
+@@ -2014,8 +2012,7 @@ static void ath_tx_processq(struct ath_s
+ spin_lock_bh(&txq->axq_lock);
+ if (list_empty(&txq->axq_q)) {
+ txq->axq_link = NULL;
+- if (sc->sc_flags & SC_OP_TXAGGR &&
+- !txq->txq_flush_inprogress)
++ if (sc->sc_flags & SC_OP_TXAGGR)
+ ath_txq_schedule(sc, txq);
+ spin_unlock_bh(&txq->axq_lock);
+ break;
+@@ -2096,7 +2093,7 @@ static void ath_tx_processq(struct ath_s
+
+ spin_lock_bh(&txq->axq_lock);
+
+- if (sc->sc_flags & SC_OP_TXAGGR && !txq->txq_flush_inprogress)
++ if (sc->sc_flags & SC_OP_TXAGGR)
+ ath_txq_schedule(sc, txq);
+ spin_unlock_bh(&txq->axq_lock);
+ }
+@@ -2267,18 +2264,17 @@ void ath_tx_edma_tasklet(struct ath_soft
+
+ spin_lock_bh(&txq->axq_lock);
+
+- if (!txq->txq_flush_inprogress) {
+- if (!list_empty(&txq->txq_fifo_pending)) {
+- INIT_LIST_HEAD(&bf_head);
+- bf = list_first_entry(&txq->txq_fifo_pending,
+- struct ath_buf, list);
+- list_cut_position(&bf_head,
+- &txq->txq_fifo_pending,
+- &bf->bf_lastbf->list);
+- ath_tx_txqaddbuf(sc, txq, &bf_head);
+- } else if (sc->sc_flags & SC_OP_TXAGGR)
+- ath_txq_schedule(sc, txq);
+- }
++ if (!list_empty(&txq->txq_fifo_pending)) {
++ INIT_LIST_HEAD(&bf_head);
++ bf = list_first_entry(&txq->txq_fifo_pending,
++ struct ath_buf, list);
++ list_cut_position(&bf_head,
++ &txq->txq_fifo_pending,
++ &bf->bf_lastbf->list);
++ ath_tx_txqaddbuf(sc, txq, &bf_head);
++ } else if (sc->sc_flags & SC_OP_TXAGGR)
++ ath_txq_schedule(sc, txq);
++
+ spin_unlock_bh(&txq->axq_lock);
+ }
+ }
+--- a/net/mac80211/chan.c
++++ b/net/mac80211/chan.c
+@@ -77,6 +77,9 @@ bool ieee80211_set_channel_type(struct i
+ switch (tmp->vif.bss_conf.channel_type) {
+ case NL80211_CHAN_NO_HT:
+ case NL80211_CHAN_HT20:
++ if (superchan > tmp->vif.bss_conf.channel_type)
++ break;
++
+ superchan = tmp->vif.bss_conf.channel_type;
+ break;
+ case NL80211_CHAN_HT40PLUS:
diff --git a/package/mac80211/patches/401-ath9k-dont-register-leds-on-ar9100.patch b/package/mac80211/patches/401-ath9k-dont-register-leds-on-ar9100.patch
index 166c133a61..22299020a0 100644
--- a/package/mac80211/patches/401-ath9k-dont-register-leds-on-ar9100.patch
+++ b/package/mac80211/patches/401-ath9k-dont-register-leds-on-ar9100.patch
@@ -1,17 +1,7 @@
--- a/drivers/net/wireless/ath/ath9k/gpio.c
+++ b/drivers/net/wireless/ath/ath9k/gpio.c
-@@ -120,6 +120,9 @@ static void ath_unregister_led(struct at
-
- void ath_deinit_leds(struct ath_softc *sc)
+@@ -41,6 +41,9 @@ void ath_init_leds(struct ath_softc *sc)
{
-+ if (AR_SREV_9100(sc->sc_ah))
-+ return;
-+
- ath_unregister_led(&sc->assoc_led);
- sc->sc_flags &= ~SC_OP_LED_ASSOCIATED;
- ath_unregister_led(&sc->tx_led);
-@@ -133,6 +136,9 @@ void ath_init_leds(struct ath_softc *sc)
- char *trigger;
int ret;
+ if (AR_SREV_9100(sc->sc_ah))
@@ -19,4 +9,4 @@
+
if (AR_SREV_9287(sc->sc_ah))
sc->sc_ah->led_pin = ATH_LED_PIN_9287;
- else
+ else if (AR_SREV_9485(sc->sc_ah))
diff --git a/package/mac80211/patches/407-ath9k-override-mac-address-from-platform-data.patch b/package/mac80211/patches/407-ath9k-override-mac-address-from-platform-data.patch
index c92245641f..6326649fc2 100644
--- a/package/mac80211/patches/407-ath9k-override-mac-address-from-platform-data.patch
+++ b/package/mac80211/patches/407-ath9k-override-mac-address-from-platform-data.patch
@@ -18,7 +18,7 @@
#include "ath9k.h"
-@@ -522,6 +523,7 @@ static void ath9k_init_misc(struct ath_s
+@@ -537,6 +538,7 @@ static void ath9k_init_misc(struct ath_s
static int ath9k_init_softc(u16 devid, struct ath_softc *sc, u16 subsysid,
const struct ath_bus_ops *bus_ops)
{
@@ -26,7 +26,7 @@
struct ath_hw *ah = NULL;
struct ath_common *common;
int ret = 0, i;
-@@ -536,7 +538,7 @@ static int ath9k_init_softc(u16 devid, s
+@@ -551,7 +553,7 @@ static int ath9k_init_softc(u16 devid, s
ah->hw_version.subsysid = subsysid;
sc->sc_ah = ah;
@@ -35,7 +35,7 @@
ah->ah_flags |= AH_USE_EEPROM;
common = ath9k_hw_common(ah);
-@@ -572,6 +574,9 @@ static int ath9k_init_softc(u16 devid, s
+@@ -587,6 +589,9 @@ static int ath9k_init_softc(u16 devid, s
if (ret)
goto err_hw;
diff --git a/package/mac80211/patches/409-ath9k_platform_settings.patch b/package/mac80211/patches/409-ath9k_platform_settings.patch
index 23a5887a1d..6ce43b6005 100644
--- a/package/mac80211/patches/409-ath9k_platform_settings.patch
+++ b/package/mac80211/patches/409-ath9k_platform_settings.patch
@@ -1,6 +1,6 @@
--- a/drivers/net/wireless/ath/ath9k/init.c
+++ b/drivers/net/wireless/ath/ath9k/init.c
-@@ -538,8 +538,14 @@ static int ath9k_init_softc(u16 devid, s
+@@ -553,8 +553,14 @@ static int ath9k_init_softc(u16 devid, s
ah->hw_version.subsysid = subsysid;
sc->sc_ah = ah;
@@ -29,17 +29,21 @@
--- a/drivers/net/wireless/ath/ath9k/gpio.c
+++ b/drivers/net/wireless/ath/ath9k/gpio.c
-@@ -139,10 +139,12 @@ void ath_init_leds(struct ath_softc *sc)
+@@ -44,12 +44,14 @@ void ath_init_leds(struct ath_softc *sc)
if (AR_SREV_9100(sc->sc_ah))
return;
- if (AR_SREV_9287(sc->sc_ah))
- sc->sc_ah->led_pin = ATH_LED_PIN_9287;
+- else if (AR_SREV_9485(sc->sc_ah))
+- sc->sc_ah->led_pin = ATH_LED_PIN_9485;
- else
- sc->sc_ah->led_pin = ATH_LED_PIN_DEF;
+ if (sc->sc_ah->led_pin < 0) {
+ if (AR_SREV_9287(sc->sc_ah))
+ sc->sc_ah->led_pin = ATH_LED_PIN_9287;
++ else if (AR_SREV_9485(sc->sc_ah))
++ sc->sc_ah->led_pin = ATH_LED_PIN_9485;
+ else
+ sc->sc_ah->led_pin = ATH_LED_PIN_DEF;
+ }
diff --git a/package/mac80211/patches/500-ath9k_eeprom_debugfs.patch b/package/mac80211/patches/500-ath9k_eeprom_debugfs.patch
index 700cf70114..0bb7082ef5 100644
--- a/package/mac80211/patches/500-ath9k_eeprom_debugfs.patch
+++ b/package/mac80211/patches/500-ath9k_eeprom_debugfs.patch
@@ -1,7 +1,7 @@
--- a/drivers/net/wireless/ath/ath9k/debug.c
+++ b/drivers/net/wireless/ath/ath9k/debug.c
-@@ -1027,6 +1027,53 @@ static const struct file_operations fops
- .llseek = default_llseek,
+@@ -1077,6 +1077,53 @@ static const struct file_operations fops
+ .llseek = default_llseek,/* read accesses f_pos */
};
+static ssize_t read_file_eeprom(struct file *file, char __user *user_buf,
@@ -54,7 +54,7 @@
int ath9k_init_debug(struct ath_hw *ah)
{
struct ath_common *common = ath9k_hw_common(ah);
-@@ -1097,6 +1144,10 @@ int ath9k_init_debug(struct ath_hw *ah)
+@@ -1151,6 +1198,10 @@ int ath9k_init_debug(struct ath_hw *ah)
debugfs_create_u32("gpio_val", S_IRUSR | S_IWUSR,
sc->debug.debugfs_phy, &sc->sc_ah->gpio_val);
diff --git a/package/mac80211/patches/520-ath9k_intr_mitigation_tweak.patch b/package/mac80211/patches/510-ath9k_intr_mitigation_tweak.patch
index 301af3c22b..301af3c22b 100644
--- a/package/mac80211/patches/520-ath9k_intr_mitigation_tweak.patch
+++ b/package/mac80211/patches/510-ath9k_intr_mitigation_tweak.patch
diff --git a/package/mac80211/patches/510-ath9k_led_cleanup.patch b/package/mac80211/patches/510-ath9k_led_cleanup.patch
deleted file mode 100644
index 352bee15fd..0000000000
--- a/package/mac80211/patches/510-ath9k_led_cleanup.patch
+++ /dev/null
@@ -1,303 +0,0 @@
---- a/drivers/net/wireless/ath/ath9k/ath9k.h
-+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
-@@ -449,26 +449,20 @@ void ath9k_btcoex_timer_pause(struct ath
-
- #define ATH_LED_PIN_DEF 1
- #define ATH_LED_PIN_9287 8
--#define ATH_LED_ON_DURATION_IDLE 350 /* in msecs */
--#define ATH_LED_OFF_DURATION_IDLE 250 /* in msecs */
--
--enum ath_led_type {
-- ATH_LED_RADIO,
-- ATH_LED_ASSOC,
-- ATH_LED_TX,
-- ATH_LED_RX
--};
--
--struct ath_led {
-- struct ath_softc *sc;
-- struct led_classdev led_cdev;
-- enum ath_led_type led_type;
-- char name[32];
-- bool registered;
--};
-
-+#ifdef CONFIG_MAC80211_LEDS
- void ath_init_leds(struct ath_softc *sc);
- void ath_deinit_leds(struct ath_softc *sc);
-+#else
-+static inline void ath_init_leds(struct ath_softc *sc)
-+{
-+}
-+
-+static inline void ath_deinit_leds(struct ath_softc *sc)
-+{
-+}
-+#endif
-+
-
- /* Antenna diversity/combining */
- #define ATH_ANT_RX_CURRENT_SHIFT 4
-@@ -620,15 +614,11 @@ struct ath_softc {
- struct ath_beacon beacon;
- struct ieee80211_supported_band sbands[IEEE80211_NUM_BANDS];
-
-- struct ath_led radio_led;
-- struct ath_led assoc_led;
-- struct ath_led tx_led;
-- struct ath_led rx_led;
-- struct delayed_work ath_led_blink_work;
-- int led_on_duration;
-- int led_off_duration;
-- int led_on_cnt;
-- int led_off_cnt;
-+#ifdef CONFIG_MAC80211_LEDS
-+ bool led_registered;
-+ char led_name[32];
-+ struct led_classdev led_cdev;
-+#endif
-
- struct ath9k_hw_cal_data caldata;
- int last_rssi;
---- a/drivers/net/wireless/ath/ath9k/gpio.c
-+++ b/drivers/net/wireless/ath/ath9k/gpio.c
-@@ -20,120 +20,25 @@
- /* LED functions */
- /********************************/
-
--static void ath_led_blink_work(struct work_struct *work)
--{
-- struct ath_softc *sc = container_of(work, struct ath_softc,
-- ath_led_blink_work.work);
--
-- if (!(sc->sc_flags & SC_OP_LED_ASSOCIATED))
-- return;
--
-- if ((sc->led_on_duration == ATH_LED_ON_DURATION_IDLE) ||
-- (sc->led_off_duration == ATH_LED_OFF_DURATION_IDLE))
-- ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, 0);
-- else
-- ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin,
-- (sc->sc_flags & SC_OP_LED_ON) ? 1 : 0);
--
-- ieee80211_queue_delayed_work(sc->hw,
-- &sc->ath_led_blink_work,
-- (sc->sc_flags & SC_OP_LED_ON) ?
-- msecs_to_jiffies(sc->led_off_duration) :
-- msecs_to_jiffies(sc->led_on_duration));
--
-- sc->led_on_duration = sc->led_on_cnt ?
-- max((ATH_LED_ON_DURATION_IDLE - sc->led_on_cnt), 25) :
-- ATH_LED_ON_DURATION_IDLE;
-- sc->led_off_duration = sc->led_off_cnt ?
-- max((ATH_LED_OFF_DURATION_IDLE - sc->led_off_cnt), 10) :
-- ATH_LED_OFF_DURATION_IDLE;
-- sc->led_on_cnt = sc->led_off_cnt = 0;
-- if (sc->sc_flags & SC_OP_LED_ON)
-- sc->sc_flags &= ~SC_OP_LED_ON;
-- else
-- sc->sc_flags |= SC_OP_LED_ON;
--}
--
-+#ifdef CONFIG_MAC80211_LEDS
- static void ath_led_brightness(struct led_classdev *led_cdev,
- enum led_brightness brightness)
- {
-- struct ath_led *led = container_of(led_cdev, struct ath_led, led_cdev);
-- struct ath_softc *sc = led->sc;
--
-- switch (brightness) {
-- case LED_OFF:
-- if (led->led_type == ATH_LED_ASSOC ||
-- led->led_type == ATH_LED_RADIO) {
-- ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin,
-- (led->led_type == ATH_LED_RADIO));
-- sc->sc_flags &= ~SC_OP_LED_ASSOCIATED;
-- if (led->led_type == ATH_LED_RADIO)
-- sc->sc_flags &= ~SC_OP_LED_ON;
-- } else {
-- sc->led_off_cnt++;
-- }
-- break;
-- case LED_FULL:
-- if (led->led_type == ATH_LED_ASSOC) {
-- sc->sc_flags |= SC_OP_LED_ASSOCIATED;
-- if (led_blink)
-- ieee80211_queue_delayed_work(sc->hw,
-- &sc->ath_led_blink_work, 0);
-- } else if (led->led_type == ATH_LED_RADIO) {
-- ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, 0);
-- sc->sc_flags |= SC_OP_LED_ON;
-- } else {
-- sc->led_on_cnt++;
-- }
-- break;
-- default:
-- break;
-- }
--}
--
--static int ath_register_led(struct ath_softc *sc, struct ath_led *led,
-- char *trigger)
--{
-- int ret;
--
-- led->sc = sc;
-- led->led_cdev.name = led->name;
-- led->led_cdev.default_trigger = trigger;
-- led->led_cdev.brightness_set = ath_led_brightness;
--
-- ret = led_classdev_register(wiphy_dev(sc->hw->wiphy), &led->led_cdev);
-- if (ret)
-- ath_err(ath9k_hw_common(sc->sc_ah),
-- "Failed to register led:%s", led->name);
-- else
-- led->registered = 1;
-- return ret;
--}
--
--static void ath_unregister_led(struct ath_led *led)
--{
-- if (led->registered) {
-- led_classdev_unregister(&led->led_cdev);
-- led->registered = 0;
-- }
-+ struct ath_softc *sc = container_of(led_cdev, struct ath_softc, led_cdev);
-+ ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, (brightness == LED_OFF));
- }
-
- void ath_deinit_leds(struct ath_softc *sc)
- {
-- if (AR_SREV_9100(sc->sc_ah))
-+ if (!sc->led_registered)
- return;
-
-- ath_unregister_led(&sc->assoc_led);
-- sc->sc_flags &= ~SC_OP_LED_ASSOCIATED;
-- ath_unregister_led(&sc->tx_led);
-- ath_unregister_led(&sc->rx_led);
-- ath_unregister_led(&sc->radio_led);
-- ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, 1);
-+ ath_led_brightness(&sc->led_cdev, LED_OFF);
-+ led_classdev_unregister(&sc->led_cdev);
- }
-
- void ath_init_leds(struct ath_softc *sc)
- {
-- char *trigger;
- int ret;
-
- if (AR_SREV_9100(sc->sc_ah))
-@@ -152,48 +57,22 @@ void ath_init_leds(struct ath_softc *sc)
- /* LED off, active low */
- ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, 1);
-
-- if (led_blink)
-- INIT_DELAYED_WORK(&sc->ath_led_blink_work, ath_led_blink_work);
-+ if (!led_blink)
-+ sc->led_cdev.default_trigger =
-+ ieee80211_get_radio_led_name(sc->hw);
-+
-+ snprintf(sc->led_name, sizeof(sc->led_name),
-+ "ath9k-%s", wiphy_name(sc->hw->wiphy));
-+ sc->led_cdev.name = sc->led_name;
-+ sc->led_cdev.brightness_set = ath_led_brightness;
-+
-+ ret = led_classdev_register(wiphy_dev(sc->hw->wiphy), &sc->led_cdev);
-+ if (ret < 0)
-+ return;
-
-- trigger = ieee80211_get_radio_led_name(sc->hw);
-- snprintf(sc->radio_led.name, sizeof(sc->radio_led.name),
-- "ath9k-%s::radio", wiphy_name(sc->hw->wiphy));
-- ret = ath_register_led(sc, &sc->radio_led, trigger);
-- sc->radio_led.led_type = ATH_LED_RADIO;
-- if (ret)
-- goto fail;
--
-- trigger = ieee80211_get_assoc_led_name(sc->hw);
-- snprintf(sc->assoc_led.name, sizeof(sc->assoc_led.name),
-- "ath9k-%s::assoc", wiphy_name(sc->hw->wiphy));
-- ret = ath_register_led(sc, &sc->assoc_led, trigger);
-- sc->assoc_led.led_type = ATH_LED_ASSOC;
-- if (ret)
-- goto fail;
--
-- trigger = ieee80211_get_tx_led_name(sc->hw);
-- snprintf(sc->tx_led.name, sizeof(sc->tx_led.name),
-- "ath9k-%s::tx", wiphy_name(sc->hw->wiphy));
-- ret = ath_register_led(sc, &sc->tx_led, trigger);
-- sc->tx_led.led_type = ATH_LED_TX;
-- if (ret)
-- goto fail;
--
-- trigger = ieee80211_get_rx_led_name(sc->hw);
-- snprintf(sc->rx_led.name, sizeof(sc->rx_led.name),
-- "ath9k-%s::rx", wiphy_name(sc->hw->wiphy));
-- ret = ath_register_led(sc, &sc->rx_led, trigger);
-- sc->rx_led.led_type = ATH_LED_RX;
-- if (ret)
-- goto fail;
--
-- return;
--
--fail:
-- if (led_blink)
-- cancel_delayed_work_sync(&sc->ath_led_blink_work);
-- ath_deinit_leds(sc);
-+ sc->led_registered = true;
- }
-+#endif
-
- /*******************/
- /* Rfkill */
---- a/drivers/net/wireless/ath/ath9k/main.c
-+++ b/drivers/net/wireless/ath/ath9k/main.c
-@@ -1216,9 +1216,6 @@ static void ath9k_stop(struct ieee80211_
-
- mutex_lock(&sc->mutex);
-
-- if (led_blink)
-- cancel_delayed_work_sync(&sc->ath_led_blink_work);
--
- cancel_delayed_work_sync(&sc->tx_complete_work);
- cancel_delayed_work_sync(&sc->hw_pll_work);
- cancel_work_sync(&sc->paprd_work);
---- a/drivers/net/wireless/ath/ath9k/init.c
-+++ b/drivers/net/wireless/ath/ath9k/init.c
-@@ -141,6 +141,21 @@ static struct ieee80211_rate ath9k_legac
- RATE(540, 0x0c, 0),
- };
-
-+#ifdef CONFIG_MAC80211_LEDS
-+static const struct ieee80211_tpt_blink ath9k_tpt_blink[] = {
-+ { .throughput = 0 * 1024, .blink_time = 334 },
-+ { .throughput = 1 * 1024, .blink_time = 260 },
-+ { .throughput = 5 * 1024, .blink_time = 220 },
-+ { .throughput = 10 * 1024, .blink_time = 190 },
-+ { .throughput = 20 * 1024, .blink_time = 170 },
-+ { .throughput = 50 * 1024, .blink_time = 150 },
-+ { .throughput = 70 * 1024, .blink_time = 130 },
-+ { .throughput = 100 * 1024, .blink_time = 110 },
-+ { .throughput = 200 * 1024, .blink_time = 80 },
-+ { .throughput = 300 * 1024, .blink_time = 50 },
-+};
-+#endif
-+
- static void ath9k_deinit_softc(struct ath_softc *sc);
-
- /*
-@@ -742,6 +757,13 @@ int ath9k_init_device(u16 devid, struct
-
- ath9k_init_txpower_limits(sc);
-
-+#ifdef CONFIG_MAC80211_LEDS
-+ /* must be initialized before ieee80211_register_hw */
-+ sc->led_cdev.default_trigger = ieee80211_create_tpt_led_trigger(sc->hw,
-+ IEEE80211_TPT_LEDTRIG_FL_RADIO, ath9k_tpt_blink,
-+ ARRAY_SIZE(ath9k_tpt_blink));
-+#endif
-+
- /* Register with mac80211 */
- error = ieee80211_register_hw(hw);
- if (error)
diff --git a/package/mac80211/patches/530-mac80211_drv_tim_override.patch b/package/mac80211/patches/520-mac80211_drv_tim_override.patch
index 198f658a61..535e35927e 100644
--- a/package/mac80211/patches/530-mac80211_drv_tim_override.patch
+++ b/package/mac80211/patches/520-mac80211_drv_tim_override.patch
@@ -1,6 +1,6 @@
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
-@@ -2209,6 +2209,18 @@ static inline int ieee80211_sta_ps_trans
+@@ -2216,6 +2216,18 @@ static inline int ieee80211_sta_ps_trans
#define IEEE80211_TX_STATUS_HEADROOM 13
/**
diff --git a/package/mac80211/patches/531-ath9k_fix_ap_ps_buffering.patch b/package/mac80211/patches/521-ath9k_fix_ap_ps_buffering.patch
index ff58c26d7a..87cc2654b5 100644
--- a/package/mac80211/patches/531-ath9k_fix_ap_ps_buffering.patch
+++ b/package/mac80211/patches/521-ath9k_fix_ap_ps_buffering.patch
@@ -1,6 +1,6 @@
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
-@@ -203,6 +203,7 @@ struct ath_atx_ac {
+@@ -202,6 +202,7 @@ struct ath_atx_ac {
int sched;
struct list_head list;
struct list_head tid_q;
@@ -8,7 +8,7 @@
};
struct ath_frame_info {
-@@ -260,6 +261,8 @@ struct ath_node {
+@@ -259,6 +260,8 @@ struct ath_node {
struct ath_atx_ac ac[WME_NUM_AC];
u16 maxampdu;
u8 mpdudensity;
@@ -17,7 +17,7 @@
};
#define AGGR_CLEANUP BIT(1)
-@@ -341,6 +344,9 @@ int ath_tx_aggr_start(struct ath_softc *
+@@ -340,6 +343,9 @@ int ath_tx_aggr_start(struct ath_softc *
void ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid);
void ath_tx_aggr_resume(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid);
@@ -57,7 +57,7 @@
static int ath9k_conf_tx(struct ieee80211_hw *hw, u16 queue,
const struct ieee80211_tx_queue_params *params)
{
-@@ -2191,6 +2212,7 @@ struct ieee80211_ops ath9k_ops = {
+@@ -2177,6 +2198,7 @@ struct ieee80211_ops ath9k_ops = {
.configure_filter = ath9k_configure_filter,
.sta_add = ath9k_sta_add,
.sta_remove = ath9k_sta_remove,
@@ -189,7 +189,7 @@
void ath_tx_aggr_resume(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid)
{
struct ath_atx_tid *txtid;
-@@ -1493,7 +1570,6 @@ static int setup_tx_flags(struct sk_buff
+@@ -1491,7 +1568,6 @@ static int setup_tx_flags(struct sk_buff
struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
int flags = 0;
@@ -197,7 +197,7 @@
flags |= ATH9K_TXDESC_INTREQ;
if (tx_info->flags & IEEE80211_TX_CTL_NO_ACK)
-@@ -1756,6 +1832,9 @@ static void ath_tx_start_dma(struct ath_
+@@ -1754,6 +1830,9 @@ static void ath_tx_start_dma(struct ath_
if (txctl->paprd)
bf->bf_state.bfs_paprd_timestamp = jiffies;
diff --git a/package/mac80211/patches/532-ath9k_remove_pending_frames_workaround.patch b/package/mac80211/patches/522-ath9k_remove_pending_frames_workaround.patch
index f7341e2a10..e368bce64b 100644
--- a/package/mac80211/patches/532-ath9k_remove_pending_frames_workaround.patch
+++ b/package/mac80211/patches/522-ath9k_remove_pending_frames_workaround.patch
@@ -1,6 +1,6 @@
--- a/drivers/net/wireless/ath/ath9k/xmit.c
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
-@@ -2226,33 +2226,6 @@ static void ath_tx_complete_poll_work(st
+@@ -2223,33 +2223,6 @@ static void ath_tx_complete_poll_work(st
} else {
txq->axq_tx_inprogress = true;
}
diff --git a/package/mac80211/patches/580-mac80211_redirect_vlan_eap_frames.patch b/package/mac80211/patches/530-mac80211_redirect_vlan_eap_frames.patch
index 03a4fe5d37..03a4fe5d37 100644
--- a/package/mac80211/patches/580-mac80211_redirect_vlan_eap_frames.patch
+++ b/package/mac80211/patches/530-mac80211_redirect_vlan_eap_frames.patch
diff --git a/package/mac80211/patches/540-mac80211_add_rx_rate.patch b/package/mac80211/patches/540-mac80211_add_rx_rate.patch
deleted file mode 100644
index d365f35245..0000000000
--- a/package/mac80211/patches/540-mac80211_add_rx_rate.patch
+++ /dev/null
@@ -1,232 +0,0 @@
---- a/include/net/cfg80211.h
-+++ b/include/net/cfg80211.h
-@@ -414,7 +414,7 @@ struct station_parameters {
- * @STATION_INFO_PLID: @plid filled
- * @STATION_INFO_PLINK_STATE: @plink_state filled
- * @STATION_INFO_SIGNAL: @signal filled
-- * @STATION_INFO_TX_BITRATE: @tx_bitrate fields are filled
-+ * @STATION_INFO_TX_BITRATE: @txrate fields are filled
- * (tx_bitrate, tx_bitrate_flags and tx_bitrate_mcs)
- * @STATION_INFO_RX_PACKETS: @rx_packets filled
- * @STATION_INFO_TX_PACKETS: @tx_packets filled
-@@ -422,6 +422,7 @@ struct station_parameters {
- * @STATION_INFO_TX_FAILED: @tx_failed filled
- * @STATION_INFO_RX_DROP_MISC: @rx_dropped_misc filled
- * @STATION_INFO_SIGNAL_AVG: @signal_avg filled
-+ * @STATION_INFO_RX_BITRATE: @rxrate fields are filled
- */
- enum station_info_flags {
- STATION_INFO_INACTIVE_TIME = 1<<0,
-@@ -438,6 +439,7 @@ enum station_info_flags {
- STATION_INFO_TX_FAILED = 1<<11,
- STATION_INFO_RX_DROP_MISC = 1<<12,
- STATION_INFO_SIGNAL_AVG = 1<<13,
-+ STATION_INFO_RX_BITRATE = 1<<14,
- };
-
- /**
-@@ -507,6 +509,7 @@ struct station_info {
- s8 signal;
- s8 signal_avg;
- struct rate_info txrate;
-+ struct rate_info rxrate;
- u32 rx_packets;
- u32 tx_packets;
- u32 tx_retries;
---- a/include/linux/nl80211.h
-+++ b/include/linux/nl80211.h
-@@ -1243,6 +1243,8 @@ enum nl80211_rate_info {
- * @NL80211_STA_INFO_LLID: the station's mesh LLID
- * @NL80211_STA_INFO_PLID: the station's mesh PLID
- * @NL80211_STA_INFO_PLINK_STATE: peer link state for the station
-+ * @NL80211_STA_INFO_RX_BITRATE: last unicast rx rate, nested attribute
-+ * containing info as possible, see &enum nl80211_sta_info_txrate.
- * @__NL80211_STA_INFO_AFTER_LAST: internal
- * @NL80211_STA_INFO_MAX: highest possible station info attribute
- */
-@@ -1261,6 +1263,7 @@ enum nl80211_sta_info {
- NL80211_STA_INFO_TX_RETRIES,
- NL80211_STA_INFO_TX_FAILED,
- NL80211_STA_INFO_SIGNAL_AVG,
-+ NL80211_STA_INFO_RX_BITRATE,
-
- /* keep last */
- __NL80211_STA_INFO_AFTER_LAST,
---- a/net/wireless/nl80211.c
-+++ b/net/wireless/nl80211.c
-@@ -1968,13 +1968,41 @@ static int parse_station_flags(struct ge
- return 0;
- }
-
-+static bool nl80211_put_sta_rate(struct sk_buff *msg, struct rate_info *info,
-+ int attr)
-+{
-+ struct nlattr *rate;
-+ u16 bitrate;
-+
-+ rate = nla_nest_start(msg, attr);
-+ if (!rate)
-+ goto nla_put_failure;
-+
-+ /* cfg80211_calculate_bitrate will return 0 for mcs >= 32 */
-+ bitrate = cfg80211_calculate_bitrate(info);
-+ if (bitrate > 0)
-+ NLA_PUT_U16(msg, NL80211_RATE_INFO_BITRATE, bitrate);
-+
-+ if (info->flags & RATE_INFO_FLAGS_MCS)
-+ NLA_PUT_U8(msg, NL80211_RATE_INFO_MCS, info->mcs);
-+ if (info->flags & RATE_INFO_FLAGS_40_MHZ_WIDTH)
-+ NLA_PUT_FLAG(msg, NL80211_RATE_INFO_40_MHZ_WIDTH);
-+ if (info->flags & RATE_INFO_FLAGS_SHORT_GI)
-+ NLA_PUT_FLAG(msg, NL80211_RATE_INFO_SHORT_GI);
-+
-+ nla_nest_end(msg, rate);
-+ return true;
-+
-+nla_put_failure:
-+ return false;
-+}
-+
- static int nl80211_send_station(struct sk_buff *msg, u32 pid, u32 seq,
- int flags, struct net_device *dev,
- const u8 *mac_addr, struct station_info *sinfo)
- {
- void *hdr;
-- struct nlattr *sinfoattr, *txrate;
-- u16 bitrate;
-+ struct nlattr *sinfoattr;
-
- hdr = nl80211hdr_put(msg, pid, seq, flags, NL80211_CMD_NEW_STATION);
- if (!hdr)
-@@ -2013,24 +2041,14 @@ static int nl80211_send_station(struct s
- NLA_PUT_U8(msg, NL80211_STA_INFO_SIGNAL_AVG,
- sinfo->signal_avg);
- if (sinfo->filled & STATION_INFO_TX_BITRATE) {
-- txrate = nla_nest_start(msg, NL80211_STA_INFO_TX_BITRATE);
-- if (!txrate)
-+ if (!nl80211_put_sta_rate(msg, &sinfo->txrate,
-+ NL80211_STA_INFO_TX_BITRATE))
-+ goto nla_put_failure;
-+ }
-+ if (sinfo->filled & STATION_INFO_RX_BITRATE) {
-+ if (!nl80211_put_sta_rate(msg, &sinfo->rxrate,
-+ NL80211_STA_INFO_RX_BITRATE))
- goto nla_put_failure;
--
-- /* cfg80211_calculate_bitrate will return 0 for mcs >= 32 */
-- bitrate = cfg80211_calculate_bitrate(&sinfo->txrate);
-- if (bitrate > 0)
-- NLA_PUT_U16(msg, NL80211_RATE_INFO_BITRATE, bitrate);
--
-- if (sinfo->txrate.flags & RATE_INFO_FLAGS_MCS)
-- NLA_PUT_U8(msg, NL80211_RATE_INFO_MCS,
-- sinfo->txrate.mcs);
-- if (sinfo->txrate.flags & RATE_INFO_FLAGS_40_MHZ_WIDTH)
-- NLA_PUT_FLAG(msg, NL80211_RATE_INFO_40_MHZ_WIDTH);
-- if (sinfo->txrate.flags & RATE_INFO_FLAGS_SHORT_GI)
-- NLA_PUT_FLAG(msg, NL80211_RATE_INFO_SHORT_GI);
--
-- nla_nest_end(msg, txrate);
- }
- if (sinfo->filled & STATION_INFO_RX_PACKETS)
- NLA_PUT_U32(msg, NL80211_STA_INFO_RX_PACKETS,
---- a/net/mac80211/sta_info.h
-+++ b/net/mac80211/sta_info.h
-@@ -212,6 +212,8 @@ enum plink_state {
- * @rate_ctrl_priv: rate control private per-STA pointer
- * @last_tx_rate: rate used for last transmit, to report to userspace as
- * "the" transmit rate
-+ * @last_rx_rate_idx: rx status rate index of the last data packet
-+ * @last_rx_rate_flag: rx status flag of the last data packet
- * @lock: used for locking all fields that require locking, see comments
- * in the header file.
- * @flaglock: spinlock for flags accesses
-@@ -314,6 +316,8 @@ struct sta_info {
- unsigned long tx_bytes;
- unsigned long tx_fragments;
- struct ieee80211_tx_rate last_tx_rate;
-+ int last_rx_rate_idx;
-+ int last_rx_rate_flag;
- u16 tid_seq[IEEE80211_QOS_CTL_TID_MASK + 1];
-
- /*
---- a/net/mac80211/rx.c
-+++ b/net/mac80211/rx.c
-@@ -1156,14 +1156,23 @@ ieee80211_rx_h_sta_process(struct ieee80
- if (rx->sdata->vif.type == NL80211_IFTYPE_ADHOC) {
- u8 *bssid = ieee80211_get_bssid(hdr, rx->skb->len,
- NL80211_IFTYPE_ADHOC);
-- if (compare_ether_addr(bssid, rx->sdata->u.ibss.bssid) == 0)
-+ if (compare_ether_addr(bssid, rx->sdata->u.ibss.bssid) == 0) {
- sta->last_rx = jiffies;
-+ if (ieee80211_is_data(hdr->frame_control)) {
-+ sta->last_rx_rate_idx = status->rate_idx;
-+ sta->last_rx_rate_flag = status->flag;
-+ }
-+ }
- } else if (!is_multicast_ether_addr(hdr->addr1)) {
- /*
- * Mesh beacons will update last_rx when if they are found to
- * match the current local configuration when processed.
- */
- sta->last_rx = jiffies;
-+ if (ieee80211_is_data(hdr->frame_control)) {
-+ sta->last_rx_rate_idx = status->rate_idx;
-+ sta->last_rx_rate_flag = status->flag;
-+ }
- }
-
- if (!(status->rx_flags & IEEE80211_RX_RA_MATCH))
---- a/net/mac80211/cfg.c
-+++ b/net/mac80211/cfg.c
-@@ -316,6 +316,17 @@ static int ieee80211_config_default_mgmt
- return 0;
- }
-
-+static void rate_idx_to_bitrate(struct rate_info *rate, struct sta_info *sta, int idx)
-+{
-+ if (!(rate->flags & RATE_INFO_FLAGS_MCS)) {
-+ struct ieee80211_supported_band *sband;
-+ sband = sta->local->hw.wiphy->bands[
-+ sta->local->hw.conf.channel->band];
-+ rate->legacy = sband->bitrates[idx].bitrate;
-+ } else
-+ rate->mcs = idx;
-+}
-+
- static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo)
- {
- struct ieee80211_sub_if_data *sdata = sta->sdata;
-@@ -330,6 +341,7 @@ static void sta_set_sinfo(struct sta_inf
- STATION_INFO_TX_RETRIES |
- STATION_INFO_TX_FAILED |
- STATION_INFO_TX_BITRATE |
-+ STATION_INFO_RX_BITRATE |
- STATION_INFO_RX_DROP_MISC;
-
- sinfo->inactive_time = jiffies_to_msecs(jiffies - sta->last_rx);
-@@ -355,15 +367,16 @@ static void sta_set_sinfo(struct sta_inf
- sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
- if (sta->last_tx_rate.flags & IEEE80211_TX_RC_SHORT_GI)
- sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
-+ rate_idx_to_bitrate(&sinfo->txrate, sta, sta->last_tx_rate.idx);
-
-- if (!(sta->last_tx_rate.flags & IEEE80211_TX_RC_MCS)) {
-- struct ieee80211_supported_band *sband;
-- sband = sta->local->hw.wiphy->bands[
-- sta->local->hw.conf.channel->band];
-- sinfo->txrate.legacy =
-- sband->bitrates[sta->last_tx_rate.idx].bitrate;
-- } else
-- sinfo->txrate.mcs = sta->last_tx_rate.idx;
-+ sinfo->rxrate.flags = 0;
-+ if (sta->last_rx_rate_flag & RX_FLAG_HT)
-+ sinfo->rxrate.flags |= RATE_INFO_FLAGS_MCS;
-+ if (sta->last_rx_rate_flag & RX_FLAG_40MHZ)
-+ sinfo->rxrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
-+ if (sta->last_rx_rate_flag & RX_FLAG_SHORT_GI)
-+ sinfo->rxrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
-+ rate_idx_to_bitrate(&sinfo->rxrate, sta, sta->last_rx_rate_idx);
-
- if (ieee80211_vif_is_mesh(&sdata->vif)) {
- #ifdef CONFIG_MAC80211_MESH
diff --git a/package/mac80211/patches/550-ath9k_no_vif_promisc_handling.patch b/package/mac80211/patches/550-ath9k_no_vif_promisc_handling.patch
deleted file mode 100644
index c3a9663266..0000000000
--- a/package/mac80211/patches/550-ath9k_no_vif_promisc_handling.patch
+++ /dev/null
@@ -1,13 +0,0 @@
---- a/drivers/net/wireless/ath/ath9k/recv.c
-+++ b/drivers/net/wireless/ath/ath9k/recv.c
-@@ -413,9 +413,7 @@ u32 ath_calcrxfilter(struct ath_softc *s
- * mode interface or when in monitor mode. AP mode does not need this
- * since it receives all in-BSS frames anyway.
- */
-- if (((sc->sc_ah->opmode != NL80211_IFTYPE_AP) &&
-- (sc->rx.rxfilter & FIF_PROMISC_IN_BSS)) ||
-- (sc->sc_ah->is_monitoring))
-+ if (sc->sc_ah->is_monitoring)
- rfilt |= ATH9K_RX_FILTER_PROM;
-
- if (sc->rx.rxfilter & FIF_CONTROL)
diff --git a/package/mac80211/patches/560-mac80211_minstrel_ht_sampling_fix.patch b/package/mac80211/patches/560-mac80211_minstrel_ht_sampling_fix.patch
deleted file mode 100644
index 011f87ad31..0000000000
--- a/package/mac80211/patches/560-mac80211_minstrel_ht_sampling_fix.patch
+++ /dev/null
@@ -1,50 +0,0 @@
---- a/net/mac80211/rc80211_minstrel_ht.c
-+++ b/net/mac80211/rc80211_minstrel_ht.c
-@@ -415,10 +415,8 @@ minstrel_ht_tx_status(void *priv, struct
- mi->sample_count--;
- }
-
-- if (info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE) {
-+ if (info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE)
- mi->sample_packets += info->status.ampdu_len;
-- minstrel_next_sample_idx(mi);
-- }
-
- for (i = 0; !last; i++) {
- last = (i == IEEE80211_TX_MAX_RATES - 1) ||
-@@ -553,13 +551,14 @@ minstrel_get_sample_rate(struct minstrel
- sample_idx = sample_table[mg->column][mg->index];
- mr = &mg->rates[sample_idx];
- sample_idx += mi->sample_group * MCS_GROUP_RATES;
-+ minstrel_next_sample_idx(mi);
-
- /*
- * When not using MRR, do not sample if the probability is already
- * higher than 95% to avoid wasting airtime
- */
- if (!mp->has_mrr && (mr->probability > MINSTREL_FRAC(95, 100)))
-- goto next;
-+ return -1;
-
- /*
- * Make sure that lower rates get sampled only occasionally,
-@@ -568,17 +567,13 @@ minstrel_get_sample_rate(struct minstrel
- if (minstrel_get_duration(sample_idx) >
- minstrel_get_duration(mi->max_tp_rate)) {
- if (mr->sample_skipped < 20)
-- goto next;
-+ return -1;
-
- if (mi->sample_slow++ > 2)
-- goto next;
-+ return -1;
- }
-
- return sample_idx;
--
--next:
-- minstrel_next_sample_idx(mi);
-- return -1;
- }
-
- static void
diff --git a/package/mac80211/patches/570-ath9k_fix_reg_bit_macros.patch b/package/mac80211/patches/570-ath9k_fix_reg_bit_macros.patch
deleted file mode 100644
index 7d961d2c2f..0000000000
--- a/package/mac80211/patches/570-ath9k_fix_reg_bit_macros.patch
+++ /dev/null
@@ -1,14 +0,0 @@
---- a/drivers/net/wireless/ath/ath9k/hw.h
-+++ b/drivers/net/wireless/ath/ath9k/hw.h
-@@ -95,9 +95,9 @@
- #define REG_READ_FIELD(_a, _r, _f) \
- (((REG_READ(_a, _r) & _f) >> _f##_S))
- #define REG_SET_BIT(_a, _r, _f) \
-- REG_WRITE(_a, _r, REG_READ(_a, _r) | _f)
-+ REG_WRITE(_a, _r, REG_READ(_a, _r) | (_f))
- #define REG_CLR_BIT(_a, _r, _f) \
-- REG_WRITE(_a, _r, REG_READ(_a, _r) & ~_f)
-+ REG_WRITE(_a, _r, REG_READ(_a, _r) & ~(_f))
-
- #define DO_DELAY(x) do { \
- if ((++(x) % 64) == 0) \
diff --git a/package/mac80211/patches/571-ath9k_fix_dma_stop.patch b/package/mac80211/patches/571-ath9k_fix_dma_stop.patch
deleted file mode 100644
index 9f7cfa82ec..0000000000
--- a/package/mac80211/patches/571-ath9k_fix_dma_stop.patch
+++ /dev/null
@@ -1,72 +0,0 @@
---- a/drivers/net/wireless/ath/ath9k/xmit.c
-+++ b/drivers/net/wireless/ath/ath9k/xmit.c
-@@ -1271,16 +1271,14 @@ bool ath_drain_all_txq(struct ath_softc
- if (sc->sc_flags & SC_OP_INVALID)
- return true;
-
-- /* Stop beacon queue */
-- ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq);
-+ ath9k_hw_abort_tx_dma(ah);
-
-- /* Stop data queues */
-+ /* Check if any queue remains active */
- for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) {
-- if (ATH_TXQ_SETUP(sc, i)) {
-- txq = &sc->tx.txq[i];
-- ath9k_hw_stoptxdma(ah, txq->axq_qnum);
-- npend += ath9k_hw_numtxpending(ah, txq->axq_qnum);
-- }
-+ if (!ATH_TXQ_SETUP(sc, i))
-+ continue;
-+
-+ npend += ath9k_hw_numtxpending(ah, sc->tx.txq[i].axq_qnum);
- }
-
- if (npend)
---- a/drivers/net/wireless/ath/ath9k/mac.c
-+++ b/drivers/net/wireless/ath/ath9k/mac.c
-@@ -143,6 +143,34 @@ bool ath9k_hw_updatetxtriglevel(struct a
- }
- EXPORT_SYMBOL(ath9k_hw_updatetxtriglevel);
-
-+void ath9k_hw_abort_tx_dma(struct ath_hw *ah)
-+{
-+ int i, q;
-+
-+ REG_WRITE(ah, AR_Q_TXD, AR_Q_TXD_M);
-+
-+ REG_SET_BIT(ah, AR_PCU_MISC, AR_PCU_FORCE_QUIET_COLL | AR_PCU_CLEAR_VMF);
-+ REG_SET_BIT(ah, AR_DIAG_SW, AR_DIAG_FORCE_CH_IDLE_HIGH);
-+ REG_SET_BIT(ah, AR_D_GBL_IFS_MISC, AR_D_GBL_IFS_MISC_IGNORE_BACKOFF);
-+
-+ for (q = 0; q < AR_NUM_QCU; q++) {
-+ for (i = 0; i < 1000; i++) {
-+ if (i)
-+ udelay(5);
-+
-+ if (!ath9k_hw_numtxpending(ah, q))
-+ break;
-+ }
-+ }
-+
-+ REG_CLR_BIT(ah, AR_PCU_MISC, AR_PCU_FORCE_QUIET_COLL | AR_PCU_CLEAR_VMF);
-+ REG_CLR_BIT(ah, AR_DIAG_SW, AR_DIAG_FORCE_CH_IDLE_HIGH);
-+ REG_CLR_BIT(ah, AR_D_GBL_IFS_MISC, AR_D_GBL_IFS_MISC_IGNORE_BACKOFF);
-+
-+ REG_WRITE(ah, AR_Q_TXD, 0);
-+}
-+EXPORT_SYMBOL(ath9k_hw_abort_tx_dma);
-+
- bool ath9k_hw_stoptxdma(struct ath_hw *ah, u32 q)
- {
- #define ATH9K_TX_STOP_DMA_TIMEOUT 4000 /* usec */
---- a/drivers/net/wireless/ath/ath9k/mac.h
-+++ b/drivers/net/wireless/ath/ath9k/mac.h
-@@ -676,6 +676,7 @@ void ath9k_hw_cleartxdesc(struct ath_hw
- u32 ath9k_hw_numtxpending(struct ath_hw *ah, u32 q);
- bool ath9k_hw_updatetxtriglevel(struct ath_hw *ah, bool bIncTrigLevel);
- bool ath9k_hw_stoptxdma(struct ath_hw *ah, u32 q);
-+void ath9k_hw_abort_tx_dma(struct ath_hw *ah);
- void ath9k_hw_gettxintrtxqs(struct ath_hw *ah, u32 *txqs);
- bool ath9k_hw_set_txq_props(struct ath_hw *ah, int q,
- const struct ath9k_tx_queue_info *qinfo);
diff --git a/package/mac80211/patches/572-ath9k_fix_tx_flush.patch b/package/mac80211/patches/572-ath9k_fix_tx_flush.patch
deleted file mode 100644
index 630abc6fdc..0000000000
--- a/package/mac80211/patches/572-ath9k_fix_tx_flush.patch
+++ /dev/null
@@ -1,141 +0,0 @@
---- a/drivers/net/wireless/ath/ath9k/main.c
-+++ b/drivers/net/wireless/ath/ath9k/main.c
-@@ -2149,56 +2149,42 @@ static void ath9k_set_coverage_class(str
-
- static void ath9k_flush(struct ieee80211_hw *hw, bool drop)
- {
--#define ATH_FLUSH_TIMEOUT 60 /* ms */
- struct ath_softc *sc = hw->priv;
-- struct ath_txq *txq = NULL;
-- struct ath_hw *ah = sc->sc_ah;
-- struct ath_common *common = ath9k_hw_common(ah);
-- int i, j, npend = 0;
-+ int timeout = 200; /* ms */
-+ int i, j;
-
-+ ath9k_ps_wakeup(sc);
- mutex_lock(&sc->mutex);
-
- cancel_delayed_work_sync(&sc->tx_complete_work);
-
-- for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) {
-- if (!ATH_TXQ_SETUP(sc, i))
-- continue;
-- txq = &sc->tx.txq[i];
--
-- if (!drop) {
-- for (j = 0; j < ATH_FLUSH_TIMEOUT; j++) {
-- if (!ath9k_has_pending_frames(sc, txq))
-- break;
-- usleep_range(1000, 2000);
-- }
-- }
-+ if (drop)
-+ timeout = 1;
-+
-+ for (j = 0; j < timeout; j++) {
-+ int npend = 0;
-+
-+ if (j)
-+ usleep_range(1000, 2000);
-
-- if (drop || ath9k_has_pending_frames(sc, txq)) {
-- ath_dbg(common, ATH_DBG_QUEUE, "Drop frames from hw queue:%d\n",
-- txq->axq_qnum);
-- spin_lock_bh(&txq->axq_lock);
-- txq->txq_flush_inprogress = true;
-- spin_unlock_bh(&txq->axq_lock);
--
-- ath9k_ps_wakeup(sc);
-- ath9k_hw_stoptxdma(ah, txq->axq_qnum);
-- npend = ath9k_hw_numtxpending(ah, txq->axq_qnum);
-- ath9k_ps_restore(sc);
-- if (npend)
-- break;
-+ for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) {
-+ if (!ATH_TXQ_SETUP(sc, i))
-+ continue;
-
-- ath_draintxq(sc, txq, false);
-- txq->txq_flush_inprogress = false;
-+ npend += ath9k_has_pending_frames(sc, &sc->tx.txq[i]);
- }
-+
-+ if (!npend)
-+ goto out;
- }
-
-- if (npend) {
-+ if (!ath_drain_all_txq(sc, false))
- ath_reset(sc, false);
-- txq->txq_flush_inprogress = false;
-- }
-
-+out:
- ieee80211_queue_delayed_work(hw, &sc->tx_complete_work, 0);
- mutex_unlock(&sc->mutex);
-+ ath9k_ps_restore(sc);
- }
-
- struct ieee80211_ops ath9k_ops = {
---- a/drivers/net/wireless/ath/ath9k/ath9k.h
-+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
-@@ -189,7 +189,6 @@ struct ath_txq {
- u32 axq_ampdu_depth;
- bool stopped;
- bool axq_tx_inprogress;
-- bool txq_flush_inprogress;
- struct list_head axq_acq;
- struct list_head txq_fifo[ATH_TXFIFO_DEPTH];
- struct list_head txq_fifo_pending;
---- a/drivers/net/wireless/ath/ath9k/xmit.c
-+++ b/drivers/net/wireless/ath/ath9k/xmit.c
-@@ -2091,8 +2091,7 @@ static void ath_tx_processq(struct ath_s
- spin_lock_bh(&txq->axq_lock);
- if (list_empty(&txq->axq_q)) {
- txq->axq_link = NULL;
-- if (sc->sc_flags & SC_OP_TXAGGR &&
-- !txq->txq_flush_inprogress)
-+ if (sc->sc_flags & SC_OP_TXAGGR)
- ath_txq_schedule(sc, txq);
- spin_unlock_bh(&txq->axq_lock);
- break;
-@@ -2173,7 +2172,7 @@ static void ath_tx_processq(struct ath_s
-
- spin_lock_bh(&txq->axq_lock);
-
-- if (sc->sc_flags & SC_OP_TXAGGR && !txq->txq_flush_inprogress)
-+ if (sc->sc_flags & SC_OP_TXAGGR)
- ath_txq_schedule(sc, txq);
- spin_unlock_bh(&txq->axq_lock);
- }
-@@ -2317,18 +2316,17 @@ void ath_tx_edma_tasklet(struct ath_soft
-
- spin_lock_bh(&txq->axq_lock);
-
-- if (!txq->txq_flush_inprogress) {
-- if (!list_empty(&txq->txq_fifo_pending)) {
-- INIT_LIST_HEAD(&bf_head);
-- bf = list_first_entry(&txq->txq_fifo_pending,
-- struct ath_buf, list);
-- list_cut_position(&bf_head,
-- &txq->txq_fifo_pending,
-- &bf->bf_lastbf->list);
-- ath_tx_txqaddbuf(sc, txq, &bf_head);
-- } else if (sc->sc_flags & SC_OP_TXAGGR)
-- ath_txq_schedule(sc, txq);
-- }
-+ if (!list_empty(&txq->txq_fifo_pending)) {
-+ INIT_LIST_HEAD(&bf_head);
-+ bf = list_first_entry(&txq->txq_fifo_pending,
-+ struct ath_buf, list);
-+ list_cut_position(&bf_head,
-+ &txq->txq_fifo_pending,
-+ &bf->bf_lastbf->list);
-+ ath_tx_txqaddbuf(sc, txq, &bf_head);
-+ } else if (sc->sc_flags & SC_OP_TXAGGR)
-+ ath_txq_schedule(sc, txq);
-+
- spin_unlock_bh(&txq->axq_lock);
- }
- }
diff --git a/package/mac80211/patches/573-ath9k_beacon_stop.patch b/package/mac80211/patches/573-ath9k_beacon_stop.patch
deleted file mode 100644
index 5574d17168..0000000000
--- a/package/mac80211/patches/573-ath9k_beacon_stop.patch
+++ /dev/null
@@ -1,143 +0,0 @@
---- a/drivers/net/wireless/ath/ath9k/mac.c
-+++ b/drivers/net/wireless/ath/ath9k/mac.c
-@@ -171,84 +171,31 @@ void ath9k_hw_abort_tx_dma(struct ath_hw
- }
- EXPORT_SYMBOL(ath9k_hw_abort_tx_dma);
-
--bool ath9k_hw_stoptxdma(struct ath_hw *ah, u32 q)
-+bool ath9k_hw_stop_dma_queue(struct ath_hw *ah, u32 q)
- {
--#define ATH9K_TX_STOP_DMA_TIMEOUT 4000 /* usec */
-+#define ATH9K_TX_STOP_DMA_TIMEOUT 1000 /* usec */
- #define ATH9K_TIME_QUANTUM 100 /* usec */
-- struct ath_common *common = ath9k_hw_common(ah);
-- struct ath9k_hw_capabilities *pCap = &ah->caps;
-- struct ath9k_tx_queue_info *qi;
-- u32 tsfLow, j, wait;
-- u32 wait_time = ATH9K_TX_STOP_DMA_TIMEOUT / ATH9K_TIME_QUANTUM;
--
-- if (q >= pCap->total_queues) {
-- ath_dbg(common, ATH_DBG_QUEUE,
-- "Stopping TX DMA, invalid queue: %u\n", q);
-- return false;
-- }
--
-- qi = &ah->txq[q];
-- if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
-- ath_dbg(common, ATH_DBG_QUEUE,
-- "Stopping TX DMA, inactive queue: %u\n", q);
-- return false;
-- }
-+ int wait_time = ATH9K_TX_STOP_DMA_TIMEOUT / ATH9K_TIME_QUANTUM;
-+ int wait;
-
- REG_WRITE(ah, AR_Q_TXD, 1 << q);
-
- for (wait = wait_time; wait != 0; wait--) {
-- if (ath9k_hw_numtxpending(ah, q) == 0)
-- break;
-- udelay(ATH9K_TIME_QUANTUM);
-- }
--
-- if (ath9k_hw_numtxpending(ah, q)) {
-- ath_dbg(common, ATH_DBG_QUEUE,
-- "%s: Num of pending TX Frames %d on Q %d\n",
-- __func__, ath9k_hw_numtxpending(ah, q), q);
--
-- for (j = 0; j < 2; j++) {
-- tsfLow = REG_READ(ah, AR_TSF_L32);
-- REG_WRITE(ah, AR_QUIET2,
-- SM(10, AR_QUIET2_QUIET_DUR));
-- REG_WRITE(ah, AR_QUIET_PERIOD, 100);
-- REG_WRITE(ah, AR_NEXT_QUIET_TIMER, tsfLow >> 10);
-- REG_SET_BIT(ah, AR_TIMER_MODE,
-- AR_QUIET_TIMER_EN);
--
-- if ((REG_READ(ah, AR_TSF_L32) >> 10) == (tsfLow >> 10))
-- break;
--
-- ath_dbg(common, ATH_DBG_QUEUE,
-- "TSF has moved while trying to set quiet time TSF: 0x%08x\n",
-- tsfLow);
-- }
--
-- REG_SET_BIT(ah, AR_DIAG_SW, AR_DIAG_FORCE_CH_IDLE_HIGH);
--
-- udelay(200);
-- REG_CLR_BIT(ah, AR_TIMER_MODE, AR_QUIET_TIMER_EN);
--
-- wait = wait_time;
-- while (ath9k_hw_numtxpending(ah, q)) {
-- if ((--wait) == 0) {
-- ath_err(common,
-- "Failed to stop TX DMA in 100 msec after killing last frame\n");
-- break;
-- }
-+ if (wait != wait_time)
- udelay(ATH9K_TIME_QUANTUM);
-- }
-
-- REG_CLR_BIT(ah, AR_DIAG_SW, AR_DIAG_FORCE_CH_IDLE_HIGH);
-+ if (ath9k_hw_numtxpending(ah, q) == 0)
-+ break;
- }
-
- REG_WRITE(ah, AR_Q_TXD, 0);
-+
- return wait != 0;
-
- #undef ATH9K_TX_STOP_DMA_TIMEOUT
- #undef ATH9K_TIME_QUANTUM
- }
--EXPORT_SYMBOL(ath9k_hw_stoptxdma);
-+EXPORT_SYMBOL(ath9k_hw_stop_dma_queue);
-
- void ath9k_hw_gettxintrtxqs(struct ath_hw *ah, u32 *txqs)
- {
---- a/drivers/net/wireless/ath/ath9k/mac.h
-+++ b/drivers/net/wireless/ath/ath9k/mac.h
-@@ -675,7 +675,7 @@ void ath9k_hw_txstart(struct ath_hw *ah,
- void ath9k_hw_cleartxdesc(struct ath_hw *ah, void *ds);
- u32 ath9k_hw_numtxpending(struct ath_hw *ah, u32 q);
- bool ath9k_hw_updatetxtriglevel(struct ath_hw *ah, bool bIncTrigLevel);
--bool ath9k_hw_stoptxdma(struct ath_hw *ah, u32 q);
-+bool ath9k_hw_stop_dma_queue(struct ath_hw *ah, u32 q);
- void ath9k_hw_abort_tx_dma(struct ath_hw *ah);
- void ath9k_hw_gettxintrtxqs(struct ath_hw *ah, u32 *txqs);
- bool ath9k_hw_set_txq_props(struct ath_hw *ah, int q,
---- a/drivers/net/wireless/ath/ath9k/beacon.c
-+++ b/drivers/net/wireless/ath/ath9k/beacon.c
-@@ -373,6 +373,7 @@ void ath_beacon_tasklet(unsigned long da
- ath_dbg(common, ATH_DBG_BSTUCK,
- "missed %u consecutive beacons\n",
- sc->beacon.bmisscnt);
-+ ath9k_hw_stop_dma_queue(ah, sc->beacon.beaconq);
- ath9k_hw_bstuck_nfcal(ah);
- } else if (sc->beacon.bmisscnt >= BSTUCK_THRESH) {
- ath_dbg(common, ATH_DBG_BSTUCK,
-@@ -450,16 +451,6 @@ void ath_beacon_tasklet(unsigned long da
- sc->beacon.updateslot = OK;
- }
- if (bfaddr != 0) {
-- /*
-- * Stop any current dma and put the new frame(s) on the queue.
-- * This should never fail since we check above that no frames
-- * are still pending on the queue.
-- */
-- if (!ath9k_hw_stoptxdma(ah, sc->beacon.beaconq)) {
-- ath_err(common, "beacon queue %u did not stop?\n",
-- sc->beacon.beaconq);
-- }
--
- /* NB: cabq traffic should already be queued and primed */
- ath9k_hw_puttxbuf(ah, sc->beacon.beaconq, bfaddr);
- ath9k_hw_txstart(ah, sc->beacon.beaconq);
-@@ -780,7 +771,7 @@ void ath9k_set_beaconing_status(struct a
- ah->imask &= ~ATH9K_INT_SWBA;
- ath9k_hw_set_interrupts(ah, ah->imask);
- tasklet_kill(&sc->bcon_tasklet);
-- ath9k_hw_stoptxdma(ah, sc->beacon.beaconq);
-+ ath9k_hw_stop_dma_queue(ah, sc->beacon.beaconq);
- }
- ath9k_ps_restore(sc);
- }
diff --git a/package/mac80211/patches/581-mac80211_chantype_change_fix.patch b/package/mac80211/patches/581-mac80211_chantype_change_fix.patch
deleted file mode 100644
index b855d1d809..0000000000
--- a/package/mac80211/patches/581-mac80211_chantype_change_fix.patch
+++ /dev/null
@@ -1,12 +0,0 @@
---- a/net/mac80211/chan.c
-+++ b/net/mac80211/chan.c
-@@ -77,6 +77,9 @@ bool ieee80211_set_channel_type(struct i
- switch (tmp->vif.bss_conf.channel_type) {
- case NL80211_CHAN_NO_HT:
- case NL80211_CHAN_HT20:
-+ if (superchan > tmp->vif.bss_conf.channel_type)
-+ break;
-+
- superchan = tmp->vif.bss_conf.channel_type;
- break;
- case NL80211_CHAN_HT40PLUS:
diff --git a/package/mac80211/patches/590-ath9k_tid_cleanup_send_bar.patch b/package/mac80211/patches/590-ath9k_tid_cleanup_send_bar.patch
deleted file mode 100644
index 0f58485914..0000000000
--- a/package/mac80211/patches/590-ath9k_tid_cleanup_send_bar.patch
+++ /dev/null
@@ -1,11 +0,0 @@
---- a/drivers/net/wireless/ath/ath9k/xmit.c
-+++ b/drivers/net/wireless/ath/ath9k/xmit.c
-@@ -166,7 +166,7 @@ static void ath_tx_flush_tid(struct ath_
- fi = get_frame_info(bf->bf_mpdu);
- if (fi->retries) {
- ath_tx_update_baw(sc, tid, fi->seqno);
-- ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, 0, 0);
-+ ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, 0, 1);
- } else {
- ath_tx_send_normal(sc, txq, NULL, &bf_head);
- }
diff --git a/package/mac80211/patches/700-mwl8k-missing-pci-id-for-WNR854T.patch b/package/mac80211/patches/700-mwl8k-missing-pci-id-for-WNR854T.patch
index c60d51a21f..ebc7c6bee9 100644
--- a/package/mac80211/patches/700-mwl8k-missing-pci-id-for-WNR854T.patch
+++ b/package/mac80211/patches/700-mwl8k-missing-pci-id-for-WNR854T.patch
@@ -1,6 +1,6 @@
--- a/drivers/net/wireless/mwl8k.c
+++ b/drivers/net/wireless/mwl8k.c
-@@ -4502,6 +4502,7 @@ MODULE_FIRMWARE("mwl8k/fmimage_8366.fw")
+@@ -4500,6 +4500,7 @@ MODULE_FIRMWARE("mwl8k/fmimage_8366.fw")
MODULE_FIRMWARE(MWL8K_8366_AP_FW(MWL8K_8366_AP_FW_API));
static DEFINE_PCI_DEVICE_TABLE(mwl8k_pci_id_table) = {
diff --git a/package/mac80211/patches/710-p54_rssi_crash_fix.patch b/package/mac80211/patches/710-p54_rssi_crash_fix.patch
deleted file mode 100644
index 73089cda55..0000000000
--- a/package/mac80211/patches/710-p54_rssi_crash_fix.patch
+++ /dev/null
@@ -1,18 +0,0 @@
---- a/drivers/net/wireless/p54/eeprom.c
-+++ b/drivers/net/wireless/p54/eeprom.c
-@@ -524,10 +524,13 @@ err_data:
-
- struct p54_rssi_db_entry *p54_rssi_find(struct p54_common *priv, const u16 freq)
- {
-- struct p54_rssi_db_entry *entry = (void *)(priv->rssi_db->data +
-- priv->rssi_db->offset);
-+ struct p54_rssi_db_entry *entry;
- int i, found = -1;
-
-+ if (!priv->rssi_db)
-+ return &p54_rssi_default;
-+
-+ entry = (void *)(priv->rssi_db->data + priv->rssi_db->offset);
- for (i = 0; i < priv->rssi_db->entries; i++) {
- if (!same_band(freq, entry[i].freq))
- continue;
diff --git a/package/mac80211/patches/720-mac80211-print-restart-warning.patch b/package/mac80211/patches/720-mac80211-print-restart-warning.patch
deleted file mode 100644
index 7a28598533..0000000000
--- a/package/mac80211/patches/720-mac80211-print-restart-warning.patch
+++ /dev/null
@@ -1,14 +0,0 @@
-Index: compat-wireless-2011-02-25/net/mac80211/main.c
-===================================================================
---- compat-wireless-2011-02-25.orig/net/mac80211/main.c 2011-03-07 12:58:14.996968980 +0100
-+++ compat-wireless-2011-02-25/net/mac80211/main.c 2011-03-07 13:03:26.732273903 +0100
-@@ -384,6 +384,9 @@ void ieee80211_restart_hw(struct ieee802
-
- trace_api_restart_hw(local);
-
-+ wiphy_info(hw->wiphy,
-+ "Hardware restart was requested\n");
-+
- /* use this reason, ieee80211_reconfig will unblock it */
- ieee80211_stop_queues_by_reason(hw,
- IEEE80211_QUEUE_STOP_REASON_SUSPEND);
diff --git a/package/mac80211/patches/721-mac80211-fix-scan-race.patch b/package/mac80211/patches/721-mac80211-fix-scan-race.patch
deleted file mode 100644
index efc01b1761..0000000000
--- a/package/mac80211/patches/721-mac80211-fix-scan-race.patch
+++ /dev/null
@@ -1,141 +0,0 @@
-Index: compat-wireless-2011-02-25/net/mac80211/scan.c
-===================================================================
---- compat-wireless-2011-02-25.orig/net/mac80211/scan.c 2011-03-07 14:43:55.695666042 +0100
-+++ compat-wireless-2011-02-25/net/mac80211/scan.c 2011-03-07 14:43:57.594439631 +0100
-@@ -258,10 +258,12 @@ static bool ieee80211_prep_hw_scan(struc
- return true;
- }
-
--static bool __ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted,
-+static void __ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted,
- bool was_hw_scan)
- {
- struct ieee80211_local *local = hw_to_local(hw);
-+ bool on_oper_chan;
-+ bool enable_beacons = false;
-
- lockdep_assert_held(&local->mtx);
-
-@@ -275,12 +277,12 @@ static bool __ieee80211_scan_completed(s
- aborted = true;
-
- if (WARN_ON(!local->scan_req))
-- return false;
-+ return;
-
- if (was_hw_scan && !aborted && ieee80211_prep_hw_scan(local)) {
- int rc = drv_hw_scan(local, local->scan_sdata, local->hw_scan_req);
- if (rc == 0)
-- return false;
-+ return;
- }
-
- kfree(local->hw_scan_req);
-@@ -294,26 +296,13 @@ static bool __ieee80211_scan_completed(s
- local->scanning = 0;
- local->scan_channel = NULL;
-
-- return true;
--}
--
--static void __ieee80211_scan_completed_finish(struct ieee80211_hw *hw,
-- bool was_hw_scan)
--{
-- struct ieee80211_local *local = hw_to_local(hw);
-- bool on_oper_chan;
-- bool enable_beacons = false;
--
-- mutex_lock(&local->mtx);
- on_oper_chan = ieee80211_cfg_on_oper_channel(local);
-
- WARN_ON(local->scanning & (SCAN_SW_SCANNING | SCAN_HW_SCANNING));
-
-- if (was_hw_scan || !on_oper_chan) {
-- if (WARN_ON(local->scan_channel))
-- local->scan_channel = NULL;
-+ if (was_hw_scan || !on_oper_chan)
- ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL);
-- } else
-+ else
- /* Set power back to normal operating levels. */
- ieee80211_hw_config(local, 0);
-
-@@ -331,7 +320,6 @@ static void __ieee80211_scan_completed_f
- }
-
- ieee80211_recalc_idle(local);
-- mutex_unlock(&local->mtx);
-
- ieee80211_mlme_notify_scan_completed(local);
- ieee80211_ibss_notify_scan_completed(local);
-@@ -686,12 +674,14 @@ void ieee80211_scan_work(struct work_str
- {
- struct ieee80211_local *local =
- container_of(work, struct ieee80211_local, scan_work.work);
-- struct ieee80211_sub_if_data *sdata = local->scan_sdata;
-+ struct ieee80211_sub_if_data *sdata;
- unsigned long next_delay = 0;
-- bool aborted, hw_scan, finish;
-+ bool aborted, hw_scan;
-
- mutex_lock(&local->mtx);
-
-+ sdata = local->scan_sdata;
-+
- if (test_and_clear_bit(SCAN_COMPLETED, &local->scanning)) {
- aborted = test_and_clear_bit(SCAN_ABORTED, &local->scanning);
- goto out_complete;
-@@ -755,17 +745,11 @@ void ieee80211_scan_work(struct work_str
- } while (next_delay == 0);
-
- ieee80211_queue_delayed_work(&local->hw, &local->scan_work, next_delay);
-- mutex_unlock(&local->mtx);
-- return;
-+ goto out;
-
- out_complete:
- hw_scan = test_bit(SCAN_HW_SCANNING, &local->scanning);
-- finish = __ieee80211_scan_completed(&local->hw, aborted, hw_scan);
-- mutex_unlock(&local->mtx);
-- if (finish)
-- __ieee80211_scan_completed_finish(&local->hw, hw_scan);
-- return;
--
-+ __ieee80211_scan_completed(&local->hw, aborted, hw_scan);
- out:
- mutex_unlock(&local->mtx);
- }
-@@ -835,7 +819,6 @@ int ieee80211_request_internal_scan(stru
- void ieee80211_scan_cancel(struct ieee80211_local *local)
- {
- bool abortscan;
-- bool finish = false;
-
- /*
- * We are only canceling software scan, or deferred scan that was not
-@@ -855,14 +838,17 @@ void ieee80211_scan_cancel(struct ieee80
-
- mutex_lock(&local->mtx);
- abortscan = local->scan_req && !test_bit(SCAN_HW_SCANNING, &local->scanning);
-- if (abortscan)
-- finish = __ieee80211_scan_completed(&local->hw, true, false);
-- mutex_unlock(&local->mtx);
--
- if (abortscan) {
-- /* The scan is canceled, but stop work from being pending */
-- cancel_delayed_work_sync(&local->scan_work);
-+ /*
-+ * The scan is canceled, but stop work from being pending.
-+ *
-+ * If the work is currently running, it must be blocked on
-+ * the mutex, but we'll set scan_sdata = NULL and it'll
-+ * simply exit once it acquires the mutex.
-+ */
-+ cancel_delayed_work(&local->scan_work);
-+ /* and clean up */
-+ __ieee80211_scan_completed(&local->hw, true, false);
- }
-- if (finish)
-- __ieee80211_scan_completed_finish(&local->hw, false);
-+ mutex_unlock(&local->mtx);
- }