wifi: mt76: abort scan/roc on hw restart

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>
This commit is contained in:
Felix Fietkau
2025-09-15 09:59:10 +02:00
parent 3f34cced88
commit b36d556102
5 changed files with 22 additions and 7 deletions

View 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;
}

View 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;

View 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);

View 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);
}

View 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;
}