aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/ath')
-rw-r--r--drivers/net/wireless/ath/ath9k/xmit.c89
1 files changed, 50 insertions, 39 deletions
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
index 3b66f2b67fec..f9e6eb2a4e0b 100644
--- a/drivers/net/wireless/ath/ath9k/xmit.c
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
@@ -1345,8 +1345,8 @@ ath_tx_form_burst(struct ath_softc *sc, struct ath_txq *txq,
1345 } while (1); 1345 } while (1);
1346} 1346}
1347 1347
1348static void ath_tx_sched_aggr(struct ath_softc *sc, struct ath_txq *txq, 1348static bool ath_tx_sched_aggr(struct ath_softc *sc, struct ath_txq *txq,
1349 struct ath_atx_tid *tid) 1349 struct ath_atx_tid *tid, bool *stop)
1350{ 1350{
1351 struct ath_buf *bf; 1351 struct ath_buf *bf;
1352 struct ieee80211_tx_info *tx_info; 1352 struct ieee80211_tx_info *tx_info;
@@ -1355,40 +1355,41 @@ static void ath_tx_sched_aggr(struct ath_softc *sc, struct ath_txq *txq,
1355 int aggr_len = 0; 1355 int aggr_len = 0;
1356 bool aggr, last = true; 1356 bool aggr, last = true;
1357 1357
1358 do { 1358 if (!ath_tid_has_buffered(tid))
1359 if (!ath_tid_has_buffered(tid)) 1359 return false;
1360 return;
1361 1360
1362 INIT_LIST_HEAD(&bf_q); 1361 INIT_LIST_HEAD(&bf_q);
1363 1362
1364 bf = ath_tx_get_tid_subframe(sc, txq, tid, &tid_q); 1363 bf = ath_tx_get_tid_subframe(sc, txq, tid, &tid_q);
1365 if (!bf) 1364 if (!bf)
1366 break; 1365 return false;
1367 1366
1368 tx_info = IEEE80211_SKB_CB(bf->bf_mpdu); 1367 tx_info = IEEE80211_SKB_CB(bf->bf_mpdu);
1369 aggr = !!(tx_info->flags & IEEE80211_TX_CTL_AMPDU); 1368 aggr = !!(tx_info->flags & IEEE80211_TX_CTL_AMPDU);
1370 if ((aggr && txq->axq_ampdu_depth >= ATH_AGGR_MIN_QDEPTH) || 1369 if ((aggr && txq->axq_ampdu_depth >= ATH_AGGR_MIN_QDEPTH) ||
1371 (!aggr && txq->axq_depth >= ATH_NON_AGGR_MIN_QDEPTH)) 1370 (!aggr && txq->axq_depth >= ATH_NON_AGGR_MIN_QDEPTH)) {
1372 break; 1371 *stop = true;
1372 return false;
1373 }
1373 1374
1374 ath_set_rates(tid->an->vif, tid->an->sta, bf); 1375 ath_set_rates(tid->an->vif, tid->an->sta, bf);
1375 if (aggr) 1376 if (aggr)
1376 last = ath_tx_form_aggr(sc, txq, tid, &bf_q, bf, 1377 last = ath_tx_form_aggr(sc, txq, tid, &bf_q, bf,
1377 tid_q, &aggr_len); 1378 tid_q, &aggr_len);
1378 else 1379 else
1379 ath_tx_form_burst(sc, txq, tid, &bf_q, bf, tid_q); 1380 ath_tx_form_burst(sc, txq, tid, &bf_q, bf, tid_q);
1380 1381
1381 if (list_empty(&bf_q)) 1382 if (list_empty(&bf_q))
1382 return; 1383 return false;
1383 1384
1384 if (tid->ac->clear_ps_filter) { 1385 if (tid->ac->clear_ps_filter) {
1385 tid->ac->clear_ps_filter = false; 1386 tid->ac->clear_ps_filter = false;
1386 tx_info->flags |= IEEE80211_TX_CTL_CLEAR_PS_FILT; 1387 tx_info->flags |= IEEE80211_TX_CTL_CLEAR_PS_FILT;
1387 } 1388 }
1388 1389
1389 ath_tx_fill_desc(sc, bf, txq, aggr_len); 1390 ath_tx_fill_desc(sc, bf, txq, aggr_len);
1390 ath_tx_txqaddbuf(sc, txq, &bf_q, false); 1391 ath_tx_txqaddbuf(sc, txq, &bf_q, false);
1391 } while (!last); 1392 return true;
1392} 1393}
1393 1394
1394int ath_tx_aggr_start(struct ath_softc *sc, struct ieee80211_sta *sta, 1395int ath_tx_aggr_start(struct ath_softc *sc, struct ieee80211_sta *sta,
@@ -1824,25 +1825,27 @@ void ath_tx_cleanupq(struct ath_softc *sc, struct ath_txq *txq)
1824 */ 1825 */
1825void ath_txq_schedule(struct ath_softc *sc, struct ath_txq *txq) 1826void ath_txq_schedule(struct ath_softc *sc, struct ath_txq *txq)
1826{ 1827{
1827 struct ath_atx_ac *ac, *ac_tmp, *last_ac; 1828 struct ath_atx_ac *ac, *last_ac;
1828 struct ath_atx_tid *tid, *last_tid; 1829 struct ath_atx_tid *tid, *last_tid;
1830 bool sent = false;
1829 1831
1830 if (test_bit(SC_OP_HW_RESET, &sc->sc_flags) || 1832 if (test_bit(SC_OP_HW_RESET, &sc->sc_flags) ||
1831 list_empty(&txq->axq_acq) || 1833 list_empty(&txq->axq_acq))
1832 txq->axq_ampdu_depth >= ATH_AGGR_MIN_QDEPTH)
1833 return; 1834 return;
1834 1835
1835 rcu_read_lock(); 1836 rcu_read_lock();
1836 1837
1837 ac = list_first_entry(&txq->axq_acq, struct ath_atx_ac, list);
1838 last_ac = list_entry(txq->axq_acq.prev, struct ath_atx_ac, list); 1838 last_ac = list_entry(txq->axq_acq.prev, struct ath_atx_ac, list);
1839 while (!list_empty(&txq->axq_acq)) {
1840 bool stop = false;
1839 1841
1840 list_for_each_entry_safe(ac, ac_tmp, &txq->axq_acq, list) { 1842 ac = list_first_entry(&txq->axq_acq, struct ath_atx_ac, list);
1841 last_tid = list_entry(ac->tid_q.prev, struct ath_atx_tid, list); 1843 last_tid = list_entry(ac->tid_q.prev, struct ath_atx_tid, list);
1842 list_del(&ac->list); 1844 list_del(&ac->list);
1843 ac->sched = false; 1845 ac->sched = false;
1844 1846
1845 while (!list_empty(&ac->tid_q)) { 1847 while (!list_empty(&ac->tid_q)) {
1848
1846 tid = list_first_entry(&ac->tid_q, struct ath_atx_tid, 1849 tid = list_first_entry(&ac->tid_q, struct ath_atx_tid,
1847 list); 1850 list);
1848 list_del(&tid->list); 1851 list_del(&tid->list);
@@ -1851,7 +1854,8 @@ void ath_txq_schedule(struct ath_softc *sc, struct ath_txq *txq)
1851 if (tid->paused) 1854 if (tid->paused)
1852 continue; 1855 continue;
1853 1856
1854 ath_tx_sched_aggr(sc, txq, tid); 1857 if (ath_tx_sched_aggr(sc, txq, tid, &stop))
1858 sent = true;
1855 1859
1856 /* 1860 /*
1857 * add tid to round-robin queue if more frames 1861 * add tid to round-robin queue if more frames
@@ -1860,8 +1864,7 @@ void ath_txq_schedule(struct ath_softc *sc, struct ath_txq *txq)
1860 if (ath_tid_has_buffered(tid)) 1864 if (ath_tid_has_buffered(tid))
1861 ath_tx_queue_tid(txq, tid); 1865 ath_tx_queue_tid(txq, tid);
1862 1866
1863 if (tid == last_tid || 1867 if (stop || tid == last_tid)
1864 txq->axq_ampdu_depth >= ATH_AGGR_MIN_QDEPTH)
1865 break; 1868 break;
1866 } 1869 }
1867 1870
@@ -1870,9 +1873,17 @@ void ath_txq_schedule(struct ath_softc *sc, struct ath_txq *txq)
1870 list_add_tail(&ac->list, &txq->axq_acq); 1873 list_add_tail(&ac->list, &txq->axq_acq);
1871 } 1874 }
1872 1875
1873 if (ac == last_ac || 1876 if (stop)
1874 txq->axq_ampdu_depth >= ATH_AGGR_MIN_QDEPTH)
1875 break; 1877 break;
1878
1879 if (ac == last_ac) {
1880 if (!sent)
1881 break;
1882
1883 sent = false;
1884 last_ac = list_entry(txq->axq_acq.prev,
1885 struct ath_atx_ac, list);
1886 }
1876 } 1887 }
1877 1888
1878 rcu_read_unlock(); 1889 rcu_read_unlock();