aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorFelix Fietkau <nbd@openwrt.org>2014-06-11 06:47:51 -0400
committerJohn W. Linville <linville@tuxdriver.com>2014-06-19 15:49:16 -0400
commit0453531e2eae61c5c0a2af7b67cdafd19c0dce68 (patch)
tree47e1997836b90775ce3ccafa6c2e36d0cac18827 /drivers/net
parentbc7e1be70c9f1c6de622aa14baa62003342034bb (diff)
ath9k: Move acq to channel context
Add support to maintain per-channel ACs list. Signed-off-by: Felix Fietkau <nbd@openwrt.org> Signed-off-by: Rajkumar Manoharan <rmanohar@qti.qualcomm.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/wireless/ath/ath9k/ath9k.h4
-rw-r--r--drivers/net/wireless/ath/ath9k/channel.c4
-rw-r--r--drivers/net/wireless/ath/ath9k/main.c25
-rw-r--r--drivers/net/wireless/ath/ath9k/xmit.c58
4 files changed, 63 insertions, 28 deletions
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
index b6f6444d109e..198cca38c24b 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -163,7 +163,6 @@ struct ath_txq {
163 u32 axq_ampdu_depth; 163 u32 axq_ampdu_depth;
164 bool stopped; 164 bool stopped;
165 bool axq_tx_inprogress; 165 bool axq_tx_inprogress;
166 struct list_head axq_acq;
167 struct list_head txq_fifo[ATH_TXFIFO_DEPTH]; 166 struct list_head txq_fifo[ATH_TXFIFO_DEPTH];
168 u8 txq_headidx; 167 u8 txq_headidx;
169 u8 txq_tailidx; 168 u8 txq_tailidx;
@@ -324,6 +323,8 @@ struct ath_rx {
324struct ath_chanctx { 323struct ath_chanctx {
325 struct cfg80211_chan_def chandef; 324 struct cfg80211_chan_def chandef;
326 struct list_head vifs; 325 struct list_head vifs;
326 struct list_head acq[IEEE80211_NUM_ACS];
327
327 u16 txpower; 328 u16 txpower;
328 bool offchannel; 329 bool offchannel;
329}; 330};
@@ -348,6 +349,7 @@ void ath_draintxq(struct ath_softc *sc, struct ath_txq *txq);
348void ath_tx_node_init(struct ath_softc *sc, struct ath_node *an); 349void ath_tx_node_init(struct ath_softc *sc, struct ath_node *an);
349void ath_tx_node_cleanup(struct ath_softc *sc, struct ath_node *an); 350void ath_tx_node_cleanup(struct ath_softc *sc, struct ath_node *an);
350void ath_txq_schedule(struct ath_softc *sc, struct ath_txq *txq); 351void ath_txq_schedule(struct ath_softc *sc, struct ath_txq *txq);
352void ath_txq_schedule_all(struct ath_softc *sc);
351int ath_tx_init(struct ath_softc *sc, int nbufs); 353int ath_tx_init(struct ath_softc *sc, int nbufs);
352int ath_txq_update(struct ath_softc *sc, int qnum, 354int ath_txq_update(struct ath_softc *sc, int qnum,
353 struct ath9k_tx_queue_info *q); 355 struct ath9k_tx_queue_info *q);
diff --git a/drivers/net/wireless/ath/ath9k/channel.c b/drivers/net/wireless/ath/ath9k/channel.c
index 1b40cf5aa955..c8d91dfcb3b9 100644
--- a/drivers/net/wireless/ath/ath9k/channel.c
+++ b/drivers/net/wireless/ath/ath9k/channel.c
@@ -107,7 +107,7 @@ void ath_chanctx_init(struct ath_softc *sc)
107 struct ath_common *common = ath9k_hw_common(sc->sc_ah); 107 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
108 struct ieee80211_supported_band *sband; 108 struct ieee80211_supported_band *sband;
109 struct ieee80211_channel *chan; 109 struct ieee80211_channel *chan;
110 int i; 110 int i, j;
111 111
112 sband = &common->sbands[IEEE80211_BAND_2GHZ]; 112 sband = &common->sbands[IEEE80211_BAND_2GHZ];
113 if (!sband->n_channels) 113 if (!sband->n_channels)
@@ -119,6 +119,8 @@ void ath_chanctx_init(struct ath_softc *sc)
119 cfg80211_chandef_create(&ctx->chandef, chan, NL80211_CHAN_HT20); 119 cfg80211_chandef_create(&ctx->chandef, chan, NL80211_CHAN_HT20);
120 INIT_LIST_HEAD(&ctx->vifs); 120 INIT_LIST_HEAD(&ctx->vifs);
121 ctx->txpower = ATH_TXPOWER_MAX; 121 ctx->txpower = ATH_TXPOWER_MAX;
122 for (j = 0; j < ARRAY_SIZE(ctx->acq); j++)
123 INIT_LIST_HEAD(&ctx->acq[j]);
122 } 124 }
123 sc->cur_chan = &sc->chanctx[0]; 125 sc->cur_chan = &sc->chanctx[0];
124} 126}
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index 5a9cee4a8935..5f7e0bf4c986 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -63,9 +63,16 @@ static bool ath9k_has_pending_frames(struct ath_softc *sc, struct ath_txq *txq)
63 63
64 spin_lock_bh(&txq->axq_lock); 64 spin_lock_bh(&txq->axq_lock);
65 65
66 if (txq->axq_depth || !list_empty(&txq->axq_acq)) 66 if (txq->axq_depth)
67 pending = true; 67 pending = true;
68 68
69 if (txq->mac80211_qnum >= 0) {
70 struct list_head *list;
71
72 list = &sc->cur_chan->acq[txq->mac80211_qnum];
73 if (!list_empty(list))
74 pending = true;
75 }
69 spin_unlock_bh(&txq->axq_lock); 76 spin_unlock_bh(&txq->axq_lock);
70 return pending; 77 return pending;
71} 78}
@@ -219,7 +226,6 @@ static bool ath_complete_reset(struct ath_softc *sc, bool start)
219 struct ath_hw *ah = sc->sc_ah; 226 struct ath_hw *ah = sc->sc_ah;
220 struct ath_common *common = ath9k_hw_common(ah); 227 struct ath_common *common = ath9k_hw_common(ah);
221 unsigned long flags; 228 unsigned long flags;
222 int i;
223 229
224 if (ath_startrecv(sc) != 0) { 230 if (ath_startrecv(sc) != 0) {
225 ath_err(common, "Unable to restart recv logic\n"); 231 ath_err(common, "Unable to restart recv logic\n");
@@ -247,15 +253,7 @@ static bool ath_complete_reset(struct ath_softc *sc, bool start)
247 } 253 }
248 work: 254 work:
249 ath_restart_work(sc); 255 ath_restart_work(sc);
250 256 ath_txq_schedule_all(sc);
251 for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) {
252 if (!ATH_TXQ_SETUP(sc, i))
253 continue;
254
255 spin_lock_bh(&sc->tx.txq[i].axq_lock);
256 ath_txq_schedule(sc, &sc->tx.txq[i]);
257 spin_unlock_bh(&sc->tx.txq[i].axq_lock);
258 }
259 } 257 }
260 258
261 sc->gtt_cnt = 0; 259 sc->gtt_cnt = 0;
@@ -1035,6 +1033,10 @@ static int ath9k_add_interface(struct ieee80211_hw *hw,
1035 1033
1036 avp->vif = vif; 1034 avp->vif = vif;
1037 1035
1036 /* XXX - will be removed once chanctx ops are added */
1037 avp->chanctx = sc->cur_chan;
1038 list_add_tail(&avp->list, &sc->cur_chan->vifs);
1039
1038 an->sc = sc; 1040 an->sc = sc;
1039 an->sta = NULL; 1041 an->sta = NULL;
1040 an->vif = vif; 1042 an->vif = vif;
@@ -1120,6 +1122,7 @@ static void ath9k_remove_interface(struct ieee80211_hw *hw,
1120 } 1122 }
1121 spin_unlock_bh(&sc->sc_pcu_lock); 1123 spin_unlock_bh(&sc->sc_pcu_lock);
1122 1124
1125 list_del(&avp->list);
1123 sc->nvifs--; 1126 sc->nvifs--;
1124 sc->tx99_vif = NULL; 1127 sc->tx99_vif = NULL;
1125 1128
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
index 66acb2cbd9df..b2e66d21af1c 100644
--- a/drivers/net/wireless/ath/ath9k/xmit.c
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
@@ -103,9 +103,16 @@ void ath_txq_unlock_complete(struct ath_softc *sc, struct ath_txq *txq)
103 ieee80211_tx_status(sc->hw, skb); 103 ieee80211_tx_status(sc->hw, skb);
104} 104}
105 105
106static void ath_tx_queue_tid(struct ath_txq *txq, struct ath_atx_tid *tid) 106static void ath_tx_queue_tid(struct ath_softc *sc, struct ath_txq *txq,
107 struct ath_atx_tid *tid)
107{ 108{
108 struct ath_atx_ac *ac = tid->ac; 109 struct ath_atx_ac *ac = tid->ac;
110 struct list_head *list;
111 struct ath_vif *avp = (struct ath_vif *) tid->an->vif->drv_priv;
112 struct ath_chanctx *ctx = avp->chanctx;
113
114 if (!ctx)
115 return;
109 116
110 if (tid->sched) 117 if (tid->sched)
111 return; 118 return;
@@ -117,7 +124,9 @@ static void ath_tx_queue_tid(struct ath_txq *txq, struct ath_atx_tid *tid)
117 return; 124 return;
118 125
119 ac->sched = true; 126 ac->sched = true;
120 list_add_tail(&ac->list, &txq->axq_acq); 127
128 list = &ctx->acq[TID_TO_WME_AC(tid->tidno)];
129 list_add_tail(&ac->list, list);
121} 130}
122 131
123static struct ath_frame_info *get_frame_info(struct sk_buff *skb) 132static struct ath_frame_info *get_frame_info(struct sk_buff *skb)
@@ -626,7 +635,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
626 635
627 skb_queue_splice_tail(&bf_pending, &tid->retry_q); 636 skb_queue_splice_tail(&bf_pending, &tid->retry_q);
628 if (!an->sleeping) { 637 if (!an->sleeping) {
629 ath_tx_queue_tid(txq, tid); 638 ath_tx_queue_tid(sc, txq, tid);
630 639
631 if (ts->ts_status & (ATH9K_TXERR_FILT | ATH9K_TXERR_XRETRY)) 640 if (ts->ts_status & (ATH9K_TXERR_FILT | ATH9K_TXERR_XRETRY))
632 tid->ac->clear_ps_filter = true; 641 tid->ac->clear_ps_filter = true;
@@ -1483,7 +1492,7 @@ void ath_tx_aggr_wakeup(struct ath_softc *sc, struct ath_node *an)
1483 ac->clear_ps_filter = true; 1492 ac->clear_ps_filter = true;
1484 1493
1485 if (ath_tid_has_buffered(tid)) { 1494 if (ath_tid_has_buffered(tid)) {
1486 ath_tx_queue_tid(txq, tid); 1495 ath_tx_queue_tid(sc, txq, tid);
1487 ath_txq_schedule(sc, txq); 1496 ath_txq_schedule(sc, txq);
1488 } 1497 }
1489 1498
@@ -1507,7 +1516,7 @@ void ath_tx_aggr_resume(struct ath_softc *sc, struct ieee80211_sta *sta,
1507 tid->baw_size = IEEE80211_MIN_AMPDU_BUF << sta->ht_cap.ampdu_factor; 1516 tid->baw_size = IEEE80211_MIN_AMPDU_BUF << sta->ht_cap.ampdu_factor;
1508 1517
1509 if (ath_tid_has_buffered(tid)) { 1518 if (ath_tid_has_buffered(tid)) {
1510 ath_tx_queue_tid(txq, tid); 1519 ath_tx_queue_tid(sc, txq, tid);
1511 ath_txq_schedule(sc, txq); 1520 ath_txq_schedule(sc, txq);
1512 } 1521 }
1513 1522
@@ -1642,7 +1651,6 @@ struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype)
1642 txq->axq_link = NULL; 1651 txq->axq_link = NULL;
1643 __skb_queue_head_init(&txq->complete_q); 1652 __skb_queue_head_init(&txq->complete_q);
1644 INIT_LIST_HEAD(&txq->axq_q); 1653 INIT_LIST_HEAD(&txq->axq_q);
1645 INIT_LIST_HEAD(&txq->axq_acq);
1646 spin_lock_init(&txq->axq_lock); 1654 spin_lock_init(&txq->axq_lock);
1647 txq->axq_depth = 0; 1655 txq->axq_depth = 0;
1648 txq->axq_ampdu_depth = 0; 1656 txq->axq_ampdu_depth = 0;
@@ -1804,7 +1812,7 @@ void ath_tx_cleanupq(struct ath_softc *sc, struct ath_txq *txq)
1804 sc->tx.txqsetup &= ~(1<<txq->axq_qnum); 1812 sc->tx.txqsetup &= ~(1<<txq->axq_qnum);
1805} 1813}
1806 1814
1807/* For each axq_acq entry, for each tid, try to schedule packets 1815/* For each acq entry, for each tid, try to schedule packets
1808 * for transmit until ampdu_depth has reached min Q depth. 1816 * for transmit until ampdu_depth has reached min Q depth.
1809 */ 1817 */
1810void ath_txq_schedule(struct ath_softc *sc, struct ath_txq *txq) 1818void ath_txq_schedule(struct ath_softc *sc, struct ath_txq *txq)
@@ -1812,19 +1820,25 @@ void ath_txq_schedule(struct ath_softc *sc, struct ath_txq *txq)
1812 struct ath_common *common = ath9k_hw_common(sc->sc_ah); 1820 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
1813 struct ath_atx_ac *ac, *last_ac; 1821 struct ath_atx_ac *ac, *last_ac;
1814 struct ath_atx_tid *tid, *last_tid; 1822 struct ath_atx_tid *tid, *last_tid;
1823 struct list_head *ac_list;
1815 bool sent = false; 1824 bool sent = false;
1816 1825
1826 if (txq->mac80211_qnum < 0)
1827 return;
1828
1829 ac_list = &sc->cur_chan->acq[txq->mac80211_qnum];
1830
1817 if (test_bit(ATH_OP_HW_RESET, &common->op_flags) || 1831 if (test_bit(ATH_OP_HW_RESET, &common->op_flags) ||
1818 list_empty(&txq->axq_acq)) 1832 list_empty(ac_list))
1819 return; 1833 return;
1820 1834
1821 rcu_read_lock(); 1835 rcu_read_lock();
1822 1836
1823 last_ac = list_entry(txq->axq_acq.prev, struct ath_atx_ac, list); 1837 last_ac = list_entry(ac_list->prev, struct ath_atx_ac, list);
1824 while (!list_empty(&txq->axq_acq)) { 1838 while (!list_empty(ac_list)) {
1825 bool stop = false; 1839 bool stop = false;
1826 1840
1827 ac = list_first_entry(&txq->axq_acq, struct ath_atx_ac, list); 1841 ac = list_first_entry(ac_list, struct ath_atx_ac, list);
1828 last_tid = list_entry(ac->tid_q.prev, struct ath_atx_tid, list); 1842 last_tid = list_entry(ac->tid_q.prev, struct ath_atx_tid, list);
1829 list_del(&ac->list); 1843 list_del(&ac->list);
1830 ac->sched = false; 1844 ac->sched = false;
@@ -1844,7 +1858,7 @@ void ath_txq_schedule(struct ath_softc *sc, struct ath_txq *txq)
1844 * are pending for the tid 1858 * are pending for the tid
1845 */ 1859 */
1846 if (ath_tid_has_buffered(tid)) 1860 if (ath_tid_has_buffered(tid))
1847 ath_tx_queue_tid(txq, tid); 1861 ath_tx_queue_tid(sc, txq, tid);
1848 1862
1849 if (stop || tid == last_tid) 1863 if (stop || tid == last_tid)
1850 break; 1864 break;
@@ -1852,7 +1866,7 @@ void ath_txq_schedule(struct ath_softc *sc, struct ath_txq *txq)
1852 1866
1853 if (!list_empty(&ac->tid_q) && !ac->sched) { 1867 if (!list_empty(&ac->tid_q) && !ac->sched) {
1854 ac->sched = true; 1868 ac->sched = true;
1855 list_add_tail(&ac->list, &txq->axq_acq); 1869 list_add_tail(&ac->list, ac_list);
1856 } 1870 }
1857 1871
1858 if (stop) 1872 if (stop)
@@ -1863,7 +1877,7 @@ void ath_txq_schedule(struct ath_softc *sc, struct ath_txq *txq)
1863 break; 1877 break;
1864 1878
1865 sent = false; 1879 sent = false;
1866 last_ac = list_entry(txq->axq_acq.prev, 1880 last_ac = list_entry(ac_list->prev,
1867 struct ath_atx_ac, list); 1881 struct ath_atx_ac, list);
1868 } 1882 }
1869 } 1883 }
@@ -1871,6 +1885,20 @@ void ath_txq_schedule(struct ath_softc *sc, struct ath_txq *txq)
1871 rcu_read_unlock(); 1885 rcu_read_unlock();
1872} 1886}
1873 1887
1888void ath_txq_schedule_all(struct ath_softc *sc)
1889{
1890 struct ath_txq *txq;
1891 int i;
1892
1893 for (i = 0; i < IEEE80211_NUM_ACS; i++) {
1894 txq = sc->tx.txq_map[i];
1895
1896 spin_lock_bh(&txq->axq_lock);
1897 ath_txq_schedule(sc, txq);
1898 spin_unlock_bh(&txq->axq_lock);
1899 }
1900}
1901
1874/***********/ 1902/***********/
1875/* TX, DMA */ 1903/* TX, DMA */
1876/***********/ 1904/***********/
@@ -2198,7 +2226,7 @@ int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb,
2198 TX_STAT_INC(txq->axq_qnum, a_queued_sw); 2226 TX_STAT_INC(txq->axq_qnum, a_queued_sw);
2199 __skb_queue_tail(&tid->buf_q, skb); 2227 __skb_queue_tail(&tid->buf_q, skb);
2200 if (!txctl->an->sleeping) 2228 if (!txctl->an->sleeping)
2201 ath_tx_queue_tid(txq, tid); 2229 ath_tx_queue_tid(sc, txq, tid);
2202 2230
2203 ath_txq_schedule(sc, txq); 2231 ath_txq_schedule(sc, txq);
2204 goto out; 2232 goto out;