LinuxKPI: 80211 / iwlwifi: improve queue management

For one initialise vif->hw_queues later set in lkpi_80211_txq_tx_one()
for drivers using them.  This may still need slightly more cleanup once
we get QUEUE_CONTROL-supporting drivers into the tree.

For the other rework and improve how we deal with tid/ac/txq in
lkpi_80211_txq_tx_one() and cleanup old comments and unused code.
This seems to reduce (remove) "Invalid TXQ id" reports from iwlwifi.
(The assumption is that the frame(s) triggering this WARN_ONCE or the
added FreeBSD specific logging were sent with lkpi_80211_mo_tx()).

Adjust the one logging from e674ddec0b
to IWL_DEBUG_TX so that now this is fixed it is also not always logged
anymore but leave it in case we need to further debug queues in the
future.

Tested by:	pstef, Kevin Oberman (rkoberman gmail.com)
Sponsored by:	The FreeBSD Foundation
MFC after:	3 days
This commit is contained in:
Bjoern A. Zeeb 2022-09-05 21:03:03 +00:00
parent ec190d9150
commit e3a0b1202b
2 changed files with 39 additions and 46 deletions

View File

@ -316,6 +316,7 @@ lkpi_nl80211_band_to_net80211_band(enum nl80211_band band)
return (0x00);
}
#if 0
static enum ieee80211_ac_numbers
lkpi_ac_net_to_l80211(int ac)
{
@ -334,6 +335,7 @@ lkpi_ac_net_to_l80211(int ac)
return (IEEE80211_AC_BE);
}
}
#endif
static enum nl80211_iftype
lkpi_opmode_to_vif_type(enum ieee80211_opmode opmode)
@ -2196,7 +2198,7 @@ lkpi_ic_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ],
struct ieee80211_vif *vif;
enum ieee80211_bss_changed changed;
size_t len;
int error;
int error, i;
if (!TAILQ_EMPTY(&ic->ic_vaps)) /* 1 so far. Add <n> once this works. */
return (NULL);
@ -2252,6 +2254,18 @@ lkpi_ic_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ],
if (vif->bss_conf.beacon_int < 16)
vif->bss_conf.beacon_int = 16;
#endif
/* Setup queue defaults; driver may override in (*add_interface). */
for (i = 0; i < IEEE80211_NUM_ACS; i++) {
if (ieee80211_hw_check(hw, QUEUE_CONTROL))
vif->hw_queue[i] = IEEE80211_INVAL_HW_QUEUE;
else if (hw->queues >= IEEE80211_NUM_ACS)
vif->hw_queue[i] = i;
else
vif->hw_queue[i] = 0;
}
vif->cab_queue = IEEE80211_INVAL_HW_QUEUE;
IMPROVE();
error = lkpi_80211_mo_start(hw);
@ -2967,8 +2981,9 @@ lkpi_80211_txq_tx_one(struct lkpi_sta *lsta, struct mbuf *m)
struct ieee80211_tx_control control;
struct ieee80211_tx_info *info;
struct ieee80211_sta *sta;
struct ieee80211_hdr *hdr;
void *buf;
int ac;
uint8_t ac, tid;
M_ASSERTPKTHDR(m);
#ifdef LINUXKPI_DEBUG_80211
@ -3047,10 +3062,15 @@ lkpi_80211_txq_tx_one(struct lkpi_sta *lsta, struct mbuf *m)
lvif = VAP_TO_LVIF(ni->ni_vap);
vif = LVIF_TO_VIF(lvif);
/* XXX-BZ review this at some point [4] vs. [8] vs. [16](TID). */
ac = M_WME_GETAC(m);
skb->priority = WME_AC_TO_TID(ac);
ac = lkpi_ac_net_to_l80211(ac);
hdr = (void *)skb->data;
tid = linuxkpi_ieee80211_get_tid(hdr, true);
if (tid == IEEE80211_NONQOS_TID) { /* == IEEE80211_NUM_TIDS */
skb->priority = 0;
ac = IEEE80211_AC_BE;
} else {
skb->priority = tid & IEEE80211_QOS_CTL_TID_MASK;
ac = tid_to_mac80211_ac[tid & 7];
}
skb_set_queue_mapping(skb, ac);
info = IEEE80211_SKB_CB(skb);
@ -3059,7 +3079,7 @@ lkpi_80211_txq_tx_one(struct lkpi_sta *lsta, struct mbuf *m)
if (c == NULL || c == IEEE80211_CHAN_ANYC)
c = ic->ic_curchan;
info->band = lkpi_net80211_chan_to_nl80211_band(c);
info->hw_queue = ac; /* XXX-BZ is this correct? */
info->hw_queue = vif->hw_queue[ac];
if (m->m_flags & M_EAPOL)
info->control.flags |= IEEE80211_TX_CTRL_PORT_CTRL_PROTO;
info->control.vif = vif;
@ -3079,50 +3099,23 @@ 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 = NULL;
if (!ieee80211_is_data_present(hdr->frame_control)) {
if (vif->type == NL80211_IFTYPE_STATION &&
lsta->added_to_drv &&
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
} else if (lsta->added_to_drv &&
sta->txq[skb->priority] != NULL) {
ltxq = TXQ_TO_LTXQ(sta->txq[skb->priority]);
}
if (ltxq == NULL)
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));
/*
* We currently do not use queues but do direct TX.
* The exception to the rule is initial packets, as we cannot
* TX until queues are allocated (at least for iwlwifi).
* So we wake_tx_queue in newstate and register any dequeue
* 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. */
while (!skb_queue_empty(&ltxq->skbq)) {
struct sk_buff *skb2;
skb2 = skb_dequeue(&ltxq->skbq);
if (skb2 != NULL) {
memset(&control, 0, sizeof(control));
control.sta = sta;
lkpi_80211_mo_tx(hw, &control, skb2);
}
}
goto ops_tx;
}
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)

View File

@ -1140,7 +1140,7 @@ static int iwl_mvm_tx_mpdu(struct iwl_mvm *mvm, struct sk_buff *skb,
if (WARN_ONCE(txq_id == IWL_MVM_INVALID_QUEUE, "Invalid TXQ id")) {
#if defined(__FreeBSD__)
IWL_ERR(mvm, "fc %#06x sta_id %u tid %u txq_id %u mvm %p "
IWL_DEBUG_TX(mvm, "fc %#06x sta_id %u tid %u txq_id %u mvm %p "
"skb %p { len %u } info %p sta %p\n", fc, mvmsta->sta_id,
tid, txq_id, mvm, skb, skb->len, info, sta);
#endif