Commit b36d5561 authored by Felix Fietkau's avatar Felix Fietkau
Browse files

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: default avatarFelix Fietkau <nbd@nbd.name>
parent 3f34cced
Loading
Loading
Loading
Loading
+9 −4
Original line number Diff line number Diff line
@@ -314,20 +314,23 @@ 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;
	if (!test_bit(MT76_MCU_RESET, &dev->phy.state))
		ieee80211_remain_on_channel_expired(phy->hw);
}

@@ -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;
	}
+3 −0
Original line number Diff line number Diff line
@@ -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;
+1 −0
Original line number Diff line number Diff line
@@ -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);
+2 −0
Original line number Diff line number Diff line
@@ -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);
	}
+7 −3
Original line number Diff line number Diff line
@@ -16,10 +16,12 @@ 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));
	if (!test_bit(MT76_MCU_RESET, &dev->phy.state))
		ieee80211_scan_completed(phy->hw, &info);
}

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