Skip to content

Commit 49fffc2

Browse files
committed
wifi: mt76: mt7921: fix missing mutex protection in multiple paths
The MT7921 driver has the same mutex protection bugs as MT7925 - they were inherited when MT7925 was forked from MT7921. Several code paths iterate over active interfaces and call MCU functions without proper mutex protection. Add mutex protection in the following locations: 1. mt7921_set_runtime_pm() in main.c: Called when runtime PM settings change. The callback mt7921_pm_interface_iter() calls MCU functions that require the device mutex to be held. 2. mt7921_regd_set_6ghz_power_type() in main.c: Called during VIF add/remove for 6GHz power type determination. Uses ieee80211_iterate_active_interfaces() without mutex. 3. mt7921_mac_reset_work() in mac.c: After firmware recovery, iterates interfaces to reconnect them. The mt7921_vif_connect_iter() callback calls MCU functions. 4. PCI/SDIO suspend paths (pci.c, sdio.c): The mt7921_roc_abort_sync() call iterates interfaces without mutex protection. These bugs can cause system hangs during: - Power management state transitions - WiFi reset/recovery - Suspend/resume cycles - 6GHz regulatory power type changes The fix follows the same pattern used in the MT7925 patches. Signed-off-by: Zac Bowling <zac@zacbowling.com>
1 parent 3c23252 commit 49fffc2

4 files changed

Lines changed: 10 additions & 0 deletions

File tree

mt7921/mac.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -693,9 +693,11 @@ void mt7921_mac_reset_work(struct work_struct *work)
693693
clear_bit(MT76_RESET, &dev->mphy.state);
694694
pm->suspended = false;
695695
ieee80211_wake_queues(hw);
696+
mt792x_mutex_acquire(dev);
696697
ieee80211_iterate_active_interfaces(hw,
697698
IEEE80211_IFACE_ITER_RESUME_ALL,
698699
mt7921_vif_connect_iter, NULL);
700+
mt792x_mutex_release(dev);
699701
mt76_connac_power_save_sched(&dev->mt76.phy, pm);
700702
}
701703

mt7921/main.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -619,9 +619,11 @@ void mt7921_set_runtime_pm(struct mt792x_dev *dev)
619619
bool monitor = !!(hw->conf.flags & IEEE80211_CONF_MONITOR);
620620

621621
pm->enable = pm->enable_user && !monitor;
622+
mt792x_mutex_acquire(dev);
622623
ieee80211_iterate_active_interfaces(hw,
623624
IEEE80211_IFACE_ITER_RESUME_ALL,
624625
mt7921_pm_interface_iter, dev);
626+
mt792x_mutex_release(dev);
625627
pm->ds_enable = pm->ds_enable_user && !monitor;
626628
mt76_connac_mcu_set_deep_sleep(&dev->mt76, pm->ds_enable);
627629
}
@@ -765,9 +767,11 @@ mt7921_regd_set_6ghz_power_type(struct ieee80211_vif *vif, bool is_add)
765767
struct mt792x_dev *dev = phy->dev;
766768
u32 valid_vif_num = 0;
767769

770+
mt792x_mutex_acquire(dev);
768771
ieee80211_iterate_active_interfaces(mt76_hw(dev),
769772
IEEE80211_IFACE_ITER_RESUME_ALL,
770773
mt7921_calc_vif_num, &valid_vif_num);
774+
mt792x_mutex_release(dev);
771775

772776
if (valid_vif_num > 1) {
773777
phy->power_type = MT_AP_DEFAULT;

mt7921/pci.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -426,7 +426,9 @@ static int mt7921_pci_suspend(struct device *device)
426426
cancel_delayed_work_sync(&pm->ps_work);
427427
cancel_work_sync(&pm->wake_work);
428428

429+
mt792x_mutex_acquire(dev);
429430
mt7921_roc_abort_sync(dev);
431+
mt792x_mutex_release(dev);
430432

431433
err = mt792x_mcu_drv_pmctrl(dev);
432434
if (err < 0)

mt7921/sdio.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,7 +219,9 @@ static int mt7921s_suspend(struct device *__dev)
219219
cancel_delayed_work_sync(&pm->ps_work);
220220
cancel_work_sync(&pm->wake_work);
221221

222+
mt792x_mutex_acquire(dev);
222223
mt7921_roc_abort_sync(dev);
224+
mt792x_mutex_release(dev);
223225

224226
err = mt792x_mcu_drv_pmctrl(dev);
225227
if (err < 0)

0 commit comments

Comments
 (0)