summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDevin Wittmayer <lucid_duck@justthetip.ca>2026-06-27 13:29:46 -0700
committerFelix Fietkau <nbd@nbd.name>2026-07-31 12:25:38 +0000
commit81faf578320df2dfc682a96baa6e85851dd68b6f (patch)
tree3b8a49ce69f85a1fc3d6e13e4e2170f43014b464
parent2889e84282dda147f10b10d94cf0efd90a349c53 (diff)
downloadlinux-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.c11
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,