[PATCH ath-next] wifi: ath12k: keep ML mgmt tx on active link
Hangtian Zhu
hangtian.zhu at oss.qualcomm.com
Mon Oct 19 23:37:19 PDT 2026
Currently ath12k_mac_get_tx_link() may select an inactive link for ML
management frame transmission. This happens when mac80211 passes
IEEE80211_LINK_UNSPECIFIED and the resolved deflink is inactive.
As a result, ML management frames such as deauthentication are sent on
an inactive link and Tx fails (the frame gets dropped).
Fix this by reselecting the Tx link only when the requested link is
IEEE80211_LINK_UNSPECIFIED and the resolved deflink is inactive.
Start from vif->active_links as the candidate set and prefer
links that are both active on the vif and valid for the peer
(sta->valid_links). If that intersection is empty, fall back to
vif->active_links. Use __ffs() to pick deterministically from the
candidate set.
If mac80211 explicitly requests a link, keep that link and do not remap
management Tx to another link.
This change is limited to ML management frames. Data frames, HW-encap
frames, and non-MLO paths are unchanged.
Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.1.c7-00108-QCAHMTSWPL_V1.0_V2.0_SILICONZ_UPSTREAM-3
Signed-off-by: Hangtian Zhu <hangtian.zhu at oss.qualcomm.com>
---
drivers/net/wireless/ath/ath12k/mac.c | 28 +++++++++++++++++++++++++++
1 file changed, 28 insertions(+)
diff --git a/drivers/net/wireless/ath/ath12k/mac.c b/drivers/net/wireless/ath/ath12k/mac.c
index 01f8c6572f65..14cffba3e354 100644
--- a/drivers/net/wireless/ath/ath12k/mac.c
+++ b/drivers/net/wireless/ath/ath12k/mac.c
@@ -9600,6 +9600,7 @@ u8 ath12k_mac_get_tx_link(struct ieee80211_sta *sta, struct ieee80211_vif *vif,
struct ieee80211_link_sta *link_sta;
struct ieee80211_bss_conf *bss_conf;
struct ath12k_sta *ahsta;
+ bool req_unspecified_link = (link == IEEE80211_LINK_UNSPECIFIED);
/* Use the link id passed or the default vif link */
if (!sta) {
@@ -9645,6 +9646,33 @@ u8 ath12k_mac_get_tx_link(struct ieee80211_sta *sta, struct ieee80211_vif *vif,
if (!ieee80211_is_mgmt(hdr->frame_control))
return link;
+ /*
+ * Keep ML management Tx on an active link only when mac80211 did
+ * not request a specific link and the selected link is inactive.
+ */
+ if (req_unspecified_link && !(vif->active_links & BIT(link))) {
+ unsigned long tx_links = vif->active_links;
+ unsigned long peer_tx_links;
+
+ if (!tx_links)
+ goto out_keep_link;
+
+ peer_tx_links = tx_links & sta->valid_links;
+
+ /*
+ * Prefer links that are both active on the vif and valid for
+ * this MLO peer. If no overlap exists, fall back to vif
+ * active links.
+ */
+ if (peer_tx_links)
+ tx_links = peer_tx_links;
+ else
+ WARN_ON_ONCE(1);
+
+ link = __ffs(tx_links);
+ }
+
+out_keep_link:
/* Perform address conversion for ML STA Tx */
bss_conf = rcu_dereference(vif->link_conf[link]);
link_sta = rcu_dereference(sta->link[link]);
base-commit: cd026e68fdbf88b9cc522b76c7a9d92c9a41f709
--
2.25.1
More information about the ath12k
mailing list