]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
wifi: mt76: abort scan/roc on hw restart
authorFelix Fietkau <nbd@nbd.name>
Mon, 15 Sep 2025 07:59:10 +0000 (09:59 +0200)
committerFelix Fietkau <nbd@nbd.name>
Mon, 15 Sep 2025 11:23:02 +0000 (13:23 +0200)
Avoid spurious channel changes and clean up allocated links

Link: https://patch.msgid.link/20250915075910.47558-15-nbd@nbd.name
Signed-off-by: Felix Fietkau <nbd@nbd.name>
drivers/net/wireless/mediatek/mt76/channel.c
drivers/net/wireless/mediatek/mt76/mac80211.c
drivers/net/wireless/mediatek/mt76/mt76.h
drivers/net/wireless/mediatek/mt76/mt7996/mac.c
drivers/net/wireless/mediatek/mt76/scan.c

index 77b75792eb488e9c5da9ca8026c04157182c13a4..130af1b254dbf408e07558e5c71829295b061e45 100644 (file)
@@ -314,21 +314,24 @@ void mt76_put_vif_phy_link(struct mt76_phy *phy, struct ieee80211_vif *vif,
        kfree(mlink);
 }
 
-static void mt76_roc_complete(struct mt76_phy *phy)
+void mt76_roc_complete(struct mt76_phy *phy)
 {
        struct mt76_vif_link *mlink = phy->roc_link;
+       struct mt76_dev *dev = phy->dev;
 
        if (!phy->roc_vif)
                return;
 
        if (mlink)
                mlink->mvif->roc_phy = NULL;
-       if (phy->main_chandef.chan)
+       if (phy->main_chandef.chan &&
+           !test_bit(MT76_MCU_RESET, &dev->phy.state))
                mt76_set_channel(phy, &phy->main_chandef, false);
        mt76_put_vif_phy_link(phy, phy->roc_vif, phy->roc_link);
        phy->roc_vif = NULL;
        phy->roc_link = NULL;
-       ieee80211_remain_on_channel_expired(phy->hw);
+       if (!test_bit(MT76_MCU_RESET, &dev->phy.state))
+               ieee80211_remain_on_channel_expired(phy->hw);
 }
 
 void mt76_roc_complete_work(struct work_struct *work)
@@ -351,6 +354,7 @@ void mt76_abort_roc(struct mt76_phy *phy)
        mt76_roc_complete(phy);
        mutex_unlock(&dev->mutex);
 }
+EXPORT_SYMBOL_GPL(mt76_abort_roc);
 
 int mt76_remain_on_channel(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
                           struct ieee80211_channel *chan, int duration,
@@ -368,7 +372,8 @@ int mt76_remain_on_channel(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
 
        mutex_lock(&dev->mutex);
 
-       if (phy->roc_vif || dev->scan.phy == phy) {
+       if (phy->roc_vif || dev->scan.phy == phy ||
+           test_bit(MT76_MCU_RESET, &dev->phy.state)) {
                ret = -EBUSY;
                goto out;
        }
index f6a494812fe1e781af0b78a21bb281f3ebbe1f18..5ceaf78c9ea064bf898c347c611a7ccdf9cb9ebc 100644 (file)
@@ -826,6 +826,7 @@ static void mt76_reset_phy(struct mt76_phy *phy)
        INIT_LIST_HEAD(&phy->tx_list);
        phy->num_sta = 0;
        phy->chanctx = NULL;
+       mt76_roc_complete(phy);
 }
 
 void mt76_reset_device(struct mt76_dev *dev)
@@ -846,6 +847,8 @@ void mt76_reset_device(struct mt76_dev *dev)
        }
        rcu_read_unlock();
 
+       mt76_abort_scan(dev);
+
        INIT_LIST_HEAD(&dev->wcid_list);
        INIT_LIST_HEAD(&dev->sta_poll_list);
        dev->vif_mask = 0;
index 883356cd0c0b01ddd003049fc4ab9ceea8872406..e0d50b58cd012910b697102bd50bb855966876f9 100644 (file)
@@ -1643,6 +1643,7 @@ int mt76_set_channel(struct mt76_phy *phy, struct cfg80211_chan_def *chandef,
 void mt76_scan_work(struct work_struct *work);
 void mt76_abort_scan(struct mt76_dev *dev);
 void mt76_roc_complete_work(struct work_struct *work);
+void mt76_roc_complete(struct mt76_phy *phy);
 void mt76_abort_roc(struct mt76_phy *phy);
 struct mt76_vif_link *mt76_get_vif_phy_link(struct mt76_phy *phy,
                                            struct ieee80211_vif *vif);
index 2d5dab5353572417d49c9de403778e2dce02bfd5..9501def3e0e3e20132fdbcfe0b1f489694afdc5f 100644 (file)
@@ -2514,10 +2514,12 @@ void mt7996_mac_reset_work(struct work_struct *work)
 
        set_bit(MT76_RESET, &dev->mphy.state);
        set_bit(MT76_MCU_RESET, &dev->mphy.state);
+       mt76_abort_scan(&dev->mt76);
        wake_up(&dev->mt76.mcu.wait);
 
        cancel_work_sync(&dev->wed_rro.work);
        mt7996_for_each_phy(dev, phy) {
+               mt76_abort_roc(phy->mt76);
                set_bit(MT76_RESET, &phy->mt76->state);
                cancel_delayed_work_sync(&phy->mt76->mac_work);
        }
index 458f8cdebc1088c2c52360a2b004cf163b0e7e8c..5a875aac410fc1cce4fbc4f0962f1e6f20a10e30 100644 (file)
@@ -16,11 +16,13 @@ static void mt76_scan_complete(struct mt76_dev *dev, bool abort)
 
        clear_bit(MT76_SCANNING, &phy->state);
 
-       if (dev->scan.chan && phy->main_chandef.chan)
+       if (dev->scan.chan && phy->main_chandef.chan &&
+           !test_bit(MT76_MCU_RESET, &dev->phy.state))
                mt76_set_channel(phy, &phy->main_chandef, false);
        mt76_put_vif_phy_link(phy, dev->scan.vif, dev->scan.mlink);
        memset(&dev->scan, 0, sizeof(dev->scan));
-       ieee80211_scan_completed(phy->hw, &info);
+       if (!test_bit(MT76_MCU_RESET, &dev->phy.state))
+               ieee80211_scan_completed(phy->hw, &info);
 }
 
 void mt76_abort_scan(struct mt76_dev *dev)
@@ -28,6 +30,7 @@ void mt76_abort_scan(struct mt76_dev *dev)
        cancel_delayed_work_sync(&dev->scan_work);
        mt76_scan_complete(dev, true);
 }
+EXPORT_SYMBOL_GPL(mt76_abort_scan);
 
 static void
 mt76_scan_send_probe(struct mt76_dev *dev, struct cfg80211_ssid *ssid)
@@ -136,7 +139,8 @@ int mt76_hw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
 
        mutex_lock(&dev->mutex);
 
-       if (dev->scan.req || phy->roc_vif) {
+       if (dev->scan.req || phy->roc_vif ||
+           test_bit(MT76_MCU_RESET, &dev->phy.state)) {
                ret = -EBUSY;
                goto out;
        }