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>
This commit is contained in:
Rajkumar Manoharan
2014-06-11 16:18:15 +05:30
committed by John W. Linville
parent 42eda11558
commit 3ad9c3861a
4 changed files with 63 additions and 7 deletions

View File

@@ -156,7 +156,8 @@ static void ath_set_rates(struct ieee80211_vif *vif, struct ieee80211_sta *sta,
static void ath_txq_skb_done(struct ath_softc *sc, struct ath_txq *txq,
struct sk_buff *skb)
{
int q;
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
int q, hw_queue;
q = skb_get_queue_mapping(skb);
if (txq == sc->tx.uapsdq)
@@ -168,9 +169,10 @@ static void ath_txq_skb_done(struct ath_softc *sc, struct ath_txq *txq,
if (WARN_ON(--txq->pending_frames < 0))
txq->pending_frames = 0;
hw_queue = (info->hw_queue >= sc->hw->queues - 2) ? q : info->hw_queue;
if (txq->stopped &&
txq->pending_frames < sc->tx.txq_max_pending[q]) {
ieee80211_wake_queue(sc->hw, q);
ieee80211_wake_queue(sc->hw, hw_queue);
txq->stopped = false;
}
}
@@ -2191,7 +2193,7 @@ int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb,
struct ath_atx_tid *tid = NULL;
struct ath_buf *bf;
bool queue;
int q;
int q, hw_queue;
int ret;
if (vif)
@@ -2211,12 +2213,13 @@ int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb,
*/
q = skb_get_queue_mapping(skb);
hw_queue = (info->hw_queue >= sc->hw->queues - 2) ? q : info->hw_queue;
ath_txq_lock(sc, txq);
if (txq == sc->tx.txq_map[q] &&
++txq->pending_frames > sc->tx.txq_max_pending[q] &&
!txq->stopped) {
ieee80211_stop_queue(sc->hw, q);
ieee80211_stop_queue(sc->hw, hw_queue);
txq->stopped = true;
}