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:
parent
ec190d9150
commit
e3a0b1202b
@ -316,6 +316,7 @@ lkpi_nl80211_band_to_net80211_band(enum nl80211_band band)
|
|||||||
return (0x00);
|
return (0x00);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
static enum ieee80211_ac_numbers
|
static enum ieee80211_ac_numbers
|
||||||
lkpi_ac_net_to_l80211(int ac)
|
lkpi_ac_net_to_l80211(int ac)
|
||||||
{
|
{
|
||||||
@ -334,6 +335,7 @@ lkpi_ac_net_to_l80211(int ac)
|
|||||||
return (IEEE80211_AC_BE);
|
return (IEEE80211_AC_BE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static enum nl80211_iftype
|
static enum nl80211_iftype
|
||||||
lkpi_opmode_to_vif_type(enum ieee80211_opmode opmode)
|
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;
|
struct ieee80211_vif *vif;
|
||||||
enum ieee80211_bss_changed changed;
|
enum ieee80211_bss_changed changed;
|
||||||
size_t len;
|
size_t len;
|
||||||
int error;
|
int error, i;
|
||||||
|
|
||||||
if (!TAILQ_EMPTY(&ic->ic_vaps)) /* 1 so far. Add <n> once this works. */
|
if (!TAILQ_EMPTY(&ic->ic_vaps)) /* 1 so far. Add <n> once this works. */
|
||||||
return (NULL);
|
return (NULL);
|
||||||
@ -2252,6 +2254,18 @@ lkpi_ic_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ],
|
|||||||
if (vif->bss_conf.beacon_int < 16)
|
if (vif->bss_conf.beacon_int < 16)
|
||||||
vif->bss_conf.beacon_int = 16;
|
vif->bss_conf.beacon_int = 16;
|
||||||
#endif
|
#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();
|
IMPROVE();
|
||||||
|
|
||||||
error = lkpi_80211_mo_start(hw);
|
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_control control;
|
||||||
struct ieee80211_tx_info *info;
|
struct ieee80211_tx_info *info;
|
||||||
struct ieee80211_sta *sta;
|
struct ieee80211_sta *sta;
|
||||||
|
struct ieee80211_hdr *hdr;
|
||||||
void *buf;
|
void *buf;
|
||||||
int ac;
|
uint8_t ac, tid;
|
||||||
|
|
||||||
M_ASSERTPKTHDR(m);
|
M_ASSERTPKTHDR(m);
|
||||||
#ifdef LINUXKPI_DEBUG_80211
|
#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);
|
lvif = VAP_TO_LVIF(ni->ni_vap);
|
||||||
vif = LVIF_TO_VIF(lvif);
|
vif = LVIF_TO_VIF(lvif);
|
||||||
|
|
||||||
/* XXX-BZ review this at some point [4] vs. [8] vs. [16](TID). */
|
hdr = (void *)skb->data;
|
||||||
ac = M_WME_GETAC(m);
|
tid = linuxkpi_ieee80211_get_tid(hdr, true);
|
||||||
skb->priority = WME_AC_TO_TID(ac);
|
if (tid == IEEE80211_NONQOS_TID) { /* == IEEE80211_NUM_TIDS */
|
||||||
ac = lkpi_ac_net_to_l80211(ac);
|
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);
|
skb_set_queue_mapping(skb, ac);
|
||||||
|
|
||||||
info = IEEE80211_SKB_CB(skb);
|
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)
|
if (c == NULL || c == IEEE80211_CHAN_ANYC)
|
||||||
c = ic->ic_curchan;
|
c = ic->ic_curchan;
|
||||||
info->band = lkpi_net80211_chan_to_nl80211_band(c);
|
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)
|
if (m->m_flags & M_EAPOL)
|
||||||
info->control.flags |= IEEE80211_TX_CTRL_PORT_CTRL_PROTO;
|
info->control.flags |= IEEE80211_TX_CTRL_PORT_CTRL_PROTO;
|
||||||
info->control.vif = vif;
|
info->control.vif = vif;
|
||||||
@ -3079,50 +3099,23 @@ lkpi_80211_txq_tx_one(struct lkpi_sta *lsta, struct mbuf *m)
|
|||||||
|
|
||||||
if (sta != NULL) {
|
if (sta != NULL) {
|
||||||
struct lkpi_txq *ltxq;
|
struct lkpi_txq *ltxq;
|
||||||
struct ieee80211_hdr *hdr;
|
|
||||||
|
|
||||||
hdr = (void *)skb->data;
|
ltxq = NULL;
|
||||||
if (lsta->added_to_drv &&
|
if (!ieee80211_is_data_present(hdr->frame_control)) {
|
||||||
!ieee80211_is_data_present(hdr->frame_control)) {
|
if (vif->type == NL80211_IFTYPE_STATION &&
|
||||||
if (sta->txq[IEEE80211_NUM_TIDS] != NULL)
|
lsta->added_to_drv &&
|
||||||
|
sta->txq[IEEE80211_NUM_TIDS] != NULL)
|
||||||
ltxq = TXQ_TO_LTXQ(sta->txq[IEEE80211_NUM_TIDS]);
|
ltxq = TXQ_TO_LTXQ(sta->txq[IEEE80211_NUM_TIDS]);
|
||||||
else
|
} else if (lsta->added_to_drv &&
|
||||||
goto ops_tx;
|
sta->txq[skb->priority] != NULL) {
|
||||||
} else if (lsta->added_to_drv) {
|
ltxq = TXQ_TO_LTXQ(sta->txq[skb->priority]);
|
||||||
ltxq = TXQ_TO_LTXQ(sta->txq[ac]); /* XXX-BZ re-check */
|
}
|
||||||
} else
|
if (ltxq == NULL)
|
||||||
goto ops_tx;
|
goto ops_tx;
|
||||||
|
|
||||||
KASSERT(ltxq != NULL, ("%s: lsta %p sta %p m %p skb %p "
|
KASSERT(ltxq != NULL, ("%s: lsta %p sta %p m %p skb %p "
|
||||||
"ltxq %p != NULL\n", __func__, lsta, sta, m, skb, ltxq));
|
"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);
|
skb_queue_tail(<xq->skbq, skb);
|
||||||
#ifdef LINUXKPI_DEBUG_80211
|
#ifdef LINUXKPI_DEBUG_80211
|
||||||
if (linuxkpi_debug_80211 & D80211_TRACE_TX)
|
if (linuxkpi_debug_80211 & D80211_TRACE_TX)
|
||||||
|
@ -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 (WARN_ONCE(txq_id == IWL_MVM_INVALID_QUEUE, "Invalid TXQ id")) {
|
||||||
#if defined(__FreeBSD__)
|
#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,
|
"skb %p { len %u } info %p sta %p\n", fc, mvmsta->sta_id,
|
||||||
tid, txq_id, mvm, skb, skb->len, info, sta);
|
tid, txq_id, mvm, skb, skb->len, info, sta);
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user