diff options
author | Felix Fietkau <nbd@openwrt.org> | 2010-08-01 16:33:50 +0000 |
---|---|---|
committer | Felix Fietkau <nbd@openwrt.org> | 2010-08-01 16:33:50 +0000 |
commit | 505c98f1f6e6b7c08eb88e9c6385684a5305dc1d (patch) | |
tree | 68a42d30369d093cf4434b94a42419ab777b6f27 | |
parent | ea27eb515b700eee13c13503071ceceb15fe31f8 (diff) | |
download | upstream-505c98f1f6e6b7c08eb88e9c6385684a5305dc1d.tar.gz upstream-505c98f1f6e6b7c08eb88e9c6385684a5305dc1d.tar.bz2 upstream-505c98f1f6e6b7c08eb88e9c6385684a5305dc1d.zip |
ath9k: fix aggregation pause/restart handling under heavy load (thx to Lorenzo Bianconi)
git-svn-id: svn://svn.openwrt.org/openwrt/trunk@22457 3c298f89-4303-0410-b956-a3cf2f4a3e73
-rw-r--r-- | package/mac80211/patches/530-ath9k_aggr_state_fix.patch | 72 |
1 files changed, 72 insertions, 0 deletions
diff --git a/package/mac80211/patches/530-ath9k_aggr_state_fix.patch b/package/mac80211/patches/530-ath9k_aggr_state_fix.patch new file mode 100644 index 0000000000..d3a7849484 --- /dev/null +++ b/package/mac80211/patches/530-ath9k_aggr_state_fix.patch @@ -0,0 +1,72 @@ +--- a/drivers/net/wireless/ath/ath9k/xmit.c ++++ b/drivers/net/wireless/ath/ath9k/xmit.c +@@ -120,26 +120,14 @@ static void ath_tx_queue_tid(struct ath_ + list_add_tail(&ac->list, &txq->axq_acq); + } + +-static void ath_tx_pause_tid(struct ath_softc *sc, struct ath_atx_tid *tid) +-{ +- struct ath_txq *txq = &sc->tx.txq[tid->ac->qnum]; +- +- spin_lock_bh(&txq->axq_lock); +- tid->paused++; +- spin_unlock_bh(&txq->axq_lock); +-} +- + static void ath_tx_resume_tid(struct ath_softc *sc, struct ath_atx_tid *tid) + { + struct ath_txq *txq = &sc->tx.txq[tid->ac->qnum]; + +- BUG_ON(tid->paused <= 0); +- spin_lock_bh(&txq->axq_lock); +- +- tid->paused--; ++ WARN_ON(!tid->paused); + +- if (tid->paused > 0) +- goto unlock; ++ spin_lock_bh(&txq->axq_lock); ++ tid->paused = false; + + if (list_empty(&tid->buf_q)) + goto unlock; +@@ -157,15 +145,10 @@ static void ath_tx_flush_tid(struct ath_ + struct list_head bf_head; + INIT_LIST_HEAD(&bf_head); + +- BUG_ON(tid->paused <= 0); +- spin_lock_bh(&txq->axq_lock); ++ WARN_ON(!tid->paused); + +- tid->paused--; +- +- if (tid->paused > 0) { +- spin_unlock_bh(&txq->axq_lock); +- return; +- } ++ spin_lock_bh(&txq->axq_lock); ++ tid->paused = false; + + while (!list_empty(&tid->buf_q)) { + bf = list_first_entry(&tid->buf_q, struct ath_buf, list); +@@ -811,7 +794,7 @@ void ath_tx_aggr_start(struct ath_softc + an = (struct ath_node *)sta->drv_priv; + txtid = ATH_AN_2_TID(an, tid); + txtid->state |= AGGR_ADDBA_PROGRESS; +- ath_tx_pause_tid(sc, txtid); ++ txtid->paused = true; + *ssn = txtid->seq_start; + } + +@@ -835,10 +818,9 @@ void ath_tx_aggr_stop(struct ath_softc * + return; + } + +- ath_tx_pause_tid(sc, txtid); +- + /* drop all software retried frames and mark this TID */ + spin_lock_bh(&txq->axq_lock); ++ txtid->paused = true; + while (!list_empty(&txtid->buf_q)) { + bf = list_first_entry(&txtid->buf_q, struct ath_buf, list); + if (!bf_isretried(bf)) { |