[PATCH 1/4] wifi: mt76: mt7615: unwind add_interface failures
From: Jiale Yao
Date: Thu Sep 24 2026 - 09:35:29 EST
mac80211 does not call remove_interface() after add_interface() fails, so
the driver must undo any state it published before returning an error.
mt7615_add_interface() records a monitor vif before resource allocation,
and later reserves vif and OMAC bits and publishes the station WCID. An
allocation or firmware failure leaves some or all of that state behind.
The stale monitor_vif can then be used by the testmode transmit path after
mac80211 frees the vif, while the leaked mask bits permanently consume
interface resources.
Unpublish the WCID and release its resources when adding device information
fails, clear the reserved mask bits after failures that occur after their
allocation, and clear monitor_vif on every failed add.
Commit 2fb6480c52f6 ("wifi: mt76: mt7915: unwind state on add_interface
failure") fixed the same failure-unwind issue in mt7915.
Fixes: 4f0bce1c8888 ("mt76: mt7615: implement testmode support")
Cc: stable@xxxxxxxxxxxxxxx
Signed-off-by: Jiale Yao <yaojiale02@xxxxxxx>
---
.../net/wireless/mediatek/mt76/mt7615/main.c | 19 ++++++++++++++++++-
1 file changed, 18 insertions(+), 1 deletion(-)
diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/main.c b/drivers/net/wireless/mediatek/mt76/mt7615/main.c
index 67f56e428d9a..d20b109666dc 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7615/main.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7615/main.c
@@ -219,7 +219,7 @@ static int mt7615_add_interface(struct ieee80211_hw *hw,
ret = mt7615_mcu_set_dbdc(dev);
if (ret)
- goto out;
+ goto err_mask;
idx = MT7615_WTBL_RESERVED - mvif->mt76.idx;
@@ -237,7 +237,24 @@ static int mt7615_add_interface(struct ieee80211_hw *hw,
}
ret = mt7615_mcu_add_dev_info(phy, vif, true);
+ if (ret)
+ goto err_wcid;
+
+ mt7615_mutex_release(dev);
+
+ return 0;
+
+err_wcid:
+ rcu_assign_pointer(dev->mt76.wcid[idx], NULL);
+ mt76_wcid_cleanup(&dev->mt76, &mvif->sta.wcid);
+err_mask:
+ dev->mt76.vif_mask &= ~BIT_ULL(mvif->mt76.idx);
+ dev->omac_mask &= ~BIT_ULL(mvif->mt76.omac_idx);
+ phy->omac_mask &= ~BIT_ULL(mvif->mt76.omac_idx);
out:
+ if (phy->monitor_vif == vif)
+ phy->monitor_vif = NULL;
+
mt7615_mutex_release(dev);
return ret;
--
2.34.1