[PATCH mt76 v2 3/4] wifi: mt76: mt7996: Switch to the secondary link if the default one is removed
Lorenzo Bianconi
lorenzo at kernel.org
Fri Dec 5 02:24:38 PST 2025
Switch to the secondary link if available in mt7996_mac_sta_remove_links
routine if the primary one is removed.
Moreover reset secondary link index for single link scenario.
Fixes: 85cd5534a3f2e ("wifi: mt76: mt7996: use correct link_id when filling TXD and TXP")
Signed-off-by: Lorenzo Bianconi <lorenzo at kernel.org>
---
drivers/net/wireless/mediatek/mt76/mt7996/mac.c | 12 +++---
drivers/net/wireless/mediatek/mt76/mt7996/main.c | 52 ++++++++++++++++--------
2 files changed, 41 insertions(+), 23 deletions(-)
diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/mac.c b/drivers/net/wireless/mediatek/mt76/mt7996/mac.c
index 2560e2f46e89a4bc46e21d796fca80b7decefa5c..4d33265971e2e00c788541a5c780dc20619e7396 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7996/mac.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7996/mac.c
@@ -2403,14 +2403,12 @@ mt7996_mac_reset_sta_iter(void *data, struct ieee80211_sta *sta)
continue;
mt7996_mac_sta_deinit_link(dev, msta_link);
-
- if (msta->deflink_id == i) {
- msta->deflink_id = IEEE80211_LINK_UNSPECIFIED;
- continue;
- }
-
- kfree_rcu(msta_link, rcu_head);
+ if (msta_link != &msta->deflink)
+ kfree_rcu(msta_link, rcu_head);
}
+
+ msta->deflink_id = IEEE80211_LINK_UNSPECIFIED;
+ msta->seclink_id = msta->deflink_id;
}
static void
diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/main.c b/drivers/net/wireless/mediatek/mt76/mt7996/main.c
index 8bf85a9beee7dc8c6741568af5b36cf89f0c1a88..1baace971ec3511dba3e8a64c236a2b55f9dbd36 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7996/main.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7996/main.c
@@ -945,6 +945,22 @@ mt7996_channel_switch_beacon(struct ieee80211_hw *hw,
mutex_unlock(&dev->mt76.mutex);
}
+static void
+mt7996_sta_init_txq_wcid(struct ieee80211_sta *sta, int idx)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(sta->txq); i++) {
+ struct mt76_txq *mtxq;
+
+ if (!sta->txq[i])
+ continue;
+
+ mtxq = (struct mt76_txq *)sta->txq[i]->drv_priv;
+ mtxq->wcid = idx;
+ }
+}
+
static int
mt7996_mac_sta_init_link(struct mt7996_dev *dev,
struct ieee80211_bss_conf *link_conf,
@@ -962,21 +978,10 @@ mt7996_mac_sta_init_link(struct mt7996_dev *dev,
return -ENOSPC;
if (msta->deflink_id == IEEE80211_LINK_UNSPECIFIED) {
- int i;
-
msta_link = &msta->deflink;
msta->deflink_id = link_id;
msta->seclink_id = msta->deflink_id;
-
- for (i = 0; i < ARRAY_SIZE(sta->txq); i++) {
- struct mt76_txq *mtxq;
-
- if (!sta->txq[i])
- continue;
-
- mtxq = (struct mt76_txq *)sta->txq[i]->drv_priv;
- mtxq->wcid = idx;
- }
+ mt7996_sta_init_txq_wcid(sta, idx);
} else {
msta_link = kzalloc(sizeof(*msta_link), GFP_KERNEL);
if (!msta_link)
@@ -1058,13 +1063,28 @@ mt7996_mac_sta_remove_links(struct mt7996_dev *dev, struct ieee80211_vif *vif,
mphy->num_sta--;
if (msta->deflink_id == link_id) {
- msta->deflink_id = IEEE80211_LINK_UNSPECIFIED;
- continue;
+ if (msta->seclink_id == msta->deflink_id) {
+ /* no secondary link available */
+ msta->deflink_id = IEEE80211_LINK_UNSPECIFIED;
+ msta->seclink_id = msta->deflink_id;
+ } else {
+ struct mt7996_sta_link *msta_seclink;
+
+ /* switch to the secondary link */
+ msta->deflink_id = msta->seclink_id;
+ msta_seclink = mt76_dereference(
+ msta->link[msta->seclink_id],
+ mdev);
+ if (msta_seclink)
+ mt7996_sta_init_txq_wcid(sta,
+ msta_seclink->wcid.idx);
+ }
} else if (msta->seclink_id == link_id) {
- msta->seclink_id = IEEE80211_LINK_UNSPECIFIED;
+ msta->seclink_id = msta->deflink_id;
}
- kfree_rcu(msta_link, rcu_head);
+ if (msta_link != &msta->deflink)
+ kfree_rcu(msta_link, rcu_head);
}
}
--
2.52.0
More information about the Linux-mediatek
mailing list