aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath/ath9k/xmit.c
diff options
context:
space:
mode:
authorRajkumar Manoharan <rmanohar@qti.qualcomm.com>2014-06-11 06:48:15 -0400
committerJohn W. Linville <linville@tuxdriver.com>2014-06-19 15:49:20 -0400
commit3ad9c3861acef2343b232d733aa288e71cc07d44 (patch)
tree52ba377424e24db7ef89e6f9d810e1f7b5a55911 /drivers/net/wireless/ath/ath9k/xmit.c
parent42eda11558559104c09f0d0924bbb210edfcf487 (diff)
ath9k: use separate HW queue for each channel context
Use seperate tx queue for each AC in each channel context and expose these information to mac80211 to avoid stopping one channel context leads to stopping the entire traffic for that AC even on other contexts. Signed-off-by: Rajkumar Manoharan <rmanohar@qti.qualcomm.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/ath/ath9k/xmit.c')
-rw-r--r--drivers/net/wireless/ath/ath9k/xmit.c11
1 files changed, 7 insertions, 4 deletions
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
index a422c20fe065..d4927c9a6bae 100644
--- a/drivers/net/wireless/ath/ath9k/xmit.c
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
@@ -156,7 +156,8 @@ static void ath_set_rates(struct ieee80211_vif *vif, struct ieee80211_sta *sta,
156static void ath_txq_skb_done(struct ath_softc *sc, struct ath_txq *txq, 156static void ath_txq_skb_done(struct ath_softc *sc, struct ath_txq *txq,
157 struct sk_buff *skb) 157 struct sk_buff *skb)
158{ 158{
159 int q; 159 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
160 int q, hw_queue;
160 161
161 q = skb_get_queue_mapping(skb); 162 q = skb_get_queue_mapping(skb);
162 if (txq == sc->tx.uapsdq) 163 if (txq == sc->tx.uapsdq)
@@ -168,9 +169,10 @@ static void ath_txq_skb_done(struct ath_softc *sc, struct ath_txq *txq,
168 if (WARN_ON(--txq->pending_frames < 0)) 169 if (WARN_ON(--txq->pending_frames < 0))
169 txq->pending_frames = 0; 170 txq->pending_frames = 0;
170 171
172 hw_queue = (info->hw_queue >= sc->hw->queues - 2) ? q : info->hw_queue;
171 if (txq->stopped && 173 if (txq->stopped &&
172 txq->pending_frames < sc->tx.txq_max_pending[q]) { 174 txq->pending_frames < sc->tx.txq_max_pending[q]) {
173 ieee80211_wake_queue(sc->hw, q); 175 ieee80211_wake_queue(sc->hw, hw_queue);
174 txq->stopped = false; 176 txq->stopped = false;
175 } 177 }
176} 178}
@@ -2191,7 +2193,7 @@ int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb,
2191 struct ath_atx_tid *tid = NULL; 2193 struct ath_atx_tid *tid = NULL;
2192 struct ath_buf *bf; 2194 struct ath_buf *bf;
2193 bool queue; 2195 bool queue;
2194 int q; 2196 int q, hw_queue;
2195 int ret; 2197 int ret;
2196 2198
2197 if (vif) 2199 if (vif)
@@ -2211,12 +2213,13 @@ int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb,
2211 */ 2213 */
2212 2214
2213 q = skb_get_queue_mapping(skb); 2215 q = skb_get_queue_mapping(skb);
2216 hw_queue = (info->hw_queue >= sc->hw->queues - 2) ? q : info->hw_queue;
2214 2217
2215 ath_txq_lock(sc, txq); 2218 ath_txq_lock(sc, txq);
2216 if (txq == sc->tx.txq_map[q] && 2219 if (txq == sc->tx.txq_map[q] &&
2217 ++txq->pending_frames > sc->tx.txq_max_pending[q] && 2220 ++txq->pending_frames > sc->tx.txq_max_pending[q] &&
2218 !txq->stopped) { 2221 !txq->stopped) {
2219 ieee80211_stop_queue(sc->hw, q); 2222 ieee80211_stop_queue(sc->hw, hw_queue);
2220 txq->stopped = true; 2223 txq->stopped = true;
2221 } 2224 }
2222 2225