summaryrefslogtreecommitdiff
path: root/drivers/net/wireless/mediatek/mt76/mt7915
diff options
context:
space:
mode:
authorFelix Fietkau <nbd@nbd.name>2026-07-24 12:47:48 +0000
committerFelix Fietkau <nbd@nbd.name>2026-07-31 12:25:40 +0000
commit2fb6480c52f611338e1b0abe5e6219be1fc9ab75 (patch)
tree992b0266bfc033aad136a0b0b7e64bcd8008636a /drivers/net/wireless/mediatek/mt76/mt7915
parent6689b4a65e88d7b019e687fa9d6943ca070f3e43 (diff)
downloadlinux-next-2fb6480c52f611338e1b0abe5e6219be1fc9ab75.tar.gz
linux-next-2fb6480c52f611338e1b0abe5e6219be1fc9ab75.zip
wifi: mt76: mt7915: unwind state on add_interface failure
When mt76_wcid_alloc() fails, mt7915_add_interface() returned without clearing the vif_mask/omac_mask bits it had already set, without removing the firmware dev info added earlier, and without clearing a monitor_vif pointer to the vif mac80211 is about to free. mac80211 does not call remove_interface() for a failed add, so the indices and firmware dev entry leaked permanently and testmode could dereference the stale monitor_vif. Add a proper error unwind. Fixes: b619e01380ee ("mt76: fix MBSS index condition in DBDC mode") Link: https://patch.msgid.link/20260724124813.3961474-4-nbd@nbd.name Signed-off-by: Felix Fietkau <nbd@nbd.name>
Diffstat (limited to 'drivers/net/wireless/mediatek/mt76/mt7915')
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7915/main.c12
1 files changed, 11 insertions, 1 deletions
diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/main.c b/drivers/net/wireless/mediatek/mt76/mt7915/main.c
index 4ed3d808654f..d2130226de64 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/main.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/main.c
@@ -249,7 +249,7 @@ static int mt7915_add_interface(struct ieee80211_hw *hw,
idx = mt76_wcid_alloc(dev->mt76.wcid_mask, mt7915_wtbl_size(dev));
if (idx < 0) {
ret = -ENOSPC;
- goto out;
+ goto err;
}
INIT_LIST_HEAD(&mvif->sta.rc_list);
@@ -277,7 +277,17 @@ static int mt7915_add_interface(struct ieee80211_hw *hw,
mt7915_mcu_add_sta(dev, vif, NULL, CONN_STATE_PORT_SECURE, true);
rcu_assign_pointer(dev->mt76.wcid[idx], &mvif->sta.wcid);
+ mutex_unlock(&dev->mt76.mutex);
+
+ return 0;
+
+err:
+ dev->mt76.vif_mask &= ~BIT_ULL(mvif->mt76.idx);
+ phy->omac_mask &= ~BIT_ULL(mvif->mt76.omac_idx);
+ mt7915_mcu_add_dev_info(phy, vif, false);
out:
+ if (phy->monitor_vif == vif)
+ phy->monitor_vif = NULL;
mutex_unlock(&dev->mt76.mutex);
return ret;