git: 74cedb5e9016 - stable/13 - LinuxKPI: 802.11: rework handling of the special IEEE80211_NUM_TIDS queue

From: Bjoern A. Zeeb <bz_at_FreeBSD.org>
Date: Fri, 01 Jul 2022 14:57:40 UTC
The branch stable/13 has been updated by bz:

URL: https://cgit.FreeBSD.org/src/commit/?id=74cedb5e90166d8d579a74444b8c72fd430045af

commit 74cedb5e90166d8d579a74444b8c72fd430045af
Author:     Bjoern A. Zeeb <bz@FreeBSD.org>
AuthorDate: 2022-06-10 14:18:57 +0000
Commit:     Bjoern A. Zeeb <bz@FreeBSD.org>
CommitDate: 2022-07-01 13:45:09 +0000

    LinuxKPI: 802.11: rework handling of the special IEEE80211_NUM_TIDS queue
    
    Rework the way we are dealing with the last queue.  If the driver
    opts in to STA_MMPDU_TXQ then preferably send all non-data frames
    via the last (IEEE80211_NUM_TIDS) queue which otherwise is not used
    in station mode.
    If we do not have that queue we do individual tx() calls for non-data
    frames now.
    Everything else goes via the selected queue if possible for as long as
    we have a ni (sta) and otherwise resorts to direct tx.
    
    Tested on:      Intel AX200 and AX210
    Sponsored by:   The FreeBSD Foundation
    
    (cherry picked from commit d0d2911035192473e8bd3f6b99ed5ca9b1b29e47)
    (cherry picked from commit fb6eaf74e9ead477be1f25cba88273ab65ece0d1)
---
 sys/compat/linuxkpi/common/src/linux_80211.c | 55 +++++++++++++++++++---------
 1 file changed, 37 insertions(+), 18 deletions(-)

diff --git a/sys/compat/linuxkpi/common/src/linux_80211.c b/sys/compat/linuxkpi/common/src/linux_80211.c
index 094724c57d10..8a6ddf63e3f5 100644
--- a/sys/compat/linuxkpi/common/src/linux_80211.c
+++ b/sys/compat/linuxkpi/common/src/linux_80211.c
@@ -219,27 +219,27 @@ lkpi_lsta_alloc(struct ieee80211vap *vap, const uint8_t mac[IEEE80211_ADDR_LEN],
 	for (tid = 0; tid < nitems(sta->txq); tid++) {
 		struct lkpi_txq *ltxq;
 
-		/*
-		 * We are neither limiting ourselves to hw.queues here,
-		 * nor do we check if driver wants IEEE80211_NUM_TIDS queue.
-		 */
-
+		/* We are not limiting ourselves to hw.queues here. */
 		ltxq = malloc(sizeof(*ltxq) + hw->txq_data_size,
 		    M_LKPI80211, M_NOWAIT | M_ZERO);
 		if (ltxq == NULL)
 			goto cleanup;
-		ltxq->seen_dequeue = false;
-		skb_queue_head_init(&ltxq->skbq);
 		/* iwlwifi//mvm/sta.c::tid_to_mac80211_ac[] */
 		if (tid == IEEE80211_NUM_TIDS) {
-			IMPROVE();
+			if (!ieee80211_hw_check(hw, STA_MMPDU_TXQ)) {
+				free(ltxq, M_LKPI80211);
+				continue;
+			}
+			IMPROVE("AP/if we support non-STA here too");
 			ltxq->txq.ac = IEEE80211_AC_VO;
 		} else {
 			ltxq->txq.ac = tid_to_mac80211_ac[tid & 7];
 		}
+		ltxq->seen_dequeue = false;
+		ltxq->txq.vif = vif;
 		ltxq->txq.tid = tid;
 		ltxq->txq.sta = sta;
-		ltxq->txq.vif = vif;
+		skb_queue_head_init(&ltxq->skbq);
 		sta->txq[tid] = &ltxq->txq;
 	}
 
@@ -3043,8 +3043,22 @@ lkpi_80211_txq_tx_one(struct lkpi_sta *lsta, struct mbuf *m)
 
 	if (sta != NULL) {
 		struct lkpi_txq *ltxq;
+		struct ieee80211_hdr *hdr;
+
+		hdr = (void *)skb->data;
+		if (lsta->added_to_drv &&
+		    !ieee80211_is_data_present(hdr->frame_control)) {
+			if (sta->txq[IEEE80211_NUM_TIDS] != NULL)
+				ltxq = TXQ_TO_LTXQ(sta->txq[IEEE80211_NUM_TIDS]);
+			else
+				goto ops_tx;
+		} else if (lsta->added_to_drv) {
+			ltxq = TXQ_TO_LTXQ(sta->txq[ac]);	/* XXX-BZ re-check */
+		} else
+			goto ops_tx;
+		KASSERT(ltxq != NULL, ("%s: lsta %p sta %p m %p skb %p "
+		    "ltxq %p != NULL\n", __func__, lsta, sta, m, skb, ltxq));
 
-		ltxq = TXQ_TO_LTXQ(sta->txq[ac]);	/* XXX-BZ re-check */
 		/*
 		 * We currently do not use queues but do direct TX.
 		 * The exception to the rule is initial packets, as we cannot
@@ -3053,6 +3067,7 @@ lkpi_80211_txq_tx_one(struct lkpi_sta *lsta, struct mbuf *m)
 		 * calls.  In the time until then we queue packets and
 		 * let the driver deal with them.
 		 */
+#if 0
 		if (!ltxq->seen_dequeue) {
 
 			/* Prevent an ordering problem, likely other issues. */
@@ -3070,25 +3085,29 @@ lkpi_80211_txq_tx_one(struct lkpi_sta *lsta, struct mbuf *m)
 		}
 		if (0 && ltxq->seen_dequeue && skb_queue_empty(&ltxq->skbq))
 			goto ops_tx;
+#endif
 
 		skb_queue_tail(&ltxq->skbq, skb);
 #ifdef LINUXKPI_DEBUG_80211
 		if (linuxkpi_debug_80211 & D80211_TRACE_TX)
-			printf("%s:%d lsta %p sta %p ni %p %6D skb %p lxtq %p "
-			    "qlen %u WAKE_TX_Q ac %d prio %u qmap %u\n",
-			    __func__, __LINE__, lsta, sta, ni,
-			    ni->ni_macaddr, ":", skb, ltxq,
-			    skb_queue_len(&ltxq->skbq), ac,
-			    skb->priority, skb->qmap);
+			printf("%s:%d mo_wake_tx_queue :: %d %u lsta %p sta %p "
+			    "ni %p %6D skb %p lxtq %p { qlen %u, ac %d tid %u } "
+			    "WAKE_TX_Q ac %d prio %u qmap %u\n",
+			    __func__, __LINE__,
+			    curthread->td_tid, (unsigned int)ticks,
+			    lsta, sta, ni, ni->ni_macaddr, ":", skb, ltxq,
+			    skb_queue_len(&ltxq->skbq), ltxq->txq.ac,
+			    ltxq->txq.tid, ac, skb->priority, skb->qmap);
 #endif
-		lkpi_80211_mo_wake_tx_queue(hw, sta->txq[ac]);	/* XXX-BZ */
+		lkpi_80211_mo_wake_tx_queue(hw, &ltxq->txq);
 		return;
 	}
 
 ops_tx:
 #ifdef LINUXKPI_DEBUG_80211
 	if (linuxkpi_debug_80211 & D80211_TRACE_TX)
-		printf("%s:%d lsta %p sta %p ni %p %6D skb %p TX ac %d prio %u qmap %u\n",
+		printf("%s:%d mo_tx :: lsta %p sta %p ni %p %6D skb %p "
+		    "TX ac %d prio %u qmap %u\n",
 		    __func__, __LINE__, lsta, sta, ni, ni->ni_macaddr, ":",
 		    skb, ac, skb->priority, skb->qmap);
 #endif