From e3a0b1202bf63f4b412e02eb6edc0fb1f64313de Mon Sep 17 00:00:00 2001 From: "Bjoern A. Zeeb" Date: Mon, 5 Sep 2022 21:03:03 +0000 Subject: [PATCH] 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 e674ddec0b4138274539587fe9336b577ff1242a 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 --- sys/compat/linuxkpi/common/src/linux_80211.c | 83 +++++++++----------- sys/contrib/dev/iwlwifi/mvm/tx.c | 2 +- 2 files changed, 39 insertions(+), 46 deletions(-) diff --git a/sys/compat/linuxkpi/common/src/linux_80211.c b/sys/compat/linuxkpi/common/src/linux_80211.c index 7f8e07dee048..1eb520b2140f 100644 --- a/sys/compat/linuxkpi/common/src/linux_80211.c +++ b/sys/compat/linuxkpi/common/src/linux_80211.c @@ -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 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(<xq->skbq)) { - struct sk_buff *skb2; - - skb2 = skb_dequeue(<xq->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(<xq->skbq)) - goto ops_tx; -#endif - skb_queue_tail(<xq->skbq, skb); #ifdef LINUXKPI_DEBUG_80211 if (linuxkpi_debug_80211 & D80211_TRACE_TX) diff --git a/sys/contrib/dev/iwlwifi/mvm/tx.c b/sys/contrib/dev/iwlwifi/mvm/tx.c index 303d9b1e5a02..ac96cff455b1 100644 --- a/sys/contrib/dev/iwlwifi/mvm/tx.c +++ b/sys/contrib/dev/iwlwifi/mvm/tx.c @@ -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