mac80211: update to wireless-testing 2011-03-11
authorFelix Fietkau <nbd@openwrt.org>
Sun, 13 Mar 2011 18:38:37 +0000 (18:38 +0000)
committerFelix Fietkau <nbd@openwrt.org>
Sun, 13 Mar 2011 18:38:37 +0000 (18:38 +0000)
SVN-Revision: 26128

33 files changed:
package/mac80211/Makefile
package/mac80211/patches/030-backport_93c86_eeprom.patch
package/mac80211/patches/050-fix_missing_include.patch [deleted file]
package/mac80211/patches/300-ath9k_gpio_settings.patch
package/mac80211/patches/310-pending_work.patch [new file with mode: 0644]
package/mac80211/patches/401-ath9k-dont-register-leds-on-ar9100.patch
package/mac80211/patches/407-ath9k-override-mac-address-from-platform-data.patch
package/mac80211/patches/409-ath9k_platform_settings.patch
package/mac80211/patches/500-ath9k_eeprom_debugfs.patch
package/mac80211/patches/510-ath9k_intr_mitigation_tweak.patch [new file with mode: 0644]
package/mac80211/patches/510-ath9k_led_cleanup.patch [deleted file]
package/mac80211/patches/520-ath9k_intr_mitigation_tweak.patch [deleted file]
package/mac80211/patches/520-mac80211_drv_tim_override.patch [new file with mode: 0644]
package/mac80211/patches/521-ath9k_fix_ap_ps_buffering.patch [new file with mode: 0644]
package/mac80211/patches/522-ath9k_remove_pending_frames_workaround.patch [new file with mode: 0644]
package/mac80211/patches/530-mac80211_drv_tim_override.patch [deleted file]
package/mac80211/patches/530-mac80211_redirect_vlan_eap_frames.patch [new file with mode: 0644]
package/mac80211/patches/531-ath9k_fix_ap_ps_buffering.patch [deleted file]
package/mac80211/patches/532-ath9k_remove_pending_frames_workaround.patch [deleted file]
package/mac80211/patches/540-mac80211_add_rx_rate.patch [deleted file]
package/mac80211/patches/550-ath9k_no_vif_promisc_handling.patch [deleted file]
package/mac80211/patches/560-mac80211_minstrel_ht_sampling_fix.patch [deleted file]
package/mac80211/patches/570-ath9k_fix_reg_bit_macros.patch [deleted file]
package/mac80211/patches/571-ath9k_fix_dma_stop.patch [deleted file]
package/mac80211/patches/572-ath9k_fix_tx_flush.patch [deleted file]
package/mac80211/patches/573-ath9k_beacon_stop.patch [deleted file]
package/mac80211/patches/580-mac80211_redirect_vlan_eap_frames.patch [deleted file]
package/mac80211/patches/581-mac80211_chantype_change_fix.patch [deleted file]
package/mac80211/patches/590-ath9k_tid_cleanup_send_bar.patch [deleted file]
package/mac80211/patches/700-mwl8k-missing-pci-id-for-WNR854T.patch
package/mac80211/patches/710-p54_rssi_crash_fix.patch [deleted file]
package/mac80211/patches/720-mac80211-print-restart-warning.patch [deleted file]
package/mac80211/patches/721-mac80211-fix-scan-race.patch [deleted file]

index c78a6cb..4629369 100644 (file)
@@ -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)
index 0415e5f..30ff85e 100644 (file)
@@ -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 (file)
index 458ff4d..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
---- a/compat/compat-2.6.39.c
-+++ b/compat/compat-2.6.39.c
-@@ -10,6 +10,7 @@
- #include <linux/compat.h>
- #include <linux/tty.h>
-+#include <linux/sched.h>
- /*
-  *            Termios Helper Methods
index e38b572..af20577 100644 (file)
@@ -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 (file)
index 0000000..57dceca
--- /dev/null
@@ -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:
index 166c133..2229902 100644 (file)
@@ -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))
index c922456..6326649 100644 (file)
@@ -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;
  
index 23a5887..6ce43b6 100644 (file)
@@ -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;
  
  
 --- 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;
 +      }
index 700cf70..0bb7082 100644 (file)
@@ -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 (file)
index 0000000..301af3c
--- /dev/null
@@ -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 (file)
index 352bee1..0000000
+++ /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 (file)
index 301af3c..0000000
+++ /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 (file)
index 0000000..535e359
--- /dev/null
@@ -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 (file)
index 0000000..87cc265
--- /dev/null
@@ -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 (file)
index 0000000..e368bce
--- /dev/null
@@ -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 (file)
index 198f658..0000000
+++ /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 (file)
index 0000000..03a4fe5
--- /dev/null
@@ -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 (file)
index ff58c26..0000000
+++ /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 (file)
index f7341e2..0000000
+++ /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 (file)
index d365f35..0000000
+++ /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 (file)
index c3a9663..0000000
+++ /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 (file)
index 011f87a..0000000
+++ /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 (file)
index 7d961d2..0000000
+++ /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 (file)
index 9f7cfa8..0000000
+++ /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 (file)
index 630abc6..0000000
+++ /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 (file)
index 5574d17..0000000
+++ /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 (file)
index 03a4fe5..0000000
+++ /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 (file)
index b855d1d..0000000
+++ /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 (file)
index 0f58485..0000000
+++ /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);
-               }
index c60d51a..ebc7c6b 100644 (file)
@@ -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 (file)
index 73089cd..0000000
+++ /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 (file)
index 7a28598..0000000
+++ /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 (file)
index efc01b1..0000000
+++ /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);
- }