[PATCH wireless-next 2/7] wifi: mac80211: tx: simplify control port frame transmission
Johannes Berg <[email protected]> Mon, 3 Aug 2026 16:08:38 +0200
| Newsgroups | org.kernel.vger.linux-wireless |
|---|---|
| Message-ID | <[email protected]> |
From: Johannes Berg <[email protected]> ieee80211_tx_control_port() already does most of the necessary work, much of which is repeated by __ieee80211_subif_start_xmit(). Most work in the latter function is completely unnecessary since these are special frames we built directly here (long enough, etc.) Call ieee80211_build_hdr() and ieee80211_xmit() directly instead. It also means some errors can now be reported to userspace rather than frames silently getting dropped, but that's a good thing. Signed-off-by: Johannes Berg <[email protected]> --- net/mac80211/tx.c | 34 +++++++++++++++++++--------------- 1 file changed, 19 insertions(+), 15 deletions(-) diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index 6c2ee181a3a7..772350f485dd 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c @@ -6596,9 +6596,6 @@ int ieee80211_tx_control_port(struct wiphy *wiphy, struct net_device *dev, skb_reset_network_header(skb); skb_reset_mac_header(skb); - if (local->hw.queues < IEEE80211_NUM_ACS) - goto start_xmit; - /* update QoS header to prioritize control port frames if possible, * prioritization also happens for control port frames send over * AF_PACKET @@ -6611,24 +6608,31 @@ int ieee80211_tx_control_port(struct wiphy *wiphy, struct net_device *dev, return err; } - if (!IS_ERR(sta)) { - u16 queue = ieee80211_select_queue(sdata, sta, skb); + if (IS_ERR(sta)) + sta = NULL; - skb_set_queue_mapping(skb, queue); + skb_set_queue_mapping(skb, ieee80211_select_queue(sdata, sta, skb)); - /* - * for MLO STA, the SA should be the AP MLD address, but - * the link ID has been selected already - */ - if (sta && sta->sta.mlo) - memcpy(ehdr->h_source, sdata->vif.addr, ETH_ALEN); + /* + * for MLO STA, the SA should be the AP MLD address, but + * the link ID has been selected already + */ + if (sta && sta->sta.mlo) + memcpy(ehdr->h_source, sdata->vif.addr, ETH_ALEN); + + skb = ieee80211_build_hdr(sdata, skb, flags, sta, ctrl_flags, cookie); + if (IS_ERR(skb)) { + rcu_read_unlock(); + return PTR_ERR(skb); } - rcu_read_unlock(); -start_xmit: + dev_sw_netstats_tx_add(dev, 1, skb->len); + ieee80211_tpt_led_trig_tx(local, skb->len); + local_bh_disable(); - __ieee80211_subif_start_xmit(skb, skb->dev, flags, ctrl_flags, cookie); + ieee80211_xmit(sdata, sta, skb); local_bh_enable(); + rcu_read_unlock(); return 0; } -- 2.55.0