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
MFC after:	3 days
This commit is contained in:
Bjoern A. Zeeb 2022-06-10 14:18:57 +00:00
parent 796d48ec41
commit d0d2911035

View File

@ -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,28 @@ 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",
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