summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWentao Guan <guanwentao@uniontech.com>2026-06-30 17:02:18 +0800
committerFelix Fietkau <nbd@nbd.name>2026-07-31 12:25:38 +0000
commit2889e84282dda147f10b10d94cf0efd90a349c53 (patch)
tree5edfc7b657157c3987b7b5b9c85aa609e6b57db9
parenteb628006a2c69228b32129a3937baa52b970a118 (diff)
downloadlinux-2889e84282dda147f10b10d94cf0efd90a349c53.tar.gz
linux-2889e84282dda147f10b10d94cf0efd90a349c53.zip
wifi: mt76: mt7925: cancel pending mlo_pm_work
If the device is reset, suspended or unregistered within that window, the pending work can still run and access vif/bss data that may already be freed, or send MCU commands while the firmware is not available. Add cancel_delayed_work_sync(&dev->mlo_pm_work) in all relevant teardown and suspend paths: - mt7925_mac_reset_work() (chip reset recovery) - mt7925e_unregister_device() (PCIe unbind) - mt7925_pci_suspend() (PCIe bus suspend) - mt7925_suspend() (mac80211 suspend) - mt7925u_suspend() (USB bus / runtime suspend) This ensures the work is stopped before the device state becomes invalid. Assisted-by: kimi-cli:kimi-k2.7 code Assisted-by: atomcode:glm-5.2 #Reported-by Fixes: 276a568832577 ("wifi: mt76: mt7925: update the power-saving flow") Cc: stable@vger.kernel.org Signed-off-by: Wentao Guan <guanwentao@uniontech.com> Link: https://patch.msgid.link/20260630090218.3202029-1-guanwentao@uniontech.com Signed-off-by: Felix Fietkau <nbd@nbd.name>
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7925/mac.c1
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7925/main.c1
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7925/pci.c2
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7925/usb.c1
4 files changed, 5 insertions, 0 deletions
diff --git a/drivers/net/wireless/mediatek/mt76/mt7925/mac.c b/drivers/net/wireless/mediatek/mt76/mt7925/mac.c
index 23ed18bd7332..2931f5176137 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7925/mac.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7925/mac.c
@@ -1525,6 +1525,7 @@ void mt7925_mac_reset_work(struct work_struct *work)
cancel_delayed_work_sync(&dev->mphy.mac_work);
cancel_delayed_work_sync(&pm->ps_work);
+ cancel_delayed_work_sync(&dev->mlo_pm_work);
cancel_work_sync(&pm->wake_work);
for (i = 0; i < 10; i++) {
diff --git a/drivers/net/wireless/mediatek/mt76/mt7925/main.c b/drivers/net/wireless/mediatek/mt76/mt7925/main.c
index abb56f6fea77..5d0eac8c4e14 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7925/main.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7925/main.c
@@ -1709,6 +1709,7 @@ static int mt7925_suspend(struct ieee80211_hw *hw,
cancel_delayed_work_sync(&phy->mt76->mac_work);
cancel_delayed_work_sync(&dev->pm.ps_work);
+ cancel_delayed_work_sync(&dev->mlo_pm_work);
mt76_connac_free_pending_tx_skbs(&dev->pm, NULL);
mt792x_mutex_acquire(dev);
diff --git a/drivers/net/wireless/mediatek/mt76/mt7925/pci.c b/drivers/net/wireless/mediatek/mt76/mt7925/pci.c
index 366541bab223..4e734f4f65d1 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7925/pci.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7925/pci.c
@@ -53,6 +53,7 @@ static void mt7925e_unregister_device(struct mt792x_dev *dev)
mt76_for_each_q_rx(&dev->mt76, i)
napi_disable(&dev->mt76.napi[i]);
cancel_delayed_work_sync(&pm->ps_work);
+ cancel_delayed_work_sync(&dev->mlo_pm_work);
cancel_work_sync(&pm->wake_work);
mt7925_tx_token_put(dev);
@@ -740,6 +741,7 @@ static int mt7925_pci_suspend(struct device *device)
dev->hif_resumed = false;
flush_work(&dev->reset_work);
cancel_delayed_work_sync(&pm->ps_work);
+ cancel_delayed_work_sync(&dev->mlo_pm_work);
cancel_work_sync(&pm->wake_work);
mt7925_roc_abort_sync(dev);
diff --git a/drivers/net/wireless/mediatek/mt76/mt7925/usb.c b/drivers/net/wireless/mediatek/mt76/mt7925/usb.c
index 49ad4fe9eb1b..1757023ea70d 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7925/usb.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7925/usb.c
@@ -276,6 +276,7 @@ static int mt7925u_suspend(struct usb_interface *intf, pm_message_t state)
pm->suspended = true;
dev->hif_resumed = false;
flush_work(&dev->reset_work);
+ cancel_delayed_work_sync(&dev->mlo_pm_work);
mt76_connac_mcu_set_hif_suspend(&dev->mt76, true, false);
ret = wait_event_timeout(dev->wait,