diff options
author | nbd <nbd@3c298f89-4303-0410-b956-a3cf2f4a3e73> | 2011-03-10 00:53:05 +0000 |
---|---|---|
committer | nbd <nbd@3c298f89-4303-0410-b956-a3cf2f4a3e73> | 2011-03-10 00:53:05 +0000 |
commit | 08ba7e86853f67cab5ad87e3da19fed703da8394 (patch) | |
tree | 00a93cb537af45db29eabaa067705d493b8ceb12 /package/mac80211/patches/572-ath9k_fix_tx_flush.patch | |
parent | 6e57744d89ef0b83360b178cac8173f9c0e28896 (diff) |
ath9k: get rid of most of those annoying dma tx stop issues
git-svn-id: svn://svn.openwrt.org/openwrt/trunk@25988 3c298f89-4303-0410-b956-a3cf2f4a3e73
Diffstat (limited to 'package/mac80211/patches/572-ath9k_fix_tx_flush.patch')
-rw-r--r-- | package/mac80211/patches/572-ath9k_fix_tx_flush.patch | 76 |
1 files changed, 76 insertions, 0 deletions
diff --git a/package/mac80211/patches/572-ath9k_fix_tx_flush.patch b/package/mac80211/patches/572-ath9k_fix_tx_flush.patch new file mode 100644 index 0000000000..55d127edfb --- /dev/null +++ b/package/mac80211/patches/572-ath9k_fix_tx_flush.patch @@ -0,0 +1,76 @@ +--- a/drivers/net/wireless/ath/ath9k/main.c ++++ b/drivers/net/wireless/ath/ath9k/main.c +@@ -2149,54 +2149,37 @@ 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 = 60; /* ms */ ++ int i, j; + + 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; + +- 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 (j = 0; j < timeout; j++) { ++ int npend = 0; ++ 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) { +- ath_reset(sc, false); +- txq->txq_flush_inprogress = false; ++ if (!npend) ++ goto out; ++ ++ usleep_range(1000, 2000); + } + ++ ath9k_ps_wakeup(sc); ++ ath_drain_all_txq(sc, false); ++ ath9k_ps_restore(sc); ++ ++out: + ieee80211_queue_delayed_work(hw, &sc->tx_complete_work, 0); + mutex_unlock(&sc->mutex); + } |