Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+32 −19
Original line number Diff line number Diff line
@@ -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)
{
	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)

	memset(&ts, 0, sizeof(ts));

	while ((skb = __skb_dequeue(&tid->buf_q))) {
	while ((skb = ath_tid_dequeue(tid))) {
		fi = get_frame_info(skb);
		bf = fi->bf;

@@ -266,7 +276,7 @@ static void ath_tid_drain(struct ath_softc *sc, struct ath_txq *txq,
	memset(&ts, 0, sizeof(ts));
	INIT_LIST_HEAD(&bf_head);

	while ((skb = __skb_dequeue(&tid->buf_q))) {
	while ((skb = ath_tid_dequeue(tid))) {
		fi = get_frame_info(skb);
		bf = fi->bf;

@@ -815,7 +825,7 @@ static int ath_compute_num_delims(struct ath_softc *sc, struct ath_atx_tid *tid,

static struct ath_buf *
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 sk_buff *skb;
@@ -823,7 +833,8 @@ ath_tx_get_tid_subframe(struct ath_softc *sc, struct ath_txq *txq,
	u16 seqno;

	while (1) {
		skb = skb_peek(&tid->buf_q);
		*q = &tid->buf_q;
		skb = skb_peek(*q);
		if (!skb)
			break;

@@ -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);

		if (!bf) {
			__skb_unlink(skb, &tid->buf_q);
			__skb_unlink(skb, *q);
			ath_txq_skb_done(sc, txq, skb);
			ieee80211_free_txskb(sc->hw, skb);
			continue;
@@ -852,7 +863,7 @@ ath_tx_get_tid_subframe(struct ath_softc *sc, struct ath_txq *txq,

			INIT_LIST_HEAD(&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_complete_buf(sc, bf, txq, &bf_head, &ts, 0);
			continue;
@@ -881,9 +892,10 @@ static enum ATH_AGGR_STATUS ath_tx_form_aggr(struct ath_softc *sc,
	struct ieee80211_tx_info *tx_info;
	struct ath_frame_info *fi;
	struct sk_buff *skb;
	struct sk_buff_head *tid_q;

	do {
		bf = ath_tx_get_tid_subframe(sc, txq, tid);
		bf = ath_tx_get_tid_subframe(sc, txq, tid, &tid_q);
		if (!bf) {
			status = ATH_AGGR_BAW_CLOSED;
			break;
@@ -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);
		bf->bf_state.ndelim = ndelim;

		__skb_unlink(skb, &tid->buf_q);
		__skb_unlink(skb, tid_q);
		list_add_tail(&bf->list, bf_q);
		if (bf_prev)
			bf_prev->bf_next = bf;

		bf_prev = bf;

	} while (!skb_queue_empty(&tid->buf_q));
	} while (ath_tid_has_buffered(tid));

	*aggr_len = al;

@@ -1250,7 +1262,7 @@ static void ath_tx_sched_aggr(struct ath_softc *sc, struct ath_txq *txq,
	int aggr_len;

	do {
		if (skb_queue_empty(&tid->buf_q))
		if (!ath_tid_has_buffered(tid))
			return;

		INIT_LIST_HEAD(&bf_q);
@@ -1354,7 +1366,7 @@ void ath_tx_aggr_sleep(struct ieee80211_sta *sta, struct ath_softc *sc,

		ath_txq_lock(sc, txq);

		buffered = !skb_queue_empty(&tid->buf_q);
		buffered = ath_tid_has_buffered(tid);

		tid->sched = false;
		list_del(&tid->list);
@@ -1386,7 +1398,7 @@ void ath_tx_aggr_wakeup(struct ath_softc *sc, struct ath_node *an)
		ath_txq_lock(sc, txq);
		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_txq_schedule(sc, txq);
		}
@@ -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->paused = false;

	if (!skb_queue_empty(&tid->buf_q)) {
	if (ath_tid_has_buffered(tid)) {
		ath_tx_queue_tid(txq, tid);
		ath_txq_schedule(sc, txq);
	}
@@ -1431,6 +1443,7 @@ void ath9k_release_buffered_frames(struct ieee80211_hw *hw,
	struct ieee80211_tx_info *info;
	struct list_head bf_q;
	struct ath_buf *bf_tail = NULL, *bf;
	struct sk_buff_head *tid_q;
	int sent = 0;
	int i;

@@ -1446,12 +1459,12 @@ void ath9k_release_buffered_frames(struct ieee80211_hw *hw,
			continue;

		ath_txq_lock(sc, tid->ac->txq);
		while (!skb_queue_empty(&tid->buf_q) && nframes > 0) {
			bf = ath_tx_get_tid_subframe(sc, sc->tx.uapsdq, tid);
		while (nframes > 0) {
			bf = ath_tx_get_tid_subframe(sc, sc->tx.uapsdq, tid, &tid_q);
			if (!bf)
				break;

			__skb_unlink(bf->bf_mpdu, &tid->buf_q);
			__skb_unlink(bf->bf_mpdu, tid_q);
			list_add_tail(&bf->list, &bf_q);
			ath_set_rates(tid->an->vif, tid->an->sta, bf);
			ath_tx_addto_baw(sc, tid, bf->bf_state.seqno);
@@ -1464,7 +1477,7 @@ void ath9k_release_buffered_frames(struct ieee80211_hw *hw,
			sent++;
			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);
		}
		ath_txq_unlock_complete(sc, tid->ac->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
			 * are pending for the tid
			 */
			if (!skb_queue_empty(&tid->buf_q))
			if (ath_tid_has_buffered(tid))
				ath_tx_queue_tid(txq, tid);

			if (tid == last_tid ||
@@ -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
	 * - 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) ||
	     txq->axq_ampdu_depth >= ATH_AGGR_MIN_QDEPTH) &&
	    txq != sc->tx.uapsdq) {