Commit a7586ee4 authored by Felix Fietkau's avatar Felix Fietkau Committed by John W. Linville

ath9k: add utility functions for accessing tid queues

Useful for further fixes / cleanups
Signed-off-by: default avatarFelix Fietkau <nbd@openwrt.org>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent e3335476
...@@ -168,6 +168,16 @@ static void ath_txq_skb_done(struct ath_softc *sc, struct ath_txq *txq, ...@@ -168,6 +168,16 @@ static void ath_txq_skb_done(struct ath_softc *sc, struct ath_txq *txq,
} }
} }
static bool ath_tid_has_buffered(struct ath_atx_tid *tid)
{
return !skb_queue_empty(&tid->buf_q);
}
static struct sk_buff *ath_tid_dequeue(struct ath_atx_tid *tid)
{
return __skb_dequeue(&tid->buf_q);
}
static void ath_tx_flush_tid(struct ath_softc *sc, struct ath_atx_tid *tid) static void ath_tx_flush_tid(struct ath_softc *sc, struct ath_atx_tid *tid)
{ {
struct ath_txq *txq = tid->ac->txq; struct ath_txq *txq = tid->ac->txq;
...@@ -182,7 +192,7 @@ static void ath_tx_flush_tid(struct ath_softc *sc, struct ath_atx_tid *tid) ...@@ -182,7 +192,7 @@ static void ath_tx_flush_tid(struct ath_softc *sc, struct ath_atx_tid *tid)
memset(&ts, 0, sizeof(ts)); memset(&ts, 0, sizeof(ts));
while ((skb = __skb_dequeue(&tid->buf_q))) { while ((skb = ath_tid_dequeue(tid))) {
fi = get_frame_info(skb); fi = get_frame_info(skb);
bf = fi->bf; bf = fi->bf;
...@@ -266,7 +276,7 @@ static void ath_tid_drain(struct ath_softc *sc, struct ath_txq *txq, ...@@ -266,7 +276,7 @@ static void ath_tid_drain(struct ath_softc *sc, struct ath_txq *txq,
memset(&ts, 0, sizeof(ts)); memset(&ts, 0, sizeof(ts));
INIT_LIST_HEAD(&bf_head); INIT_LIST_HEAD(&bf_head);
while ((skb = __skb_dequeue(&tid->buf_q))) { while ((skb = ath_tid_dequeue(tid))) {
fi = get_frame_info(skb); fi = get_frame_info(skb);
bf = fi->bf; bf = fi->bf;
...@@ -815,7 +825,7 @@ static int ath_compute_num_delims(struct ath_softc *sc, struct ath_atx_tid *tid, ...@@ -815,7 +825,7 @@ static int ath_compute_num_delims(struct ath_softc *sc, struct ath_atx_tid *tid,
static struct ath_buf * static struct ath_buf *
ath_tx_get_tid_subframe(struct ath_softc *sc, struct ath_txq *txq, ath_tx_get_tid_subframe(struct ath_softc *sc, struct ath_txq *txq,
struct ath_atx_tid *tid) struct ath_atx_tid *tid, struct sk_buff_head **q)
{ {
struct ath_frame_info *fi; struct ath_frame_info *fi;
struct sk_buff *skb; struct sk_buff *skb;
...@@ -823,7 +833,8 @@ ath_tx_get_tid_subframe(struct ath_softc *sc, struct ath_txq *txq, ...@@ -823,7 +833,8 @@ ath_tx_get_tid_subframe(struct ath_softc *sc, struct ath_txq *txq,
u16 seqno; u16 seqno;
while (1) { while (1) {
skb = skb_peek(&tid->buf_q); *q = &tid->buf_q;
skb = skb_peek(*q);
if (!skb) if (!skb)
break; break;
...@@ -833,7 +844,7 @@ ath_tx_get_tid_subframe(struct ath_softc *sc, struct ath_txq *txq, ...@@ -833,7 +844,7 @@ ath_tx_get_tid_subframe(struct ath_softc *sc, struct ath_txq *txq,
bf = ath_tx_setup_buffer(sc, txq, tid, skb); bf = ath_tx_setup_buffer(sc, txq, tid, skb);
if (!bf) { if (!bf) {
__skb_unlink(skb, &tid->buf_q); __skb_unlink(skb, *q);
ath_txq_skb_done(sc, txq, skb); ath_txq_skb_done(sc, txq, skb);
ieee80211_free_txskb(sc->hw, skb); ieee80211_free_txskb(sc->hw, skb);
continue; continue;
...@@ -852,7 +863,7 @@ ath_tx_get_tid_subframe(struct ath_softc *sc, struct ath_txq *txq, ...@@ -852,7 +863,7 @@ ath_tx_get_tid_subframe(struct ath_softc *sc, struct ath_txq *txq,
INIT_LIST_HEAD(&bf_head); INIT_LIST_HEAD(&bf_head);
list_add(&bf->list, &bf_head); list_add(&bf->list, &bf_head);
__skb_unlink(skb, &tid->buf_q); __skb_unlink(skb, *q);
ath_tx_update_baw(sc, tid, seqno); ath_tx_update_baw(sc, tid, seqno);
ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, 0); ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, 0);
continue; continue;
...@@ -881,9 +892,10 @@ static enum ATH_AGGR_STATUS ath_tx_form_aggr(struct ath_softc *sc, ...@@ -881,9 +892,10 @@ static enum ATH_AGGR_STATUS ath_tx_form_aggr(struct ath_softc *sc,
struct ieee80211_tx_info *tx_info; struct ieee80211_tx_info *tx_info;
struct ath_frame_info *fi; struct ath_frame_info *fi;
struct sk_buff *skb; struct sk_buff *skb;
struct sk_buff_head *tid_q;
do { do {
bf = ath_tx_get_tid_subframe(sc, txq, tid); bf = ath_tx_get_tid_subframe(sc, txq, tid, &tid_q);
if (!bf) { if (!bf) {
status = ATH_AGGR_BAW_CLOSED; status = ATH_AGGR_BAW_CLOSED;
break; break;
...@@ -940,14 +952,14 @@ static enum ATH_AGGR_STATUS ath_tx_form_aggr(struct ath_softc *sc, ...@@ -940,14 +952,14 @@ static enum ATH_AGGR_STATUS ath_tx_form_aggr(struct ath_softc *sc,
ath_tx_addto_baw(sc, tid, bf->bf_state.seqno); ath_tx_addto_baw(sc, tid, bf->bf_state.seqno);
bf->bf_state.ndelim = ndelim; bf->bf_state.ndelim = ndelim;
__skb_unlink(skb, &tid->buf_q); __skb_unlink(skb, tid_q);
list_add_tail(&bf->list, bf_q); list_add_tail(&bf->list, bf_q);
if (bf_prev) if (bf_prev)
bf_prev->bf_next = bf; bf_prev->bf_next = bf;
bf_prev = bf; bf_prev = bf;
} while (!skb_queue_empty(&tid->buf_q)); } while (ath_tid_has_buffered(tid));
*aggr_len = al; *aggr_len = al;
...@@ -1250,7 +1262,7 @@ static void ath_tx_sched_aggr(struct ath_softc *sc, struct ath_txq *txq, ...@@ -1250,7 +1262,7 @@ static void ath_tx_sched_aggr(struct ath_softc *sc, struct ath_txq *txq,
int aggr_len; int aggr_len;
do { do {
if (skb_queue_empty(&tid->buf_q)) if (!ath_tid_has_buffered(tid))
return; return;
INIT_LIST_HEAD(&bf_q); INIT_LIST_HEAD(&bf_q);
...@@ -1354,7 +1366,7 @@ void ath_tx_aggr_sleep(struct ieee80211_sta *sta, struct ath_softc *sc, ...@@ -1354,7 +1366,7 @@ void ath_tx_aggr_sleep(struct ieee80211_sta *sta, struct ath_softc *sc,
ath_txq_lock(sc, txq); ath_txq_lock(sc, txq);
buffered = !skb_queue_empty(&tid->buf_q); buffered = ath_tid_has_buffered(tid);
tid->sched = false; tid->sched = false;
list_del(&tid->list); list_del(&tid->list);
...@@ -1386,7 +1398,7 @@ void ath_tx_aggr_wakeup(struct ath_softc *sc, struct ath_node *an) ...@@ -1386,7 +1398,7 @@ void ath_tx_aggr_wakeup(struct ath_softc *sc, struct ath_node *an)
ath_txq_lock(sc, txq); ath_txq_lock(sc, txq);
ac->clear_ps_filter = true; ac->clear_ps_filter = true;
if (!skb_queue_empty(&tid->buf_q) && !tid->paused) { if (!tid->paused && ath_tid_has_buffered(tid)) {
ath_tx_queue_tid(txq, tid); ath_tx_queue_tid(txq, tid);
ath_txq_schedule(sc, txq); ath_txq_schedule(sc, txq);
} }
...@@ -1411,7 +1423,7 @@ void ath_tx_aggr_resume(struct ath_softc *sc, struct ieee80211_sta *sta, ...@@ -1411,7 +1423,7 @@ void ath_tx_aggr_resume(struct ath_softc *sc, struct ieee80211_sta *sta,
tid->baw_size = IEEE80211_MIN_AMPDU_BUF << sta->ht_cap.ampdu_factor; tid->baw_size = IEEE80211_MIN_AMPDU_BUF << sta->ht_cap.ampdu_factor;
tid->paused = false; tid->paused = false;
if (!skb_queue_empty(&tid->buf_q)) { if (ath_tid_has_buffered(tid)) {
ath_tx_queue_tid(txq, tid); ath_tx_queue_tid(txq, tid);
ath_txq_schedule(sc, txq); ath_txq_schedule(sc, txq);
} }
...@@ -1431,6 +1443,7 @@ void ath9k_release_buffered_frames(struct ieee80211_hw *hw, ...@@ -1431,6 +1443,7 @@ void ath9k_release_buffered_frames(struct ieee80211_hw *hw,
struct ieee80211_tx_info *info; struct ieee80211_tx_info *info;
struct list_head bf_q; struct list_head bf_q;
struct ath_buf *bf_tail = NULL, *bf; struct ath_buf *bf_tail = NULL, *bf;
struct sk_buff_head *tid_q;
int sent = 0; int sent = 0;
int i; int i;
...@@ -1446,12 +1459,12 @@ void ath9k_release_buffered_frames(struct ieee80211_hw *hw, ...@@ -1446,12 +1459,12 @@ void ath9k_release_buffered_frames(struct ieee80211_hw *hw,
continue; continue;
ath_txq_lock(sc, tid->ac->txq); ath_txq_lock(sc, tid->ac->txq);
while (!skb_queue_empty(&tid->buf_q) && nframes > 0) { while (nframes > 0) {
bf = ath_tx_get_tid_subframe(sc, sc->tx.uapsdq, tid); bf = ath_tx_get_tid_subframe(sc, sc->tx.uapsdq, tid, &tid_q);
if (!bf) if (!bf)
break; break;
__skb_unlink(bf->bf_mpdu, &tid->buf_q); __skb_unlink(bf->bf_mpdu, tid_q);
list_add_tail(&bf->list, &bf_q); list_add_tail(&bf->list, &bf_q);
ath_set_rates(tid->an->vif, tid->an->sta, bf); ath_set_rates(tid->an->vif, tid->an->sta, bf);
ath_tx_addto_baw(sc, tid, bf->bf_state.seqno); ath_tx_addto_baw(sc, tid, bf->bf_state.seqno);
...@@ -1464,7 +1477,7 @@ void ath9k_release_buffered_frames(struct ieee80211_hw *hw, ...@@ -1464,7 +1477,7 @@ void ath9k_release_buffered_frames(struct ieee80211_hw *hw,
sent++; sent++;
TX_STAT_INC(txq->axq_qnum, a_queued_hw); TX_STAT_INC(txq->axq_qnum, a_queued_hw);
if (skb_queue_empty(&tid->buf_q)) if (!ath_tid_has_buffered(tid))
ieee80211_sta_set_buffered(an->sta, i, false); ieee80211_sta_set_buffered(an->sta, i, false);
} }
ath_txq_unlock_complete(sc, tid->ac->txq); ath_txq_unlock_complete(sc, tid->ac->txq);
...@@ -1750,7 +1763,7 @@ void ath_txq_schedule(struct ath_softc *sc, struct ath_txq *txq) ...@@ -1750,7 +1763,7 @@ void ath_txq_schedule(struct ath_softc *sc, struct ath_txq *txq)
* add tid to round-robin queue if more frames * add tid to round-robin queue if more frames
* are pending for the tid * are pending for the tid
*/ */
if (!skb_queue_empty(&tid->buf_q)) if (ath_tid_has_buffered(tid))
ath_tx_queue_tid(txq, tid); ath_tx_queue_tid(txq, tid);
if (tid == last_tid || if (tid == last_tid ||
...@@ -1859,7 +1872,7 @@ static void ath_tx_send_ampdu(struct ath_softc *sc, struct ath_txq *txq, ...@@ -1859,7 +1872,7 @@ static void ath_tx_send_ampdu(struct ath_softc *sc, struct ath_txq *txq,
* - seqno is not within block-ack window * - seqno is not within block-ack window
* - h/w queue depth exceeds low water mark * - h/w queue depth exceeds low water mark
*/ */
if ((!skb_queue_empty(&tid->buf_q) || tid->paused || if ((ath_tid_has_buffered(tid) || tid->paused ||
!BAW_WITHIN(tid->seq_start, tid->baw_size, tid->seq_next) || !BAW_WITHIN(tid->seq_start, tid->baw_size, tid->seq_next) ||
txq->axq_ampdu_depth >= ATH_AGGR_MIN_QDEPTH) && txq->axq_ampdu_depth >= ATH_AGGR_MIN_QDEPTH) &&
txq != sc->tx.uapsdq) { txq != sc->tx.uapsdq) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment