]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
wifi: mt76: mt7996: Use proper link_id in link_sta_rc_update callback
authorLorenzo Bianconi <lorenzo@kernel.org>
Sun, 31 Aug 2025 22:14:37 +0000 (00:14 +0200)
committerFelix Fietkau <nbd@nbd.name>
Mon, 15 Sep 2025 07:47:39 +0000 (09:47 +0200)
Do not always use deflink_id in link_sta_rc_update mac80211
callback but use the proper link_id provided by mac80211.

Fixes: 0762bdd30279f ("wifi: mt76: mt7996: rework mt7996_mac_sta_rc_work to support MLO")
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
Link: https://patch.msgid.link/20250901-mt7996-fix-link_sta_rc_update-callback-v1-1-e24caf196222@kernel.org
Signed-off-by: Felix Fietkau <nbd@nbd.name>
drivers/net/wireless/mediatek/mt76/mt7996/main.c

index 8a90fee6e8b3c01f0b665540d1db4317ddb3866f..05d894182676e17689095644c73486dc4fafddde 100644 (file)
@@ -1669,19 +1669,13 @@ static void mt7996_sta_statistics(struct ieee80211_hw *hw,
        }
 }
 
-static void mt7996_link_rate_ctrl_update(void *data, struct ieee80211_sta *sta)
+static void mt7996_link_rate_ctrl_update(void *data,
+                                        struct mt7996_sta_link *msta_link)
 {
-       struct mt7996_sta *msta = (struct mt7996_sta *)sta->drv_priv;
+       struct mt7996_sta *msta = msta_link->sta;
        struct mt7996_dev *dev = msta->vif->deflink.phy->dev;
-       struct mt7996_sta_link *msta_link;
        u32 *changed = data;
 
-       rcu_read_lock();
-
-       msta_link = rcu_dereference(msta->link[msta->deflink_id]);
-       if (!msta_link)
-               goto out;
-
        spin_lock_bh(&dev->mt76.sta_poll_lock);
 
        msta_link->changed |= *changed;
@@ -1689,8 +1683,6 @@ static void mt7996_link_rate_ctrl_update(void *data, struct ieee80211_sta *sta)
                list_add_tail(&msta_link->rc_list, &dev->sta_rc_list);
 
        spin_unlock_bh(&dev->mt76.sta_poll_lock);
-out:
-       rcu_read_unlock();
 }
 
 static void mt7996_link_sta_rc_update(struct ieee80211_hw *hw,
@@ -1698,11 +1690,32 @@ static void mt7996_link_sta_rc_update(struct ieee80211_hw *hw,
                                      struct ieee80211_link_sta *link_sta,
                                      u32 changed)
 {
-       struct mt7996_dev *dev = mt7996_hw_dev(hw);
        struct ieee80211_sta *sta = link_sta->sta;
+       struct mt7996_sta *msta = (struct mt7996_sta *)sta->drv_priv;
+       struct mt7996_sta_link *msta_link;
 
-       mt7996_link_rate_ctrl_update(&changed, sta);
-       ieee80211_queue_work(hw, &dev->rc_work);
+       rcu_read_lock();
+
+       msta_link = rcu_dereference(msta->link[link_sta->link_id]);
+       if (msta_link) {
+               struct mt7996_dev *dev = mt7996_hw_dev(hw);
+
+               mt7996_link_rate_ctrl_update(&changed, msta_link);
+               ieee80211_queue_work(hw, &dev->rc_work);
+       }
+
+       rcu_read_unlock();
+}
+
+static void mt7996_sta_rate_ctrl_update(void *data, struct ieee80211_sta *sta)
+{
+       struct mt7996_sta *msta = (struct mt7996_sta *)sta->drv_priv;
+       struct mt7996_sta_link *msta_link;
+       u32 *changed = data;
+
+       msta_link = rcu_dereference(msta->link[msta->deflink_id]);
+       if (msta_link)
+               mt7996_link_rate_ctrl_update(&changed, msta_link);
 }
 
 static int
@@ -1723,7 +1736,7 @@ mt7996_set_bitrate_mask(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
         * - multiple rates: if it's not in range format i.e 0-{7,8,9} for VHT
         * then multiple MCS setting (MCS 4,5,6) is not supported.
         */
-       ieee80211_iterate_stations_atomic(hw, mt7996_link_rate_ctrl_update,
+       ieee80211_iterate_stations_atomic(hw, mt7996_sta_rate_ctrl_update,
                                          &changed);
        ieee80211_queue_work(hw, &dev->rc_work);