From 7ae2f4974863322a7ca42c58031d0e5f1293eff7 Mon Sep 17 00:00:00 2001 From: nbd Date: Sun, 13 Mar 2011 18:38:37 +0000 Subject: mac80211: update to wireless-testing 2011-03-11 git-svn-id: svn://svn.openwrt.org/openwrt/trunk@26128 3c298f89-4303-0410-b956-a3cf2f4a3e73 --- package/mac80211/Makefile | 4 +- .../patches/030-backport_93c86_eeprom.patch | 6 +- .../mac80211/patches/050-fix_missing_include.patch | 10 - .../mac80211/patches/300-ath9k_gpio_settings.patch | 4 +- package/mac80211/patches/310-pending_work.patch | 366 +++++++++++++++++++++ .../401-ath9k-dont-register-leds-on-ar9100.patch | 14 +- ...k-override-mac-address-from-platform-data.patch | 6 +- .../patches/409-ath9k_platform_settings.patch | 8 +- .../patches/500-ath9k_eeprom_debugfs.patch | 6 +- .../patches/510-ath9k_intr_mitigation_tweak.patch | 13 + .../mac80211/patches/510-ath9k_led_cleanup.patch | 303 ----------------- .../patches/520-ath9k_intr_mitigation_tweak.patch | 13 - .../patches/520-mac80211_drv_tim_override.patch | 73 ++++ .../patches/521-ath9k_fix_ap_ps_buffering.patch | 311 +++++++++++++++++ ...22-ath9k_remove_pending_frames_workaround.patch | 36 ++ .../patches/530-mac80211_drv_tim_override.patch | 73 ---- .../530-mac80211_redirect_vlan_eap_frames.patch | 67 ++++ .../patches/531-ath9k_fix_ap_ps_buffering.patch | 311 ----------------- ...32-ath9k_remove_pending_frames_workaround.patch | 36 -- .../patches/540-mac80211_add_rx_rate.patch | 232 ------------- .../550-ath9k_no_vif_promisc_handling.patch | 13 - .../560-mac80211_minstrel_ht_sampling_fix.patch | 50 --- .../patches/570-ath9k_fix_reg_bit_macros.patch | 14 - .../mac80211/patches/571-ath9k_fix_dma_stop.patch | 72 ---- .../mac80211/patches/572-ath9k_fix_tx_flush.patch | 141 -------- .../mac80211/patches/573-ath9k_beacon_stop.patch | 143 -------- .../580-mac80211_redirect_vlan_eap_frames.patch | 67 ---- .../patches/581-mac80211_chantype_change_fix.patch | 12 - .../patches/590-ath9k_tid_cleanup_send_bar.patch | 11 - .../700-mwl8k-missing-pci-id-for-WNR854T.patch | 2 +- .../mac80211/patches/710-p54_rssi_crash_fix.patch | 18 - .../720-mac80211-print-restart-warning.patch | 14 - .../patches/721-mac80211-fix-scan-race.patch | 141 -------- 33 files changed, 888 insertions(+), 1702 deletions(-) delete mode 100644 package/mac80211/patches/050-fix_missing_include.patch create mode 100644 package/mac80211/patches/310-pending_work.patch create mode 100644 package/mac80211/patches/510-ath9k_intr_mitigation_tweak.patch delete mode 100644 package/mac80211/patches/510-ath9k_led_cleanup.patch delete mode 100644 package/mac80211/patches/520-ath9k_intr_mitigation_tweak.patch create mode 100644 package/mac80211/patches/520-mac80211_drv_tim_override.patch create mode 100644 package/mac80211/patches/521-ath9k_fix_ap_ps_buffering.patch create mode 100644 package/mac80211/patches/522-ath9k_remove_pending_frames_workaround.patch delete mode 100644 package/mac80211/patches/530-mac80211_drv_tim_override.patch create mode 100644 package/mac80211/patches/530-mac80211_redirect_vlan_eap_frames.patch delete mode 100644 package/mac80211/patches/531-ath9k_fix_ap_ps_buffering.patch delete mode 100644 package/mac80211/patches/532-ath9k_remove_pending_frames_workaround.patch delete mode 100644 package/mac80211/patches/540-mac80211_add_rx_rate.patch delete mode 100644 package/mac80211/patches/550-ath9k_no_vif_promisc_handling.patch delete mode 100644 package/mac80211/patches/560-mac80211_minstrel_ht_sampling_fix.patch delete mode 100644 package/mac80211/patches/570-ath9k_fix_reg_bit_macros.patch delete mode 100644 package/mac80211/patches/571-ath9k_fix_dma_stop.patch delete mode 100644 package/mac80211/patches/572-ath9k_fix_tx_flush.patch delete mode 100644 package/mac80211/patches/573-ath9k_beacon_stop.patch delete mode 100644 package/mac80211/patches/580-mac80211_redirect_vlan_eap_frames.patch delete mode 100644 package/mac80211/patches/581-mac80211_chantype_change_fix.patch delete mode 100644 package/mac80211/patches/590-ath9k_tid_cleanup_send_bar.patch delete mode 100644 package/mac80211/patches/710-p54_rssi_crash_fix.patch delete mode 100644 package/mac80211/patches/720-mac80211-print-restart-warning.patch delete mode 100644 package/mac80211/patches/721-mac80211-fix-scan-race.patch (limited to 'package') diff --git a/package/mac80211/Makefile b/package/mac80211/Makefile index c78a6cb0a..46293696c 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 0415e5f1f..30ff85ed0 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 458ff4d86..000000000 --- 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 - #include -+#include - - /* - * Termios Helper Methods diff --git a/package/mac80211/patches/300-ath9k_gpio_settings.patch b/package/mac80211/patches/300-ath9k_gpio_settings.patch index e38b572e5..af2057759 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 000000000..57dcecaf1 --- /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 166c133a6..22299020a 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 c92245641..6326649fc 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 23a5887a1..6ce43b600 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 700cf7011..0bb7082ef 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/510-ath9k_intr_mitigation_tweak.patch b/package/mac80211/patches/510-ath9k_intr_mitigation_tweak.patch new file mode 100644 index 000000000..301af3c22 --- /dev/null +++ b/package/mac80211/patches/510-ath9k_intr_mitigation_tweak.patch @@ -0,0 +1,13 @@ +--- a/drivers/net/wireless/ath/ath9k/hw.c ++++ b/drivers/net/wireless/ath/ath9k/hw.c +@@ -1466,8 +1466,8 @@ int ath9k_hw_reset(struct ath_hw *ah, st + REG_WRITE(ah, AR_OBS, 8); + + if (ah->config.rx_intr_mitigation) { +- REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_LAST, 500); +- REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_FIRST, 2000); ++ REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_LAST, 250); ++ REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_FIRST, 500); + } + + if (ah->config.tx_intr_mitigation) { 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 352bee15f..000000000 --- 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/520-ath9k_intr_mitigation_tweak.patch b/package/mac80211/patches/520-ath9k_intr_mitigation_tweak.patch deleted file mode 100644 index 301af3c22..000000000 --- a/package/mac80211/patches/520-ath9k_intr_mitigation_tweak.patch +++ /dev/null @@ -1,13 +0,0 @@ ---- a/drivers/net/wireless/ath/ath9k/hw.c -+++ b/drivers/net/wireless/ath/ath9k/hw.c -@@ -1466,8 +1466,8 @@ int ath9k_hw_reset(struct ath_hw *ah, st - REG_WRITE(ah, AR_OBS, 8); - - if (ah->config.rx_intr_mitigation) { -- REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_LAST, 500); -- REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_FIRST, 2000); -+ REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_LAST, 250); -+ REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_FIRST, 500); - } - - if (ah->config.tx_intr_mitigation) { diff --git a/package/mac80211/patches/520-mac80211_drv_tim_override.patch b/package/mac80211/patches/520-mac80211_drv_tim_override.patch new file mode 100644 index 000000000..535e35927 --- /dev/null +++ b/package/mac80211/patches/520-mac80211_drv_tim_override.patch @@ -0,0 +1,73 @@ +--- a/include/net/mac80211.h ++++ b/include/net/mac80211.h +@@ -2216,6 +2216,18 @@ static inline int ieee80211_sta_ps_trans + #define IEEE80211_TX_STATUS_HEADROOM 13 + + /** ++ * ieee80211_sta_set_tim - set the TIM bit for a sleeping station ++ * ++ * If a driver buffers frames for a powersave station instead of passing ++ * them back to mac80211 for retransmission, the station needs to be told ++ * to wake up using the TIM bitmap in the beacon. ++ * ++ * This function sets the station's TIM bit - it will be cleared when the ++ * station wakes up. ++ */ ++void ieee80211_sta_set_tim(struct ieee80211_sta *sta); ++ ++/** + * ieee80211_tx_status - transmit status callback + * + * Call this function for all transmitted frames after they have been +--- a/net/mac80211/sta_info.c ++++ b/net/mac80211/sta_info.c +@@ -608,7 +608,8 @@ static bool sta_info_cleanup_expire_buff + #endif + dev_kfree_skb(skb); + +- if (skb_queue_empty(&sta->ps_tx_buf)) ++ if (skb_queue_empty(&sta->ps_tx_buf) && ++ !test_sta_flags(sta, WLAN_STA_PS_DRIVER_BUF)) + sta_info_clear_tim_bit(sta); + } + +@@ -899,6 +900,7 @@ void ieee80211_sta_ps_deliver_wakeup(str + struct ieee80211_local *local = sdata->local; + int sent, buffered; + ++ clear_sta_flags(sta, WLAN_STA_PS_DRIVER_BUF); + if (!(local->hw.flags & IEEE80211_HW_AP_LINK_PS)) + drv_sta_notify(local, sdata, STA_NOTIFY_AWAKE, &sta->sta); + +@@ -991,3 +993,12 @@ void ieee80211_sta_block_awake(struct ie + ieee80211_queue_work(hw, &sta->drv_unblock_wk); + } + EXPORT_SYMBOL(ieee80211_sta_block_awake); ++ ++void ieee80211_sta_set_tim(struct ieee80211_sta *pubsta) ++{ ++ struct sta_info *sta = container_of(pubsta, struct sta_info, sta); ++ ++ set_sta_flags(sta, WLAN_STA_PS_DRIVER_BUF); ++ sta_info_set_tim_bit(sta); ++} ++EXPORT_SYMBOL(ieee80211_sta_set_tim); +--- a/net/mac80211/sta_info.h ++++ b/net/mac80211/sta_info.h +@@ -43,6 +43,8 @@ + * be in the queues + * @WLAN_STA_PSPOLL: Station sent PS-poll while driver was keeping + * station in power-save mode, reply when the driver unblocks. ++ * @WLAN_STA_PS_DRIVER_BUF: Station has frames pending in driver internal ++ * buffers. Automatically cleared on station wake-up. + */ + enum ieee80211_sta_info_flags { + WLAN_STA_AUTH = 1<<0, +@@ -58,6 +60,7 @@ enum ieee80211_sta_info_flags { + WLAN_STA_BLOCK_BA = 1<<11, + WLAN_STA_PS_DRIVER = 1<<12, + WLAN_STA_PSPOLL = 1<<13, ++ WLAN_STA_PS_DRIVER_BUF = 1<<14, + }; + + #define STA_TID_NUM 16 diff --git a/package/mac80211/patches/521-ath9k_fix_ap_ps_buffering.patch b/package/mac80211/patches/521-ath9k_fix_ap_ps_buffering.patch new file mode 100644 index 000000000..87cc2654b --- /dev/null +++ b/package/mac80211/patches/521-ath9k_fix_ap_ps_buffering.patch @@ -0,0 +1,311 @@ +--- a/drivers/net/wireless/ath/ath9k/ath9k.h ++++ b/drivers/net/wireless/ath/ath9k/ath9k.h +@@ -202,6 +202,7 @@ struct ath_atx_ac { + int sched; + struct list_head list; + struct list_head tid_q; ++ bool clear_ps_filter; + }; + + struct ath_frame_info { +@@ -259,6 +260,8 @@ struct ath_node { + struct ath_atx_ac ac[WME_NUM_AC]; + u16 maxampdu; + u8 mpdudensity; ++ ++ bool sleeping; + }; + + #define AGGR_CLEANUP BIT(1) +@@ -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); + ++void ath_tx_aggr_wakeup(struct ath_softc *sc, struct ath_node *an); ++bool ath_tx_aggr_sleep(struct ath_softc *sc, struct ath_node *an); ++ + /********/ + /* VIFs */ + /********/ +--- a/drivers/net/wireless/ath/ath9k/main.c ++++ b/drivers/net/wireless/ath/ath9k/main.c +@@ -1791,6 +1791,27 @@ static int ath9k_sta_remove(struct ieee8 + return 0; + } + ++static void ath9k_sta_notify(struct ieee80211_hw *hw, ++ struct ieee80211_vif *vif, ++ enum sta_notify_cmd cmd, ++ struct ieee80211_sta *sta) ++{ ++ struct ath_softc *sc = hw->priv; ++ struct ath_node *an = (struct ath_node *) sta->drv_priv; ++ ++ switch (cmd) { ++ case STA_NOTIFY_SLEEP: ++ an->sleeping = true; ++ if (ath_tx_aggr_sleep(sc, an)) ++ ieee80211_sta_set_tim(sta); ++ break; ++ case STA_NOTIFY_AWAKE: ++ an->sleeping = false; ++ ath_tx_aggr_wakeup(sc, an); ++ break; ++ } ++} ++ + static int ath9k_conf_tx(struct ieee80211_hw *hw, u16 queue, + const struct ieee80211_tx_queue_params *params) + { +@@ -2177,6 +2198,7 @@ struct ieee80211_ops ath9k_ops = { + .configure_filter = ath9k_configure_filter, + .sta_add = ath9k_sta_add, + .sta_remove = ath9k_sta_remove, ++ .sta_notify = ath9k_sta_notify, + .conf_tx = ath9k_conf_tx, + .bss_info_changed = ath9k_bss_info_changed, + .set_key = ath9k_set_key, +--- a/drivers/net/wireless/ath/ath9k/xmit.c ++++ b/drivers/net/wireless/ath/ath9k/xmit.c +@@ -357,6 +357,7 @@ static void ath_tx_complete_aggr(struct + struct ath_frame_info *fi; + int nframes; + u8 tidno; ++ bool clear_filter; + + skb = bf->bf_mpdu; + hdr = (struct ieee80211_hdr *)skb->data; +@@ -442,7 +443,11 @@ static void ath_tx_complete_aggr(struct + acked_cnt++; + } else { + if (!(tid->state & AGGR_CLEANUP) && retry) { +- if (fi->retries < ATH_MAX_SW_RETRIES) { ++ if (ts->ts_status & ATH9K_TXERR_FILT) { ++ if (!an->sleeping) ++ clear_filter = true; ++ txpending = 1; ++ } else if (fi->retries < ATH_MAX_SW_RETRIES) { + ath_tx_set_retry(sc, txq, bf->bf_mpdu); + txpending = 1; + } else { +@@ -496,6 +501,7 @@ static void ath_tx_complete_aggr(struct + !txfail, sendbar); + } else { + /* retry the un-acked ones */ ++ ath9k_hw_set_clrdmask(sc->sc_ah, bf->bf_desc, false); + if (!(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA)) { + if (bf->bf_next == NULL && bf_last->bf_stale) { + struct ath_buf *tbf; +@@ -546,7 +552,12 @@ static void ath_tx_complete_aggr(struct + + /* prepend un-acked frames to the beginning of the pending frame queue */ + if (!list_empty(&bf_pending)) { ++ if (an->sleeping) ++ ieee80211_sta_set_tim(sta); ++ + spin_lock_bh(&txq->axq_lock); ++ if (clear_filter) ++ tid->ac->clear_ps_filter = true; + list_splice(&bf_pending, &tid->buf_q); + ath_tx_queue_tid(txq, tid); + spin_unlock_bh(&txq->axq_lock); +@@ -816,6 +827,11 @@ static void ath_tx_sched_aggr(struct ath + bf = list_first_entry(&bf_q, struct ath_buf, list); + bf->bf_lastbf = list_entry(bf_q.prev, struct ath_buf, list); + ++ if (tid->ac->clear_ps_filter) { ++ tid->ac->clear_ps_filter = false; ++ ath9k_hw_set_clrdmask(sc->sc_ah, bf->bf_desc, true); ++ } ++ + /* if only one frame, send as non-aggregate */ + if (bf == bf->bf_lastbf) { + fi = get_frame_info(bf->bf_mpdu); +@@ -896,6 +912,67 @@ void ath_tx_aggr_stop(struct ath_softc * + ath_tx_flush_tid(sc, txtid); + } + ++bool ath_tx_aggr_sleep(struct ath_softc *sc, struct ath_node *an) ++{ ++ struct ath_atx_tid *tid; ++ struct ath_atx_ac *ac; ++ struct ath_txq *txq; ++ bool buffered = false; ++ int tidno; ++ ++ for (tidno = 0, tid = &an->tid[tidno]; ++ tidno < WME_NUM_TID; tidno++, tid++) { ++ ++ if (!tid->sched) ++ continue; ++ ++ ac = tid->ac; ++ txq = ac->txq; ++ ++ spin_lock_bh(&txq->axq_lock); ++ ++ if (!list_empty(&tid->buf_q)) ++ buffered = true; ++ ++ tid->sched = false; ++ list_del(&tid->list); ++ ++ if (ac->sched) { ++ ac->sched = false; ++ list_del(&ac->list); ++ } ++ ++ spin_unlock_bh(&txq->axq_lock); ++ } ++ ++ return buffered; ++} ++ ++void ath_tx_aggr_wakeup(struct ath_softc *sc, struct ath_node *an) ++{ ++ struct ath_atx_tid *tid; ++ struct ath_atx_ac *ac; ++ struct ath_txq *txq; ++ int tidno; ++ ++ for (tidno = 0, tid = &an->tid[tidno]; ++ tidno < WME_NUM_TID; tidno++, tid++) { ++ ++ ac = tid->ac; ++ txq = ac->txq; ++ ++ spin_lock_bh(&txq->axq_lock); ++ ac->clear_ps_filter = true; ++ ++ if (!list_empty(&tid->buf_q) && !tid->paused) { ++ ath_tx_queue_tid(txq, tid); ++ ath_txq_schedule(sc, txq); ++ } ++ ++ spin_unlock_bh(&txq->axq_lock); ++ } ++} ++ + void ath_tx_aggr_resume(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid) + { + struct ath_atx_tid *txtid; +@@ -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; + +- flags |= ATH9K_TXDESC_CLRDMASK; /* needed for crypto errors */ + flags |= ATH9K_TXDESC_INTREQ; + + if (tx_info->flags & IEEE80211_TX_CTL_NO_ACK) +@@ -1754,6 +1830,9 @@ static void ath_tx_start_dma(struct ath_ + if (txctl->paprd) + bf->bf_state.bfs_paprd_timestamp = jiffies; + ++ 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); + } + +--- a/drivers/net/wireless/ath/ath9k/hw-ops.h ++++ b/drivers/net/wireless/ath/ath9k/hw-ops.h +@@ -128,6 +128,11 @@ static inline void ath9k_hw_set11n_virtu + ath9k_hw_ops(ah)->set11n_virtualmorefrag(ah, ds, vmf); + } + ++static inline void ath9k_hw_set_clrdmask(struct ath_hw *ah, void *ds, bool val) ++{ ++ ath9k_hw_ops(ah)->set_clrdmask(ah, ds, val); ++} ++ + /* Private hardware call ops */ + + /* PHY ops */ +--- a/drivers/net/wireless/ath/ath9k/hw.h ++++ b/drivers/net/wireless/ath/ath9k/hw.h +@@ -642,6 +642,7 @@ struct ath_hw_ops { + u32 burstDuration); + void (*set11n_virtualmorefrag)(struct ath_hw *ah, void *ds, + u32 vmf); ++ void (*set_clrdmask)(struct ath_hw *ah, void *ds, bool val); + }; + + struct ath_nf_limits { +--- a/drivers/net/wireless/ath/ath9k/ar9002_mac.c ++++ b/drivers/net/wireless/ath/ath9k/ar9002_mac.c +@@ -290,7 +290,6 @@ static void ar9002_hw_set11n_txdesc(stru + | (flags & ATH9K_TXDESC_VMF ? AR_VirtMoreFrag : 0) + | SM(txPower, AR_XmitPower) + | (flags & ATH9K_TXDESC_VEOL ? AR_VEOL : 0) +- | (flags & ATH9K_TXDESC_CLRDMASK ? AR_ClrDestMask : 0) + | (flags & ATH9K_TXDESC_INTREQ ? AR_TxIntrReq : 0) + | (keyIx != ATH9K_TXKEYIX_INVALID ? AR_DestIdxValid : 0); + +@@ -311,6 +310,16 @@ static void ar9002_hw_set11n_txdesc(stru + } + } + ++static void ar9002_hw_set_clrdmask(struct ath_hw *ah, void *ds, bool val) ++{ ++ struct ar5416_desc *ads = AR5416DESC(ds); ++ ++ if (val) ++ ads->ds_ctl0 |= AR_ClrDestMask; ++ else ++ ads->ds_ctl0 &= ~AR_ClrDestMask; ++} ++ + static void ar9002_hw_set11n_ratescenario(struct ath_hw *ah, void *ds, + void *lastds, + u32 durUpdateEn, u32 rtsctsRate, +@@ -460,4 +469,5 @@ void ar9002_hw_attach_mac_ops(struct ath + ops->clr11n_aggr = ar9002_hw_clr11n_aggr; + ops->set11n_burstduration = ar9002_hw_set11n_burstduration; + ops->set11n_virtualmorefrag = ar9002_hw_set11n_virtualmorefrag; ++ ops->set_clrdmask = ar9002_hw_set_clrdmask; + } +--- a/drivers/net/wireless/ath/ath9k/ar9003_mac.c ++++ b/drivers/net/wireless/ath/ath9k/ar9003_mac.c +@@ -329,7 +329,6 @@ static void ar9003_hw_set11n_txdesc(stru + | (flags & ATH9K_TXDESC_VMF ? AR_VirtMoreFrag : 0) + | SM(txpower, AR_XmitPower) + | (flags & ATH9K_TXDESC_VEOL ? AR_VEOL : 0) +- | (flags & ATH9K_TXDESC_CLRDMASK ? AR_ClrDestMask : 0) + | (keyIx != ATH9K_TXKEYIX_INVALID ? AR_DestIdxValid : 0) + | (flags & ATH9K_TXDESC_LOWRXCHAIN ? AR_LowRxChain : 0); + +@@ -350,6 +349,16 @@ static void ar9003_hw_set11n_txdesc(stru + ads->ctl22 = 0; + } + ++static void ar9003_hw_set_clrdmask(struct ath_hw *ah, void *ds, bool val) ++{ ++ struct ar9003_txc *ads = (struct ar9003_txc *) ds; ++ ++ if (val) ++ ads->ctl11 |= AR_ClrDestMask; ++ else ++ ads->ctl11 &= ~AR_ClrDestMask; ++} ++ + static void ar9003_hw_set11n_ratescenario(struct ath_hw *ah, void *ds, + void *lastds, + u32 durUpdateEn, u32 rtsctsRate, +@@ -522,6 +531,7 @@ void ar9003_hw_attach_mac_ops(struct ath + ops->clr11n_aggr = ar9003_hw_clr11n_aggr; + ops->set11n_burstduration = ar9003_hw_set11n_burstduration; + ops->set11n_virtualmorefrag = ar9003_hw_set11n_virtualmorefrag; ++ ops->set_clrdmask = ar9003_hw_set_clrdmask; + } + + void ath9k_hw_set_rx_bufsize(struct ath_hw *ah, u16 buf_size) +--- a/drivers/net/wireless/ath/ath9k/mac.h ++++ b/drivers/net/wireless/ath/ath9k/mac.h +@@ -239,7 +239,6 @@ struct ath_desc { + void *ds_vdata; + } __packed __aligned(4); + +-#define ATH9K_TXDESC_CLRDMASK 0x0001 + #define ATH9K_TXDESC_NOACK 0x0002 + #define ATH9K_TXDESC_RTSENA 0x0004 + #define ATH9K_TXDESC_CTSENA 0x0008 diff --git a/package/mac80211/patches/522-ath9k_remove_pending_frames_workaround.patch b/package/mac80211/patches/522-ath9k_remove_pending_frames_workaround.patch new file mode 100644 index 000000000..e368bce64 --- /dev/null +++ b/package/mac80211/patches/522-ath9k_remove_pending_frames_workaround.patch @@ -0,0 +1,36 @@ +--- a/drivers/net/wireless/ath/ath9k/xmit.c ++++ b/drivers/net/wireless/ath/ath9k/xmit.c +@@ -2223,33 +2223,6 @@ static void ath_tx_complete_poll_work(st + } else { + txq->axq_tx_inprogress = true; + } +- } else { +- /* If the queue has pending buffers, then it +- * should be doing tx work (and have axq_depth). +- * Shouldn't get to this state I think..but +- * we do. +- */ +- if (!(sc->sc_flags & (SC_OP_OFFCHANNEL)) && +- (txq->pending_frames > 0 || +- !list_empty(&txq->axq_acq) || +- txq->stopped)) { +- ath_err(ath9k_hw_common(sc->sc_ah), +- "txq: %p axq_qnum: %u," +- " mac80211_qnum: %i" +- " axq_link: %p" +- " pending frames: %i" +- " axq_acq empty: %i" +- " stopped: %i" +- " axq_depth: 0 Attempting to" +- " restart tx logic.\n", +- txq, txq->axq_qnum, +- txq->mac80211_qnum, +- txq->axq_link, +- txq->pending_frames, +- list_empty(&txq->axq_acq), +- txq->stopped); +- ath_txq_schedule(sc, txq); +- } + } + spin_unlock_bh(&txq->axq_lock); + } diff --git a/package/mac80211/patches/530-mac80211_drv_tim_override.patch b/package/mac80211/patches/530-mac80211_drv_tim_override.patch deleted file mode 100644 index 198f658a6..000000000 --- a/package/mac80211/patches/530-mac80211_drv_tim_override.patch +++ /dev/null @@ -1,73 +0,0 @@ ---- a/include/net/mac80211.h -+++ b/include/net/mac80211.h -@@ -2209,6 +2209,18 @@ static inline int ieee80211_sta_ps_trans - #define IEEE80211_TX_STATUS_HEADROOM 13 - - /** -+ * ieee80211_sta_set_tim - set the TIM bit for a sleeping station -+ * -+ * If a driver buffers frames for a powersave station instead of passing -+ * them back to mac80211 for retransmission, the station needs to be told -+ * to wake up using the TIM bitmap in the beacon. -+ * -+ * This function sets the station's TIM bit - it will be cleared when the -+ * station wakes up. -+ */ -+void ieee80211_sta_set_tim(struct ieee80211_sta *sta); -+ -+/** - * ieee80211_tx_status - transmit status callback - * - * Call this function for all transmitted frames after they have been ---- a/net/mac80211/sta_info.c -+++ b/net/mac80211/sta_info.c -@@ -608,7 +608,8 @@ static bool sta_info_cleanup_expire_buff - #endif - dev_kfree_skb(skb); - -- if (skb_queue_empty(&sta->ps_tx_buf)) -+ if (skb_queue_empty(&sta->ps_tx_buf) && -+ !test_sta_flags(sta, WLAN_STA_PS_DRIVER_BUF)) - sta_info_clear_tim_bit(sta); - } - -@@ -899,6 +900,7 @@ void ieee80211_sta_ps_deliver_wakeup(str - struct ieee80211_local *local = sdata->local; - int sent, buffered; - -+ clear_sta_flags(sta, WLAN_STA_PS_DRIVER_BUF); - if (!(local->hw.flags & IEEE80211_HW_AP_LINK_PS)) - drv_sta_notify(local, sdata, STA_NOTIFY_AWAKE, &sta->sta); - -@@ -991,3 +993,12 @@ void ieee80211_sta_block_awake(struct ie - ieee80211_queue_work(hw, &sta->drv_unblock_wk); - } - EXPORT_SYMBOL(ieee80211_sta_block_awake); -+ -+void ieee80211_sta_set_tim(struct ieee80211_sta *pubsta) -+{ -+ struct sta_info *sta = container_of(pubsta, struct sta_info, sta); -+ -+ set_sta_flags(sta, WLAN_STA_PS_DRIVER_BUF); -+ sta_info_set_tim_bit(sta); -+} -+EXPORT_SYMBOL(ieee80211_sta_set_tim); ---- a/net/mac80211/sta_info.h -+++ b/net/mac80211/sta_info.h -@@ -43,6 +43,8 @@ - * be in the queues - * @WLAN_STA_PSPOLL: Station sent PS-poll while driver was keeping - * station in power-save mode, reply when the driver unblocks. -+ * @WLAN_STA_PS_DRIVER_BUF: Station has frames pending in driver internal -+ * buffers. Automatically cleared on station wake-up. - */ - enum ieee80211_sta_info_flags { - WLAN_STA_AUTH = 1<<0, -@@ -58,6 +60,7 @@ enum ieee80211_sta_info_flags { - WLAN_STA_BLOCK_BA = 1<<11, - WLAN_STA_PS_DRIVER = 1<<12, - WLAN_STA_PSPOLL = 1<<13, -+ WLAN_STA_PS_DRIVER_BUF = 1<<14, - }; - - #define STA_TID_NUM 16 diff --git a/package/mac80211/patches/530-mac80211_redirect_vlan_eap_frames.patch b/package/mac80211/patches/530-mac80211_redirect_vlan_eap_frames.patch new file mode 100644 index 000000000..03a4fe5d3 --- /dev/null +++ b/package/mac80211/patches/530-mac80211_redirect_vlan_eap_frames.patch @@ -0,0 +1,67 @@ +--- a/net/mac80211/rx.c ++++ b/net/mac80211/rx.c +@@ -1582,7 +1582,7 @@ ieee80211_drop_unencrypted_mgmt(struct i + } + + static int +-__ieee80211_data_to_8023(struct ieee80211_rx_data *rx) ++__ieee80211_data_to_8023(struct ieee80211_rx_data *rx, bool *port_control) + { + struct ieee80211_sub_if_data *sdata = rx->sdata; + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data; +@@ -1590,6 +1590,7 @@ __ieee80211_data_to_8023(struct ieee8021 + struct ethhdr *ehdr; + int ret; + ++ *port_control = false; + if (ieee80211_has_a4(hdr->frame_control) && + sdata->vif.type == NL80211_IFTYPE_AP_VLAN && !sdata->u.vlan.sta) + return -1; +@@ -1608,11 +1609,14 @@ __ieee80211_data_to_8023(struct ieee8021 + return -1; + + ret = ieee80211_data_to_8023(rx->skb, sdata->vif.addr, sdata->vif.type); +- if (ret < 0 || !check_port_control) ++ if (ret < 0) + return ret; + + ehdr = (struct ethhdr *) rx->skb->data; +- if (ehdr->h_proto != rx->sdata->control_port_protocol) ++ if (ehdr->h_proto == rx->sdata->control_port_protocol) ++ *port_control = true; ++ ++ if (check_port_control && !*port_control) + return -1; + + return 0; +@@ -1913,6 +1917,7 @@ ieee80211_rx_h_data(struct ieee80211_rx_ + struct net_device *dev = sdata->dev; + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data; + __le16 fc = hdr->frame_control; ++ bool port_control; + int err; + + if (unlikely(!ieee80211_is_data(hdr->frame_control))) +@@ -1929,13 +1934,21 @@ ieee80211_rx_h_data(struct ieee80211_rx_ + sdata->vif.type == NL80211_IFTYPE_AP) + return RX_DROP_MONITOR; + +- err = __ieee80211_data_to_8023(rx); ++ err = __ieee80211_data_to_8023(rx, &port_control); + if (unlikely(err)) + return RX_DROP_UNUSABLE; + + if (!ieee80211_frame_allowed(rx, fc)) + return RX_DROP_MONITOR; + ++ if (rx->sdata->vif.type == NL80211_IFTYPE_AP_VLAN && ++ unlikely(port_control) && sdata->bss) { ++ sdata = container_of(sdata->bss, struct ieee80211_sub_if_data, ++ u.ap); ++ dev = sdata->dev; ++ rx->sdata = sdata; ++ } ++ + rx->skb->dev = dev; + + dev->stats.rx_packets++; diff --git a/package/mac80211/patches/531-ath9k_fix_ap_ps_buffering.patch b/package/mac80211/patches/531-ath9k_fix_ap_ps_buffering.patch deleted file mode 100644 index ff58c26d7..000000000 --- a/package/mac80211/patches/531-ath9k_fix_ap_ps_buffering.patch +++ /dev/null @@ -1,311 +0,0 @@ ---- a/drivers/net/wireless/ath/ath9k/ath9k.h -+++ b/drivers/net/wireless/ath/ath9k/ath9k.h -@@ -203,6 +203,7 @@ struct ath_atx_ac { - int sched; - struct list_head list; - struct list_head tid_q; -+ bool clear_ps_filter; - }; - - struct ath_frame_info { -@@ -260,6 +261,8 @@ struct ath_node { - struct ath_atx_ac ac[WME_NUM_AC]; - u16 maxampdu; - u8 mpdudensity; -+ -+ bool sleeping; - }; - - #define AGGR_CLEANUP BIT(1) -@@ -341,6 +344,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); - -+void ath_tx_aggr_wakeup(struct ath_softc *sc, struct ath_node *an); -+bool ath_tx_aggr_sleep(struct ath_softc *sc, struct ath_node *an); -+ - /********/ - /* VIFs */ - /********/ ---- a/drivers/net/wireless/ath/ath9k/main.c -+++ b/drivers/net/wireless/ath/ath9k/main.c -@@ -1791,6 +1791,27 @@ static int ath9k_sta_remove(struct ieee8 - return 0; - } - -+static void ath9k_sta_notify(struct ieee80211_hw *hw, -+ struct ieee80211_vif *vif, -+ enum sta_notify_cmd cmd, -+ struct ieee80211_sta *sta) -+{ -+ struct ath_softc *sc = hw->priv; -+ struct ath_node *an = (struct ath_node *) sta->drv_priv; -+ -+ switch (cmd) { -+ case STA_NOTIFY_SLEEP: -+ an->sleeping = true; -+ if (ath_tx_aggr_sleep(sc, an)) -+ ieee80211_sta_set_tim(sta); -+ break; -+ case STA_NOTIFY_AWAKE: -+ an->sleeping = false; -+ ath_tx_aggr_wakeup(sc, an); -+ break; -+ } -+} -+ - 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 = { - .configure_filter = ath9k_configure_filter, - .sta_add = ath9k_sta_add, - .sta_remove = ath9k_sta_remove, -+ .sta_notify = ath9k_sta_notify, - .conf_tx = ath9k_conf_tx, - .bss_info_changed = ath9k_bss_info_changed, - .set_key = ath9k_set_key, ---- a/drivers/net/wireless/ath/ath9k/xmit.c -+++ b/drivers/net/wireless/ath/ath9k/xmit.c -@@ -357,6 +357,7 @@ static void ath_tx_complete_aggr(struct - struct ath_frame_info *fi; - int nframes; - u8 tidno; -+ bool clear_filter; - - skb = bf->bf_mpdu; - hdr = (struct ieee80211_hdr *)skb->data; -@@ -442,7 +443,11 @@ static void ath_tx_complete_aggr(struct - acked_cnt++; - } else { - if (!(tid->state & AGGR_CLEANUP) && retry) { -- if (fi->retries < ATH_MAX_SW_RETRIES) { -+ if (ts->ts_status & ATH9K_TXERR_FILT) { -+ if (!an->sleeping) -+ clear_filter = true; -+ txpending = 1; -+ } else if (fi->retries < ATH_MAX_SW_RETRIES) { - ath_tx_set_retry(sc, txq, bf->bf_mpdu); - txpending = 1; - } else { -@@ -496,6 +501,7 @@ static void ath_tx_complete_aggr(struct - !txfail, sendbar); - } else { - /* retry the un-acked ones */ -+ ath9k_hw_set_clrdmask(sc->sc_ah, bf->bf_desc, false); - if (!(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA)) { - if (bf->bf_next == NULL && bf_last->bf_stale) { - struct ath_buf *tbf; -@@ -546,7 +552,12 @@ static void ath_tx_complete_aggr(struct - - /* prepend un-acked frames to the beginning of the pending frame queue */ - if (!list_empty(&bf_pending)) { -+ if (an->sleeping) -+ ieee80211_sta_set_tim(sta); -+ - spin_lock_bh(&txq->axq_lock); -+ if (clear_filter) -+ tid->ac->clear_ps_filter = true; - list_splice(&bf_pending, &tid->buf_q); - ath_tx_queue_tid(txq, tid); - spin_unlock_bh(&txq->axq_lock); -@@ -816,6 +827,11 @@ static void ath_tx_sched_aggr(struct ath - bf = list_first_entry(&bf_q, struct ath_buf, list); - bf->bf_lastbf = list_entry(bf_q.prev, struct ath_buf, list); - -+ if (tid->ac->clear_ps_filter) { -+ tid->ac->clear_ps_filter = false; -+ ath9k_hw_set_clrdmask(sc->sc_ah, bf->bf_desc, true); -+ } -+ - /* if only one frame, send as non-aggregate */ - if (bf == bf->bf_lastbf) { - fi = get_frame_info(bf->bf_mpdu); -@@ -896,6 +912,67 @@ void ath_tx_aggr_stop(struct ath_softc * - ath_tx_flush_tid(sc, txtid); - } - -+bool ath_tx_aggr_sleep(struct ath_softc *sc, struct ath_node *an) -+{ -+ struct ath_atx_tid *tid; -+ struct ath_atx_ac *ac; -+ struct ath_txq *txq; -+ bool buffered = false; -+ int tidno; -+ -+ for (tidno = 0, tid = &an->tid[tidno]; -+ tidno < WME_NUM_TID; tidno++, tid++) { -+ -+ if (!tid->sched) -+ continue; -+ -+ ac = tid->ac; -+ txq = ac->txq; -+ -+ spin_lock_bh(&txq->axq_lock); -+ -+ if (!list_empty(&tid->buf_q)) -+ buffered = true; -+ -+ tid->sched = false; -+ list_del(&tid->list); -+ -+ if (ac->sched) { -+ ac->sched = false; -+ list_del(&ac->list); -+ } -+ -+ spin_unlock_bh(&txq->axq_lock); -+ } -+ -+ return buffered; -+} -+ -+void ath_tx_aggr_wakeup(struct ath_softc *sc, struct ath_node *an) -+{ -+ struct ath_atx_tid *tid; -+ struct ath_atx_ac *ac; -+ struct ath_txq *txq; -+ int tidno; -+ -+ for (tidno = 0, tid = &an->tid[tidno]; -+ tidno < WME_NUM_TID; tidno++, tid++) { -+ -+ ac = tid->ac; -+ txq = ac->txq; -+ -+ spin_lock_bh(&txq->axq_lock); -+ ac->clear_ps_filter = true; -+ -+ if (!list_empty(&tid->buf_q) && !tid->paused) { -+ ath_tx_queue_tid(txq, tid); -+ ath_txq_schedule(sc, txq); -+ } -+ -+ spin_unlock_bh(&txq->axq_lock); -+ } -+} -+ - 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 - struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); - int flags = 0; - -- flags |= ATH9K_TXDESC_CLRDMASK; /* needed for crypto errors */ - 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_ - if (txctl->paprd) - bf->bf_state.bfs_paprd_timestamp = jiffies; - -+ 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); - } - ---- a/drivers/net/wireless/ath/ath9k/hw-ops.h -+++ b/drivers/net/wireless/ath/ath9k/hw-ops.h -@@ -128,6 +128,11 @@ static inline void ath9k_hw_set11n_virtu - ath9k_hw_ops(ah)->set11n_virtualmorefrag(ah, ds, vmf); - } - -+static inline void ath9k_hw_set_clrdmask(struct ath_hw *ah, void *ds, bool val) -+{ -+ ath9k_hw_ops(ah)->set_clrdmask(ah, ds, val); -+} -+ - /* Private hardware call ops */ - - /* PHY ops */ ---- a/drivers/net/wireless/ath/ath9k/hw.h -+++ b/drivers/net/wireless/ath/ath9k/hw.h -@@ -642,6 +642,7 @@ struct ath_hw_ops { - u32 burstDuration); - void (*set11n_virtualmorefrag)(struct ath_hw *ah, void *ds, - u32 vmf); -+ void (*set_clrdmask)(struct ath_hw *ah, void *ds, bool val); - }; - - struct ath_nf_limits { ---- a/drivers/net/wireless/ath/ath9k/ar9002_mac.c -+++ b/drivers/net/wireless/ath/ath9k/ar9002_mac.c -@@ -290,7 +290,6 @@ static void ar9002_hw_set11n_txdesc(stru - | (flags & ATH9K_TXDESC_VMF ? AR_VirtMoreFrag : 0) - | SM(txPower, AR_XmitPower) - | (flags & ATH9K_TXDESC_VEOL ? AR_VEOL : 0) -- | (flags & ATH9K_TXDESC_CLRDMASK ? AR_ClrDestMask : 0) - | (flags & ATH9K_TXDESC_INTREQ ? AR_TxIntrReq : 0) - | (keyIx != ATH9K_TXKEYIX_INVALID ? AR_DestIdxValid : 0); - -@@ -311,6 +310,16 @@ static void ar9002_hw_set11n_txdesc(stru - } - } - -+static void ar9002_hw_set_clrdmask(struct ath_hw *ah, void *ds, bool val) -+{ -+ struct ar5416_desc *ads = AR5416DESC(ds); -+ -+ if (val) -+ ads->ds_ctl0 |= AR_ClrDestMask; -+ else -+ ads->ds_ctl0 &= ~AR_ClrDestMask; -+} -+ - static void ar9002_hw_set11n_ratescenario(struct ath_hw *ah, void *ds, - void *lastds, - u32 durUpdateEn, u32 rtsctsRate, -@@ -460,4 +469,5 @@ void ar9002_hw_attach_mac_ops(struct ath - ops->clr11n_aggr = ar9002_hw_clr11n_aggr; - ops->set11n_burstduration = ar9002_hw_set11n_burstduration; - ops->set11n_virtualmorefrag = ar9002_hw_set11n_virtualmorefrag; -+ ops->set_clrdmask = ar9002_hw_set_clrdmask; - } ---- a/drivers/net/wireless/ath/ath9k/ar9003_mac.c -+++ b/drivers/net/wireless/ath/ath9k/ar9003_mac.c -@@ -329,7 +329,6 @@ static void ar9003_hw_set11n_txdesc(stru - | (flags & ATH9K_TXDESC_VMF ? AR_VirtMoreFrag : 0) - | SM(txpower, AR_XmitPower) - | (flags & ATH9K_TXDESC_VEOL ? AR_VEOL : 0) -- | (flags & ATH9K_TXDESC_CLRDMASK ? AR_ClrDestMask : 0) - | (keyIx != ATH9K_TXKEYIX_INVALID ? AR_DestIdxValid : 0) - | (flags & ATH9K_TXDESC_LOWRXCHAIN ? AR_LowRxChain : 0); - -@@ -350,6 +349,16 @@ static void ar9003_hw_set11n_txdesc(stru - ads->ctl22 = 0; - } - -+static void ar9003_hw_set_clrdmask(struct ath_hw *ah, void *ds, bool val) -+{ -+ struct ar9003_txc *ads = (struct ar9003_txc *) ds; -+ -+ if (val) -+ ads->ctl11 |= AR_ClrDestMask; -+ else -+ ads->ctl11 &= ~AR_ClrDestMask; -+} -+ - static void ar9003_hw_set11n_ratescenario(struct ath_hw *ah, void *ds, - void *lastds, - u32 durUpdateEn, u32 rtsctsRate, -@@ -522,6 +531,7 @@ void ar9003_hw_attach_mac_ops(struct ath - ops->clr11n_aggr = ar9003_hw_clr11n_aggr; - ops->set11n_burstduration = ar9003_hw_set11n_burstduration; - ops->set11n_virtualmorefrag = ar9003_hw_set11n_virtualmorefrag; -+ ops->set_clrdmask = ar9003_hw_set_clrdmask; - } - - void ath9k_hw_set_rx_bufsize(struct ath_hw *ah, u16 buf_size) ---- a/drivers/net/wireless/ath/ath9k/mac.h -+++ b/drivers/net/wireless/ath/ath9k/mac.h -@@ -239,7 +239,6 @@ struct ath_desc { - void *ds_vdata; - } __packed __aligned(4); - --#define ATH9K_TXDESC_CLRDMASK 0x0001 - #define ATH9K_TXDESC_NOACK 0x0002 - #define ATH9K_TXDESC_RTSENA 0x0004 - #define ATH9K_TXDESC_CTSENA 0x0008 diff --git a/package/mac80211/patches/532-ath9k_remove_pending_frames_workaround.patch b/package/mac80211/patches/532-ath9k_remove_pending_frames_workaround.patch deleted file mode 100644 index f7341e2a1..000000000 --- a/package/mac80211/patches/532-ath9k_remove_pending_frames_workaround.patch +++ /dev/null @@ -1,36 +0,0 @@ ---- 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 - } else { - txq->axq_tx_inprogress = true; - } -- } else { -- /* If the queue has pending buffers, then it -- * should be doing tx work (and have axq_depth). -- * Shouldn't get to this state I think..but -- * we do. -- */ -- if (!(sc->sc_flags & (SC_OP_OFFCHANNEL)) && -- (txq->pending_frames > 0 || -- !list_empty(&txq->axq_acq) || -- txq->stopped)) { -- ath_err(ath9k_hw_common(sc->sc_ah), -- "txq: %p axq_qnum: %u," -- " mac80211_qnum: %i" -- " axq_link: %p" -- " pending frames: %i" -- " axq_acq empty: %i" -- " stopped: %i" -- " axq_depth: 0 Attempting to" -- " restart tx logic.\n", -- txq, txq->axq_qnum, -- txq->mac80211_qnum, -- txq->axq_link, -- txq->pending_frames, -- list_empty(&txq->axq_acq), -- txq->stopped); -- ath_txq_schedule(sc, txq); -- } - } - spin_unlock_bh(&txq->axq_lock); - } 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 d365f3524..000000000 --- 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 c3a966326..000000000 --- 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 011f87ad3..000000000 --- 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 7d961d2c2..000000000 --- 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 9f7cfa82e..000000000 --- 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 630abc6fd..000000000 --- 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 5574d1716..000000000 --- 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/580-mac80211_redirect_vlan_eap_frames.patch b/package/mac80211/patches/580-mac80211_redirect_vlan_eap_frames.patch deleted file mode 100644 index 03a4fe5d3..000000000 --- a/package/mac80211/patches/580-mac80211_redirect_vlan_eap_frames.patch +++ /dev/null @@ -1,67 +0,0 @@ ---- a/net/mac80211/rx.c -+++ b/net/mac80211/rx.c -@@ -1582,7 +1582,7 @@ ieee80211_drop_unencrypted_mgmt(struct i - } - - static int --__ieee80211_data_to_8023(struct ieee80211_rx_data *rx) -+__ieee80211_data_to_8023(struct ieee80211_rx_data *rx, bool *port_control) - { - struct ieee80211_sub_if_data *sdata = rx->sdata; - struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data; -@@ -1590,6 +1590,7 @@ __ieee80211_data_to_8023(struct ieee8021 - struct ethhdr *ehdr; - int ret; - -+ *port_control = false; - if (ieee80211_has_a4(hdr->frame_control) && - sdata->vif.type == NL80211_IFTYPE_AP_VLAN && !sdata->u.vlan.sta) - return -1; -@@ -1608,11 +1609,14 @@ __ieee80211_data_to_8023(struct ieee8021 - return -1; - - ret = ieee80211_data_to_8023(rx->skb, sdata->vif.addr, sdata->vif.type); -- if (ret < 0 || !check_port_control) -+ if (ret < 0) - return ret; - - ehdr = (struct ethhdr *) rx->skb->data; -- if (ehdr->h_proto != rx->sdata->control_port_protocol) -+ if (ehdr->h_proto == rx->sdata->control_port_protocol) -+ *port_control = true; -+ -+ if (check_port_control && !*port_control) - return -1; - - return 0; -@@ -1913,6 +1917,7 @@ ieee80211_rx_h_data(struct ieee80211_rx_ - struct net_device *dev = sdata->dev; - struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data; - __le16 fc = hdr->frame_control; -+ bool port_control; - int err; - - if (unlikely(!ieee80211_is_data(hdr->frame_control))) -@@ -1929,13 +1934,21 @@ ieee80211_rx_h_data(struct ieee80211_rx_ - sdata->vif.type == NL80211_IFTYPE_AP) - return RX_DROP_MONITOR; - -- err = __ieee80211_data_to_8023(rx); -+ err = __ieee80211_data_to_8023(rx, &port_control); - if (unlikely(err)) - return RX_DROP_UNUSABLE; - - if (!ieee80211_frame_allowed(rx, fc)) - return RX_DROP_MONITOR; - -+ if (rx->sdata->vif.type == NL80211_IFTYPE_AP_VLAN && -+ unlikely(port_control) && sdata->bss) { -+ sdata = container_of(sdata->bss, struct ieee80211_sub_if_data, -+ u.ap); -+ dev = sdata->dev; -+ rx->sdata = sdata; -+ } -+ - rx->skb->dev = dev; - - dev->stats.rx_packets++; 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 b855d1d80..000000000 --- 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 0f5848591..000000000 --- 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 c60d51a21..ebc7c6bee 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 73089cda5..000000000 --- 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 7a2859853..000000000 --- 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 efc01b176..000000000 --- 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); - } -- cgit v1.2.3