[PATCH AUTOSEL 6.18-5.10] wifi: mt76: transform aspm_conf for pci_disable_link_state
Sasha Levin
sashal at kernel.org
Mon Aug 31 06:25:25 PDT 2026
From: Jiajia Liu <liujiajia at kylinos.cn>
[ Upstream commit 2dd78856223484895306351df1f903a4b75d213f ]
commit b478e162f227 ("PCI/ASPM: Consolidate link state defines") changed
PCIE_LINK_STATE_L0S (1) to (BIT(0) | BIT(1)). PCI_EXP_LNKCTL_ASPM_L0S (1)
and PCI_EXP_LNKCTL_ASPM_L1 (2) are no longer matched with
PCIE_LINK_STATE_L0S (3) and PCIE_LINK_STATE_L1 (4).
On the platform enabling ASPM L0s and L1, mt76_pci_disable_aspm is not able
to disable L1. Fix this by transforming aspm_conf to pcie link state.
Signed-off-by: Jiajia Liu <liujiajia at kylinos.cn>
Link: https://patch.msgid.link/20260602054349.42429-1-liujia6264@gmail.com
Signed-off-by: Felix Fietkau <nbd at nbd.name>
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
LLM Generated explanations, may be completely bogus:
## Phase 1: Commit Message Forensics
### Step 1.1: Subject Line
**Record:** `[wifi: mt76]` `[transform]` — Convert PCI LNKCTL ASPM
register bits to `PCIE_LINK_STATE_*` values before calling
`pci_disable_link_state()`.
### Step 1.2: Commit Message Tags
**Record:**
- **Signed-off-by:** Jiajia Liu `<liujiajia at kylinos.cn>` (author)
- **Link:**
https://patch.msgid.link/20260602054349.42429-1-liujia6264@gmail.com
- **Signed-off-by:** Felix Fietkau `<nbd at nbd.name>` (mt76 maintainer)
- No `Fixes:`, `Reported-by:`, `Cc: stable`, `Tested-by:`, or `Reviewed-
by:` tags
- References upstream commit `b478e162f227` ("PCI/ASPM: Consolidate link
state defines") as the change that broke the existing code
### Step 1.3: Commit Body Analysis
**Record:**
- **Bug:** `mt76_pci_disable_aspm()` passes raw `PCI_EXP_LNKCTL`
register bits (`aspm_conf`) directly to `pci_disable_link_state()`,
but after `b478e162f227` the `PCIE_LINK_STATE_*` constants no longer
match those register bit positions.
- **Symptom:** On platforms with ASPM L0s and L1 enabled, L1 cannot be
disabled via `pci_disable_link_state()`; the function returns success
and exits early.
- **Root cause:** `PCIE_LINK_STATE_L0S` changed from `1` to `3`
(`BIT(0)|BIT(1)`); `PCIE_LINK_STATE_L1` changed from `2` to `4`
(`BIT(2)`). `PCI_EXP_LNKCTL_ASPM_L0S`/`L1` remain `1`/`2`.
- **Version info:** Regression tied to `b478e162f227` (merged May 2024).
### Step 1.4: Hidden Bug Fix Detection
**Record:** Yes — despite the neutral "transform" wording, this is a
functional regression fix. The driver was written to disable ASPM
because it causes MCU hangs and WiFi instability on mt76 hardware; the
broken mapping silently leaves L1 active.
---
## Phase 2: Diff Analysis
### Step 2.1: Change Inventory
**Record:**
- **Files:** `drivers/net/wireless/mediatek/mt76/pci.c` only (+7 / -1)
- **Function modified:** `mt76_pci_disable_aspm()`
- **Scope:** Single-file surgical fix
### Step 2.2: Code Flow Change
**Record:**
- **Before:** `pci_disable_link_state(pdev, aspm_conf)` where
`aspm_conf` holds `PCI_EXP_LNKCTL` bits (e.g. `0x3` for L0s+L1).
- **After:** Build `state` by mapping register bits to API constants:
- `PCI_EXP_LNKCTL_ASPM_L0S` → `PCIE_LINK_STATE_L0S`
- `PCI_EXP_LNKCTL_ASPM_L1` → `PCIE_LINK_STATE_L1`
- Then call `pci_disable_link_state(pdev, state)`.
- **Path affected:** Normal probe path when `CONFIG_PCIEASPM` is enabled
and the OS has ASPM control.
### Step 2.3: Bug Mechanism
**Record:** **Logic/correctness fix — API value mismatch regression.**
When `aspm_conf = 0x3` (L0s+L1 in LNKCTL):
- Broken: `pci_disable_link_state(pdev, 0x3)` sets `link->aspm_disable
|= 0x3`
- In `pcie_config_aspm_link()`: `state &= (link->aspm_capable &
~link->aspm_disable)` — bits 0 and 1 are cleared, but
`PCIE_LINK_STATE_L1` is `BIT(2)` = 4, which is **not** cleared
- Function returns 0 (success) and exits early — L1 remains enabled
When `aspm_conf = 0x2` (L1 only): `aspm_disable |= 2` does not map to
`PCIE_LINK_STATE_L1` (4) — L1 not disabled.
### Step 2.4: Fix Quality
**Record:** Obviously correct — matches how every other driver in the
tree calls `pci_disable_link_state()` (using `PCIE_LINK_STATE_*`
constants, not register values). Minimal, no new APIs, very low
regression risk.
---
## Phase 3: Git History Investigation
### Step 3.1: Blame
**Record:** Buggy `pci_disable_link_state(pdev, aspm_conf)` call
introduced in `f37f05503575c` (Oct 2019, "mt76: mt76x2e: disable
pcie_aspm by default"). Worked correctly until `b478e162f227` changed
the `PCIE_LINK_STATE_*` definitions.
### Step 3.2: Fixes Tag
**Record:** N/A — no `Fixes:` tag. Referenced commit `b478e162f227` is
confirmed in this tree (`git merge-base --is-ancestor` succeeds).
### Step 3.3: Related File History
**Record:** `pci.c` has only 3 commits in this tree. No related fix
already applied. The fix commit itself is not yet in
`stable/linux-6.18.y`.
### Step 3.4: Author Context
**Record:** Jiajia Liu has other kernel contributions. Felix Fietkau
(mt76 maintainer) Signed-off-by on the patch.
### Step 3.5: Dependencies
**Record:** Requires `b478e162f227` (present in tree). Standalone — no
series dependencies. Applies cleanly to current `pci.c`.
---
## Phase 4: Mailing List and External Research
### Step 4.1: Original Patch Discussion
**Record:** `b4 am 20260602054349.42429-1-liujia6264 at gmail.com` found
thread at
https://patch.msgid.link/20260602054349.42429-1-liujia6264@gmail.com.
Single-message thread (initial submission only); no review replies or
stable nominations in the mbox.
### Step 4.2: Reviewers
**Record:** `b4 am` reported 0 code-review messages. Felix Fietkau
maintainer sign-off in the patch itself.
### Step 4.3: Bug Report
**Record:** No external bug report or syzbot link. Bug identified via
code analysis of the `b478e162f227` API change impact.
### Step 4.4: Related Patches
**Record:** Standalone 1-patch fix. mt76 is the only driver passing raw
LNKCTL values to `pci_disable_link_state()` (verified via grep).
### Step 4.5: Stable List History
**Record:** Not searched — no stable discussion found in the patch
thread. Not applicable as a negative signal.
---
## Phase 5: Code Semantic Analysis
### Step 5.1: Key Functions
**Record:** `mt76_pci_disable_aspm()` modified.
### Step 5.2: Callers
**Record:** Called during PCI probe from:
- `mt76x0/pci.c`, `mt76x2/pci.c` — always
- `mt7615/pci.c`, `mt7915/pci.c`, `mt7996/pci.c` — always
- `mt7921/pci.c`, `mt7925/pci.c` — when `disable_aspm` module param is
set (default false)
### Step 5.3: Callees
**Record:** `pci_disable_link_state()` → `__pci_disable_link_state()` →
sets `link->aspm_disable` and calls `pcie_config_aspm_link()`. Fallback:
`pcie_capability_clear_word()` on LNKCTL if API call fails.
### Step 5.4: Reachability
**Record:** Triggered at device probe on systems with `CONFIG_PCIEASPM`
and ASPM enabled in firmware/BIOS — common on laptops and desktops. Not
userspace-triggerable, but affects every boot/probe of affected mt76
hardware.
### Step 5.5: Similar Patterns
**Record:** All other `pci_disable_link_state()` callers use
`PCIE_LINK_STATE_*` constants correctly. mt76 is the sole offender.
---
## Phase 6: Cross-Reference Against Local Tree
### Step 6.1: Buggy Code Present?
**Record:** **Yes.** Local tree is **v6.18.44** (`stable/linux-6.18.y`).
Buggy code at line 34 of `pci.c`. Regression commit `b478e162f227` is an
ancestor of HEAD.
### Step 6.2: Backport Complications
**Record:** Clean apply expected — no conflicting changes to this
function in 6.18.y.
### Step 6.3: Fix Already Present?
**Record:** No — fix not in tree. `git log --grep='transform aspm_conf'`
returns nothing.
---
## Phase 7: Subsystem Context
### Step 7.1: Subsystem Criticality
**Record:** `drivers/net/wireless/mediatek/mt76` — IMPORTANT (WiFi
driver, multiple widely-used MediaTek chips).
### Step 7.2: Activity Level
**Record:** Actively maintained; mt76 is a core WiFi driver family with
ongoing development.
---
## Phase 8: Impact and Risk Assessment
### Step 8.1: Who Is Affected
**Record:** Users of mt76x0, mt76x2, mt7615, mt7915, mt7996 PCI WiFi
devices (always calls ASPM disable). mt7921/mt7925 users who set
`disable_aspm=1`. Config-dependent on `CONFIG_PCIEASPM` and platform
ASPM settings.
### Step 8.2: Trigger Conditions
**Record:** Device probe on platforms with ASPM L0s and/or L1 enabled in
PCI config — common default on modern systems. Not timing-dependent.
### Step 8.3: Failure Mode Severity
**Record:** **HIGH** functional impact — ASPM L1 remains active when the
driver intends to disable it. Original 2019 commit documented this
causes "continuous mcu hangs and instability" on mt76 hardware. Not a
kernel oops, but serious WiFi reliability regression.
### Step 8.4: Risk-Benefit
**Record:**
- **Benefit:** HIGH for affected mt76 users — restores intended ASPM
disabling behavior
- **Risk:** VERY LOW — 6-line mapping fix, maintainer-approved, matches
established driver patterns
- **Ratio:** Strongly favors backport
---
## Phase 9: Final Synthesis
### Step 9.1: Evidence Summary
**FOR backport:**
- Real regression from `b478e162f227` (in tree since v6.9)
- Prevents ASPM L1 disable on mt76 — known to cause MCU
hangs/instability
- Small, surgical, maintainer-signed fix
- Buggy code and prerequisite both present in v6.18.44
- Only driver in tree with this incorrect usage pattern
**AGAINST backport:**
- No syzbot report or user bug report filed
- mt7921/mt7925 only affected when module param set
- Not a security issue or kernel crash
**Unresolved:** No review-thread discussion beyond initial submission.
### Step 9.2: Stable Rules Checklist
1. Obviously correct and tested? **PASS** — mapping is verifiably
correct; maintainer SOB
2. Fixes a real bug? **PASS** — regression from PCI API change
3. Important issue? **PASS** — WiFi instability on affected hardware
(HIGH functional)
4. Small and contained? **PASS** — 7 lines, 1 file
5. No new features/APIs? **PASS**
6. Can apply to local tree? **PASS** — prerequisite present, clean apply
### Step 9.3: Exception Categories
**Record:** Hardware workaround — restoring ASPM disable that prevents
known hardware instability. Qualifies under quirk/workaround exception.
### Step 9.4: Decision Rationale
This is a clear regression fix for the locally checked-out **6.18.y**
tree. Commit `b478e162f227` changed `PCIE_LINK_STATE_*` semantics; mt76
was the only driver still passing raw LNKCTL register values. The result
is that `pci_disable_link_state()` returns success without actually
disabling L1, leaving mt76 devices exposed to the exact ASPM-related
instability the driver was designed to prevent. The fix is minimal,
correct, and maintainer-approved.
---
## Verification
- [Phase 1] Parsed subject, tags, body; identified regression from
`b478e162f227`
- [Phase 2] Read diff: 7 lines in `mt76_pci_disable_aspm()`, maps LNKCTL
bits to `PCIE_LINK_STATE_*`
- [Phase 2] Verified values: `PCI_EXP_LNKCTL_ASPM_L0S=1`, `L1=2`;
`PCIE_LINK_STATE_L0S=3`, `L1=4` in `include/linux/pci.h`
- [Phase 2] Traced `pcie_config_aspm_link()` line 961: `state &=
(capable & ~aspm_disable)` — confirmed L1 (bit 2) not cleared when
`aspm_disable=0x3`
- [Phase 3] `git describe HEAD`: v6.18.44
- [Phase 3] `git merge-base --is-ancestor b478e162f227 HEAD`: confirmed
present
- [Phase 3] `git show b478e162f227^:include/linux/pci.h`: old
`PCIE_LINK_STATE_L0S=BIT(0)`, `L1=BIT(1)` matched register bits
- [Phase 3] `git blame pci.c:34`: introduced in `f37f05503575c` (2019)
- [Phase 3] Fix not in tree: `git log --grep='transform aspm_conf'`
empty
- [Phase 4] `b4 am 20260602054349...`: found patch thread, 1 message,
Felix Fietkau SOB
- [Phase 5] `grep mt76_pci_disable_aspm`: 7 call sites across mt76 PCI
drivers
- [Phase 5] `grep pci_disable_link_state`: mt76 is sole driver passing
register values
- [Phase 6] Buggy code confirmed at `pci.c:34` in v6.18.44
- [Phase 6] `b478e162f227` on `stable/linux-6.18.y` via grep of branch
log
- [Phase 8] Original commit `f37f05503575c` message documents ASPM
causes "mcu hangs and instability"
**YES**The background checks finished and match the earlier analysis:
- **Stable branch search:** `b478e162f227d` ("PCI/ASPM: Consolidate link
state defines") is on `stable/linux-6.18.y`, so the regression this
mt76 fix addresses is present in your v6.18.44 tree.
- **Author history:** Jiajia Liu has other kernel fixes (Bluetooth,
mt76, btmtk, i915); Felix Fietkau signed off on this patch.
**Verdict unchanged: YES** — backport the fix to restore correct ASPM
disabling on mt76 PCI WiFi devices.
drivers/net/wireless/mediatek/mt76/pci.c | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/drivers/net/wireless/mediatek/mt76/pci.c b/drivers/net/wireless/mediatek/mt76/pci.c
index b5031ca7f73fb..4c864afefe2f2 100644
--- a/drivers/net/wireless/mediatek/mt76/pci.c
+++ b/drivers/net/wireless/mediatek/mt76/pci.c
@@ -30,8 +30,14 @@ void mt76_pci_disable_aspm(struct pci_dev *pdev)
if (IS_ENABLED(CONFIG_PCIEASPM)) {
int err;
+ int state = 0;
- err = pci_disable_link_state(pdev, aspm_conf);
+ if (aspm_conf & PCI_EXP_LNKCTL_ASPM_L0S)
+ state |= PCIE_LINK_STATE_L0S;
+ if (aspm_conf & PCI_EXP_LNKCTL_ASPM_L1)
+ state |= PCIE_LINK_STATE_L1;
+
+ err = pci_disable_link_state(pdev, state);
if (!err)
return;
}
--
2.53.0
More information about the linux-arm-kernel
mailing list