diff options
| author | Devin Wittmayer <lucid_duck@justthetip.ca> | 2026-06-27 13:29:46 -0700 |
|---|---|---|
| committer | Felix Fietkau <nbd@nbd.name> | 2026-07-31 12:25:38 +0000 |
| commit | 81faf578320df2dfc682a96baa6e85851dd68b6f (patch) | |
| tree | 3b8a49ce69f85a1fc3d6e13e4e2170f43014b464 | |
| parent | 2889e84282dda147f10b10d94cf0efd90a349c53 (diff) | |
| download | linux-81faf578320df2dfc682a96baa6e85851dd68b6f.tar.gz linux-81faf578320df2dfc682a96baa6e85851dd68b6f.zip | |
wifi: mt76: mt7925: cancel mlo_pm_work on stop
mt7925 queues mlo_pm_work with a 5 second delay during multi-link
power-save setup and never cancels it on the stop path. If the device is
torn down inside that window, the work outlives the teardown and its timer
fires afterwards, trying to queue onto the workqueue that is already gone:
workqueue: cannot queue mt7925_mlo_pm_work [mt7925_common] on wq phy0
WARNING: kernel/workqueue.c:2283 at __queue_work+0x59/0xa0, CPU#1: swapper/1/0
call_timer_fn+0x2a/0x140
__run_timers+0x203/0x330
run_timer_softirq+0x86/0xf0
mt7921 already has its own stop callback, so add one for mt7925 that
cancels the work before calling mt792x_stop(). mt7925_ops backs both the
PCIe and USB drivers, so this covers both.
Fixes: 276a56883257 ("wifi: mt76: mt7925: update the power-saving flow")
Cc: stable@vger.kernel.org
Tested-by: Traockl <281473483+Traockl@users.noreply.github.com>
Signed-off-by: Devin Wittmayer <lucid_duck@justthetip.ca>
Link: https://patch.msgid.link/20260627202946.25598-1-lucid_duck@justthetip.ca
Signed-off-by: Felix Fietkau <nbd@nbd.name>
| -rw-r--r-- | drivers/net/wireless/mediatek/mt76/mt7925/main.c | 11 |
1 files changed, 10 insertions, 1 deletions
diff --git a/drivers/net/wireless/mediatek/mt76/mt7925/main.c b/drivers/net/wireless/mediatek/mt76/mt7925/main.c index 5d0eac8c4e14..ec0bc61a9158 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7925/main.c +++ b/drivers/net/wireless/mediatek/mt76/mt7925/main.c @@ -2696,10 +2696,19 @@ static void mt7925_sta_pre_rcu_remove(struct ieee80211_hw *hw, mutex_unlock(&dev->mutex); } +static void mt7925_stop(struct ieee80211_hw *hw, bool suspend) +{ + struct mt792x_dev *dev = mt792x_hw_dev(hw); + + cancel_delayed_work_sync(&dev->mlo_pm_work); + + mt792x_stop(hw, suspend); +} + const struct ieee80211_ops mt7925_ops = { .tx = mt792x_tx, .start = mt7925_start, - .stop = mt792x_stop, + .stop = mt7925_stop, .add_interface = mt7925_add_interface, .remove_interface = mt7925_remove_interface, .config = mt7925_config, |
