]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
wifi: mt76: mt7996: Switch to the secondary link if the default one is removed
authorLorenzo Bianconi <lorenzo@kernel.org>
Fri, 5 Dec 2025 10:24:38 +0000 (11:24 +0100)
committerFelix Fietkau <nbd@nbd.name>
Mon, 23 Mar 2026 09:21:24 +0000 (09:21 +0000)
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@kernel.org>
Link: https://patch.msgid.link/20251205-mt76-txq-wicd-fix-v2-3-f19ba48af7c1@kernel.org
Signed-off-by: Felix Fietkau <nbd@nbd.name>
drivers/net/wireless/mediatek/mt76/mt7996/mac.c
drivers/net/wireless/mediatek/mt76/mt7996/main.c

index 77040980dea397bb125f383effd0755e7efc3b3d..cf7b0f290328ff6a8519fb4eb213e14e0c42d5c8 100644 (file)
@@ -2365,14 +2365,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
index 8a610e0e9bae7301af4f421f83d2916ada5ebb1d..3585a9674adcb4f30422e35c730d8e0f0e5b66bb 100644 (file)
@@ -994,6 +994,22 @@ out:
        return ret;
 }
 
+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,
@@ -1011,21 +1027,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_obj(*msta_link);
                if (!msta_link)
@@ -1108,12 +1113,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 == link_id) {
+                               /* no secondary link available */
+                               msta->seclink_id = msta->deflink_id;
+                       } else {
+                               struct mt7996_sta_link *msta_seclink;
+
+                               /* switch to the secondary link */
+                               msta_seclink = mt76_dereference(
+                                               msta->link[msta->seclink_id],
+                                               mdev);
+                               if (msta_seclink) {
+                                       msta->deflink_id = msta->seclink_id;
+                                       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);
        }
 }