* [PATCH v2 0/2] wifi: mt76: mt7921: fix hibernate and suspend resume
@ 2026-10-24 13:16 Hedi Ben Hamida
2026-10-24 13:16 ` [PATCH v2 1/2] wifi: mt76: mt7921: add pci restore for hibernate Hedi Ben Hamida
2026-10-24 13:16 ` [PATCH v2 2/2] wifi: mt76: mt7921: reset on HIF resume timeout Hedi Ben Hamida
0 siblings, 2 replies; 3+ messages in thread
From: Hedi Ben Hamida @ 2026-10-24 13:16 UTC (permalink / raw)
To: Felix Fietkau, Lorenzo Bianconi
Cc: Ryder Lee, Shayne Chen, Sean Wang, linux-wireless, linux-mediatek,
stable, Hedi Ben Hamida
This series fixes two MT7921/MT7922 power-management resume paths.
Patch 1 adds a dedicated .restore callback for hibernate. Without it the
S4 restore path runs the normal resume sequence and times out waiting for
the HIF suspend MCU handshake.
Patch 2 recovers from the same HIF resume timeout on S3: the firmware does
not return the HIF_CTRL response after D3, so reset the device and report
success instead of failing the resume.
Both were tested on MEDIATEK MT7922 (14c3:7922) on kernel 6.12.113.
v2: add the suspend resume fix; patch 1 is unchanged.
Hedi Ben Hamida (2):
wifi: mt76: mt7921: add pci restore for hibernate
wifi: mt76: mt7921: reset on HIF resume timeout
.../net/wireless/mediatek/mt76/mt7921/pci.c | 34 +++++++++++++++++--
1 file changed, 31 insertions(+), 3 deletions(-)
--
2.47.3
^ permalink raw reply [flat|nested] 3+ messages in thread
* [PATCH v2 1/2] wifi: mt76: mt7921: add pci restore for hibernate
2026-10-24 13:16 [PATCH v2 0/2] wifi: mt76: mt7921: fix hibernate and suspend resume Hedi Ben Hamida
@ 2026-10-24 13:16 ` Hedi Ben Hamida
2026-10-24 13:16 ` [PATCH v2 2/2] wifi: mt76: mt7921: reset on HIF resume timeout Hedi Ben Hamida
1 sibling, 0 replies; 3+ messages in thread
From: Hedi Ben Hamida @ 2026-10-24 13:16 UTC (permalink / raw)
To: Felix Fietkau, Lorenzo Bianconi
Cc: Ryder Lee, Shayne Chen, Sean Wang, linux-wireless, linux-mediatek,
stable, Hedi Ben Hamida
Hibernation powers the device off and on. On resume the generic restore
path runs the normal resume sequence and can time out waiting for the
hif-suspend MCU handshake:
mt7921e 0000:03:00.0: Message 00020007 (seq 12) timeout
mt7921e 0000:03:00.0: PM: dpm_run_callback(): pci_pm_restore returns -110
Add a dedicated .restore callback, mirroring mt7925, which skips the
handshake, resets the device and returns it to its pre-hibernate state.
Tested on MEDIATEK MT7922 (14c3:7922) on kernel 6.12.113.
Cc: stable@vger.kernel.org
Signed-off-by: Hedi Ben Hamida <hedihamida096@gmail.com>
---
.../net/wireless/mediatek/mt76/mt7921/pci.c | 26 ++++++++++++++++---
1 file changed, 23 insertions(+), 3 deletions(-)
diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/pci.c b/drivers/net/wireless/mediatek/mt76/mt7921/pci.c
index f87c44f2a..00532b29f 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7921/pci.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7921/pci.c
@@ -549,7 +549,7 @@ static int mt7921_pci_suspend(struct device *device)
return err;
}
-static int mt7921_pci_resume(struct device *device)
+static int _mt7921_pci_resume(struct device *device, bool restore)
{
struct pci_dev *pdev = to_pci_dev(device);
struct mt76_dev *mdev = pci_get_drvdata(pdev);
@@ -589,6 +589,9 @@ static int mt7921_pci_resume(struct device *device)
napi_schedule(&mdev->tx_napi);
local_bh_enable();
+ if (restore)
+ goto failed;
+
/* restore previous ds setting */
if (!pm->ds_enable)
mt76_connac_mcu_set_deep_sleep(&dev->mt76, false);
@@ -602,7 +605,7 @@ static int mt7921_pci_resume(struct device *device)
failed:
pm->suspended = false;
- if (err < 0)
+ if (err < 0 || restore)
mt792x_reset(&dev->mt76);
return err;
@@ -715,7 +718,24 @@ static void mt7921_pci_shutdown(struct pci_dev *pdev)
mt7921_pci_remove(pdev);
}
-static DEFINE_SIMPLE_DEV_PM_OPS(mt7921_pm_ops, mt7921_pci_suspend, mt7921_pci_resume);
+static int mt7921_pci_resume(struct device *device)
+{
+ return _mt7921_pci_resume(device, false);
+}
+
+static int mt7921_pci_restore(struct device *device)
+{
+ return _mt7921_pci_resume(device, true);
+}
+
+static const struct dev_pm_ops mt7921_pm_ops = {
+ .suspend = pm_sleep_ptr(mt7921_pci_suspend),
+ .resume = pm_sleep_ptr(mt7921_pci_resume),
+ .freeze = pm_sleep_ptr(mt7921_pci_suspend),
+ .thaw = pm_sleep_ptr(mt7921_pci_resume),
+ .poweroff = pm_sleep_ptr(mt7921_pci_suspend),
+ .restore = pm_sleep_ptr(mt7921_pci_restore),
+};
static struct pci_driver mt7921_pci_driver = {
.name = KBUILD_MODNAME,
--
2.47.3
^ permalink raw reply related [flat|nested] 3+ messages in thread
* [PATCH v2 2/2] wifi: mt76: mt7921: reset on HIF resume timeout
2026-10-24 13:16 [PATCH v2 0/2] wifi: mt76: mt7921: fix hibernate and suspend resume Hedi Ben Hamida
2026-10-24 13:16 ` [PATCH v2 1/2] wifi: mt76: mt7921: add pci restore for hibernate Hedi Ben Hamida
@ 2026-10-24 13:16 ` Hedi Ben Hamida
1 sibling, 0 replies; 3+ messages in thread
From: Hedi Ben Hamida @ 2026-10-24 13:16 UTC (permalink / raw)
To: Felix Fietkau, Lorenzo Bianconi
Cc: Ryder Lee, Shayne Chen, Sean Wang, linux-wireless, linux-mediatek,
stable, Hedi Ben Hamida
On some MT7922 firmware the HIF_CTRL resume command does not return a
response after D3, so mt7921_pci_resume() returns -ETIMEDOUT and the
PM core reports the resume as failed:
mt7921e 0000:03:00.0: Message 00020007 (seq 6) timeout
mt7921e 0000:03:00.0: PM: dpm_run_callback(): pci_pm_resume returns -110
The driver already resets the device on this error, and the reset
restores it. Treat the timeout as recovered after queueing the reset
and return success, so the PM core does not mark the resume as failed.
Tested on MEDIATEK MT7922 (14c3:7922) on kernel 6.12.113: suspend/resume
no longer returns -110 and Wi-Fi recovers; hibernate/resume still works.
Cc: stable@vger.kernel.org
Signed-off-by: Hedi Ben Hamida <hedihamida096@gmail.com>
---
drivers/net/wireless/mediatek/mt76/mt7921/pci.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/pci.c b/drivers/net/wireless/mediatek/mt76/mt7921/pci.c
index 00532b29f..dce88fcc7 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7921/pci.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7921/pci.c
@@ -597,6 +597,14 @@ static int _mt7921_pci_resume(struct device *device, bool restore)
mt76_connac_mcu_set_deep_sleep(&dev->mt76, false);
err = mt76_connac_mcu_set_hif_suspend(mdev, false, true);
+ if (err == -ETIMEDOUT) {
+ /* Firmware may not reply after D3; the reset recovers it. */
+ dev_warn(dev->mt76.dev,
+ "HIF resume timed out, resetting\n");
+ pm->suspended = false;
+ mt792x_reset(&dev->mt76);
+ return 0;
+ }
if (err < 0)
goto failed;
--
2.47.3
^ permalink raw reply related [flat|nested] 3+ messages in thread
end of thread, other threads:[~2026-10-24 13:18 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-10-24 13:16 [PATCH v2 0/2] wifi: mt76: mt7921: fix hibernate and suspend resume Hedi Ben Hamida
2026-10-24 13:16 ` [PATCH v2 1/2] wifi: mt76: mt7921: add pci restore for hibernate Hedi Ben Hamida
2026-10-24 13:16 ` [PATCH v2 2/2] wifi: mt76: mt7921: reset on HIF resume timeout Hedi Ben Hamida
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox