MT7902 (14c3:7902) does not come back from s2idle: "driver own failed" after resume; root port D3cold is the trigger (workaround inside)

Open
#1,180 2 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Assessment

Difficulty
5/5
Estimated time
Over a week
Newbie friendliness
35/100
Issue type
Bug
Clarity
Mostly clear
Activity status
Active
Tech stack
c, linux

Research direction

Start with the PCI power management and resume path in mt7921/pci.c, which the issue says matches the reproducing DKMS backport apart from a vendor ID macro; compare it with the in-kernel driver, which the reporter has not tested. Reproduce on the named MT7902 laptop using s2idle and the provided D3cold workaround, then investigate whether the failure is device-wide or needs a platform quirk. Done means resume succeeds without errors and S0ix remains available; the issue does not name a test file.

Written by the indexing model from the issue text.

Description

Cross-posted from morrownr/mt76#143, the DKMS backport where this was reproduced. Its mt7921/pci.c is identical to current mainline apart from a vendor ID macro, so the issue should apply here too.

Summary

On an ASUS Vivobook 15 X1504MA (Intel Wildcat Lake), the MT7902 never comes back from suspend (s2idle). On resume the root port reports Data Link Layer Link Active not set, the driver logs driver own failed / chip reset failed, and Wi-Fi stays dead until reboot. Reboots and later suspends often hang, so the machine has to be forced off.

The trigger is the root port (00:06.0) going to D3cold during suspend. With D3cold blocked for the card, Wi-Fi resumes reliably. Blocking D3cold with the defaults still in place stopped the SoC from reaching S0ix. Enabling ASPM L1.2 restored S0ix. The full workaround is below, with measured power figures.

System
Laptop ASUS Vivobook 15 X1504MA, BIOS X1504MA.304 (06/04/2026)
CPU Intel Core 5 320 (Wildcat Lake)
Wi-Fi MEDIATEK 14c3:7902, subsystem AzureWave 1a3b:6040, behind root port 8086:4d61 (00:06.0, ACPI \_SB.PC00.RP05)
OS / kernel Pop!_OS 24.04, 7.2.15-76070215-generic (also reproduced on 7.0.11)
Driver morrownr/mt76 DKMS, commit c539593 (2026-10-31)
Firmware WIFI_MT7902 patch/RAM build 20251212 (HW/SW Version: 0x8a108a10)
Sleep s2idle (default). deep is offered, but the machine never wakes from it (separate issue, probably BIOS).

The BIOS also logs ACPI errors on the Wi-Fi's own ACPI path, which may be related:

ACPI BIOS Error (bug): Failure creating named object [\_SB.PC00.RP05.PXSX.WVID], AE_ALREADY_EXISTS
ACPI BIOS Error (bug): Failure creating named object [\_SB.PC00.RP05.PXSX._DSM], AE_ALREADY_EXISTS
ACPI BIOS Error (bug): Failure creating named object [\_SB.PC00.RP05.PXSX._PRR], AE_ALREADY_EXISTS
Failure (default configuration, first suspend)
PM: suspend entry (s2idle)
pcieport 0000:00:06.0: Data Link Layer Link Active not set in 100 msec
mt7921e_git 0000:01:00.0: driver own failed
mt7921e_git 0000:01:00.0: PM: dpm_run_callback(): pci_pm_resume returns -5
mt7921e_git 0000:01:00.0: PM: failed to resume async: error -5
PM: suspend exit
mt7921e_git 0000:01:00.0: driver own failed
mt7921e_git 0000:01:00.0: Message 000046ed (seq 5) timeout
...
mt7921e_git 0000:01:00.0: chip reset failed

After this, every later suspend fails (pci_pm_suspend(): mt7921_pci_suspend returns -5), wpa_supplicant hangs in D state, and reboot hangs after systemd-shutdown.

What was tested
Configuration Wi-Fi after resume S0ix (low_power_idle_system_residency_us) Power in suspend
Defaults dead n/a n/a
disable_pm=Y + disable_aspm=Y dead (same errors) n/a n/a
Unload module before suspend, reload after probe fails: driver own failed, probe with driver mt7921e_git failed with error -5 n/a n/a
Remove the PCI device before suspend, rescan after card never re-enumerates reached (138.8 s of 142 s) not measured
d3cold_allowed=0 on 01:00.0, with disable_pm=Y + disable_aspm=Y + module reload hook works 0 (SoC stays in Package C2) ~1.7 W
deep (S3) machine never wakes n/a ~0.2 W
d3cold_allowed=0 + ASPM enabled + pcie_aspm.policy=powersupersave + disable_pm=N (no hook) works, 0 errors in ~18 h over 4 suspends ~99.6% of suspend time (S0i2.2) ~0.85 W

Once the card is gone after resume, none of these recover it:

  • link retrain (LnkCtl bit 5 on 00:06.0);
  • secondary bus reset (reset_subordinate);
  • toggling the asus-wlan rfkill;
  • removing the root port and rescanning.

Only a reboot brings it back.

Notes:

  • With D3cold blocked but ASPM disabled, intel_pmc_core (warn_on_s0ix_failures=Y) reported CPU did not enter Package C10. Enabling L1.2 fixed that.
  • The module reload hook was not only unnecessary but harmful for S0ix. With the driver loaded, its own suspend path lets the link reach L1.2.
  • Power figures come from upower battery history across real suspends (43.8 Wh battery).
Workaround
# /etc/udev/rules.d/80-mt7902-no-d3cold.rules
ACTION=="add", SUBSYSTEM=="pci", ATTR{vendor}=="0x14c3", ATTR{device}=="0x7902", ATTR{d3cold_allowed}="0"
  • Kernel command line: pcie_aspm.policy=powersupersave
  • /etc/modprobe.d/mt76_git.conf: options mt7921_common_git disable_pm=N (the default), and no disable_aspm=Y.
Questions
  1. Is this known for MT7902 on Intel s2idle platforms? The card seems unable to bring the link back after the root port's D3cold power cycle.
  2. Would it be acceptable for the driver to call pci_d3cold_disable() for 0x7902 in probe, or should this be a DMI/platform quirk, since the BIOS errors above suggest a firmware problem on this laptop?

I have not tested the in-kernel mt7921e (it is blacklisted by this repo's config) or kernels newer than 7.2.15. I can test patches, or provide the full pmc_core debugfs dump and logs.

Dominant language
C
Stars
895
Forks
461
PR merge metrics
No merged PRs in 30d

Getting set up

This project ships no dev container, Dockerfile or contributing guide, so setting up is up to you: start from its README, and see our first-contribution guide for the general steps.

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from openwrt/mt76

All issues in openwrt/mt76

Similar issues

More C issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.