]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
wifi: mt76: mt7925: program BA state on active links
authorSean Wang <sean.wang@mediatek.com>
Sat, 25 Apr 2026 15:47:21 +0000 (10:47 -0500)
committerFelix Fietkau <nbd@nbd.name>
Tue, 9 Jun 2026 10:15:21 +0000 (10:15 +0000)
With MLO, traffic for one TID can be sent on any active link. Programming
BA state only on the default link leaves the other active links out of
sync.

Program BA state on all active links instead.

Fixes: 766ea2cf5a39 ("Revert "wifi: mt76: mt7925: Update mt7925_mcu_uni_[tx,rx]_ba for MLO"")
Tested-by: Yao Ting Hsieh <yao-ting.hsieh@mediatek.com>
Signed-off-by: Sean Wang <sean.wang@mediatek.com>
Link: https://patch.msgid.link/20260425154721.738101-3-sean.wang@kernel.org
Signed-off-by: Felix Fietkau <nbd@nbd.name>
drivers/net/wireless/mediatek/mt76/mt7925/main.c
drivers/net/wireless/mediatek/mt76/mt7925/mcu.c
drivers/net/wireless/mediatek/mt76/mt7925/mt7925.h

index 2599b738496fda9c281724749ac3e7299a61dbb0..c20e5316fae07902a25982bc4cb754cfd3f001b7 100644 (file)
@@ -1410,22 +1410,22 @@ mt7925_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
        case IEEE80211_AMPDU_RX_START:
                mt76_rx_aggr_start(&dev->mt76, &msta->deflink.wcid, tid, ssn,
                                   params->buf_size);
-               mt7925_mcu_uni_rx_ba(dev, params, true);
+               mt7925_mcu_uni_rx_ba(dev, params, vif, true);
                break;
        case IEEE80211_AMPDU_RX_STOP:
                mt76_rx_aggr_stop(&dev->mt76, &msta->deflink.wcid, tid);
-               mt7925_mcu_uni_rx_ba(dev, params, false);
+               mt7925_mcu_uni_rx_ba(dev, params, vif, false);
                break;
        case IEEE80211_AMPDU_TX_OPERATIONAL:
                mtxq->aggr = true;
                mtxq->send_bar = false;
-               mt7925_mcu_uni_tx_ba(dev, params, true);
+               mt7925_mcu_uni_tx_ba(dev, params, vif, true);
                break;
        case IEEE80211_AMPDU_TX_STOP_FLUSH:
        case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT:
                mtxq->aggr = false;
                clear_bit(tid, &msta->deflink.wcid.ampdu_state);
-               mt7925_mcu_uni_tx_ba(dev, params, false);
+               mt7925_mcu_uni_tx_ba(dev, params, vif, false);
                break;
        case IEEE80211_AMPDU_TX_START:
                set_bit(tid, &msta->deflink.wcid.ampdu_state);
@@ -1434,7 +1434,7 @@ mt7925_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
        case IEEE80211_AMPDU_TX_STOP_CONT:
                mtxq->aggr = false;
                clear_bit(tid, &msta->deflink.wcid.ampdu_state);
-               mt7925_mcu_uni_tx_ba(dev, params, false);
+               mt7925_mcu_uni_tx_ba(dev, params, vif, false);
                ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid);
                break;
        }
index 8f0970d2ba31d3ba1fa1e3df09985f13a33be705..e94fa544ff20779ac9cf3be93692f7233b8478c9 100644 (file)
@@ -682,32 +682,69 @@ mt7925_mcu_sta_ba(struct mt76_dev *dev, struct mt76_vif_link *mvif,
                                     MCU_UNI_CMD(STA_REC_UPDATE), true);
 }
 
-/** starec & wtbl **/
 int mt7925_mcu_uni_tx_ba(struct mt792x_dev *dev,
                         struct ieee80211_ampdu_params *params,
-                        bool enable)
+                        struct ieee80211_vif *vif, bool enable)
 {
-       struct mt792x_sta *msta = (struct mt792x_sta *)params->sta->drv_priv;
-       struct mt792x_vif *mvif = msta->vif;
+       struct ieee80211_sta *sta = params->sta;
+       struct mt792x_sta *msta = (struct mt792x_sta *)sta->drv_priv;
+       struct ieee80211_link_sta *link_sta;
+       unsigned int link_id;
+
+       for_each_sta_active_link(vif, sta, link_sta, link_id) {
+               struct mt792x_link_sta *mlink;
+               struct mt792x_bss_conf *mconf;
+               int ret;
+
+               mlink = mt792x_sta_to_link(msta, link_id);
+               if (!mlink)
+                       return -EINVAL;
 
-       if (enable && !params->amsdu)
-               msta->deflink.wcid.amsdu = false;
+               mconf = mt792x_vif_to_link(msta->vif, link_id);
+               if (!mconf)
+                       return -EINVAL;
+
+               if (enable && !params->amsdu)
+                       mlink->wcid.amsdu = false;
 
-       return mt7925_mcu_sta_ba(&dev->mt76, &mvif->bss_conf.mt76, params,
-                                &msta->deflink.wcid,
-                                enable, true);
+               ret = mt7925_mcu_sta_ba(&dev->mt76, &mconf->mt76, params,
+                                       &mlink->wcid, enable, true);
+               if (ret)
+                       return ret;
+       }
+
+       return 0;
 }
 
 int mt7925_mcu_uni_rx_ba(struct mt792x_dev *dev,
                         struct ieee80211_ampdu_params *params,
-                        bool enable)
+                        struct ieee80211_vif *vif, bool enable)
 {
-       struct mt792x_sta *msta = (struct mt792x_sta *)params->sta->drv_priv;
-       struct mt792x_vif *mvif = msta->vif;
+       struct ieee80211_sta *sta = params->sta;
+       struct mt792x_sta *msta = (struct mt792x_sta *)sta->drv_priv;
+       struct ieee80211_link_sta *link_sta;
+       unsigned int link_id;
+
+       for_each_sta_active_link(vif, sta, link_sta, link_id) {
+               struct mt792x_link_sta *mlink;
+               struct mt792x_bss_conf *mconf;
+               int ret;
+
+               mlink = mt792x_sta_to_link(msta, link_id);
+               if (!mlink)
+                       return -EINVAL;
 
-       return mt7925_mcu_sta_ba(&dev->mt76, &mvif->bss_conf.mt76, params,
-                                &msta->deflink.wcid,
-                                enable, false);
+               mconf = mt792x_vif_to_link(msta->vif, link_id);
+               if (!mconf)
+                       return -EINVAL;
+
+               ret = mt7925_mcu_sta_ba(&dev->mt76, &mconf->mt76, params,
+                                       &mlink->wcid, enable, false);
+               if (ret)
+                       return ret;
+       }
+
+       return 0;
 }
 
 static int mt7925_mcu_read_eeprom(struct mt792x_dev *dev, u32 offset, u8 *val)
index 242f83f90dd41598aab4241fd41566e01de0ac1b..4cc259418afca88ac5f73c5f2ab42e1019610596 100644 (file)
@@ -318,10 +318,10 @@ int mt7925_mcu_set_beacon_filter(struct mt792x_dev *dev,
                                 bool enable);
 int mt7925_mcu_uni_tx_ba(struct mt792x_dev *dev,
                         struct ieee80211_ampdu_params *params,
-                        bool enable);
+                        struct ieee80211_vif *vif, bool enable);
 int mt7925_mcu_uni_rx_ba(struct mt792x_dev *dev,
                         struct ieee80211_ampdu_params *params,
-                        bool enable);
+                        struct ieee80211_vif *vif, bool enable);
 void mt7925_mlo_pm_work(struct work_struct *work);
 void mt7925_scan_work(struct work_struct *work);
 void mt7925_roc_work(struct work_struct *work);