aboutsummaryrefslogtreecommitdiffstats
path: root/package/mac80211/patches/310-ath9k_pending_work.patch
diff options
context:
space:
mode:
Diffstat (limited to 'package/mac80211/patches/310-ath9k_pending_work.patch')
-rw-r--r--package/mac80211/patches/310-ath9k_pending_work.patch90
1 files changed, 90 insertions, 0 deletions
diff --git a/package/mac80211/patches/310-ath9k_pending_work.patch b/package/mac80211/patches/310-ath9k_pending_work.patch
new file mode 100644
index 0000000000..0a3372c467
--- /dev/null
+++ b/package/mac80211/patches/310-ath9k_pending_work.patch
@@ -0,0 +1,90 @@
+--- a/drivers/net/wireless/ath/ath9k/xmit.c
++++ b/drivers/net/wireless/ath/ath9k/xmit.c
+@@ -1221,49 +1221,59 @@ void ath_tx_cleanupq(struct ath_softc *s
+ sc->tx.txqsetup &= ~(1<<txq->axq_qnum);
+ }
+
++/* For each axq_acq entry, for each tid, try to schedule packets
++ * for transmit until ampdu_depth has reached min Q depth.
++ */
+ void ath_txq_schedule(struct ath_softc *sc, struct ath_txq *txq)
+ {
+- struct ath_atx_ac *ac;
+- struct ath_atx_tid *tid, *last;
++ struct ath_atx_ac *ac, *ac_tmp, *last_ac;
++ struct ath_atx_tid *tid, *last_tid;
+
+ if (list_empty(&txq->axq_acq) ||
+ txq->axq_ampdu_depth >= ATH_AGGR_MIN_QDEPTH)
+ return;
+
+ ac = list_first_entry(&txq->axq_acq, struct ath_atx_ac, list);
+- last = list_entry(ac->tid_q.prev, struct ath_atx_tid, list);
+- list_del(&ac->list);
+- ac->sched = false;
++ last_ac = list_entry(txq->axq_acq.prev, struct ath_atx_ac, list);
+
+- do {
+- if (list_empty(&ac->tid_q))
+- return;
+-
+- tid = list_first_entry(&ac->tid_q, struct ath_atx_tid, list);
+- list_del(&tid->list);
+- tid->sched = false;
++ list_for_each_entry_safe(ac, ac_tmp, &txq->axq_acq, list) {
++ last_tid = list_entry(ac->tid_q.prev, struct ath_atx_tid, list);
++ list_del(&ac->list);
++ ac->sched = false;
++
++ while (!list_empty(&ac->tid_q)) {
++ tid = list_first_entry(&ac->tid_q, struct ath_atx_tid,
++ list);
++ list_del(&tid->list);
++ tid->sched = false;
+
+- if (tid->paused)
+- continue;
++ if (tid->paused)
++ continue;
+
+- ath_tx_sched_aggr(sc, txq, tid);
++ ath_tx_sched_aggr(sc, txq, tid);
+
+- /*
+- * add tid to round-robin queue if more frames
+- * are pending for the tid
+- */
+- if (!list_empty(&tid->buf_q))
+- ath_tx_queue_tid(txq, tid);
++ /*
++ * add tid to round-robin queue if more frames
++ * are pending for the tid
++ */
++ if (!list_empty(&tid->buf_q))
++ ath_tx_queue_tid(txq, tid);
+
+- if (tid == last || txq->axq_ampdu_depth >= ATH_AGGR_MIN_QDEPTH)
+- break;
+- } while (!list_empty(&ac->tid_q));
++ if (tid == last_tid ||
++ txq->axq_ampdu_depth >= ATH_AGGR_MIN_QDEPTH)
++ break;
++ }
+
+- if (!list_empty(&ac->tid_q)) {
+- if (!ac->sched) {
+- ac->sched = true;
+- list_add_tail(&ac->list, &txq->axq_acq);
++ if (!list_empty(&ac->tid_q)) {
++ if (!ac->sched) {
++ ac->sched = true;
++ list_add_tail(&ac->list, &txq->axq_acq);
++ }
+ }
++
++ if (ac == last_ac ||
++ txq->axq_ampdu_depth >= ATH_AGGR_MIN_QDEPTH)
++ return;
+ }
+ }
+