* [PATCH AUTOSEL 6.18] clk: mediatek: mt6735-vencsys: add missing MODULE_DEVICE_TABLE()
2026-10-19 13:44 [PATCH AUTOSEL 6.18-6.12] net: dsa: mt7530: check CORE_PLL_GROUP4 access in mt7531_setup() Sasha Levin
@ 2026-10-19 13:45 ` Sasha Levin
2026-10-19 13:46 ` [PATCH AUTOSEL 6.18-6.1] wifi: mt76: mt7921: fix memory leak when skb_linearize fails in mcu rx event Sasha Levin
` (17 subsequent siblings)
18 siblings, 0 replies; 20+ messages in thread
From: Sasha Levin @ 2026-10-19 13:45 UTC (permalink / raw)
To: patches, stable
Cc: Pengpeng Hou, Brian Masney, Sasha Levin, y.oudjana, sboyd,
bmasney+clk, jbrunet+clk, matthias.bgg, angelogioacchino.delregno,
linux-clk, linux-mediatek, linux-kernel, linux-arm-kernel
From: Pengpeng Hou <pengpeng@iscas.ac.cn>
[ Upstream commit 36cf8d279ff90835f4b002dec28eedb059554842 ]
The driver has an OF match table wired to .of_match_table, but does
not export the table with MODULE_DEVICE_TABLE().
Add the missing MODULE_DEVICE_TABLE(of, ...) entry so module alias
information is generated for OF based module autoloading.
This is a source-level fix. It does not claim dynamic hardware
reproduction; the evidence is the driver-owned match table, its use by
the platform driver, and the missing module alias publication.
Signed-off-by: Pengpeng Hou <pengpeng@iscas.ac.cn>
Reviewed-by: Brian Masney <bmasney@redhat.com>
Signed-off-by: Brian Masney <bmasney@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
LLM Generated explanations, may be completely bogus:
Connection lost, reconnecting to https://agentn.us.api5.cursor.sh
(attempt 1)...
Retry attempt 1...
This tree is **Linux 7.3.0-rc4** (`v7.3-rc4-27-gf0100363d8c37`). The
driver exists here; the change is a one-line `MODULE_DEVICE_TABLE(of,
...)` so the vencsys clock module can autoload from DT.
## Phase 1: Commit message forensics
**Step 1.1: Subject line**
- Record: `[clk/mediatek] [add] add missing MODULE_DEVICE_TABLE() for
mt6735-vencsys`
**Step 1.2: Tags**
- Record:
- **Fixes:** none (expected for this review)
- **Reported-by:** none
- **Tested-by:** none
- **Reviewed-by:** Brian Masney `<bmasney@redhat.com>` (COMMON CLK
FRAMEWORK maintainer)
- **Acked-by:** none
- **Link:** none in the commit; mailing list found via `b4 dig`
- **Cc: stable:** none (not a negative signal)
- **Signed-off-by:** Pengpeng Hou `<pengpeng@iscas.ac.cn>` (author);
Brian Masney `<bmasney@redhat.com>` (clk maintainer who applied it)
- Notable: maintainer review + maintainer SOB; no user/syzbot report
**Step 1.3: Body**
- Record:
- **Bug:** OF match table is wired to `.of_match_table` but not
exported with `MODULE_DEVICE_TABLE()`, so `file2alias` does not emit
`of:` aliases.
- **Symptom:** when `CONFIG_COMMON_CLK_MT6735_VENCSYS=m`,
udev/modprobe cannot autoload `clk-mt6735-vencsys` from
`mediatek,mt6735-vencsys`.
- **Version info:** none in the message. Git: driver added in
**v6.13-rc1** (`0bd9b1211f741`); this fix first appears in
**v7.3-rc1**.
- **Root cause:** omitted alias publication, not a runtime logic
error.
**Step 1.4: Hidden bug fix?**
- Record: Not hidden. It is a real functional gap (module autoload), not
a crash/UAF. The “source-level fix / no hardware reproduction” wording
matches the original lore submission, not pipeline decoration.
## Phase 2: Diff analysis
**Step 2.1: Inventory**
- Record:
- `drivers/clk/mediatek/clk-mt6735-vencsys.c`: **+1 / -0**
- Function/data: `of_match_mt6735_vencsys[]` (file scope)
- Scope: single-file, one-line surgical change
**Step 2.2: Code flow**
- Record: Before, the table is only consumed by
`platform_driver.driver.of_match_table` (bind if the module is already
loaded or built-in). After, `MODULE_DEVICE_TABLE(of,
of_match_mt6735_vencsys)` also creates a `__mod_device_table` alias so
`scripts/mod/file2alias.c` `do_of_entry()` emits
`of:N*T*Cmediatek,mt6735-vencsys`. Build-time metadata only; no probe-
path change.
**Step 2.3: Bug mechanism**
- Record: **Hardware matching / module autoload** (same class as missing
device IDs). Match table exists but is not published for modules.
**Step 2.4: Fix quality**
- Record: Obviously correct; matches sibling MT6735 files that shipped
with `MODULE_DEVICE_TABLE` (`apmixedsys`, `infracfg`, `pericfg`,
`topckgen`). No runtime lock/API/data-structure change. Regression
risk is essentially none. `imgsys` and `mfgcfg` still lack the macro;
this patch does not depend on those.
## Phase 3: Git history
**Step 3.1: Blame**
- Record: Match table and driver introduced by `0bd9b1211f741` (“clk:
mediatek: Add drivers for MT6735 syscon clock and reset controllers”,
Yassine Oudjana, 2024-11-06, applied 2024-11-14). First in
**v6.13-rc1**. `MODULE_DEVICE_TABLE` line is this commit
`36cf8d279ff90`.
**Step 3.2: Fixes: tag**
- Record: No `Fixes:` tag. The omission dates from the introducing
commit `0bd9b1211f741`, which **is** an ancestor of this tree.
**Step 3.3: File history**
- Record: Only two commits on this file: introducer + this fix. No later
conflicting refactor. Sibling same-day commit `096ab64a0e694` does the
same for `clk-mt6735-vdecsys.c`. Standalone; not patch 2/N.
**Step 3.4: Author**
- Record: Pengpeng Hou is not the MT6735 clk maintainer (that is Yassine
Oudjana). Same author also added `MODULE_DEVICE_TABLE` in `clk-
mt6735-vdecsys.c` and two i.MX clk drivers. Applied by clk co-
maintainer Brian Masney.
**Step 3.5: Dependencies**
- Record: None. Uses existing `MODULE_DEVICE_TABLE` / `of_device_id`.
Applies on top of the original driver with no prerequisites.
## Phase 4: Mailing list and external research
**Step 4.1: Original discussion**
- Record: `b4 dig -c 36cf8d279ff90` →
https://patch.msgid.link/20260704124808.19916-1-pengpeng@iscas.ac.cn
- `b4 dig -a`: **v1 only** (2026-07-04). Applied version is that v1.
- Thread (mbox): author patch + Brian Masney `Reviewed-by`. No NAK, no
stable nomination, no risk discussion.
**Step 4.2: Recipients (`b4 dig -w`)**
- Record: Yassine Oudjana (MT6735 clk maintainer), Stephen Boyd, Brian
Masney, Michael Turquette, Matthias Brugger, AngeloGioacchino Del
Regno; `linux-clk`, `linux-mediatek`, `linux-arm-kernel`, `linux-
kernel`. Right maintainers and lists.
**Step 4.3: Bug report**
- Record: No Reported-by, no syzbot, no bugzilla. Author states there
was no hardware reproduction.
**Step 4.4: Series**
- Record: Independent single patches (vencsys + vdecsys), not a numbered
series. This commit does not need the vdecsys patch.
**Step 4.5: Stable list**
- Record: **UNVERIFIED.** `curl` to lore.kernel.org/stable returned HTTP
403. No in-tree evidence this was rejected for stable.
## Phase 5: Code semantic analysis
**Step 5.1: Functions**
- Record: No function body changed. Adds `MODULE_DEVICE_TABLE` next to
`of_match_mt6735_vencsys[]`. Driver still uses
`module_platform_driver` → `mtk_clk_simple_probe` /
`mtk_clk_simple_remove`.
**Step 5.2: Callers**
- Record: Platform core binds via OF compatible. Probe is boot/device-
instantiation, not a syscall hot path. Impact is whether the **module
is loaded at all**.
**Step 5.3: Callees**
- Record: Unchanged. `mtk_clk_simple_probe()` in `clk-mtk.c` registers
the vencsys gates from `vencsys_clks`.
**Step 5.4: Reachability**
- Record: Reachable when DT has `mediatek,mt6735-vencsys` and the driver
is a module. **No in-tree `.dts`/`.dtsi` uses that compatible** (only
`Documentation/devicetree/bindings/clock/mediatek,syscon.yaml`). Users
need out-of-tree DT (typical for older MT6735 phones). Built-in (`=y`)
is unaffected.
**Step 5.5: Similar patterns**
- Record: Same omission still present in `clk-mt6735-imgsys.c` and `clk-
mt6735-mfgcfg.c`. Four other MT6735 clk files had
`MODULE_DEVICE_TABLE` from day one (`43c04ed791892` for apmixedsys).
Pattern is systematic but this patch is complete for vencsys.
## Phase 6: Local tree cross-reference
**Step 6.1: Buggy code in this tree?**
- Record: Yes. File exists; current tree already has the fix at line 40.
Bug was the missing alias from v6.13 until v7.3-rc1.
`CONFIG_COMMON_CLK_MT6735_VENCSYS` is **tristate**.
**Step 6.2: Backport difficulty**
- Record: **Clean apply.** File is essentially unchanged since
introduction. One inserted line after the match table.
**Step 6.3: Related fixes already here**
- Record: This exact commit is already an ancestor of HEAD (`git merge-
base --is-ancestor 36cf8d279ff90 HEAD` → yes). That is mainline
history, not a reason to reject on merit. No alternate fix. Sibling
vdecsys fix is also present; imgsys/mfgcfg still missing.
## Phase 7: Subsystem context
**Step 7.1: Subsystem / criticality**
- Record: `drivers/clk/mediatek/` — SoC clock driver. **PERIPHERAL**
(MT6735 video-encoder clocks only). Not mm/fs/net core.
**Step 7.2: Activity**
- Record: Mediatek clk is actively maintained; this file is not. Two
commits total. Mature omission, not churn.
## Phase 8: Impact and risk
**Step 8.1: Who is affected**
- Record: Only MT6735 systems with `CONFIG_COMMON_CLK_MT6735_VENCSYS=m`
and a DT node `mediatek,mt6735-vencsys`. Driver- and config-specific;
small population (no in-tree board DTS).
**Step 8.2: Trigger**
- Record: Modular boot + OF device present. Not a race. Unprivileged
users do not trigger it; udev autoload fails. Built-in and manual
`modprobe` work.
**Step 8.3: Failure mode**
- Record: Module does not autoload → vencsys clocks (smi_larb3, venc,
jpgenc, jpgdec) never register → video encode/JPEG on that SoC can
fail. **Severity: MEDIUM** (functional miss, not
oops/corruption/deadlock). Fits stable-rules “oh, that’s not good” and
the device-ID-style enablement exception.
**Step 8.4: Risk-benefit**
- Record: **Benefit:** correct autoload for a supported tristate driver;
one line. **Risk:** negligible (modinfo/depmod metadata only). Ratio
favors applying it on trees that have this driver.
## Phase 9: Final synthesis
**Step 9.1: Evidence**
FOR:
- Real autoload bug: match table used, aliases not published
- One line, obviously correct, reviewed and applied by clk maintainer
Brian Masney
- Driver is tristate; modular build is an intended config
- Same class as device-ID additions (publish existing OF IDs)
- Sibling MT6735 files already had the macro; this was an omission from
`0bd9b1211f741`
- Zero runtime regression risk; applies cleanly
- Driver and bug exist in this 7.3 tree (introduced v6.13)
AGAINST:
- Not a crash, UAF, deadlock, or security issue
- No user report and no hardware reproduction
- No in-tree DT consumer for this compatible
- Niche SoC; often clocks are built-in
UNRESOLVED:
- Whether this was discussed on the stable list (lore HTTP 403)
**Step 9.2: Stable rules checklist**
1. Obviously correct and tested? **PASS** — one-line, standard macro,
maintainer Reviewed-by/SOB. No runtime test; correctness is
mechanical.
2. Real bug that affects users? **PASS** — modular OF autoload is
broken. User set is small but real if they use `=m`.
3. Important issue? **PASS** (low end of “oh, that’s not good” /
hardware-enablement), not CRITICAL.
4. Small and contained? **PASS** — +1 line, one file.
5. No new features or APIs? **PASS** — publishes existing match table.
6. Can apply to this tree? **PASS** — file and table exist; patch is a
clean one-liner.
**Step 9.3: Exception category**
- Record: Closest match is **device ID / hardware matching** (OF module
aliases), not a new driver.
**Step 9.4: Decision**
Backport this. It is a one-line, obviously correct fix for failed OF
module autoload on an existing tristate driver. That is the same kind of
enablement stable already takes for new device IDs, with no runtime
behavior change if the module is built-in or loaded by other means. This
7.3 tree has the driver (since v6.13); there are no missing
prerequisites. Limited hardware and no crash report lower urgency, not
correctness.
### What it solves for stable users
If `clk-mt6735-vencsys` is a module, userspace cannot match
`mediatek,mt6735-vencsys` and load it. Video-encoder clocks then never
appear. `MODULE_DEVICE_TABLE(of, ...)` generates the aliases
`file2alias` already knows how to emit.
### Risk vs benefit
Benefit is correct autoload on MT6735 modular configs. Risk is
negligible: no probe, locking, or ABI change.
## Verification
- [Phase 1] Parsed tags: Reviewed-by + SOB Brian Masney; no
Fixes/Reported-by/Cc:stable
- [Phase 1] `git show -s 36cf8d279ff90`: body matches the candidate;
“source-level fix” is in the real commit and lore v1
- [Phase 2] Diff: +1 `MODULE_DEVICE_TABLE(of, of_match_mt6735_vencsys)`
in `clk-mt6735-vencsys.c`
- [Phase 2] `include/linux/module.h` and `scripts/mod/file2alias.c`
`do_of_entry()`: confirmed alias generation from that macro
- [Phase 3] `git blame`: table from `0bd9b1211f741` (v6.13-rc1); macro
from `36cf8d279ff90`
- [Phase 3] `git describe --contains 0bd9b1211f741`: v6.13-rc1; fix
contained in v7.3-rc1; `git merge-base --is-ancestor` vs v7.2: not in
v7.2
- [Phase 3] File log: only introducer + this commit; sibling
`096ab64a0e694` for vdecsys
- [Phase 4] `b4 dig -c/-a/-w/-m`: v1 lore thread; Masney Reviewed-by;
correct clk/mediatek CCs; no NAK
- [Phase 4] WebFetch lore/msgid.link: HTTP 403; used mbox instead
- [Phase 5] Kconfig: `COMMON_CLK_MT6735_VENCSYS` tristate; Makefile
`obj-$(CONFIG_COMMON_CLK_MT6735_VENCSYS)`
- [Phase 5] `mtk_clk_simple_probe` in `clk-mtk.c` used unchanged
- [Phase 5] Grep: no in-tree dts/dtsi `mediatek,mt6735-vencsys`; binding
in `mediatek,syscon.yaml`
- [Phase 5] imgsys/mfgcfg still lack `MODULE_DEVICE_TABLE`
- [Phase 6] `make kernelversion` / `git describe HEAD`: 7.3.0-rc4 /
v7.3-rc4-27-gf0100363d8c37
- [Phase 6] File currently contains the macro; `git merge-base --is-
ancestor 36cf8d279ff90 HEAD` = yes
- [Phase 7] MAINTAINERS: MT6735 clk → Yassine Oudjana; COMMON CLK →
Stephen Boyd, Brian Masney, Jerome Brunet
- [Phase 8] Failure mode: missing module autoload, not oops; severity
MEDIUM
- UNVERIFIED: stable@ lore discussion (HTTP 403)
**YES**
drivers/clk/mediatek/clk-mt6735-vencsys.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/clk/mediatek/clk-mt6735-vencsys.c b/drivers/clk/mediatek/clk-mt6735-vencsys.c
index 8dec7f98492ac..64ba9da9fd427 100644
--- a/drivers/clk/mediatek/clk-mt6735-vencsys.c
+++ b/drivers/clk/mediatek/clk-mt6735-vencsys.c
@@ -37,6 +37,7 @@ static const struct of_device_id of_match_mt6735_vencsys[] = {
{ .compatible = "mediatek,mt6735-vencsys", .data = &vencsys_clks },
{ /* sentinel */ }
};
+MODULE_DEVICE_TABLE(of, of_match_mt6735_vencsys);
static struct platform_driver clk_mt6735_vencsys = {
.probe = mtk_clk_simple_probe,
--
2.53.0
^ permalink raw reply related [flat|nested] 20+ messages in thread* [PATCH AUTOSEL 6.18-6.1] wifi: mt76: mt7921: fix memory leak when skb_linearize fails in mcu rx event
2026-10-19 13:44 [PATCH AUTOSEL 6.18-6.12] net: dsa: mt7530: check CORE_PLL_GROUP4 access in mt7531_setup() Sasha Levin
2026-10-19 13:45 ` [PATCH AUTOSEL 6.18] clk: mediatek: mt6735-vencsys: add missing MODULE_DEVICE_TABLE() Sasha Levin
@ 2026-10-19 13:46 ` Sasha Levin
2026-10-19 13:46 ` [PATCH AUTOSEL 6.18-5.15] wifi: mt76: set the EOSP bit in the QoS header of the last released frame Sasha Levin
` (16 subsequent siblings)
18 siblings, 0 replies; 20+ messages in thread
From: Sasha Levin @ 2026-10-19 13:46 UTC (permalink / raw)
To: patches, stable
Cc: Prashant Rahul, Felix Fietkau, Sasha Levin, lorenzo, ryder.lee,
matthias.bgg, angelogioacchino.delregno, linux-wireless,
linux-kernel, linux-arm-kernel, linux-mediatek
From: Prashant Rahul <prashantrahul23@gmail.com>
[ Upstream commit 4361f1660101270611eb5dc39799f620b35f2e4d ]
The ownership of sk_buff skb is passed to mt7921_queue_rx_skb, each
path inside it under the switch case handles cleaning of skb and it
is true for mt7921_mcu_rx_event as well.
mt7921_mcu_rx_event, on a success path, either queues skb via
mt76_mcu_rx_event or cleans it immediately inside
mt7921_mcu_uni_rx_unsolicited_event.
However inside mt7921_mcu_rx_event, if skb_linearize fails, the function
returns immediately and never bothers cleaning skb which leaks skb.
Since skb is fully owned at this point, it is safe to call
dev_kfree_skb which fixes the leak.
Granted, the skb_linearize failure is rare as it can only fail under
heavy memory usage, but at the same time, leaking memory under heavy
memory usage can worsen the OOM condition.
Signed-off-by: Prashant Rahul <prashantrahul23@gmail.com>
Link: https://patch.msgid.link/20260716-mt7921-mem-leak-v1-1-6e9c0ea19f63@gmail.com
Signed-off-by: Felix Fietkau <nbd@nbd.name>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
LLM Generated explanations, may be completely bogus:
# Stable backport analysis: mt7921 MCU RX skb leak
**Tree decided:** `pending-6.6` (6.6.157), SHA `04810563abb71`.
At the start of this evaluation `git describe`/`make kernelversion`
reported **6.6.157**. The working copy later moved to v7.3-rc4; every
presence/absence claim below was rechecked against **`pending-6.6`**,
not that later checkout.
The candidate is mainline `4361f16601012` (`wifi: mt76: mt7921: fix
memory leak when skb_linearize fails in mcu rx event`).
---
## PHASE 1: COMMIT MESSAGE FORENSICS
**Step 1.1 — Subject**
Record: **[wifi: mt76: mt7921]** **[fix]** memory leak when
`skb_linearize` fails in MCU RX event.
**Step 1.2 — Tags**
- `Signed-off-by: Prashant Rahul <prashantrahul23@gmail.com>` (author)
- `Link: https://patch.msgid.link/20260716-mt7921-mem-
leak-v1-1-6e9c0ea19f63@gmail.com`
- `Signed-off-by: Felix Fietkau <nbd@nbd.name>` (mt76 maintainer;
applied the patch)
- No `Fixes:`, `Reported-by:`, `Tested-by:`, `Reviewed-by:`, `Acked-
by:`, or `Cc: stable` (absence of Fixes/Cc-stable is expected for this
review).
Record: Maintainer SOB; msgid shows **v1 patch 1/1** (standalone).
**Step 1.3 — Body**
Record:
- **Bug:** `mt7921_queue_rx_skb` transfers skb ownership into
`mt7921_mcu_rx_event`. Success paths free or queue the skb. If
`skb_linearize()` fails, the function returns without freeing.
- **Symptom:** skb leak. Author notes failure is rare (ENOMEM) but
leaking under memory pressure can worsen OOM.
- **Root cause:** missing `dev_kfree_skb` on the linearize error path.
- **Version info in message:** none.
**Step 1.4 — Hidden bug fix?**
Record: **No disguise.** This is an explicit leak fix, not cleanup-as-
fix.
---
## PHASE 2: DIFF ANALYSIS
**Step 2.1 — Inventory**
Record:
- File: `drivers/net/wireless/mediatek/mt76/mt7921/mcu.c` (**+3 / −1**)
- Function: `mt7921_mcu_rx_event`
- Scope: **single-file surgical fix**
**Step 2.2 — Flow**
Before (pending-6.6 `mcu.c:312-313`):
```
if (skb_linearize(skb))
return;
```
After:
```
if (skb_linearize(skb)) {
dev_kfree_skb(skb);
return;
}
```
Record: **error path only.** Success paths unchanged.
**Step 2.3 — Bug mechanism**
Record: **[resource leak]** On `skb_linearize` failure (`-ENOMEM` for
nonlinear skbs), the still-owned skb is dropped. Caller
`mt7921_queue_rx_skb` does not free after `PKT_TYPE_RX_EVENT`. Other
switch arms in the same caller (`dev_kfree_skb` / `napi_consume_skb`)
and other arms of `mt7921_mcu_rx_event` (`dev_kfree_skb`,
`mt76_mcu_rx_event` queue) already consume the skb.
**Step 2.4 — Fix quality**
Record: **Obviously correct.** Matches established kernel pattern (`if
(skb_linearize(skb)) { dev_kfree_skb(_any)(skb); return; }`). Same free
helper already used in this MCU event path. No API/lock/data-structure
change. Regression risk: **very low** (could only be a double-free if
linearize already freed; it does not — see Phase 5).
---
## PHASE 3: GIT HISTORY
**Step 3.1 — Blame**
Record: Leak introduced by **`f0ff5d3aa64812`** (`mt76: mt7921: make all
event parser reusable between mt7921s and mt7921e`, Sean Wang,
2021-10-19). That commit added `skb_linearize` + early return and never
freed on failure. Present since ~5.16-era; **`git merge-base --is-
ancestor f0ff5d3aa64812 pending-6.6` succeeds.**
**Step 3.2 — Fixes: tag**
Record: **None.** Introducer identified by blame: `f0ff5d3aa64812`,
which **is** in this 6.6 tree.
**Step 3.3 — File history (pending-6.6)**
Recent 6.6 work on this file is CLC firmware validation, not MCU RX. No
competing leak fix. Record: **standalone**; not part of a multi-patch
series.
**Step 3.4 — Author**
Prashant Rahul has **no other commits** in this tree’s mt76 history.
Applied by **Felix Fietkau**, listed maintainer of MEDIATEK MT76 in
`MAINTAINERS`. Record: one-off contributor; **maintainer-applied**.
**Step 3.5 — Dependencies**
The hunk only needs `mt7921_mcu_rx_event` + `skb_linearize` +
`dev_kfree_skb`, all present. Mailing-list patch context matches 6.6
(the extra `MCU_EVENT_RSSI_NOTIFY` in later mainline is **below** the
change). Record: **applies standalone**.
---
## PHASE 4: MAILING LIST / EXTERNAL
**Step 4.1 — Original discussion**
- `b4 dig -c <msgid>` / `b4 mbox`: no match (404).
- lore.kernel.org: **403**.
- Recovered from Openwall and Ratatoskr:
https://lists.openwall.net/linux-kernel/2026/07/16/1707
msgid `20260716-mt7921-mem-leak-v1-1-6e9c0ea19f63@gmail.com`
Record: **v1, single patch**, applied as submitted (`4361f16601012`
matches that diff). No v2/v3.
**Step 4.2 — Recipients (`b4 dig -w` unavailable; headers from
Openwall)**
To: Felix Fietkau, Lorenzo Bianconi, Ryder Lee, Shayne Chen, Sean Wang
(mt76 maintainers/reviewers), plus MediaTek ARM contacts. Cc: linux-
wireless, linux-kernel, linux-mediatek, linux-arm-kernel. Record:
**correct maintainer set**.
**Step 4.3 — Bug report**
Record: **No syzbot/bugzilla.** Static ownership analysis; author states
the leak is rare.
**Step 4.4 — Series**
Record: **1/1 standalone.** No sibling mt7925/mt7915 patches required
for this tree (only mt7921 has this `skb_linearize` in pending-6.6).
**Step 4.5 — Stable list**
Search for this subject on lore stable returned unrelated hits. Record:
**no prior stable NAK found** (lore 403 limited this).
---
## PHASE 5: CODE SEMANTIC ANALYSIS
**Step 5.1 — Functions**
Record: `mt7921_mcu_rx_event` only.
**Step 5.2 — Callers**
`mt7921_queue_rx_skb()` (`mac.c`) `case PKT_TYPE_RX_EVENT:` calls it and
does **not** free afterwards.
That `rx_skb` hook is registered for **PCIe, USB, and SDIO**:
- `mt7921/pci.c`, `usb.c`, `sdio.c` → `.rx_skb = mt7921_queue_rx_skb`
- Invoked from `mt76_dma_rx_process` (NAPI), `mt76u` USB RX,
`mt76s_process_rx_queue` (SDIO)
Record: **hot RX path** for MT7921E/S/U.
**Step 5.3 — Callees**
`skb_linearize` → `__skb_linearize` → `__pskb_pull_tail`; returns
`-ENOMEM` on failure and **does not free** the skb
(`include/linux/skbuff.h`: “If there is no free memory -ENOMEM is
returned”). Success continues to `mt7921_mcu_uni_rx_unsolicited_event` /
`mt76_mcu_rx_event` / `mt7921_mcu_rx_unsolicited_event`.
**Step 5.4 — Reachability**
Nonlinear MCU events are real:
- SDIO `mt76s_build_rx_skb` uses `skb_add_rx_frag` when payload >
`MT_SKB_HEAD_LEN` — this is **why** `f0ff5d3aa64812` added linearize
(“paged fragment skb for the SDIO device”).
- USB `mt76u_build_rx_skb` same pattern.
- DMA `mt76_add_fragment` builds fraglists for multi-buffer RX.
Record: reachable from normal firmware MCU events; unprivileged users
can generate MCU traffic by using WiFi. Failure needs **ENOMEM during
linearize**.
**Step 5.5 — Similar patterns**
In pending-6.6, `skb_linearize` appears **only here** under mt76. No
duplicate site left unfixed in this tree.
---
## PHASE 6: LOCAL TREE (pending-6.6 / 6.6.157)
**Step 6.1 — Buggy code present?**
Record: **Yes.**
`pending-6.6:drivers/net/wireless/mediatek/mt76/mt7921/mcu.c:312-313`:
```
if (skb_linearize(skb))
return;
```
`git merge-base --is-ancestor 4361f16601012 pending-6.6` → **false**
(fix not here).
`git merge-base --is-ancestor f0ff5d3aa64812 pending-6.6` → **true**
(bug intro is here).
Bug age: **2021**, well before 6.6.
**Step 6.2 — Backport difficulty**
Submitted hunk is 4 lines around `skb_linearize` with context that
matches 6.6 (`struct mt76_connac2_mcu_rxd *rxd` then the if).
`MCU_EVENT_RSSI_NOTIFY` is later mainline-only context **below** the
edit. Record: **clean apply / trivial**.
**Step 6.3 — Related fixes already here?**
`git log --grep=skb_linearize` on mt76 in this tree: **empty**. No
alternate fix. Record: **none**.
---
## PHASE 7: SUBSYSTEM CONTEXT
**Step 7.1**
Record: **wifi / mt76 / mt7921**. Criticality: **IMPORTANT** — MT7921E
is a common laptop WiFi 6 adapter (PCIe); USB/SDIO variants exist
(`MT7921E/S/U` in Kconfig). Not core mm/net, not staging.
**Step 7.2**
Record: Mature driver (MCU support from `1c099ab44727c8`, 2021). 6.6
still receives mt76 bugfixes (CLC, etc.).
---
## PHASE 8: IMPACT AND RISK
**Step 8.1 — Who is affected**
Record: **driver-specific**, users with MediaTek MT7921 (very common on
laptops). Config: `CONFIG_MT7921E/S/U`.
**Step 8.2 — Trigger**
Record: Firmware MCU RX event whose skb is nonlinear, **and**
`skb_linearize` fails (GFP/ENOMEM). Unprivileged WiFi use can generate
events; the failure itself is **uncommon**. SDIO long events are the
originally cited nonlinear case; USB/DMA can also fragment.
**Step 8.3 — Failure mode**
Record: **skb leak under memory pressure**, which can deepen OOM. Not a
panic/UAF. Severity: **MEDIUM–HIGH** (hot-path leak, not a one-time
probe leak).
**Step 8.4 — Risk/benefit**
- Benefit: **medium** — stops a real leak on a widely shipped chip; most
valuable when the system is already under memory pressure.
- Risk: **very low** — 3 lines, error path, same free as sibling paths.
- Ratio: **favor backport**.
---
## PHASE 9: SYNTHESIS
**Step 9.1 — Evidence**
**For:**
- Real leak with verified ownership (caller does not free).
- Code and introducer are in 6.6.157; fix is not.
- Tiny, obviously correct, maintainer-applied.
- MT7921 is production hardware, not staging.
- Leak on an RX path under OOM is a stability issue, not a style
cleanup.
**Against:**
- Trigger is rare (`skb_linearize` ENOMEM).
- No crash/syzbot/CVE.
- No explicit `Cc: stable` (not a negative per the review rules).
**Unresolved:** Full lore thread (403/404); no reviewer comments beyond
maintainer merge. Does not change the technical verdict.
**Step 9.2 — Stable rules**
1. Obviously correct and tested — **PASS** (3-line ownership fix; in
mainline via Felix).
2. Real bug affecting users — **PASS** (skb leak on MT7921 MCU RX).
3. Important (crash/security/corruption/deadlock) — **PASS** as an RX-
path leak that can worsen OOM; not a panic, but in the leak class
stable regularly takes.
4. Small and contained — **PASS** (4 lines, one function).
5. No new features/APIs — **PASS**.
6. Can apply to this tree — **PASS** (hunk matches 6.6).
**Step 9.3 — Exceptions**
Record: none needed (not an ID/quirk/DT/build/doc exception). Ordinary
small leak fix.
**Step 9.4 — Decision**
Backport to **this** 6.6.157 tree. The bug exists here, the fix is
surgical, and regression risk is negligible.
---
## What the commit solves for stable users
On MT7921, firmware MCU events are handed to `mt7921_mcu_rx_event` with
full skb ownership. Nonlinear events (especially SDIO, also USB/DMA
fragments) are linearized first. If that allocation fails, 6.6 returns
and leaks the skb. Under memory pressure that leak makes OOM worse.
Adding `dev_kfree_skb(skb)` on that path closes the leak without
changing success behavior.
## Risk vs benefit
Benefit is a real leak fix on a common WiFi chip; risk is a three-line
error-path free that matches existing code in the same function.
## Concerns
None material: no prerequisites, no API change, no locking, expected
clean apply. Trigger rarity is the only weak point and is not enough to
reject a contained leak fix.
---
## Verification
- **[Phase 1]** Parsed tags: author SOB, Link msgid, Felix Fietkau SOB;
no Fixes/Reported-by/Cc-stable.
- **[Phase 2]** Diff: +3/−1 in `mt7921_mcu_rx_event`; adds
`dev_kfree_skb` on `skb_linearize` failure.
- **[Phase 3]** `git blame` on pending-6.6: leak from `f0ff5d3aa64812`
(2021-10-19); `git merge-base --is-ancestor f0ff5d3aa64812
pending-6.6` true.
- **[Phase 3]** `git show f0ff5d3aa64812`: added `if
(skb_linearize(skb)) return;` with no free.
- **[Phase 3]** `git log --author=Prashant Rahul`: no other mt76 commits
in this history.
- **[Phase 4]** Openwall/Ratatoskr: v1 1/1, same diff as
`4361f16601012`; mt76 maintainers on To:.
- **[Phase 4]** `b4 mbox` msgid: 404; lore.kernel.org: 403.
**UNVERIFIED:** full review replies / explicit stable nomination.
- **[Phase 5]** Callers: `mt7921_queue_rx_skb` (no free on
`PKT_TYPE_RX_EVENT`); hooked from pci/usb/sdio `.rx_skb`.
- **[Phase 5]** `skb_linearize` documented to return `-ENOMEM` and not
free; USB/SDIO `skb_add_rx_frag` makes nonlinear skbs.
- **[Phase 6]** `git describe` at start: `p-6.6-3-g04810563abb71`, `make
kernelversion` 6.6.157.
- **[Phase 6]** `git grep` on `pending-6.6`: leak at `mcu.c:312-313`.
- **[Phase 6]** `git merge-base --is-ancestor 4361f16601012 pending-6.6`
false.
- **[Phase 8]** Failure mode: skb leak under ENOMEM on MCU RX; severity
MEDIUM–HIGH.
- **UNVERIFIED:** complete lore thread text after 403.
The fix is small, matches stable leak-fix practice, and the buggy code
is in this 6.6 tree.
**YES**
drivers/net/wireless/mediatek/mt76/mt7921/mcu.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c
index 8c8b35cba856c..f63ef02542387 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c
@@ -354,8 +354,10 @@ void mt7921_mcu_rx_event(struct mt792x_dev *dev, struct sk_buff *skb)
{
struct mt76_connac2_mcu_rxd *rxd;
- if (skb_linearize(skb))
+ if (skb_linearize(skb)) {
+ dev_kfree_skb(skb);
return;
+ }
rxd = (struct mt76_connac2_mcu_rxd *)skb->data;
--
2.53.0
^ permalink raw reply related [flat|nested] 20+ messages in thread* [PATCH AUTOSEL 6.18-5.15] wifi: mt76: set the EOSP bit in the QoS header of the last released frame
2026-10-19 13:44 [PATCH AUTOSEL 6.18-6.12] net: dsa: mt7530: check CORE_PLL_GROUP4 access in mt7531_setup() Sasha Levin
2026-10-19 13:45 ` [PATCH AUTOSEL 6.18] clk: mediatek: mt6735-vencsys: add missing MODULE_DEVICE_TABLE() Sasha Levin
2026-10-19 13:46 ` [PATCH AUTOSEL 6.18-6.1] wifi: mt76: mt7921: fix memory leak when skb_linearize fails in mcu rx event Sasha Levin
@ 2026-10-19 13:46 ` Sasha Levin
2026-10-19 13:46 ` [PATCH AUTOSEL 6.18-5.10] usb: mtu3: Fix double dereference in TP_printk Sasha Levin
` (15 subsequent siblings)
18 siblings, 0 replies; 20+ messages in thread
From: Sasha Levin @ 2026-10-19 13:46 UTC (permalink / raw)
To: patches, stable
Cc: Felix Fietkau, Sasha Levin, lorenzo, ryder.lee, matthias.bgg,
angelogioacchino.delregno, linux-wireless, linux-kernel,
linux-arm-kernel, linux-mediatek
From: Felix Fietkau <nbd@nbd.name>
[ Upstream commit 0b8d2524716099ea4743fa65bc364f94b3106a31 ]
When the driver implements .release_buffered_frames, mac80211 leaves the
U-APSD signalling entirely to the driver: "In this case it is also
responsible for setting the EOSP flag in the QoS header of the frames"
(include/net/mac80211.h). Only IEEE80211_TX_STATUS_EOSP was being set,
which merely ends the service period inside mac80211, so on air the
service period was never terminated. Clients that wait for EOSP before
going back to doze keep the SP open and stop triggering, which stalls all
downlink traffic for that station.
Set the wire EOSP bit on the last frame of a U-APSD service period.
EOSP has no meaning for a PS-Poll response, so pass the release reason
down and leave those frames alone.
Link: https://patch.msgid.link/20260801145334.1166751-4-nbd@nbd.name
Signed-off-by: Felix Fietkau <nbd@nbd.name>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
LLM Generated explanations, may be completely bogus:
This is a real U-APSD protocol bug in mt76 that already exists in this
5.15.221 tree. The fix is small, applies here, and is independent of the
rest of the series.
## Phase 1: Commit message forensics
**Step 1.1 — subject**
Record: `[wifi: mt76:]` `[set]` set the EOSP bit in the QoS header of
the last released frame. “Set” here is a protocol-correctness fix, not a
feature add.
**Step 1.2 — tags**
Record:
- `Link: https://patch.msgid.link/20260801145334.1166751-4-nbd@nbd.name`
(linux-wireless, series 04/10)
- `Signed-off-by: Felix Fietkau <nbd@nbd.name>` (mt76 maintainer; Sasha
Levin SOB ignored per instructions)
- No `Fixes:`, `Reported-by:`, `Tested-by:`, `Reviewed-by:`, `Cc:
stable` (absence is expected)
Mainline SHA (from `origin/master`, path-limited log):
`0b8d2524716099ea4743fa65bc364f94b3106a31`. First containing tag:
`v7.3-rc1`. Not an ancestor of this HEAD.
**Step 1.3 — body**
Record:
- **Bug:** `.release_buffered_frames` means mac80211 does not set the
on-air EOSP bit; the driver must. mt76 only set
`IEEE80211_TX_STATUS_EOSP` (ends the SP inside mac80211).
- **Symptom:** U-APSD clients that wait for EOSP never see it, keep the
service period open, stop triggering, **all downlink for that STA
stalls**.
- **Root cause:** missing `IEEE80211_QOS_CTL_EOSP` on the last QoS frame
of a U-APSD SP. PS-Poll must not get EOSP.
- **Version info:** none in the message. Buggy code dates to 2017.
**Step 1.4 — hidden fix?**
Record: Not hidden. Explicit protocol/connectivity fix.
## Phase 2: Diff analysis
**Step 2.1 — inventory**
Record:
- File: `drivers/net/wireless/mediatek/mt76/tx.c` (`+12 / -4`)
- Functions: `mt76_queue_ps_skb`, `mt76_release_buffered_frames`
- Scope: single-file surgical change. `mt76_queue_ps_skb` is static;
exported `mt76_release_buffered_frames` signature already has
`reason`.
**Step 2.2 — flow**
Record:
- Before: last PS-release frame gets `IEEE80211_TX_STATUS_EOSP |
IEEE80211_TX_CTL_REQ_TX_STATUS` and More Data cleared. QoS Control on
the wire is untouched.
- After: same flags, plus if `reason == IEEE80211_FRAME_RELEASE_UAPSD`
and the frame is QoS data, OR `IEEE80211_QOS_CTL_EOSP` into the QoS
control field. `reason` is passed through both call sites.
- Path: U-APSD/PS-Poll release via `.release_buffered_frames`, not the
normal TX burst path.
**Step 2.3 — bug mechanism**
Record: **Logic / protocol correctness.** mac80211’s own release path
(`net/mac80211/sta_info.c`) does `*qoshdr |= IEEE80211_QOS_CTL_EOSP` for
U-APSD. Drivers that implement `.release_buffered_frames` must do the
same (`include/net/mac80211.h`). mt76 did not.
**Step 2.4 — quality**
Record: Obviously correct and aligned with mac80211. Guards match the
docs (U-APSD only; QoS data only). skb is exclusively owned after
`ieee80211_tx_dequeue`. Header at `skb->data` matches existing
`mt76_skb_set_moredata()`. Regression risk is low: PS-Poll unchanged;
non-QoS last frames still lack wire EOSP (mac80211 already assumes
drivers mostly buffer QoS-data, or add a QoS-Null themselves). Pre-
existing unused `more_data` parameter is not changed.
## Phase 3: Git history
**Step 3.1 — blame**
Record: `mt76_queue_ps_skb` / `mt76_release_buffered_frames` introduced
in `17f1de56df0512` (“mt76: add common code…”, 2017-12-07,
**v4.16-rc1**). `IEEE80211_TX_STATUS_EOSP` added in `7267a7965dd7b`
(2018). Present for the entire 5.15 lifetime.
**Step 3.2 — Fixes: tag**
Record: None. Introducer is `17f1de56df0512`, which **is** in this tree.
**Step 3.3 — related file history**
Record: Recent 5.15 `tx.c` work is unrelated (locking, UAF, queue id).
This tree already has U-APSD AP support: `b807b368c4f9b` (mt76 AP
U-APSD), `4bf04d33f5b7e` (mt7915). No earlier EOSP-on-wire fix.
**Step 3.4 — author**
Record: Felix Fietkau is listed in `MAINTAINERS` as mt76 maintainer.
Sibling series patch 05 (`697badc27a9b3`, mt7603 U-APSD termination) is
a separate chip-specific fix, not a prerequisite.
**Step 3.5 — prerequisites**
Record: Series is **01–10**, but 04 does **not** depend on 01–03. Patch
01 (`a547b414bf7ea`) changes `mt76_txq_send_burst` / HW TIM buffering
and does not touch `mt76_queue_ps_skb`. 02/03/09/10 are
mt7915/mt7996/MLO (mt7996 is not in 5.15). 05–08 are mt7603-only. 04 is
standalone. All helpers used (`ieee80211_is_data_qos`,
`ieee80211_get_qos_ctl`, `IEEE80211_QOS_CTL_EOSP`,
`IEEE80211_FRAME_RELEASE_UAPSD`) exist in this tree via `mt76.h` →
`<net/mac80211.h>` / `ieee80211.h`.
## Phase 4: Mailing list / external
**Step 4.1 — original discussion**
Record: `b4 dig -c 0b8d252471609` →
https://patch.msgid.link/20260801145334.1166751-4-nbd@nbd.name
`b4 dig -a`: single **v1** series, 2026-08-01. Applied version is that
v1. Thread has the 10 patches plus a kernel-test-robot build error on
**10/10** (`ieee80211_txq_aql_pending` / patch 01), **not** on 04. No
NAK, no reviewer concern about EOSP. Merged via `wireless-
next-2026-08-06` into `v7.3-rc1`.
**Step 4.2 — recipients (`b4 dig -w`)**
Record: Felix Fietkau, `linux-wireless@vger.kernel.org`. Maintainer-
authored self-merge; no extra Reviewed-by. Normal for mt76.
**Step 4.3 — bug report**
Record: No syzbot/bugzilla. The series commit messages describe a
concrete on-air failure (clients waiting for EOSP). Unverified: no
public user stack trace beyond the author’s analysis.
**Step 4.4 — series context**
Record: 04 is the common-path EOSP fix. 05 is the mt7603 driver-PS-queue
analogue. Taking 04 without 05 still fixes mac80211-buffered frames on
**all** chips that use `mt76_release_buffered_frames` (mt76x0/x2,
mt7615, mt7915, mt7921, and mt7603’s fallback).
**Step 4.5 — stable list**
Record: `lore.kernel.org/stable/?q=mt76+EOSP+QoS` → **No results
found**. No recorded reason to skip it.
## Phase 5: Semantic / call graph
**Step 5.1 — functions**
Record: `mt76_queue_ps_skb`, `mt76_release_buffered_frames`.
**Step 5.2 — callers**
Record: `mt76_queue_ps_skb` only from `mt76_release_buffered_frames`.
That is `.release_buffered_frames` for mt76x0, mt76x2, mt7615, mt7915,
mt7921; mt7603 wraps it after draining `msta->psq`. mac80211 calls it
from `ieee80211_sta_ps_deliver_response()` →
`drv_release_buffered_frames()`.
**Step 5.3 — callees**
Record: `IEEE80211_SKB_CB`, `ieee80211_is_data_qos`,
`ieee80211_get_qos_ctl`, `mt76_skb_set_moredata`, `__mt76_tx_queue_skb`.
No new locks/allocs.
**Step 5.4 — reachability**
Record: Yes, from the air. AP RX of a U-APSD trigger
(`ieee80211_sta_uapsd_trigger` in `mac80211.c` / `rx.c`) →
`ieee80211_sta_ps_deliver_uapsd` → driver release. This tree sets
`WIPHY_FLAG_AP_UAPSD`. Typical trigger: a phone associated to an mt76
AP.
**Step 5.5 — similar patterns**
Record: mac80211 `sta_info.c` uses the same `*qoshdr |=
IEEE80211_QOS_CTL_EOSP`. Sibling mt7603 patch 05 does the same for TXD-
prefixed PS-queue frames (`skb->data[MT_TXD_SIZE]`). Common-path frames
from `ieee80211_tx_dequeue` have the 802.11 header at `skb->data` (same
as `mt76_skb_set_moredata`).
## Phase 6: This tree (5.15.221)
**Step 6.1 — buggy code present?**
Record: **Yes.** `drivers/net/wireless/mediatek/mt76/tx.c`
`mt76_queue_ps_skb()` (lines 344–358) sets only
`IEEE80211_TX_STATUS_EOSP`, not the QoS EOSP bit. Introduced v4.16;
U-APSD AP enabled here since 2020.
`git describe HEAD`: `p-5.15-2-g6703e5d2f3a29`. `make kernelversion`:
**5.15.221**. `git merge-base --is-ancestor 0b8d252471609 HEAD` → **not
present**.
**Step 6.2 — backport difficulty**
Record: **Clean apply.** `git apply --check` succeeded; hunks applied at
offset −69 only because `mt76_txq_dequeue` still uses
`MT_TX_HW_QUEUE_EXT_PHY` here vs `FIELD_PREP(MT_TX_HW_QUEUE_PHY, …)`
upstream. That function is context, not part of the change.
**Step 6.3 — related fixes already here?**
Record: No. Only `7267a7965dd7b` (TX status for the software EOSP flag),
which is exactly the incomplete behavior this commit finishes.
## Phase 7: Subsystem
**Step 7.1**
Record: `drivers/net/wireless/mediatek/mt76` — Wi-Fi driver.
**IMPORTANT** (not core kernel, but widely used: OpenWrt/home routers,
mt76x0/x2/7603/7615/7915/7921).
**Step 7.2**
Record: Mature driver; this PS-release path has been stable since 2017.
Not a bug in brand-new code.
## Phase 8: Impact and risk
**Step 8.1 — who**
Record: Driver/config-specific: `CONFIG_MT76*` AP mode with U-APSD
clients. Large real-world set (MediaTek AP SoCs).
**Step 8.2 — trigger**
Record: Associated STA in power-save using U-APSD (typical phones) sends
a trigger; AP releases buffered QoS data. Not a rare error path.
Unprivileged on the air (associated client). PS-Poll-only clients are
unaffected by the new bit.
**Step 8.3 — failure mode**
Record: **Station downlink stall** until the client gives up the SP. Not
a kernel oops. Severity: **HIGH** (loss of connectivity for that STA),
not CRITICAL (no panic/corruption).
**Step 8.4 — risk/benefit**
Record: Benefit high for mt76 AP + U-APSD clients. Risk very low: ~12
lines, QoS bit only on last U-APSD QoS-data frame, same pattern as
mac80211, clean apply, no API/struct change. Patch 01’s
`ieee80211_txq_aql_pending` is **not** required.
## Phase 9: Synthesis
**Step 9.1 — evidence**
For:
- Real, documented 802.11 bug: missing on-air EOSP → downlink stall
- Code and AP U-APSD flag exist in 5.15.221
- Bug since v4.16
- Maintainer-authored, merged to mainline (`v7.3-rc1`), no revert, no
later rewrite of this function
- 12 insertions / 4 deletions, clean apply
- Matches mac80211
- Standalone despite 04/10 numbering
Against:
- Not crash/security/corruption
- No `Reported-by` / syzbot
- No extra reviewer
- mt7603 hardware PS-queue still wrong without patch 05 (does not make
04 incorrect or unusable)
Unresolved: no independent end-user report found beyond the maintainer’s
analysis.
**Step 9.2 — stable rules**
1. Obviously correct and tested? **PASS** — same as mac80211; in
mainline since v7.3-rc1
2. Real bug affecting users? **PASS** — U-APSD clients on mt76 APs
3. Important? **PASS** — full downlink stall for the STA (HIGH)
4. Small/contained? **PASS** — one file, ~12 lines
5. No new features/APIs? **PASS** — sets a standard 802.11 bit the
driver was already required to set
6. Applies to this tree? **PASS** — `git apply --check` clean
**Step 9.3 — exceptions**
Record: None (not an ID/quirk/DT/build/doc exception). Qualifies as a
normal bugfix.
**Step 9.4 — decision**
This 5.15.221 tree has the buggy path, U-APSD AP support, and every API
the patch needs. The change is a small, self-contained protocol fix for
a serious AP-mode connectivity failure. It should be backported here.
---
### What it solves for 5.15 users
On MediaTek mt76 APs, U-APSD service periods never get the EOSP bit on
the last released QoS frame. mac80211 thinks the SP ended
(`IEEE80211_TX_STATUS_EOSP`), but the client never sees EOSP on the air,
stops triggering, and **downlink to that station stalls**. Setting
`IEEE80211_QOS_CTL_EOSP` on the last U-APSD QoS-data frame is what
mac80211 already documents and implements when the driver does not take
`.release_buffered_frames`.
### Stable rules / risk
Meets all six criteria. Benefit is restoring buffered downlink for
U-APSD clients; risk is a one-bit header update on a path that already
rewrites More Data. No series dependencies for this hunk. mt7603’s
separate PS-queue EOSP bug is a sibling, not a blocker.
### Verification
- [Phase 1] Parsed tags: Link to 04/10, author SOB only; no
Fixes/Reported-by/Cc:stable
- [Phase 1] `git log origin/master --grep='set the EOSP bit' --
drivers/net/wireless/mediatek/mt76/`: `0b8d252471609`
- [Phase 1] `git describe --contains --match 'v*' 0b8d252471609`:
`v7.3-rc1~133^2~99^2~15^2~8`
- [Phase 2] Diff: `mt76_queue_ps_skb` + `reason`; EOSP OR on last U-APSD
QoS-data frame; two call sites
- [Phase 2] Compared to `net/mac80211/sta_info.c:1708` (`*qoshdr |=
IEEE80211_QOS_CTL_EOSP`) — same mechanism
- [Phase 2] Confirmed `include/net/mac80211.h` requires the driver to
set EOSP when `.release_buffered_frames` is implemented
- [Phase 3] `git blame` on `tx.c` 345–403: introduced `17f1de56df0512`
(v4.16-rc1)
- [Phase 3] `git log --grep='EOSP' --
drivers/net/wireless/mediatek/mt76/`: only TX-status EOSP
(`7267a7965dd7b`) in this tree
- [Phase 3] Patch 01 `a547b414bf7ea` does not touch `mt76_queue_ps_skb`
(not a prerequisite)
- [Phase 4] `b4 dig -c 0b8d252471609`: lore URL above; `b4 dig -a`: v1
only; `b4 dig -w`: linux-wireless + author
- [Phase 4] 11-message mbox: no NAK on 04; kbuild error is on 10/10 /
patch 01
- [Phase 4] `curl` stable lore for `mt76 EOSP QoS`: no results
- [Phase 5] Callers: mt76x0/x2, mt7615, mt7915, mt7921 ops; mt7603
wrapper; mac80211 `drv_release_buffered_frames`
- [Phase 5] This tree: `WIPHY_FLAG_AP_UAPSD` and
`ieee80211_sta_uapsd_trigger` in `mt76/mac80211.c`
- [Phase 6] `git describe HEAD`: `p-5.15-2-g6703e5d2f3a29`; `make
kernelversion`: 5.15.221
- [Phase 6] `git merge-base --is-ancestor 0b8d252471609 HEAD`: not in
tree
- [Phase 6] `git apply --check` of 04/10: success, offset −69
- [Phase 6] APIs present: `IEEE80211_QOS_CTL_EOSP` `0x0010`,
`ieee80211_get_qos_ctl`, `ieee80211_is_data_qos`,
`IEEE80211_FRAME_RELEASE_UAPSD`
- [Phase 8] Failure mode: STA downlink stall (HIGH), not oops
- UNVERIFIED: no independent user bugzilla/syzbot report; impact
inferred from protocol + maintainer description
**YES**
drivers/net/wireless/mediatek/mt76/tx.c | 16 ++++++++++++----
1 file changed, 12 insertions(+), 4 deletions(-)
diff --git a/drivers/net/wireless/mediatek/mt76/tx.c b/drivers/net/wireless/mediatek/mt76/tx.c
index 731caeda72b52..93275bb692fa5 100644
--- a/drivers/net/wireless/mediatek/mt76/tx.c
+++ b/drivers/net/wireless/mediatek/mt76/tx.c
@@ -415,16 +415,23 @@ mt76_txq_dequeue(struct mt76_phy *phy, struct mt76_txq *mtxq)
static void
mt76_queue_ps_skb(struct mt76_phy *phy, struct ieee80211_sta *sta,
- struct sk_buff *skb, bool last)
+ struct sk_buff *skb, bool last,
+ enum ieee80211_frame_release_type reason)
{
struct mt76_wcid *wcid = (struct mt76_wcid *)sta->drv_priv;
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+ struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
info->control.flags |= IEEE80211_TX_CTRL_PS_RESPONSE;
- if (last)
+ if (last) {
info->flags |= IEEE80211_TX_STATUS_EOSP |
IEEE80211_TX_CTL_REQ_TX_STATUS;
+ if (reason == IEEE80211_FRAME_RELEASE_UAPSD &&
+ ieee80211_is_data_qos(hdr->frame_control))
+ *ieee80211_get_qos_ctl(hdr) |= IEEE80211_QOS_CTL_EOSP;
+ }
+
mt76_skb_set_moredata(skb, !last);
__mt76_tx_queue_skb(phy, MT_TXQ_PSD, skb, wcid, sta, NULL);
}
@@ -457,14 +464,15 @@ mt76_release_buffered_frames(struct ieee80211_hw *hw, struct ieee80211_sta *sta,
nframes--;
if (last_skb)
- mt76_queue_ps_skb(phy, sta, last_skb, false);
+ mt76_queue_ps_skb(phy, sta, last_skb, false,
+ reason);
last_skb = skb;
} while (nframes);
}
if (last_skb) {
- mt76_queue_ps_skb(phy, sta, last_skb, true);
+ mt76_queue_ps_skb(phy, sta, last_skb, true, reason);
dev->queue_ops->kick(dev, hwq);
} else {
ieee80211_sta_eosp(sta);
--
2.53.0
^ permalink raw reply related [flat|nested] 20+ messages in thread* [PATCH AUTOSEL 6.18-5.10] usb: mtu3: Fix double dereference in TP_printk
2026-10-19 13:44 [PATCH AUTOSEL 6.18-6.12] net: dsa: mt7530: check CORE_PLL_GROUP4 access in mt7531_setup() Sasha Levin
` (2 preceding siblings ...)
2026-10-19 13:46 ` [PATCH AUTOSEL 6.18-5.15] wifi: mt76: set the EOSP bit in the QoS header of the last released frame Sasha Levin
@ 2026-10-19 13:46 ` Sasha Levin
2026-10-19 13:46 ` [PATCH AUTOSEL 6.18] wifi: mt76: wed: fix kernel panic on non-DBDC MT7986 Sasha Levin
` (14 subsequent siblings)
18 siblings, 0 replies; 20+ messages in thread
From: Sasha Levin @ 2026-10-19 13:46 UTC (permalink / raw)
To: patches, stable
Cc: Vladimir Murzin, Paul E. McKenney, Mark Rutland, Steven Rostedt,
Sasha Levin, chunfeng.yun, gregkh, linux-usb, linux-arm-kernel,
linux-mediatek, linux-kernel
From: Vladimir Murzin <vladimir.murzin@arm.com>
[ Upstream commit cfb3293c4573289f11f913611f530ea6b1926d67 ]
Paul reported kernel splat:
[ 0.000000] TRACE EVENT ERROR: Event mtu3_gadget_ep_set_halt has double dereference in TP_printk: &REC->gpd_ring->dma
[ 0.000000] ------------[ cut here ]------------
[ 0.000000] Event mtu3_gadget_ep_set_halt has double dereference in TP_printk: &REC->gpd_ring->dma
[ 0.000000] WARNING: kernel/trace/trace_events.c:420 at test_double_dereference+0x144/0x14c, CPU#0: swapper/0/0
[ 0.000000] Modules linked in:
[ 0.000000] CPU: 0 UID: 0 PID: 0 Comm: swapper/0 Not tainted 7.3.0-rc1 #15247 PREEMPT
[ 0.000000] Hardware name: linux,dummy-virt (DT)
[ 0.000000] pstate: 600000c5 (nZCv daIF -PAN -UAO -TCO -DIT -SSBS BTYPE=--)
[ 0.000000] pc : test_double_dereference+0x144/0x14c
[ 0.000000] lr : test_double_dereference+0x144/0x14c
[ 0.000000] sp : ffffc80aa7633bf0
[ 0.000000] x29: ffffc80aa7633bf0 x28: ffffc80aa7c0f047 x27: 000508b58019388f
[ 0.000000] x26: 0000000000000003 x25: 0000000000000007 x24: ffffc80aa5fceff8
[ 0.000000] x23: ffffc80aa7c0f05a x22: ffffc80aa64edfe8 x21: ffffc80aa7c0fce8
[ 0.000000] x20: ffffc80aa7c0f047 x19: 0000000000000013 x18: 0000000000000001
[ 0.000000] x17: 6572656420656c62 x16: 756f642073616820 x15: 746c61685f746573
[ 0.000000] x14: 0000000000000000 x13: ffff000139d90000 x12: 0000000000000045
[ 0.000000] x11: 00000000000000cf x10: ffff00013f546428 x9 : ffff000139d90000
[ 0.000000] x8 : 3fffffffffffc000 x7 : 0000000000000001 x6 : 0000000000000001
[ 0.000000] x5 : ffff00013f4e6440 x4 : 0000000000000000 x3 : 0000000000000000
[ 0.000000] x2 : 0000000000000000 x1 : 0000000000000000 x0 : ffffc80aa764a700
[ 0.000000] Call trace:
[ 0.000000] test_double_dereference+0x144/0x14c (P)
[ 0.000000] trace_event_raw_init+0x37c/0x5d8
[ 0.000000] event_init+0x34/0xc0
[ 0.000000] trace_event_init+0xec/0x588
[ 0.000000] trace_init+0x24/0x6e0
[ 0.000000] start_kernel+0x4a0/0x8ec
[ 0.000000] __primary_switched+0x88/0x90
[ 0.000000] irq event stamp: 0
[ 0.000000] hardirqs last enabled at (0): [<0000000000000000>] 0x0
[ 0.000000] hardirqs last disabled at (0): [<0000000000000000>] 0x0
[ 0.000000] softirqs last enabled at (0): [<0000000000000000>] 0x0
[ 0.000000] softirqs last disabled at (0): [<0000000000000000>] 0x0
[ 0.000000] ---[ end trace 0000000000000000 ]---
[ 0.000000] TRACE EVENT ERROR: Event mtu3_gadget_ep_disable has double dereference in TP_printk: &REC->gpd_ring->dma
[ 0.000000] TRACE EVENT ERROR: Event mtu3_gadget_ep_enable has double dereference in TP_printk: &REC->gpd_ring->dma
Which also observed by Mark and myself.
The splat it result of new check introduced by b5cc230af5e5 ("tracing:
Warn when an event dereferences a pointer in TP_printk()") which
correctly catches issue with %pad dereferencing the address saved in
the ring buffer. TP_fast_assign() logic gets executed when the
tracepoint is triggered, however the TP_printk() is executed when the
user reads the trace buffer which could be seconds, minutes, hours,
days, even months later and nothing guarantee that __entry->gpd_ring
pointer will still be pointing to what it was when it was recorded.
Fix the issue by capturing immediate value of gpd_ring.dma when trace
point is triggered.
Reported-by: Paul E. McKenney <paulmck@kernel.org>
Tested-by: Mark Rutland <mark.rutland@arm.com>
Reviewed-by: Steven Rostedt <rostedt@goodmis.org>
Signed-off-by: Vladimir Murzin <vladimir.murzin@arm.com>
Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
LLM Generated explanations, may be completely bogus:
## Phase 1: Commit message forensics
**Step 1.1: Subject line**
Record: **[usb/mtu3]** **[Fix]** Double dereference in `TP_printk` for
the `mtu3_log_ep` trace class
(`mtu3_gadget_ep_enable/disable/set_halt`).
**Step 1.2: Tags**
Record:
- **Reported-by:** Paul E. McKenney
- **Tested-by:** Mark Rutland
- **Reviewed-by:** Steven Rostedt (tracing maintainer)
- **Signed-off-by:** Vladimir Murzin (author); Paul E. McKenney (merged
via his tree)
- **No Fixes:** tag (expected for this review)
- **No Cc: stable** (expected)
- No syzbot, no CVE, no bugzilla Link
- Ignore pipeline “Upstream commit” / Sasha Levin SOB
Notable: three independent observers (Paul, Mark, the author). Rostedt
reviewed it.
**Step 1.3: Body**
Record:
- **Bug:** `TP_printk` uses `%pad` with `&REC->gpd_ring->dma`, i.e. it
follows a pointer stored in the ring buffer when the trace is printed,
not when it is recorded.
- **Symptom that motivated the patch:** boot `WARNING` in
`test_double_dereference()` on 7.3.0-rc1 (`linux,dummy-virt`), events
`mtu3_gadget_ep_set_halt/disable/enable`.
- **Root cause (author):** check added by `b5cc230af5e5` (“tracing: Warn
when an event dereferences a pointer in TP_printk()”).
`TP_fast_assign()` runs at the tracepoint; `TP_printk()` can run much
later, when `__entry->gpd_ring` may be stale.
- **Fix:** snapshot `mep->gpd_ring.dma` into a `dma_addr_t` field at
assign time and print `&__entry->gpd_ring_dma`.
- **Versions in the message:** 7.3.0-rc1 only. Mailing list later says
the splat was still present in 7.3-rc5/rc6.
Linus’s merge of `8fc6e594884a` describes the same bug as pre-existing:
it can dump garbage traces because `TP_printk()` may run after the
pointed-to memory is gone. Extra tracing checks only **exposed** it.
**Step 1.4: Hidden bug fix?**
Record: Not hidden. It is an explicit tracing UAF/stale-pointer fix. The
boot WARN is how it was found; the real defect is delayed dereference of
a saved kernel pointer.
---
## Phase 2: Diff analysis
**Step 2.1: Inventory**
Record:
- File: `drivers/usb/mtu3/mtu3_trace.h` only (+3 / −1; 4-line class)
- Function/class: `DECLARE_EVENT_CLASS(mtu3_log_ep)` (shared by
`mtu3_gadget_ep_enable`, `mtu3_gadget_ep_disable`,
`mtu3_gadget_ep_set_halt`)
- Scope: single-file surgical tracing fix
**Step 2.2: Code flow**
Record: **Before:** `TP_fast_assign` stores `__entry->gpd_ring =
&mep->gpd_ring`. `TP_printk` prints `%p/%pad` with `__entry->gpd_ring,
&__entry->gpd_ring->dma`. **After:** also stores `__entry->gpd_ring_dma
= mep->gpd_ring.dma` and prints `&__entry->gpd_ring_dma`. Affected path
is trace **print**, not gadget I/O.
Verified in this tree’s `lib/vsprintf.c` `address_val()`: `%pad` does
`*(const dma_addr_t *)addr`. The old argument therefore both follows
`gpd_ring` and then dereferences `.dma`.
**Step 2.3: Bug mechanism**
Record: **Memory safety / delayed pointer dereference in tracing (UAF or
garbage).** `%p` of the saved pointer is safe; `%pad` is not. `gpd_ring`
is embedded in `struct mtu3_ep` (`mtu3.h`). `mtu3_gpd_ring_free()`
`memset`s the ring on disable; the `mtu3_ep` itself is freed on unbind.
Reading traces after unbind is a use-after-free. Reading after disable
but before unbind can print a later (zeroed) DMA address instead of the
recorded one.
**Step 2.4: Fix quality**
Record: Obviously correct and minimal. `%pad` still gets a `dma_addr_t
*`, now into the ring-buffer entry. The missing semicolon on the new
assign is harmless: `TP_fast_assign` is expanded with a trailing `;`. No
API/locking/hot-path change. Regression risk is very low. The leftover
`__field(struct mtu3_gpd_ring *, gpd_ring)` is still only printed with
`%p`.
---
## Phase 3: Git history
**Step 3.1: Blame**
Record: Buggy `mtu3_log_ep` pattern comes from `83374e035b628` (“usb:
mtu3: add tracepoints to help debug”, Chunfeng Yun, 2019-03-21). Present
in this tree (`git merge-base --is-ancestor 83374e035b628 HEAD`
succeeded). Long-lived, not recent code.
**Step 3.2: Fixes: tag**
Record: None on the merged commit. An earlier unused submission
(Shixiong Ou, 2026-08-28) tagged `Fixes: 83374e035b62`. That introducing
commit **is** in this tree.
**Step 3.3: File history**
Record (path-limited log):
- `83374e035b628` add tracepoints
- later style/`__vstring`/`__assign_str` churn
- this fix
Standalone; not patch X/Y. No prerequisite refactor in this file beyond
what 6.18 already has (`__assign_str(name)` without a second argument is
already here).
**Step 3.4: Author**
Record: Vladimir Murzin is not the mtu3 maintainer (that is Chunfeng
Yun, CC’d). He is an ARM engineer fixing a splat he, Paul, and Mark hit.
Rostedt reviewed. Paul merged it when USB maintainers were slow (splat
still in 7.3-rc6).
**Step 3.5: Dependencies**
Record: None. Uses existing `dma_addr_t`, `TP_*`, and
`mep->gpd_ring.dma`. No new tracing helpers. `b5cc230af5e5` is the
detector, **not** a prerequisite for the fix.
---
## Phase 4: Mailing list / external
**Step 4.1: Original discussion**
Record:
- `b4 dig -c cfb3293c4573289f11f913611f530ea6b1926d67` → https://patch.m
sgid.link/20260922103756.104846-1-vladimir.murzin@arm.com
- `b4 dig -a`: single revision (v1 only)
- Thread: ping for 7.3-rc5/rc6 splat; Paul offered to merge because the
WARN broke his tests; later merged and Linus pulled it
- No NAK. No reviewer asked for `Cc: stable`
- lore.kernel.org fetch returned 403; thread recovered via `b4 dig -m`
**Step 4.2: Recipients (`b4 dig -w`)**
Record: linux-usb, linux-arm-kernel, linux-mediatek, linux-kernel,
Chunfeng Yun, Greg KH, Steven Rostedt, Paul McKenney, Mark Rutland.
Right lists and maintainers.
**Step 4.3: Bug report**
Record: Reproduced by Paul, Mark, and Vladimir on 7.3-rc1+ (dummy-virt).
Independent earlier patch from Shixiong Ou describes the same WARN and
the same stale-pointer/UAF. Severity for **those** kernels is a boot
WARN whenever `CONFIG_USB_MTU3` is built. That WARN is **not** in
6.18.y.
**Step 4.4: Series**
Record: Standalone. Duplicate independently submitted by Shixiong Ou
(same approach, field named `gpd_dma`). Murzin’s version is what merged.
**Step 4.5: Stable list**
Record: No useful hit on lore stable for this subject. Not a documented
“do not backport.”
---
## Phase 5: Semantic / call graph
**Step 5.1: Functions**
Record: `mtu3_log_ep` class; events `mtu3_gadget_ep_enable`,
`mtu3_gadget_ep_disable`, `mtu3_gadget_ep_set_halt`.
**Step 5.2: Callers**
Record (this tree):
- `mtu3_gadget_ep_enable()` — `drivers/usb/mtu3/mtu3_gadget.c:202`
- `mtu3_gadget_ep_disable()` — line 214 (before `mtu3_ep_disable()` /
`mtu3_gpd_ring_free()`)
- `mtu3_gadget_ep_set_halt()` — line 404
These are USB gadget ep ops: enable/disable/halt from gadget drivers /
configfs. Common on MediaTek gadget/OTG, not a syscall of its own.
**Step 5.3: Callees**
Record: TRACE_EVENT assign/print only. No alloc/lock/I/O in the changed
code. `%pad` → `address_val()` → dereference `dma_addr_t *`.
**Step 5.4: Reachability**
Record: Recording: gadget ep enable/disable/halt with these events on.
Printing: reading the trace buffer. UAF: print after `mtu3_ep` is freed
(driver unbind). Boot WARN: only if `test_double_dereference()` exists
(it does not here). Unprivileged users normally cannot enable tracefs.
**Step 5.5: Similar patterns**
Record: Other mtu3 events print saved pointers with `%p` only (safe).
Same class already in this 6.18.y tree: `0b0d2f9db2406` (“eth: ice:
don't dereference pointers from TP_printk()”), also written against
`b5cc230af5e5`, and it **is** an ancestor of `v6.18.57`.
---
## Phase 6: This checkout only
**Step 6.1: Does the buggy code exist?**
Record: **Yes, in v6.18.57.** `git describe HEAD` →
`v6.18.57-155-gcdf239ca885b2`; `make kernelversion` → **6.18.57**.
v6.18.57 `mtu3_trace.h` still has `__entry->gpd_ring,
&__entry->gpd_ring->dma`. Introduced 2019. `git merge-base --is-ancestor
dff6c93cf7131 v6.18.57` failed (fix not in 6.18.57).
`test_double_dereference` is **absent** from `kernel/trace/`
(`b5cc230af5e5` is not an ancestor of HEAD).
**Step 6.2: Backport difficulty**
Record: **Clean apply.** `git diff v6.18.57 dff6c93cf7131 --
drivers/usb/mtu3/mtu3_trace.h` is exactly this 4-line change. Context
matches 6.18 (`__assign_str(name)` already present).
**Step 6.3: Related fix already here?**
Record: No other mtu3 `TP_printk` fix in `v6.18..v6.18.57`. The ice
analogue **is** already in 6.18.57. That does not replace this mtu3 bug.
---
## Phase 7: Subsystem context
**Step 7.1**
Record: **drivers/usb/mtu3** — MediaTek USB3 dual-role. Criticality:
**PERIPHERAL/IMPORTANT for MTK** (`CONFIG_USB_MTU3`, `depends on
ARCH_MEDIATEK || COMPILE_TEST`). Tracepoints compiled with the driver
when `CONFIG_TRACEPOINTS` is on.
**Step 7.2**
Record: Mature driver (tracepoints since 2019). Recent 6.18.y mtu3 fixes
include DMA unmap on queue failure and suspend-with-gadget. Not staging.
---
## Phase 8: Impact and risk
**Step 8.1: Who is affected**
Record: MediaTek USB3 gadget users who enable these ftrace events and
later print the buffer. Distro kernels that build mtu3 for
`COMPILE_TEST` do **not** get the 7.3 boot WARN here, because that check
is missing.
**Step 8.2: Trigger**
Record: Not every boot on 6.18.y. Needs `CONFIG_USB_MTU3` + tracepoints
+ enable these events + later print. UAF additionally needs the
endpoint/device object to have been freed. Not unprivileged. The 7.3
boot WARN fires even on dummy-virt; **that path does not exist in this
tree**.
**Step 8.3: Failure mode**
Record:
- On 7.3+: boot `WARNING` — **does not apply to 6.18.57**
- On this tree: delayed deref → **garbage DMA address in traces**, or
**UAF/oops** if `mtu3_ep` was freed — severity **HIGH** when hit,
**MEDIUM** overall because the trigger is a debug path
**Step 8.4: Risk vs benefit**
Record: **Benefit:** closes a real stale-pointer/UAF in mtu3 gadget
traces; same class already taken for ice on this series. **Risk:** very
low (3 insertions, print-time only). Ratio favors backport.
---
## Phase 9: Synthesis
**Step 9.1: Evidence**
For:
- Real delayed dereference of a kernel pointer from the trace buffer
(`%pad` confirmed to dereference)
- Buggy code present in this 6.18.y tree since 2019
- Small, obviously correct, applies cleanly
- Reviewed by Rostedt; reported/tested by McKenney and Rutland
- Same class (`TP_printk` must not follow saved pointers) already in
v6.18.57 for ice
- No new API/feature; no series dependency
Against:
- The boot splat that drove the patch **cannot happen here**
(`test_double_dereference` / `b5cc230af5e5` not in 6.18.y)
- Debug/tracing path, MediaTek-specific, needs events enabled
- Failure is often wrong trace text rather than a production USB failure
- No `Cc: stable` in review (not a negative per the rules)
Unresolved: lore.kernel.org HTTP 403 (thread read from `b4` mbox
instead).
**Step 9.2: Stable rules**
1. Obviously correct and tested? **PASS** (Rostedt Reviewed-by, Mark
Tested-by, logic is local)
2. Real bug that affects users? **PASS** (stale pointer / UAF when
traces are printed)
3. Important (crash/security/corruption/deadlock)? **PASS** (UAF/oops
possible on print after free; garbage traces otherwise). The 7.3 boot
WARN is not the important part **for this tree**.
4. Small and contained? **PASS** (one header, 4 lines)
5. No new features/APIs? **PASS**
6. Can apply to this tree? **PASS** (clean vs v6.18.57)
**Step 9.3: Exception category**
Record: None (not a device ID/quirk/DT/build/docs exception). It is a
normal small bugfix.
**Step 9.4: Decision**
The 7.3 boot WARN is not a reason to take this on 6.18.y. The reason to
take it is the pre-existing `TP_printk` dereference, which **is** in
this tree, is a real UAF/garbage-print bug, is a 4-line no-brainer, and
matches a fix this series already accepted for ice.
---
## What this means for 6.18.y users
`mtu3_log_ep` stores `&mep->gpd_ring` and later does `%pad` on
`&gpd_ring->dma`. Print can happen long after disable/unbind. That is a
real bug in this tree. The patch only snapshots `gpd_ring.dma` at event
time. It does not change gadget behavior.
## Verification
- **[Phase 1]** Parsed tags: Reported-by Paul McKenney, Tested-by Mark
Rutland, Reviewed-by Steven Rostedt; no Fixes/Cc-stable
- **[Phase 2]** Diff: +`gpd_ring_dma` field, assign `mep->gpd_ring.dma`,
print `&__entry->gpd_ring_dma`
- **[Phase 2]** `%pad` in `lib/vsprintf.c` `address_val()`: `num =
*(const dma_addr_t *)addr`
- **[Phase 2]** `struct mtu3_ep` has embedded `struct mtu3_gpd_ring
gpd_ring`; `mtu3_gpd_ring_free()` memsets it
- **[Phase 3]** Blame: `83374e035b628` (2019) introduced the pattern;
ancestor of HEAD
- **[Phase 3]** `git merge-base --is-ancestor b5cc230af5e5 HEAD` failed;
no `test_double_dereference` in this tree
- **[Phase 3]** Author log on `drivers/usb/`: this commit plus unrelated
xhci work
- **[Phase 4]** `b4 dig -c cfb3293c4573`: msgid
`20260922103756.104846-1-vladimir.murzin@arm.com`; v1 only
- **[Phase 4]** `b4 dig -w`: USB/Mediatek lists, Greg KH, Chunfeng Yun,
Rostedt
- **[Phase 4]** mbox: Paul merged after 7.3-rc5/rc6 pings; no NAK; no
stable nomination
- **[Phase 4]** UNVERIFIED: live lore.kernel.org page (403)
- **[Phase 5]** Callers: `mtu3_gadget_ep_enable/disable/set_halt` in
`mtu3_gadget.c`
- **[Phase 6]** `git describe HEAD` = v6.18.57-155-gcdf239ca885b2;
kernelversion 6.18.57
- **[Phase 6]** v6.18.57 still has `&__entry->gpd_ring->dma`; fix not an
ancestor of v6.18.57
- **[Phase 6]** File diff vs v6.18.57 is exactly this patch (clean)
- **[Phase 6]** ice TP_printk analogue `0b0d2f9db2406` **is** in
v6.18.57
- **[Phase 8]** Boot WARN not reachable here; UAF/garbage on delayed
print is
The fix is small, correct, already matches this tree’s context, and
closes a real tracing UAF, not a 7.3-only WARN.
**YES**
drivers/usb/mtu3/mtu3_trace.h | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/usb/mtu3/mtu3_trace.h b/drivers/usb/mtu3/mtu3_trace.h
index 89870175d6356..9aaa167d69c13 100644
--- a/drivers/usb/mtu3/mtu3_trace.h
+++ b/drivers/usb/mtu3/mtu3_trace.h
@@ -224,6 +224,7 @@ DECLARE_EVENT_CLASS(mtu3_log_ep,
__field(unsigned int, flags)
__field(unsigned int, direction)
__field(struct mtu3_gpd_ring *, gpd_ring)
+ __field(dma_addr_t, gpd_ring_dma)
),
TP_fast_assign(
__assign_str(name);
@@ -235,12 +236,13 @@ DECLARE_EVENT_CLASS(mtu3_log_ep,
__entry->flags = mep->flags;
__entry->direction = mep->is_in;
__entry->gpd_ring = &mep->gpd_ring;
+ __entry->gpd_ring_dma = mep->gpd_ring.dma
),
TP_printk("%s: type %s maxp %d slot %d mult %d burst %d ring %p/%pad flags %c:%c%c%c:%c",
__get_str(name), usb_ep_type_string(__entry->type),
__entry->maxp, __entry->slot,
__entry->mult, __entry->maxburst,
- __entry->gpd_ring, &__entry->gpd_ring->dma,
+ __entry->gpd_ring, &__entry->gpd_ring_dma,
__entry->flags & MTU3_EP_ENABLED ? 'E' : 'e',
__entry->flags & MTU3_EP_STALL ? 'S' : 's',
__entry->flags & MTU3_EP_WEDGE ? 'W' : 'w',
--
2.53.0
^ permalink raw reply related [flat|nested] 20+ messages in thread* [PATCH AUTOSEL 6.18] wifi: mt76: wed: fix kernel panic on non-DBDC MT7986
2026-10-19 13:44 [PATCH AUTOSEL 6.18-6.12] net: dsa: mt7530: check CORE_PLL_GROUP4 access in mt7531_setup() Sasha Levin
` (3 preceding siblings ...)
2026-10-19 13:46 ` [PATCH AUTOSEL 6.18-5.10] usb: mtu3: Fix double dereference in TP_printk Sasha Levin
@ 2026-10-19 13:46 ` Sasha Levin
2026-10-19 13:47 ` [PATCH AUTOSEL 6.18] soc: mediatek: add missing MODULE_DEVICE_TABLE() Sasha Levin
` (13 subsequent siblings)
18 siblings, 0 replies; 20+ messages in thread
From: Sasha Levin @ 2026-10-19 13:46 UTC (permalink / raw)
To: patches, stable
Cc: Zhi-Jun You, Felix Fietkau, Sasha Levin, lorenzo, ryder.lee,
matthias.bgg, angelogioacchino.delregno, linux-wireless,
linux-kernel, linux-arm-kernel, linux-mediatek
From: Zhi-Jun You <hujy652@gmail.com>
[ Upstream commit 8a177dabeeead47dda4d4f91331282790eed0097 ]
In mt76_wed_init_rx_buf, it's hardcoded to use MT_RXQ_MAIN.
But for non-DBDC MT7986 MT_RXQ_BAND1 is used for RX data queue which
leads to kernel panic when attaching WED.
Use the correct RX queue by checking WED version and band_idx.
v2 and band 1 -> MT_RXQ_BAND1
Others -> MT_RXQ_MAIN
Kernel panic:
Unable to handle kernel access to user memory outside uaccess routines at virtual address 0000000000000000
Mem abort info:
ESR = 0x0000000096000005
EC = 0x25: DABT (current EL), IL = 32 bits
SET = 0, FnV = 0
EA = 0, S1PTW = 0
FSC = 0x05: level 1 translation fault
Data abort info:
ISV = 0, ISS = 0x00000005, ISS2 = 0x00000000
CM = 0, WnR = 0, TnD = 0, TagAccess = 0
GCS = 0, Overlay = 0, DirtyBit = 0, Xs = 0
Internal error: Oops: 0000000096000005 [#1] SMP
CPU: 1 UID: 0 PID: 925 Comm: kmodloader Tainted: G O 6.18.26 #0 NONE
Tainted: [O]=OOT_MODULE
Hardware name: Acer Connect Vero W6m (DT)
pstate: 40400005 (nZcv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--)
pc : page_pool_alloc_frag_netmem+0x1c/0x1bc
lr : page_pool_alloc_frag+0xc/0x34
sp : ffffffc081dab660
x29: ffffffc081dab660 x28: ffffffc081dabc60 x27: ffffff80091af040
x26: 0000008000000000 x25: ffffff80091a8898 x24: ffffff80091a5440
x23: 0000000000001000 x22: 0000000140000000 x21: ffffff80091a2040
x20: ffffff8003f1d780 x19: 0000000000000000 x18: 0000000000000020
x17: ffffffbfbf0ac000 x16: ffffffc080ee0000 x15: ffffff80049d47ca
x14: 000000000000037b x13: 000000000000037b x12: 0000000000000001
x11: 0000000000000000 x10: 0000000000000000 x9 : 0000000000000000
x8 : ffffff8003f1d7c0 x7 : 0000000000000000 x6 : ffffff8003f1d780
x5 : 0000000000000680 x4 : 0000000000000000 x3 : 0000000000002824
x2 : 0000000000000000 x1 : ffffffc081dab71c x0 : 0000000000000000
Call trace:
page_pool_alloc_frag_netmem+0x1c/0x1bc (P)
page_pool_alloc_frag+0xc/0x34
mt76_wed_init_rx_buf+0xf8/0x2ac [mt76]
mtk_wed_start+0x79c/0x12ac
mt7915_dma_start+0x274/0x63c [mt7915e]
mt7915_dma_start+0x5b4/0x63c [mt7915e]
mt7915_dma_init+0x49c/0x81c [mt7915e]
mt7915_register_device+0x24c/0x530 [mt7915e]
mt7915_mmio_probe+0x91c/0x1980 [mt7915e]
platform_probe+0x58/0xa0
really_probe+0xb8/0x2a8
__driver_probe_device+0x74/0x118
driver_probe_device+0x3c/0xe0
__driver_attach+0x88/0x154
bus_for_each_dev+0x60/0xb0
driver_attach+0x20/0x28
bus_add_driver+0xdc/0x200
driver_register+0x64/0x118
__platform_driver_register+0x20/0x30
init_module+0x74/0x1000 [mt7915e]
do_one_initcall+0x4c/0x1f8
do_init_module+0x50/0x210
load_module+0x15f8/0x1b10
__do_sys_init_module+0x1a8/0x260
__arm64_sys_init_module+0x18/0x20
invoke_syscall.constprop.0+0x4c/0xd0
do_el0_svc+0x3c/0xd0
el0_svc+0x18/0x60
el0t_64_sync_handler+0x98/0xdc
el0t_64_sync+0x158/0x15c
Code: aa0003f3 a9025bf5 a90363f7 d2820017 (b9400000)
Signed-off-by: Zhi-Jun You <hujy652@gmail.com>
Link: https://patch.msgid.link/20260715152113.553-1-hujy652@gmail.com
Signed-off-by: Felix Fietkau <nbd@nbd.name>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
LLM Generated explanations, may be completely bogus:
This tree is **6.6.157** (`pending-6.6`). The panic is real here, but
the mainline patch has to be rewritten onto `mt7915/mmio.c` because
`wed.c` does not exist yet.
===============================================================
PHASE 1: COMMIT MESSAGE FORENSICS
===============================================================
**Step 1.1: PARSE THE SUBJECT LINE**
Record: `[wifi: mt76: wed:] [fix] [kernel panic on non-DBDC MT7986 when
attaching WED because RX buf init used the wrong queue]`
**Step 1.2: PARSE ALL COMMIT MESSAGE TAGS**
Record:
- `Signed-off-by: Zhi-Jun You <hujy652@gmail.com>` (author)
- `Link:
https://patch.msgid.link/20260715152113.553-1-hujy652@gmail.com` (v2
1/2 of a 2-patch series)
- `Signed-off-by: Felix Fietkau <nbd@nbd.name>` (mt76 maintainer)
- No `Fixes:` tag (expected for this review)
- No `Cc: stable@vger.kernel.org` (expected)
- No `Reported-by:` / `Tested-by:` / `Reviewed-by:` / `Acked-by:`
- Sibling patch 2/2 has the same msgid stem `20260715152113.553-2` and
**is already in this 6.6 tree** as `8eae5e5aa09da` (`wifi: mt76:
mt7915: fix net_fill_forward_path for non-DBDC mt7986`)
**Step 1.3: ANALYZE THE COMMIT BODY TEXT**
Record:
- **Bug:** `mt76_wed_init_rx_buf` always uses `MT_RXQ_MAIN`. Non-DBDC
MT7986 uses `MT_RXQ_BAND1` for the RX data queue.
- **Symptom:** NULL deref oops while attaching WED, in
`page_pool_alloc_frag_netmem`. Full oops from **Acer Connect Vero
W6m**, kernel 6.18.26, PID `kmodloader` during `mt7915e` probe.
- **Root cause:** wrong RX queue → uninitialized `page_pool` (NULL) →
fault at `page_pool_alloc_frag*`.
- **Fix:** `wed->version == 2 && dev->phy.band_idx` → `MT_RXQ_BAND1`,
else `MT_RXQ_MAIN`.
- Crash taint includes `O` (OOT module), but the call trace is in-tree
`mt76` / `mt7915e` / `mtk_wed_start`.
**Step 1.4: DETECT HIDDEN BUG FIXES**
Record: Not hidden. Explicit panic fix with a stack trace. Not
cleanup/refactor.
===============================================================
PHASE 2: DIFF ANALYSIS - LINE BY LINE
===============================================================
**Step 2.1: INVENTORY THE CHANGES**
Record:
- File: `drivers/net/wireless/mediatek/mt76/wed.c` (+6 / −1)
- Function: `mt76_wed_init_rx_buf`
- Scope: single-file, surgical (~5 lines of logic)
**Step 2.2: UNDERSTAND THE CODE FLOW CHANGE**
Record:
- **Before:** `q = &dev->q_rx[MT_RXQ_MAIN]` always, then
`mt76_get_page_pool_buf(q, ...)`.
- **After:** pick `MT_RXQ_BAND1` for WED v2 + band 1; otherwise
`MT_RXQ_MAIN`.
- Path: WED RX buffer init during `mtk_wed_start` from
`mt7915_dma_start` (probe / DMA start), not a rare error path.
**Step 2.3: IDENTIFY THE BUG MECHANISM**
Record:
- Category: **NULL pointer dereference** (memory safety) from **wrong-
queue logic**.
- Mechanism: for non-DBDC MT7986, `mt7915_band_config` sets `band_idx =
1` and DMA only allocates `q_rx[MT_RXQ_BAND1]`. `MT_RXQ_MAIN` is left
with `page_pool == NULL`. `mt76_get_page_pool_buf` →
`page_pool_dev_alloc_frag(NULL)` → oops.
**Step 2.4: ASSESS THE FIX QUALITY**
Record:
- Obviously correct given DMA queue allocation in `mt7915/dma.c`.
- Minimal; no API/locking/refcount changes.
- Regression risk low: DBDC and band-0 devices still use `MT_RXQ_MAIN`.
- Backport caveat: in 6.6 the same logic lives in
`mt7915_mmio_wed_init_rx_buf` (`dev` is `struct mt7915_dev *`), so the
condition must use `dev->mt76.phy.band_idx` (or
`dev->phy.mt76->band_idx`), not `dev->phy.band_idx`.
===============================================================
PHASE 3: GIT HISTORY INVESTIGATION
===============================================================
**Step 3.1: BLAME THE CHANGED LINES**
Record:
- Hardcoded `MT_RXQ_MAIN` in 6.6: `mt7915/mmio.c:635`, from
`2f5c3c77fc9b6` (`wifi: mt76: switch to page_pool allocator`,
2023-02-03). Present in this tree.
- WED RX itself: `4f831d18d12da` (`wifi: mt76: mt7915: enable WED RX
support`, 2022-12-01). Present.
- MT7986 one-A-die `band_idx = 1`: `mt7915_band_config` in `init.c`.
Present.
**Step 3.2: FOLLOW THE FIXES: TAG**
Record: No `Fixes:` tag. Bug is the hardcoded MAIN queue vs MT7986
band-1 mapping, present since WED RX + page_pool.
**Step 3.3: CHECK FILE HISTORY FOR RELATED CHANGES**
Record:
- `wed.c` added later by `8a7386e787ef4` (`wifi: mt76: move wed common
utilities in wed.c`, 2024-02-22). **Not in pending-6.6** (`git merge-
base --is-ancestor` → not ancestor).
- Related 6.6 history: WED enable for MT7986, WED RX, page_pool switch,
several WED robustness fixes.
**Step 3.4: CHECK THE AUTHOR'S OTHER COMMITS**
Record:
- Author is not the mt76 maintainer; maintainer Felix Fietkau signed
off.
- Same author, same series date: `8eae5e5aa09da` already on pending-6.6
(patch 2/2).
- Felix has many mt7915/WED fixes on this branch.
**Step 3.5: CHECK FOR DEPENDENT/PREREQUISITE COMMITS**
Record:
- Standalone logic; does **not** need the `wed.c` move.
- Needed in 6.6: `wed->version` (exists, `u8 version` in
`mtk_wed_device`), `phy.band_idx`, `MT_RXQ_BAND1`, page_pool RX — all
present.
- Series 1/2; 2/2 is independent (forward-path queue) and already
applied.
===============================================================
PHASE 4: MAILING LIST AND EXTERNAL RESEARCH
===============================================================
**Step 4.1: FIND THE ORIGINAL PATCH DISCUSSION**
Record:
- `b4 dig` on sibling `8eae5e5aa09da` matched msgid
`20260715152113.553-*`.
- RFC (2026-06-13): “single band MT7986”
- v1 (2026-06-30):
https://patch.msgid.link/20260630150649.1629-1-hujy652@gmail.com (and
1629-2)
- v2 (2026-07-15, applied):
https://patch.msgid.link/20260715152113.553-1-hujy652@gmail.com
- v2 1/2 is the committed version. Change vs RFC: “single band” → “non-
DBDC”.
- lore.kernel.org fetches returned 403; thread text confirmed via
ratatoskr mirrors.
- No NAK found. Merged by Felix Fietkau (2026-07-31) as `8a177dabeeead`.
**Step 4.2: CHECK WHO REVIEWED THE PATCH**
Record (`b4 dig -w` on sibling): Zhi-Jun You; Felix Fietkau
(`nbd@nbd.name`); Lorenzo Bianconi; Ryder Lee / Shayne Chen / Sean Wang
(MediaTek); `linux-wireless`; `linux-mediatek`; Benjamin Larsson
(Suggested-by on 2/2). Maintainer merged it.
**Step 4.3: SEARCH FOR THE BUG REPORT**
Record: No syzbot/bugzilla. Concrete oops from Acer Connect Vero W6m
(MT7986). Real hardware, probe-time crash with WED.
**Step 4.4: CHECK FOR RELATED PATCHES AND SERIES**
Record: 2-patch v2 series. 1/2 = this panic. 2/2 =
`net_fill_forward_path` wrong WDMA queue; already in 6.6. Independent;
1/2 is the crash fix.
**Step 4.5: CHECK STABLE MAILING LIST HISTORY**
Record: lore.kernel.org/stable returned 403. **UNVERIFIED** whether
anyone mailed stable@. 2/2 of the same series is already in this 6.6
tree, so the series is treated as 6.6-relevant.
===============================================================
PHASE 5: CODE SEMANTIC ANALYSIS
===============================================================
**Step 5.1: IDENTIFY KEY FUNCTIONS IN THE DIFF**
Record: Mainline `mt76_wed_init_rx_buf`. In this tree:
`mt7915_mmio_wed_init_rx_buf`.
**Step 5.2: TRACE CALLERS**
Record:
- Assigned as `wed->wlan.init_rx_buf` in `mt7915_mmio_wed_init`.
- Called from `mtk_wed_rx_buffer_alloc` → `dev->wlan.init_rx_buf(dev,
dev->wlan.rx_npkt)` (`mtk_wed.c`).
- That runs from `mtk_wed_start` ← `mt7915_dma_start` ←
`mt7915_dma_init` ← `mt7915_register_device` ← probe.
- Reachable on device probe when WED is attached (`wed_enable` module
param).
**Step 5.3: TRACE CALLEES**
Record: `mt76_get_rxwi`, `mt76_get_page_pool_buf` →
`page_pool_dev_alloc_frag(q->page_pool)`, `mt76_rx_token_consume`. First
page_pool alloc is the crash site.
**Step 5.4: FOLLOW THE CALL CHAIN**
Record:
```
module load mt7915e
→ mt7915_mmio_probe / register_device
→ mt7915_dma_init → mt7915_dma_start
→ mtk_wed_device_start → mtk_wed_rx_buffer_alloc
→ mt7915_mmio_wed_init_rx_buf
→ mt76_get_page_pool_buf(uninitialized MT_RXQ_MAIN)
→ oops
```
Userspace-reachable via loading the driver (typically root). Not a
syscall fuzz path; it is a boot/probe crash on affected hardware.
**Step 5.5: SEARCH FOR SIMILAR PATTERNS**
Record: `mt7915/testmode.c` already uses `q = phy->mt76->band_idx ?
MT_RXQ_BAND1 : MT_RXQ_MAIN`. DMA init uses the same band_idx split. Same
author’s 2/2 fixes the matching forward-path mistake.
===============================================================
PHASE 6: CROSS-REFERENCING AGAINST THE LOCAL TREE
===============================================================
**Step 6.1: DOES THE BUGGY CODE EXIST IN THIS TREE?**
Record: **Yes.** Tree is 6.6.157 (`pending-6.6`). `wed.c` is absent.
Equivalent bug:
```
mt7915_mmio_wed_init_rx_buf:
q = &dev->mt76.q_rx[MT_RXQ_MAIN]; /* mmio.c:635 */
```
`mt7915_dma.c`: allocate `MT_RXQ_MAIN` only if
`!dev->phy.mt76->band_idx`; allocate `MT_RXQ_BAND1` if `dbdc_support ||
band_idx`. `mt7915_band_config` sets `band_idx = 1` for MT7986 one-A-die
(non-DBDC). Introduced with WED RX + page_pool (2022–2023), well before
6.6.
`git merge-base --is-ancestor 8a177dabeeead pending-6.6` → **not
present**.
**Step 6.2: CHECK FOR BACKPORT COMPLICATIONS**
Record: **Needs a small backport**, not a clean apply. Same if/else in
`mt7915/mmio.c`, with `dev->mt76.phy.band_idx` /
`dev->phy.mt76->band_idx`. `wed->version` exists and is set to 2 for
non-netsys-v1 (MT7986) in `mtk_wed.c`. Minor conflict, not a rewrite.
**Step 6.3: CHECK IF RELATED FIXES ARE ALREADY HERE**
Record: No equivalent RX-buf queue selection. 2/2 (`8eae5e5aa09da`) is
here and addresses the same hardware mapping, not this NULL deref.
===============================================================
PHASE 7: SUBSYSTEM AND MAINTAINER CONTEXT
===============================================================
**Step 7.1: IDENTIFY THE SUBSYSTEM AND ITS CRITICALITY**
Record: `drivers/net/wireless/mediatek/mt76` + MediaTek WED.
**IMPORTANT** (common Filogic/MT7986 WiFi, OpenWrt/embedded), not core
mm/VFS.
**Step 7.2: ASSESS SUBSYSTEM ACTIVITY**
Record: Mature and actively fixed on 6.6 (WED null-ptr, register
mapping, MT7981, chainmask for non-DBDC band 1).
===============================================================
PHASE 8: IMPACT AND RISK ASSESSMENT
===============================================================
**Step 8.1: DETERMINE WHO IS AFFECTED**
Record: Driver-specific: MT7986 (and similar mt798x) **non-DBDC**
(single A-die) with `CONFIG_NET_MEDIATEK_SOC_WED` and `wed_enable`. Real
product: Acer Connect Vero W6m. Default `wed_enable` is false, but WED
is used on these SoCs.
**Step 8.2: DETERMINE THE TRIGGER CONDITIONS**
Record: Every probe with WED attached on that SKU. Not a race. Needs
privilege to load the module; typical as a platform driver at boot.
**Step 8.3: DETERMINE THE FAILURE MODE SEVERITY**
Record: Kernel oops/panic on WiFi/WED attach. **CRITICAL** for those
devices (WiFi unusable; can panic the box).
**Step 8.4: CALCULATE RISK-BENEFIT RATIO**
Record:
- **Benefit:** high for MT7986 non-DBDC + WED (prevents probe oops).
- **Risk:** low (5-line queue index; other SKUs unchanged).
- **Ratio:** benefit ≫ risk. Backport must retarget `mmio.c`.
===============================================================
PHASE 9: FINAL SYNTHESIS
===============================================================
**Step 9.1: COMPILE THE EVIDENCE**
FOR:
- Documented oops: NULL `page_pool` in WED RX init.
- Same bug in this tree (`mt7915_mmio_wed_init_rx_buf` + DMA not
allocating MAIN when `band_idx == 1`).
- Small, obviously correct queue selection.
- mt76 maintainer signed off; RFC → v1 → v2.
- Sibling 2/2 already on 6.6.
- MT7986 + WED RX + page_pool all exist here.
- `wed->version` and `band_idx` exist.
AGAINST:
- Patch file `wed.c` is not in 6.6 (moved in 6.8-era `8a7386e787ef4`).
- Needs a few-line context backport.
- WED off by default; subset of MT7986 boards.
- Crash log tainted OOT; still in-tree frames.
UNRESOLVED:
- Stable ML discussion (lore/stable 403).
- Whether every reviewer asked for Cc: stable (not seen on v2 1/2).
**Step 9.2: APPLY THE STABLE RULES CHECKLIST**
1. Obviously correct and tested? **PASS** — matches DMA allocation;
maintainer merged; oops on real HW.
2. Fixes a real bug that affects users? **PASS** — probe oops on non-
DBDC MT7986 + WED.
3. Important issue? **PASS** — kernel oops, severity CRITICAL for that
hardware.
4. Small and contained? **PASS** — ~5 lines, one function.
5. No new features or APIs? **PASS**.
6. Can apply to the local tree? **PASS** with a backport to
`mt7915/mmio.c` (stable rule: apply cleanly **or come with a
backport**). Not a missing-feature case.
**Step 9.3: CHECK FOR EXCEPTION CATEGORIES**
Record: None (not a device ID/quirk/DT/build/doc). Ordinary crash fix.
**Step 9.4: MAKE YOUR DECISION**
The 6.6 tree has the same panic path under a pre-`wed.c` name. Selecting
this for 6.6 is justified; apply the same `version == 2 && band_idx`
check in `mt7915_mmio_wed_init_rx_buf`.
---
**What the commit solves for this tree:** On non-DBDC MT7986, the main
phy is band 1, so only `MT_RXQ_BAND1` is allocated. WED RX init still
pulls from `MT_RXQ_MAIN`, whose `page_pool` is NULL, and the kernel
oopses in `page_pool_alloc_frag` during `mt7915e` probe. That mapping is
already in 6.6 `init.c`/`dma.c`; only the RX-buf picker is wrong.
**Stable rules:** Real, important crash; tiny logic fix; no new API.
File path changed after 6.6, so it needs a short backport, not a NAK.
**Risk vs benefit:** Low risk, high benefit on Filogic devices that
enable WED (including the reported Acer Vero W6m class).
**Concerns:** Must edit
`drivers/net/wireless/mediatek/mt76/mt7915/mmio.c` and use
`dev->mt76.phy.band_idx` (or `dev->phy.mt76->band_idx`) because `dev` is
`struct mt7915_dev *` here. Do not require `8a7386e787ef4`.
Verification:
- [Phase 1] Subject/tags: fix panic; SOB Zhi-Jun You + Felix Fietkau;
Link `20260715152113.553-1`; no Fixes/Cc-stable
- [Phase 1] Series: v2 1/2; 2/2 already `8eae5e5aa09da` on pending-6.6
- [Phase 2] Diff: 6 insertions in `mt76_wed_init_rx_buf`; queue MAIN vs
BAND1
- [Phase 3] Blame on 6.6: `q = &dev->mt76.q_rx[MT_RXQ_MAIN]` from
`2f5c3c77fc9b6` (page_pool); present
- [Phase 3] `8a7386e787ef4` (wed.c split) **not** ancestor of
pending-6.6
- [Phase 3] Fix `8a177dabeeead` **not** ancestor of pending-6.6
- [Phase 4] b4 dig: RFC → v1 → v2; applied v2; Felix merged 2026-07-31
- [Phase 4] Recipients: mt76 maintainers + linux-wireless/mediatek
- [Phase 4] UNVERIFIED: lore.kernel.org and lore.kernel.org/stable HTTP
403; used ratatoskr mirrors
- [Phase 5] Caller: `mtk_wed_rx_buffer_alloc` → `wlan.init_rx_buf` from
`mtk_wed_start` / probe
- [Phase 6] `git show pending-6.6:Makefile`: VERSION 6 / PATCHLEVEL 6 /
SUBLEVEL 157
- [Phase 6] `git cat-file` pending-6.6 `wed.c`: path does not exist
- [Phase 6] pending-6.6 `mmio.c:635`: hardcoded `MT_RXQ_MAIN`; `init.c`
sets `band_idx = 1` for one-A-die MT7986
- [Phase 6] DMA: MAIN allocated only if `!band_idx`; BAND1 if
`dbdc_support || band_idx`
- [Phase 6] `wed->version` exists; set to 2 for MT7986-class WED
- [Phase 8] Failure: NULL page_pool deref → oops; CRITICAL for that
SKU+WED
- UNVERIFIED: whether an out-of-tree module contributed besides in-tree
frames (taint `O`)
**YES**
drivers/net/wireless/mediatek/mt76/wed.c | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/drivers/net/wireless/mediatek/mt76/wed.c b/drivers/net/wireless/mediatek/mt76/wed.c
index fbd7e59c73aaf..2ebf4edc689e9 100644
--- a/drivers/net/wireless/mediatek/mt76/wed.c
+++ b/drivers/net/wireless/mediatek/mt76/wed.c
@@ -33,10 +33,15 @@ u32 mt76_wed_init_rx_buf(struct mtk_wed_device *wed, int size)
{
struct mtk_wed_bm_desc *desc = wed->rx_buf_ring.desc;
struct mt76_dev *dev = mt76_wed_to_dev(wed);
- struct mt76_queue *q = &dev->q_rx[MT_RXQ_MAIN];
struct mt76_txwi_cache *t = NULL;
+ struct mt76_queue *q;
int i;
+ if (wed->version == 2 && dev->phy.band_idx)
+ q = &dev->q_rx[MT_RXQ_BAND1];
+ else
+ q = &dev->q_rx[MT_RXQ_MAIN];
+
for (i = 0; i < size; i++) {
dma_addr_t addr;
u32 offset;
--
2.53.0
^ permalink raw reply related [flat|nested] 20+ messages in thread* [PATCH AUTOSEL 6.18] soc: mediatek: add missing MODULE_DEVICE_TABLE()
2026-10-19 13:44 [PATCH AUTOSEL 6.18-6.12] net: dsa: mt7530: check CORE_PLL_GROUP4 access in mt7531_setup() Sasha Levin
` (4 preceding siblings ...)
2026-10-19 13:46 ` [PATCH AUTOSEL 6.18] wifi: mt76: wed: fix kernel panic on non-DBDC MT7986 Sasha Levin
@ 2026-10-19 13:47 ` Sasha Levin
2026-10-19 13:47 ` [PATCH AUTOSEL 6.18-5.10] net: dsa: mt7530: error out on failed PHY_IAC command writes Sasha Levin
` (12 subsequent siblings)
18 siblings, 0 replies; 20+ messages in thread
From: Sasha Levin @ 2026-10-19 13:47 UTC (permalink / raw)
To: patches, stable
Cc: Pengpeng Hou, AngeloGioacchino Del Regno, Sasha Levin,
matthias.bgg, linux-kernel, linux-arm-kernel, linux-mediatek
From: Pengpeng Hou <pengpeng@iscas.ac.cn>
[ Upstream commit ec762057868d70d474a9816e9c293c2ef801c3c9 ]
The driver has an OF match table wired to .of_match_table, but does
not export the table with MODULE_DEVICE_TABLE().
Add the missing MODULE_DEVICE_TABLE(of, ...) entry so module alias
information is generated for OF based module autoloading.
This is a source-level fix. It does not claim dynamic hardware
reproduction; the evidence is the driver-owned match table, its use by
the platform driver, and the missing module alias publication.
Signed-off-by: Pengpeng Hou <pengpeng@iscas.ac.cn>
Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
LLM Generated explanations, may be completely bogus:
The local checkout is **7.3-rc4**. The DVFSRC driver is modular, had an
OF match table, and did not publish aliases, so autoload is broken for
`CONFIG_MTK_DVFSRC=m`. That is a real, one-line hardware-enablement bug.
===============================================================
PHASE 1: COMMIT MESSAGE FORENSICS
===============================================================
Step 1.1: PARSE THE SUBJECT LINE
Record: **[soc: mediatek] [add] [missing MODULE_DEVICE_TABLE() for OF
module autoload]**
- Subsystem: `soc: mediatek`
- Verb: **add** (missing export; the body is a fix, not a feature)
- Intent: publish the existing OF match table as module aliases
Step 1.2: PARSE ALL COMMIT MESSAGE TAGS
Verified from `git show ec762057868d70`:
- Signed-off-by: Pengpeng Hou \<pengpeng@iscas.ac.cn\> (author)
- Signed-off-by: AngeloGioacchino Del Regno
\<angelogioacchino.delregno@collabora.com\> (MediaTek SoC maintainer;
applied the patch)
- No Fixes:, Reported-by, Tested-by, Reviewed-by, Acked-by, Link:, or
Cc: stable
- Absence of Fixes:/Cc: stable is expected for this review and is not a
negative
Step 1.3: ANALYZE THE COMMIT BODY TEXT
Record:
- **Bug:** OF match table is wired to `.of_match_table` but not exported
via `MODULE_DEVICE_TABLE(of, ...)`
- **Symptom:** `depmod`/`file2alias` never emit
`of:N*T*Cmediatek,mtXXXX-dvfsrc` aliases, so udev/kmod will not
autoload `mtk-dvfsrc.ko`
- **Version info:** none in the message. Driver landed in v6.13; this
fix is in v7.3-rc4
- **Root cause:** forgotten alias publication on a tristate
`module_platform_driver`
The extra “source-level fix / no dynamic hardware reproduction”
paragraph is in the original lore submission as well (not a stable-
pipeline marker).
Step 1.4: DETECT HIDDEN BUG FIXES
Record: **Not hidden.** It is an explicit autoload/modalias bug fix
disguised only by the verb “add”. Same class as a missing device-ID
table export.
===============================================================
PHASE 2: DIFF ANALYSIS - LINE BY LINE
===============================================================
Step 2.1: INVENTORY THE CHANGES
Record:
- File: `drivers/soc/mediatek/mtk-dvfsrc.c` (**+1 / −0**)
- One line after `mtk_dvfsrc_of_match[]`
- Scope: **single-file surgical fix**
Step 2.2: UNDERSTAND THE CODE FLOW CHANGE
Record:
- **Before:** match table exists and is used for platform binding, but
no `__mod_of__mtk_dvfsrc_of_match` alias is generated
- **After:** `MODULE_DEVICE_TABLE(of, mtk_dvfsrc_of_match)` creates that
alias for `scripts/mod/file2alias.c`
- Affected path: **module build / autoload**, not probe logic. Built-in
(`=y`) is unchanged at runtime
Step 2.3: IDENTIFY THE BUG MECHANISM
Record:
- **Category:** hardware enablement / missing module alias (OF
equivalent of a missing device ID table)
- **Mechanism:** without `MODULE_DEVICE_TABLE`, kmod cannot map DT
`compatible` to `mtk-dvfsrc.ko`. Probe never runs unless the module is
loaded by hand
- Not UAF, leak, race, or locking
Step 2.4: ASSESS THE FIX QUALITY
Record:
- **Obviously correct:** one standard macro next to the table, same
pattern as `mtk-mmsys.c`, `mtk-svs.c`, `mtk-mutex.c` in this tree
- **Regression risk: negligible.** No runtime code, locking, or API
change; only `.modinfo` aliases when built as a module
===============================================================
PHASE 3: GIT HISTORY INVESTIGATION
===============================================================
Step 3.1: BLAME THE CHANGED LINES
Record:
- Match table introduced in **192514ae05687** (“Add MediaTek DVFS
Resource Collector (DVFSRC) driver”, AngeloGioacchino Del Regno, 2024)
- Present in **v6.13-rc1**; **not** in v6.12 or v6.6
- Original file already had `.of_match_table` and
`module_platform_driver` and **never** had `MODULE_DEVICE_TABLE` (`git
show 192514ae05687a:drivers/soc/mediatek/mtk-dvfsrc.c`)
- The one-line fix is **ec762057868d70** (Pengpeng Hou, 2026-07-04;
applied 2026-07-30)
Step 3.2: FOLLOW THE FIXES: TAG
Record: **No Fixes: tag.** Bug is the original omission in
192514ae05687, which **is** an ancestor of this tree.
Step 3.3: CHECK FILE HISTORY FOR RELATED CHANGES
Record: later DVFSRC work (MT6893, MT8196, bandwidth rework) only grew
the match table. No prerequisite refactor is required for this one line.
**Standalone.**
Step 3.4: CHECK THE AUTHOR'S OTHER COMMITS
Record: Pengpeng Hou has a series of the same “add missing
MODULE_DEVICE_TABLE()” fixes (rtc, vdpa, watchdog, hwmon, aspeed,
ixp4xx). This is a systematic audit, not a one-off. The applying
maintainer is the MediaTek SoC co-maintainer.
Step 3.5: CHECK FOR DEPENDENT/PREREQUISITE COMMITS
Record: **None.** Needs only `mtk_dvfsrc_of_match` and `module.h`, both
present since the driver was added. Applies standalone.
===============================================================
PHASE 4: MAILING LIST AND EXTERNAL RESEARCH
===============================================================
Step 4.1: FIND THE ORIGINAL PATCH DISCUSSION
Record:
- `b4 dig -c ec762057868d70` →
https://patch.msgid.link/20260704124308.6241-1-pengpeng@iscas.ac.cn
- `b4 dig -a`: **v1 only** (no v2/v3)
- Thread (saved via `b4 dig -m`): maintainer reply “Applied to
v7.2-next/soc, thanks!” (commit 0ef07f74aff2 while in the MTK tree)
- No NAKs, no requested changes, no Cc: stable in review
Step 4.2: CHECK WHO REVIEWED THE PATCH
Record (`b4 dig -w`): To/Cc included both MediaTek SoC maintainers
(Matthias Brugger, AngeloGioacchino Del Regno) and linux-mediatek /
linux-arm-kernel / linux-kernel. Applied by the subsystem maintainer.
Step 4.3: SEARCH FOR THE BUG REPORT
Record: **No Reported-by / bugzilla / syzbot.** Evidence is the source
mismatch (match table vs missing export), which is deterministic for
`=m` builds.
Step 4.4: CHECK FOR RELATED PATCHES AND SERIES
Record: not a numbered series. Sibling same-cycle fixes exist (`soc:
aspeed`, `soc: ixp4xx: npe/qmgr`). Each is self-contained. Historical
MediaTek analogs: `6f42f5e73bb43` (mtk-svs), `10687632307c0` (mtk-
mmsys).
Step 4.5: CHECK STABLE MAILING LIST HISTORY
Record: **UNVERIFIED.** lore.kernel.org returned HTTP 403 for WebFetch
and curl. No local evidence of a stable NAK.
===============================================================
PHASE 5: CODE SEMANTIC ANALYSIS
===============================================================
Step 5.1: IDENTIFY KEY FUNCTIONS IN THE DIFF
Record: **No function body changed.** The new line is
`MODULE_DEVICE_TABLE(of, mtk_dvfsrc_of_match)` beside the existing
table. Related runtime entry is `mtk_dvfsrc_probe`.
Step 5.2: TRACE CALLERS
Record:
- `module_platform_driver(mtk_dvfsrc_driver)` → OF platform probe
- Exported `mtk_dvfsrc_send_request` / `mtk_dvfsrc_query_info` used by:
- `drivers/interconnect/mediatek/icc-emi.c`
(`INTERCONNECT_MTK_DVFSRC_EMI` depends on `MTK_DVFSRC`)
- `drivers/regulator/mtk-dvfsrc-regulator.c` (`REGULATOR_MTK_DVFSRC`
depends on `MTK_DVFSRC`)
- Probe also `devm_of_platform_populate()`, so child
interconnect/regulator nodes never appear if this module never loads
Step 5.3: TRACE CALLEES
Record: probe does SMC init/start of the DVFSRC IP, clock enable, child
populate. Autoload failure means that entire stack never starts.
Step 5.4: FOLLOW THE CALL CHAIN
Record: **Userspace-reachable via normal boot on MediaTek DT platforms**
(kmod/udev matching `compatible`). Unprivileged users do not need a
special syscall; they just boot. Trigger requires `CONFIG_MTK_DVFSRC=m`
and a matching DT node.
Step 5.5: SEARCH FOR SIMILAR PATTERNS
Record: other `drivers/soc/mediatek/` drivers already have
`MODULE_DEVICE_TABLE(of, ...)`. This was the omission.
===============================================================
PHASE 6: CROSS-REFERENCING AGAINST THE LOCAL TREE
===============================================================
Step 6.1: DOES THE BUGGY CODE EXIST IN THIS TREE?
Record:
- `git describe HEAD` → **v7.3-rc4-27-gf0100363d8c37**; `make
kernelversion` → **7.3.0-rc4**
- File and match table exist. Before ec762057868d70 there was **no**
`MODULE_DEVICE_TABLE` (`git show ec762057868d70^:...`)
- Bug introduced with the driver in **v6.13** (192514ae05687)
- `git merge-base --is-ancestor ec762057868d70 HEAD` → yes (this
checkout already contains the fix as mainline, which does not change
whether the bug class is real)
Step 6.2: CHECK FOR BACKPORT COMPLICATIONS
Record: **clean apply.** One line after the sentinel entry. Compatible
strings may differ on older stables, but the macro is independent of
table contents.
Step 6.3: CHECK IF RELATED FIXES ARE ALREADY HERE
Record: this is the fix. No earlier equivalent. Sibling SoC drivers
already had the macro.
===============================================================
PHASE 7: SUBSYSTEM AND MAINTAINER CONTEXT
===============================================================
Step 7.1: IDENTIFY THE SUBSYSTEM AND ITS CRITICALITY
Record:
- **Subsystem:** `drivers/soc/mediatek` (MediaTek SoC DVFS resource
collector)
- **Criticality: IMPORTANT** on ARCH_MEDIATEK (Chromebooks/boards with
MT8183/MT8195/MT8196/MT6893), **PERIPHERAL** globally
- Kconfig: `config MTK_DVFSRC` **tristate**, `depends on ARCH_MEDIATEK`
Step 7.2: ASSESS SUBSYSTEM ACTIVITY
Record: actively maintained (MT8196/DVFSRCv4, bandwidth rework,
mmsys/cmdq work). DVFSRC itself is a few years old (6.13), not brand-new
staging code.
===============================================================
PHASE 8: IMPACT AND RISK ASSESSMENT
===============================================================
Step 8.1: DETERMINE WHO IS AFFECTED
Record: **platform-specific / config-specific** — `ARCH_MEDIATEK` +
`CONFIG_MTK_DVFSRC=m` + DT `compatible` in the match table. Built-in
configs are unaffected.
Step 8.2: DETERMINE THE TRIGGER CONDITIONS
Record:
- Trigger: boot (or DT overlay) with the module not already loaded
- Common on distro-style `=m` kernels; Chromebook/embedded images often
use `=y` (then a no-op)
- Not a race; **100%** for modular builds
- Unprivileged user is not required beyond using the machine
Step 8.3: DETERMINE THE FAILURE MODE SEVERITY
Record:
- **Failure:** DVFSRC module does not autoload → probe skipped → child
devices not populated → interconnect EMI bandwidth votes and DVFSRC
regulators return failure/`-ENODEV`
- Not an oops/UAF/corruption
- **Severity: MEDIUM** (device/stack does not come up; power/bandwidth
management broken on those SoCs). For users who ship this as a module,
it is a real “hardware doesn’t work” bug, in the same bucket as
missing device IDs
Step 8.4: CALCULATE RISK-BENEFIT RATIO
Record:
- **Benefit:** high for modular MediaTek kernels; zero elsewhere
- **Risk:** very low (1 line, `.modinfo` only)
- **Ratio:** strongly favors including it
===============================================================
PHASE 9: FINAL SYNTHESIS
===============================================================
Step 9.1: COMPILE THE EVIDENCE
FOR:
- Real, deterministic autoload bug on a **tristate** driver that already
has an OF table
- DVFSRC is the parent of interconnect and regulator children; missing
autoload takes down that DVFS/bandwidth stack
- 1-line, standard `MODULE_DEVICE_TABLE(of, ...)` pattern already used
by sibling MediaTek SoC drivers
- Applied by the MediaTek SoC maintainer; v1 accepted unchanged
- Same class as device-ID additions (explicit stable exception):
existing driver, existing hardware, missing match publication
- Driver has been in this lineage since v6.13; the omission is old, not
a just-landed feature
AGAINST:
- No user/syzbot report; author describes it as source-level
- Not a crash, deadlock, or data-corruption fix
- `=y` builds are unaffected; no in-tree defconfig sets
`CONFIG_MTK_DVFSRC`
- No Cc: stable (expected here; not used as a negative)
UNRESOLVED:
- lore.kernel.org stable-list search (HTTP 403)
- Whether a given distro actually builds this as `=m` (unverified)
Step 9.2: APPLY THE STABLE RULES CHECKLIST
1. Obviously correct and tested? **PASS** — one established macro;
maintainer applied v1
2. Fixes a real bug that affects users? **PASS** — module will not
autoload for OF devices (`stable-kernel-rules.rst`: “real bug that
bothers people **or** just add a device ID”)
3. Important issue? **PASS** as hardware-does-not-bind / missing ID-
table export, not as a panic. Severity MEDIUM but in the device-ID
exception class
4. Small and contained? **PASS** — +1 line, one file
5. No new features or APIs? **PASS** — only publishes an existing table
6. Can apply to the local tree? **PASS** — file and table exist; the
line is already the correct form here
Step 9.3: CHECK FOR EXCEPTION CATEGORIES
Record: **Device ID / match-table publication for an existing driver.**
Closest documented exception: “just add a device ID.”
Step 9.4: MAKE YOUR DECISION
This is a one-line, obviously correct fix for a real modular-boot
failure on MediaTek SoCs that already have this driver. Risk is
negligible. It belongs in this tree’s stable lineage.
### What it solves for stable users
If `mtk-dvfsrc` is built as a module, kmod never gets `of:` aliases for
`mediatek,mt8183-dvfsrc` and the other compatibles. The driver never
probes, so DVFSRC children (EMI interconnect, DVFSRC regulators) never
appear. Adding `MODULE_DEVICE_TABLE` is the supported way to generate
those aliases (`include/linux/module.h` + `scripts/mod/file2alias.c`).
### Risk vs benefit
Benefit is restoring autoload for a SoC DVFS block; risk is a `.modinfo`
addition with no runtime logic change.
### Concerns
Needs no extra commits. Older stables without `mtk-dvfsrc.c` (pre-6.13)
would not apply; **this** checkout has the driver. Lore stable
discussion could not be fetched (403).
Verification:
- [Phase 1] `git show ec762057868d70`: subject/tags/body as above; no
Fixes/Cc stable/Reported-by
- [Phase 2] Diff is exactly `+MODULE_DEVICE_TABLE(of,
mtk_dvfsrc_of_match);` in `mtk-dvfsrc.c`
- [Phase 3] Blame: table from 192514ae05687; MODULE_DEVICE_TABLE line
from ec762057868d70
- [Phase 3] `git show 192514ae05687a:drivers/soc/mediatek/mtk-dvfsrc.c`:
of_match_table + module_platform_driver, no MODULE_DEVICE_TABLE
- [Phase 3] `git merge-base --is-ancestor 192514ae05687 v6.13-rc1` yes;
not in v6.12
- [Phase 3] `git merge-base --is-ancestor ec762057868d70 HEAD` yes
- [Phase 4] `b4 dig -c/-a/-w/-m`: lore msgid
20260704124308.6241-1-pengpeng@iscas.ac.cn; v1 only; maintainers CC’d;
Angelo applied to v7.2-next/soc
- [Phase 4] lore.kernel.org HTTP 403 — stable-list discussion UNVERIFIED
- [Phase 5] Callers: `icc-emi.c`, `mtk-dvfsrc-regulator.c`; Kconfig
`depends on MTK_DVFSRC`; probe uses `devm_of_platform_populate`
- [Phase 5] `CONFIG_MTK_DVFSRC` is tristate in
`drivers/soc/mediatek/Kconfig`
- [Phase 6] `git describe HEAD` = v7.3-rc4-27-gf0100363d8c37;
kernelversion 7.3.0-rc4
- [Phase 6] Pre-commit file has match table and no MODULE_DEVICE_TABLE
- [Phase 7] MAINTAINERS: ARM/Mediatek SoC support → AngeloGioacchino Del
Regno (applier)
- [Phase 8] Failure mode: module not autoloaded → DVFSRC/DVFS stack
down; not an oops
- UNVERIFIED: distro `=m` vs `=y` defaults; stable@ lore thread
**YES**
drivers/soc/mediatek/mtk-dvfsrc.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/soc/mediatek/mtk-dvfsrc.c b/drivers/soc/mediatek/mtk-dvfsrc.c
index 41add5636b03c..af35d71615baf 100644
--- a/drivers/soc/mediatek/mtk-dvfsrc.c
+++ b/drivers/soc/mediatek/mtk-dvfsrc.c
@@ -562,6 +562,7 @@ static const struct of_device_id mtk_dvfsrc_of_match[] = {
{ .compatible = "mediatek,mt8195-dvfsrc", .data = &mt8195_data },
{ /* sentinel */ }
};
+MODULE_DEVICE_TABLE(of, mtk_dvfsrc_of_match);
static struct platform_driver mtk_dvfsrc_driver = {
.probe = mtk_dvfsrc_probe,
--
2.53.0
^ permalink raw reply related [flat|nested] 20+ messages in thread* [PATCH AUTOSEL 6.18-5.10] net: dsa: mt7530: error out on failed PHY_IAC command writes
2026-10-19 13:44 [PATCH AUTOSEL 6.18-6.12] net: dsa: mt7530: check CORE_PLL_GROUP4 access in mt7531_setup() Sasha Levin
` (5 preceding siblings ...)
2026-10-19 13:47 ` [PATCH AUTOSEL 6.18] soc: mediatek: add missing MODULE_DEVICE_TABLE() Sasha Levin
@ 2026-10-19 13:47 ` Sasha Levin
2026-10-19 13:47 ` [PATCH AUTOSEL 6.18-6.12] net: dsa: mt7530: check bus->read() error in core_rmw() Sasha Levin
` (11 subsequent siblings)
18 siblings, 0 replies; 20+ messages in thread
From: Sasha Levin @ 2026-10-19 13:47 UTC (permalink / raw)
To: patches, stable
Cc: Daniel Golle, Andrew Lunn, Jakub Kicinski, Sasha Levin,
chester.a.unal, olteanv, davem, edumazet, pabeni, matthias.bgg,
angelogioacchino.delregno, netdev, linux-kernel, linux-arm-kernel,
linux-mediatek
From: Daniel Golle <daniel@makrotopia.org>
[ Upstream commit 1c95dcb7e923beebccdc79adc3dc1ec8c52295d0 ]
MT7531_PHY_ACS_ST is only ever set by the command write that precedes
each poll in the MT7531 indirect PHY access functions, and that
write's return value is discarded. A failed write leaves ACS_ST at 0
from the previous access, so the poll succeeds on its first iteration
and the functions return stale IAC contents as if they were fresh PHY
data. Check the writes and bail out before polling.
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Link: https://patch.msgid.link/c34602e63a20ebbfb97babd145c82832d7a0b523.1785811140.git.daniel@makrotopia.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
LLM Generated explanations, may be completely bogus:
## Phase 1: Commit message forensics
**Step 1.1: Subject line**
Record: **[net/dsa/mt7530] [error out] Check PHY_IAC command writes and
abort on failure instead of polling stale IAC contents.**
**Step 1.2: Tags**
Record (candidate message, ignoring pipeline SOBs):
- **Reviewed-by:** Andrew Lunn `<andrew@lunn.ch>` (DSA reviewer)
- **Link:** `https://patch.msgid.link/c34602e63a20ebbfb97babd145c82832d7
a0b523.1785811140.git.daniel@makrotopia.org`
- **Signed-off-by:** Daniel Golle (author; MediaTek switch co-
maintainer)
- **Signed-off-by:** Jakub Kicinski (netdev)
- No Reported-by / Tested-by / syzbot / Cc: stable in the candidate text
Independent of the candidate text, the original LKML submission also had
**`Fixes: c288575f7810 ("net: dsa: mt7530: Add the support of MT7531
switch")`**. That tag is not used as a “already selected” signal; it
only identifies the introducing commit.
**Step 1.3: Body**
Record:
- **Bug:** `MT7531_PHY_ACS_ST` is set only by the command write before
each poll. The write return is discarded.
- **Failure mode:** A failed write leaves ACS_ST at 0 from the previous
access. The poll condition `!(val & MT7531_PHY_ACS_ST)` is already
true, so the poll returns immediately and the helpers treat leftover
IAC contents as a completed PHY access.
- **Symptom:** Reads return stale IAC data as PHY register values;
writes return poll-success (`0`) even though the PHY was not written.
- **Root cause:** Missing error check on `mt7530_mii_write()` of
`MT7531_PHY_IAC`.
- **Version info in body:** none. Introducing commit is from 2020.
**Step 1.4: Hidden bug fix?**
Record: **Not hidden.** This is an explicit error-propagation fix, not a
cleanup.
## Phase 2: Diff analysis
**Step 2.1: Inventory**
Record:
- **File:** `drivers/net/dsa/mt7530.c` only
- **Scope:** ~+12 / −6 (six identical two-line checks)
- **Functions:** `mt7531_ind_c45_phy_read`, `mt7531_ind_c45_phy_write`,
`mt7531_ind_c22_phy_read`, `mt7531_ind_c22_phy_write`
- **Classification:** single-file surgical error-path fix
**Step 2.2: Code flow**
Record: each helper already polls until ACS_ST is clear, writes a
command with ACS_ST set, then polls again. **Before:**
`mt7530_mii_write()` result is ignored; polling always runs. **After:**
a negative write return jumps to `out`, which already unlocks the MDIO
mutex and returns `ret`.
**Step 2.3: Bug mechanism**
Record: **logic / error-path correctness.** ACS_ST is `BIT(31)` of
`MT7531_PHY_IAC` (`0x701C`). Poll success is “bit clear.” A failed
command write never sets that bit, so the poll succeeds on the first
iteration.
Verified on the write helpers: after a successful poll, `ret` is `0`
from `regmap_read_poll_timeout()`, so a failed PHY write is currently
reported as **success**. On reads, `ret = val &
MT7531_MDIO_RW_DATA_MASK` returns leftover IAC data as a 16-bit PHY
value.
**Step 2.4: Fix quality**
Record: **obviously correct.** Same `goto out` path already used for
poll failures. No new locks, APIs, or data structures. Regression risk
is low: only failed bus writes change behavior, and they now return the
real errno instead of fake success / stale data.
## Phase 3: Git history
**Step 3.1: Blame**
Record: the unchecked `mt7530_mii_write(..., MT7531_PHY_IAC, ...)` lines
were introduced in **`c288575f7810` (Landen Chao, 2020-09-11), “Add the
support of MT7531 switch”**. `mt7530_mii_write()` has returned `int`
since **`a08c045580e060` (2023-04-03, regmap conversion)**. Both are in
this tree.
**Step 3.2: Fixes: target**
Record: `git merge-base --is-ancestor c288575f7810 HEAD` succeeded. The
bug is in this 6.12 tree. No later local commit already checks these
writes (`ret = mt7530_mii_write(priv, MT7531_PHY_IAC` count is 0).
**Step 3.3: File history / related commits**
Record: this tree already contains the sibling **`96e0f5184af69`**
(`v6.12.103~217`), “error out on failed reads in MT7531 PHY polling”
(upstream `77a9ebe8818cf6`). That converted the polls to
`regmap_read_poll_timeout()` but left command writes unchecked. Also
present: **`93d46870c5440`**, “check bus->read() errors in the MDIO
regmap backend” — same author, same class of swallowed MDIO errors.
**Step 3.4: Author**
Record: Daniel Golle is listed as a **MEDIATEK SWITCH DRIVER**
maintainer. Other mt7530 error-propagation fixes by him are already in
this tree.
**Step 3.5: Dependencies**
Record: **standalone.** Needs `mt7530_mii_write()` returning `int` and
the existing `goto out` + mutex unlock — all present. It does **not**
need the rest of the later 6-patch series (`core_rmw`, CORE_PLL_GROUP4,
FDB/VLAN writes, IRQ serialization).
## Phase 4: Mailing list
**Step 4.1:** Candidate is not a local commit, so `b4 dig -c` on this
SHA was not possible. `b4 dig -c 96e0f5184af69` found the earlier poll-
timeout series. This patch was submitted as **`[PATCH net 3/4]`** then
**`[PATCH net v2 3/6]`** in “fix remaining swallowed MDIO access
errors.”
Record: lore/msgid `c34602e63a20ebbfb97babd145c82832d7a0b523.1785811140.
git.daniel@makrotopia.org`; LKML copy at
https://lkml.iu.edu/hypermail/linux/kernel/2608.0/04802.html. **v2: no
changes** to this patch. Cover letter: this write check was a companion
that had been folded into the already-applied PHY-polling patch and was
split out. No NAKs found.
**Step 4.2:** Recipients included DSA/netdev maintainers (Lunn, Oltean,
Kicinski, netdev). Andrew Lunn replied **Reviewed-by** with no requested
changes (https://www.spinics.net/lists/kernel/msg6350713.html).
**Step 4.3:** No syzbot or bugzilla. Mechanism is from code review
(cover letter: Sashiko AI review of the earlier series).
**Step 4.4:** Series mates are independent swallowed-error checks. This
hunk set does not depend on them.
**Step 4.5:** Search of lore.kernel.org/stable for this subject found
**no** prior stable discussion or rejection.
## Phase 5: Semantic / call graph
semcode MCP is not available; callers were found with grep.
**Step 5.1:** Functions listed in 2.1.
**Step 5.2: Callers**
- Wired as `phy_read/write_c22/c45` for **ID_MT7531, ID_MT7988,
ID_EN7581** in `mt753x_table`.
- MDIO bus ops: `mt7530_setup_mdio()` sets
`bus->read/write/read_c45/write_c45` to wrappers that call these
helpers. That is the phylib/phylink path (link polling, PHY config).
- Direct: `mt7531_setup()` uses `mt7531_ind_c45_phy_read/write` for
CORE_PLL_GROUP4 / EEE (those call sites still ignore the return; a
later series patch addresses that and is **not** required for this
MDIO-bus fix).
**Step 5.3: Callees**
`mt7530_mutex_lock/unlock`, `mt7530_mii_write` → `regmap_write`,
`regmap_read_poll_timeout`.
**Step 5.4: Reachability**
Yes, from userspace-visible networking: phylib MDIO reads/writes on
MT7531/MT7988/EN7581 switch PHYs. Trigger is a failed switch register
write (MDIO/MMIO/regmap error), not a rare debug ioctl.
**Step 5.5:** Same swallowed-error pattern already fixed for MDIO
backend reads and PHY_IAC **polls** in this tree. This is the remaining
write side of that PHY_IAC path.
## Phase 6: This tree (6.12.y)
**Step 6.1:** Local tree is **`pending-6.12` / 6.12.111**. All six
PHY_IAC command writes are still unchecked. Bug exists here.
**Step 6.2:** Current source matches the patch “before” context
(including `regmap_read_poll_timeout` from `96e0f5184af69`). **Expected
apply: clean.**
**Step 6.3:** No other local commit already checks these writes. The
poll-timeout backport left this hole open; this is the companion.
## Phase 7: Subsystem
**Step 7.1:** `drivers/net/dsa/mt7530.c` — MediaTek DSA switch.
**IMPORTANT** (not core mm/VFS, but common on MT7988/MT7531 routers,
OpenWrt, embedded). Config: `NET_DSA_MT7530`.
**Step 7.2:** File is actively maintained; several mt7530 fixes already
landed in this 6.12 branch.
## Phase 8: Impact and risk
**Step 8.1:** Users of MT7531, MT7988, and EN7581 switches (not
MT7530/MT7621, which use nested `mdiobus_*` instead of these indirect
helpers).
**Step 8.2:** Triggers on failed `regmap_write` of PHY_IAC. Unprivileged
users do not need a special exploit; phylib link/config traffic hits
this path. Frequency is error-path, but MDIO/MMIO glitches on these
boards are real.
**Step 8.3:** Failure mode: **silent wrong PHY data / false write
success**, not an oops. Phylib can see a live link or apply settings
that never reached the PHY. Severity: **HIGH** for networking
correctness on error; not a panic.
**Step 8.4:**
- **Benefit:** Completes the already-backported PHY_IAC poll hardening;
stops fake-success writes and stale reads.
- **Risk:** Very low (12 lines, error path only).
- **Ratio:** Favorable.
## Phase 9: Synthesis
**For backporting**
- Real bug with a verified mechanism (ACS_ST only set by the discarded
write).
- Write helpers currently return **0 on a failed PHY write**.
- Small, obviously correct, maintainer-authored, Reviewed-by Andrew
Lunn.
- Buggy code and `Fixes:` target are in this 6.12 tree.
- Sibling poll-timeout fix is already here; this closes the remaining
hole that series called out.
- Applies cleanly; no new API.
**Against**
- Error-path only (healthy bus never hits it).
- Driver-specific, not a universal crash/UAF.
- No user crash report; found by review.
**Unresolved**
- Could not `b4 dig` this exact SHA (not in the checkout); lore/LKML
used instead.
- lore.kernel.org WebFetch returned 403; discussion taken from
LKML/spinics.
**Stable rules**
1. Obviously correct and tested? **PASS** (Reviewed-by Lunn; merged via
netdev)
2. Real user-visible bug? **PASS** (false MDIO success / stale PHY data)
3. Important? **PASS** (silent PHY misconfiguration; same class as
already-backported mt7530 MDIO error fixes)
4. Small/contained? **PASS** (~12 lines, one file)
5. No new features/APIs? **PASS**
6. Applies to this tree? **PASS**
Not an ID/quirk/DT/docs exception; it qualifies as a normal contained
bugfix.
This should be backported to this 6.12 tree: the bug is present, the fix
is surgical, and it finishes error handling that 6.12 already took for
the same helpers.
Verification:
- [Phase 1] Parsed candidate tags: Reviewed-by Andrew Lunn, msgid link,
Golle/Kicinski SOBs; original LKML also had Fixes: c288575f7810
- [Phase 2] Diff: six `ret = mt7530_mii_write(); if (ret < 0) goto out;`
in four PHY_IAC helpers
- [Phase 2] Header: ACS_ST is BIT(31); poll waits for it clear —
confirmed in mt7530.h
- [Phase 2] Write helpers return poll `ret` (0 on success) — failed
write currently looks successful
- [Phase 3] Blame: writes from c288575f7810 (2020); ancestor of HEAD
- [Phase 3] Sibling 96e0f5184af69 already in tree (v6.12.103~217);
93d46870c5440 MDIO read-error fix also in tree
- [Phase 3] `git log --grep='PHY_IAC command writes'` on this file:
empty
- [Phase 4] LKML v2 3/6: “v2: no changes”; Lunn Reviewed-by, no NAK
- [Phase 4] Cover letter: companion to already-applied PHY polling patch
- [Phase 4] stable@ search: no hits
- [Phase 5] Callers: mt753x_table ID_MT7531/MT7988/EN7581;
bus->read/write in mt7530_setup_mdio
- [Phase 6] `git describe HEAD` / Makefile: 6.12.111 pending-6.12; six
unchecked PHY_IAC writes remain
- [Phase 6] Current lines match the patch context (including
regmap_read_poll_timeout)
- [Phase 7] MAINTAINERS: Daniel Golle is MediaTek switch co-maintainer
- [Phase 8] Failure: stale PHY data / false write success, not oops
- UNVERIFIED: b4 dig of this exact mainline SHA (commit not in
checkout); lore.kernel.org 403
**YES**
drivers/net/dsa/mt7530.c | 24 ++++++++++++++++++------
1 file changed, 18 insertions(+), 6 deletions(-)
diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c
index bd0a37ead0dec..24c7cb225da1a 100644
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
@@ -557,7 +557,9 @@ mt7531_ind_c45_phy_read(struct mt7530_priv *priv, int port, int devad,
reg = MT7531_MDIO_CL45_ADDR | MT7531_MDIO_PHY_ADDR(port) |
MT7531_MDIO_DEV_ADDR(devad) | regnum;
- mt7530_mii_write(priv, MT7531_PHY_IAC, reg | MT7531_PHY_ACS_ST);
+ ret = mt7530_mii_write(priv, MT7531_PHY_IAC, reg | MT7531_PHY_ACS_ST);
+ if (ret < 0)
+ goto out;
ret = regmap_read_poll_timeout(priv->regmap, MT7531_PHY_IAC, val,
!(val & MT7531_PHY_ACS_ST), 20, 100000);
@@ -568,7 +570,9 @@ mt7531_ind_c45_phy_read(struct mt7530_priv *priv, int port, int devad,
reg = MT7531_MDIO_CL45_READ | MT7531_MDIO_PHY_ADDR(port) |
MT7531_MDIO_DEV_ADDR(devad);
- mt7530_mii_write(priv, MT7531_PHY_IAC, reg | MT7531_PHY_ACS_ST);
+ ret = mt7530_mii_write(priv, MT7531_PHY_IAC, reg | MT7531_PHY_ACS_ST);
+ if (ret < 0)
+ goto out;
ret = regmap_read_poll_timeout(priv->regmap, MT7531_PHY_IAC, val,
!(val & MT7531_PHY_ACS_ST), 20, 100000);
@@ -602,7 +606,9 @@ mt7531_ind_c45_phy_write(struct mt7530_priv *priv, int port, int devad,
reg = MT7531_MDIO_CL45_ADDR | MT7531_MDIO_PHY_ADDR(port) |
MT7531_MDIO_DEV_ADDR(devad) | regnum;
- mt7530_mii_write(priv, MT7531_PHY_IAC, reg | MT7531_PHY_ACS_ST);
+ ret = mt7530_mii_write(priv, MT7531_PHY_IAC, reg | MT7531_PHY_ACS_ST);
+ if (ret < 0)
+ goto out;
ret = regmap_read_poll_timeout(priv->regmap, MT7531_PHY_IAC, val,
!(val & MT7531_PHY_ACS_ST), 20, 100000);
@@ -613,7 +619,9 @@ mt7531_ind_c45_phy_write(struct mt7530_priv *priv, int port, int devad,
reg = MT7531_MDIO_CL45_WRITE | MT7531_MDIO_PHY_ADDR(port) |
MT7531_MDIO_DEV_ADDR(devad) | data;
- mt7530_mii_write(priv, MT7531_PHY_IAC, reg | MT7531_PHY_ACS_ST);
+ ret = mt7530_mii_write(priv, MT7531_PHY_IAC, reg | MT7531_PHY_ACS_ST);
+ if (ret < 0)
+ goto out;
ret = regmap_read_poll_timeout(priv->regmap, MT7531_PHY_IAC, val,
!(val & MT7531_PHY_ACS_ST), 20, 100000);
@@ -646,7 +654,9 @@ mt7531_ind_c22_phy_read(struct mt7530_priv *priv, int port, int regnum)
val = MT7531_MDIO_CL22_READ | MT7531_MDIO_PHY_ADDR(port) |
MT7531_MDIO_REG_ADDR(regnum);
- mt7530_mii_write(priv, MT7531_PHY_IAC, val | MT7531_PHY_ACS_ST);
+ ret = mt7530_mii_write(priv, MT7531_PHY_IAC, val | MT7531_PHY_ACS_ST);
+ if (ret < 0)
+ goto out;
ret = regmap_read_poll_timeout(priv->regmap, MT7531_PHY_IAC, val,
!(val & MT7531_PHY_ACS_ST), 20, 100000);
@@ -681,7 +691,9 @@ mt7531_ind_c22_phy_write(struct mt7530_priv *priv, int port, int regnum,
reg = MT7531_MDIO_CL22_WRITE | MT7531_MDIO_PHY_ADDR(port) |
MT7531_MDIO_REG_ADDR(regnum) | data;
- mt7530_mii_write(priv, MT7531_PHY_IAC, reg | MT7531_PHY_ACS_ST);
+ ret = mt7530_mii_write(priv, MT7531_PHY_IAC, reg | MT7531_PHY_ACS_ST);
+ if (ret < 0)
+ goto out;
ret = regmap_read_poll_timeout(priv->regmap, MT7531_PHY_IAC, reg,
!(reg & MT7531_PHY_ACS_ST), 20, 100000);
--
2.53.0
^ permalink raw reply related [flat|nested] 20+ messages in thread* [PATCH AUTOSEL 6.18-6.12] net: dsa: mt7530: check bus->read() error in core_rmw()
2026-10-19 13:44 [PATCH AUTOSEL 6.18-6.12] net: dsa: mt7530: check CORE_PLL_GROUP4 access in mt7531_setup() Sasha Levin
` (6 preceding siblings ...)
2026-10-19 13:47 ` [PATCH AUTOSEL 6.18-5.10] net: dsa: mt7530: error out on failed PHY_IAC command writes Sasha Levin
@ 2026-10-19 13:47 ` Sasha Levin
2026-10-19 13:47 ` [PATCH AUTOSEL 6.18-5.15] wifi: mt76: mt7603: free beacon SKB on error Sasha Levin
` (10 subsequent siblings)
18 siblings, 0 replies; 20+ messages in thread
From: Sasha Levin @ 2026-10-19 13:47 UTC (permalink / raw)
To: patches, stable
Cc: Daniel Golle, Andrew Lunn, Jakub Kicinski, Sasha Levin,
chester.a.unal, olteanv, davem, edumazet, pabeni, matthias.bgg,
angelogioacchino.delregno, netdev, linux-kernel, linux-arm-kernel,
linux-mediatek
From: Daniel Golle <daniel@makrotopia.org>
[ Upstream commit 573d6e3afe3d01e34dc82c77bf22ca96a74d805e ]
core_rmw() accesses the MMD core registers directly rather than
through the regmap and has the same unchecked bus->read() as the
one just fixed in the MDIO regmap backend: a negative errno is
consumed as register data, modified and written back to the switch.
Check the read and bail out like the surrounding bus accesses do.
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Link: https://patch.msgid.link/48bb9f0b311a9efeda2a6b24a7e05d4792393a3b.1785811140.git.daniel@makrotopia.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
LLM Generated explanations, may be completely bogus:
## Phase 1: Commit message forensics
**Step 1.1: Subject line**
Record: `[net: dsa: mt7530]` [`check`] [detect `bus->read()` failure in
`core_rmw()` instead of treating errno as register data]
**Step 1.2: Tags**
Record:
- `Signed-off-by: Daniel Golle <daniel@makrotopia.org>` (author)
- `Reviewed-by: Andrew Lunn <andrew@lunn.ch>` (DSA co-maintainer)
- `Link: https://patch.msgid.link/48bb9f0b311a9efeda2a6b24a7e05d4792393a
3b.1785811140.git.daniel@makrotopia.org`
- `Signed-off-by: Jakub Kicinski <kuba@kernel.org>` (netdev maintainer)
- No `Fixes:` in the committed message
- Mailing-list submission **did** include `Fixes: b8f126a8d543 ("net-
next: dsa: add dsa support for Mediatek MT7530 switch")` (verified in
the saved mbox); it was dropped before mainline
- No `Reported-by:`, `Tested-by:`, `Cc: stable` in the committed message
(absence is expected)
**Step 1.3: Body**
Record:
- **Bug:** `core_rmw()` talks to MMD core registers via raw
`bus->read()`/`bus->write()`, not regmap. A failed `bus->read()`
returns a negative errno, which is used as the current register value,
masked/ORed, and written back.
- **Symptom:** garbage RMW into switch MMD registers (clock-gate bits on
this path).
- **Root cause:** same unchecked-read pattern as the MDIO regmap
backend, which this tree already has as `93d46870c5440`.
- **Version info:** none in the body. The inlined form is from
`7c5e37d7ee78d` (v6.11 era, present here). The mailing-list `Fixes:`
points at the 2017 driver introduction; the old
`core_read_mmd_indirect()` had the same unchecked read.
**Step 1.4: Hidden bug fix?**
Record: Not hidden. Explicit error-path correctness fix: missing check →
errno treated as data → written to hardware.
---
## Phase 2: Diff analysis
**Step 2.1: Inventory**
Record:
- File: `drivers/net/dsa/mt7530.c`
- Scope: ~5 insertions / 1 deletion in one function
- Function: `core_rmw()`
- Classification: single-file surgical fix
**Step 2.2: Code flow**
Record:
- **Before:** after three checked MMD address writes, `val =
bus->read(...)`. No check. `val &= ~mask; val |= set;` then
`bus->write(...)`.
- **After:** `ret = bus->read(...)`; if `ret < 0` goto the existing
`err` path (log + unlock); else `val = ret` and continue the RMW.
- Path: error path of an MDIO read during RMW. Normal success path
unchanged.
**Step 2.3: Bug mechanism**
Record:
- Category: logic / correctness on an error path (errno consumed as
register data, then written back). Same class as the already-present
MDIO regmap fix.
- `mii_bus->read` returns a 16-bit value or a negative errno
(`include/linux/mdio.h`: “returns value or negative error code”).
`val` is `u32`, so `-ETIMEDOUT` (-110) becomes `0xffffff92`.
`bus->write()` takes `u16`, so the switch sees `0xff92` with the
intended bit tweaks, not the real register contents.
- Mechanism: check `ret < 0` and skip the write, matching the
surrounding writes.
**Step 2.4: Fix quality**
Record:
- Obviously correct; copies the existing write-error pattern in the same
function.
- Minimal; no unrelated edits, no API change.
- Regression risk: very low. On read failure it no longer writes.
`core_rmw()` is still `void` and still only logs (pre-existing); this
patch does not invent a new return convention.
- `val = ret` after the check is safe: success values are 0..0xffff.
---
## Phase 3: Git history
**Step 3.1: Blame**
Record:
- Unchecked read at lines 155–156: `7c5e37d7ee78d` (“simplify core
operations”, Arınç ÜNAL, 2024-04-18).
- That commit inlined `core_read_mmd_indirect()`, which already returned
`bus->read()` without checking. The defect dates to `b8f126a8d543`
(2017), driver introduction.
- Inlined form is in this tree (`git merge-base --is-ancestor
7c5e37d7ee78d HEAD` succeeded). `git describe --contains` places it
around v6.11-rc1, so it is in 6.12.
**Step 3.2: Fixes: tag**
Record: No `Fixes:` on the committed patch. Submission tagged
`b8f126a8d543`, which **is** an ancestor of this tree. Intermediate:
`7c5e37d7ee78d` inlined the helper and kept the bug.
**Step 3.3: File history**
Record:
- This tree already has the sibling: `93d46870c5440` “check bus->read()
errors in the MDIO regmap backend”.
- Also: `96e0f5184af69` “error out on failed reads in MT7531 PHY
polling”.
- Candidate `573d6e3afe3d0` is **not** an ancestor of HEAD.
- Standalone vs series: mailing-list subject is `[PATCH net v2 2/6]`.
Diff does not depend on 1/6 or 3–6/6.
**Step 3.4: Author**
Record: Daniel Golle is a regular MT7530 contributor (OpenWrt/MediaTek).
Nearby commits by him in this tree are the other MDIO-error fixes.
Reviewed by Andrew Lunn.
**Step 3.5: Dependencies**
Record: None for this hunk. It uses existing `ret`, `goto err`, and
`bus->read`/`bus->write`. `git apply --check` succeeded (hunk offset 28
lines only).
---
## Phase 4: Mailing list / external research
**Step 4.1: Original discussion**
Record:
- `b4 dig -c 573d6e3afe3d0` → https://patch.msgid.link/48bb9f0b311a9efed
a2a6b24a7e05d4792393a3b.1785811140.git.daniel@makrotopia.org
- Series: `[PATCH net v2 0/6] net: dsa: mt7530: fix remaining swallowed
MDIO access errors`
- v2: “no changes” for this patch; Andrew’s `Reviewed-by` kept.
- Cover letter: leftover companion of the first “swallowed MDIO read
errors” series (already on `net`); this is the unchecked `bus->read()`
in `core_rmw()`.
- Sent to `net` (fixes), not `net-next`.
- No NAK in the saved mbox. Applied by Jakub Kicinski (`0200d48477602`
merge).
**Step 4.2: Recipients (`b4 dig -w`)**
Record: Andrew Lunn, Vladimir Oltean, netdev maintainers, MediaTek,
`netdev@`, `linux-mediatek@`. Right audience. Lunn reviewed.
**Step 4.3: Bug report**
Record: No syzbot/bugzilla. Found by review of the same MDIO-error class
(cover letter cites Sashiko AI review of the parent series).
**Step 4.4: Series**
Record: 6 patches. This is 2/6 and is self-contained. 3–5/6 are other
swallowed-error sites; 1/6 is `pcs-mtk-lynxi`; 6/6 is IRQ-chip
serialization. Not required for this hunk.
**Step 4.5: Stable list**
Record: **UNVERIFIED** — lore.kernel.org returned 403/503 to
WebFetch/curl. No local evidence this was rejected for stable.
---
## Phase 5: Code semantics
**Step 5.1: Functions**
Record: `core_rmw()` only.
**Step 5.2: Callers**
Record:
- `core_set()` / `core_clear()` → `core_rmw()`
- `mt7530_pll_setup()`: clear/set `REG_GSWCK_EN` on
`CORE_TRGMII_GSW_CLK_CG` (switch setup, 40 MHz XTAL)
- `mt7530_setup_port6()`: clear/set `REG_TRGMIICK_EN` (port 6 TRGMII
clock)
- `mt7530_pll_setup()` from `mt7530_setup()` (~line 2422)
- `mt7530_setup_port6()` from `mt7530_mac_config()` when `port == 6`
**Step 5.3: Callees**
Record: `mt7530_mutex_lock/unlock`, `bus->write`, `bus->read`,
`dev_err`.
**Step 5.4: Reachability**
Record: Yes, from DSA probe/setup and phylink MAC config on MT7530
(common in MediaTek routers). Not a syscall hot path; hit on bring-up
and port-6 mode changes. Userspace/netlink can trigger `mac_config`.
**Step 5.5: Similar patterns**
Record: Same bug already fixed in `mt7530_regmap_read()` in this tree.
`core_write()` only writes (no analogous read). Remaining siblings
(PHY_IAC writes, CORE_PLL_GROUP4, FDB/VLAN cmd) are other series
patches, not prerequisites.
---
## Phase 6: This tree (6.12.y)
**Step 6.1: Buggy code present?**
Record: Yes. Tree is `pending-6.12` / `6.12.111`
(`p-6.12-4-gbf6fcdf761abd`). Current `core_rmw()` still does `val =
bus->read(...)` with no check (`drivers/net/dsa/mt7530.c:155-156`).
`573d6e3afe3d0` is not an ancestor of HEAD.
**Step 6.2: Backport difficulty**
Record: Clean apply (`git apply --check`: hunk succeeded at offset 28).
Surrounding `core_rmw()` matches the pre-image.
**Step 6.3: Related fixes already here?**
Record: Regmap-backend check is here; PHY polling check is here. This
leftover `core_rmw()` instance is not. No alternate fix of this
function.
---
## Phase 7: Subsystem context
**Step 7.1**
Record: `drivers/net/dsa/mt7530.c` — MediaTek MT7530 DSA. **IMPORTANT**
(common embedded/router switch), not core mm/VFS, not staging.
**Step 7.2**
Record: Actively maintained; recent 6.12 backports already include other
MT7530 MDIO-error and hardware fixes.
---
## Phase 8: Impact and risk
**Step 8.1: Who is affected**
Record: Driver-specific: `CONFIG_NET_DSA_MT7530` (MDIO-attached
MT7530/MT7531, common on MT7621/MT798x-class boards).
**Step 8.2: Trigger**
Record: `bus->read()` failure during PLL/clock RMW (timeout, NACK, flaky
MDIO). Not every boot if the bus is healthy. Unprivileged users do not
trigger MDIO failure directly; they can hit the RMW via interface/port
config. Timing/hardware dependent.
**Step 8.3: Failure mode**
Record: On MDIO read failure, a truncated errno (e.g. `0xff92`) is
written to `CORE_TRGMII_GSW_CLK_CG` (core / TRGMII clock gates) instead
of toggling bit 0 or 1. That can leave clocks misconfigured (no link /
switch not forwarding) rather than failing closed. Severity: **HIGH** on
that error path (hardware misconfiguration), not a panic/UAF.
**Step 8.4: Risk-benefit**
Record:
- Benefit: stops garbage writes to switch clock-gate MMDs; completes the
same class already backported via the regmap patch.
- Risk: very low (4–5 lines, existing `err` path, no locking/API
change).
- Ratio: favorable.
---
## Phase 9: Synthesis
**For backporting**
- Real bug: negative MDIO errno used as register data and written back.
- Consequence: corrupt RMW of switch clock-gate registers.
- Small, obviously correct, reviewed by Andrew Lunn, taken into `net` as
a fix.
- Buggy code is in this 6.12 tree; patch applies cleanly.
- Same class as `93d46870c5440`, already in this tree; this is the
leftover `core_rmw()` site.
**Against**
- Error path only (MDIO must already be failing).
- Still `void`; errors are only logged (pre-existing).
- No syzbot/user crash report.
- Labelled 2/6, but this hunk does not need the rest.
**Unresolved**
- Stable-list discussion (lore 403/503). Does not change the technical
case.
**Stable rules**
1. Obviously correct and tested? **PASS** — matches surrounding checks;
Lunn `Reviewed-by`; in mainline `net`.
2. Real user-affecting bug? **PASS** — garbage written to MT7530 clock-
gate MMDs on read failure.
3. Important (crash/security/corruption/deadlock)? **PASS** — hardware
misconfiguration of switch clocks; same class already accepted in
this tree.
4. Small and contained? **PASS** — ~5 lines, one function.
5. No new features/APIs? **PASS**.
6. Applies to this tree? **PASS** — `git apply --check` clean.
**Exception category:** none (not an ID/quirk/DT/build/doc exception).
Qualifies as a normal small driver bugfix.
---
### What the commit solves for this tree
In 6.12, `core_rmw()` still assigns `bus->read()` to `u32 val` without
checking. On timeout/NACK that errno is masked, OR’d, and written to
`CORE_TRGMII_GSW_CLK_CG` during PLL setup and port-6 TRGMII clock
enable. The fix bails out like the three preceding writes. It is the
companion to the regmap-backend check already present here.
Risk is negligible; benefit is avoiding a bad clock-gate RMW when MDIO
fails on a widely used MediaTek DSA switch.
Verification:
- [Phase 1] Parsed tags: Lunn `Reviewed-by`, msgid link; no committed
`Fixes:`; mbox had `Fixes: b8f126a8d543`
- [Phase 2] Diff: 5 insertions in `core_rmw()`; check `ret < 0` before
RMW write
- [Phase 3] Blame: inlined by `7c5e37d7ee78d` (v6.11, in this tree);
original unchecked read in `b8f126a8d543` (2017)
- [Phase 3] `git merge-base --is-ancestor 573d6e3afe3d0 HEAD` → not in
tree; `7c5e37d7ee78d` is in tree
- [Phase 3] Sibling `93d46870c5440` is in this tree
- [Phase 4] `b4 dig -c 573d6e3afe3d0`: v2 2/6 of “fix remaining
swallowed MDIO access errors”; v2 no changes; Lunn review on 1–3 and 6
- [Phase 4] Cover letter: leftover `core_rmw()` companion of the first
MDIO-error series
- [Phase 4] `b4 dig -w`: netdev + DSA + MediaTek CCs
- [Phase 4] lore WebFetch/curl 403/503; thread recovered via `b4 dig -m`
- [Phase 5] Callers: `mt7530_pll_setup`, `mt7530_setup_port6` → DSA
setup / `mac_config`
- [Phase 5] `bus->read` contract: value or negative errno
(`include/linux/mdio.h`)
- [Phase 6] `git describe HEAD`: `p-6.12-4-gbf6fcdf761abd`; `make
kernelversion`: 6.12.111; buggy `val = bus->read` still at
mt7530.c:155
- [Phase 6] `git apply --check` of `573d6e3afe3d0`: succeeded (offset
28)
- [Phase 8] Failure mode: truncated errno written to
`CORE_TRGMII_GSW_CLK_CG`; severity HIGH on that error path
- UNVERIFIED: whether stable@ discussed this commit (lore unreachable)
**YES**
drivers/net/dsa/mt7530.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c
index 24c7cb225da1a..d2dcc2f1522f4 100644
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
@@ -124,8 +124,12 @@ core_rmw(struct mt7530_priv *priv, u32 reg, u32 mask, u32 set)
goto err;
/* Read the content of the MMD's selected register */
- val = bus->read(bus, MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr),
+ ret = bus->read(bus, MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr),
MII_MMD_DATA);
+ if (ret < 0)
+ goto err;
+ val = ret;
+
val &= ~mask;
val |= set;
/* Write the data into MMD's selected register */
--
2.53.0
^ permalink raw reply related [flat|nested] 20+ messages in thread* [PATCH AUTOSEL 6.18-5.15] wifi: mt76: mt7603: free beacon SKB on error
2026-10-19 13:44 [PATCH AUTOSEL 6.18-6.12] net: dsa: mt7530: check CORE_PLL_GROUP4 access in mt7531_setup() Sasha Levin
` (7 preceding siblings ...)
2026-10-19 13:47 ` [PATCH AUTOSEL 6.18-6.12] net: dsa: mt7530: check bus->read() error in core_rmw() Sasha Levin
@ 2026-10-19 13:47 ` Sasha Levin
2026-10-19 13:47 ` [PATCH AUTOSEL 6.18-6.1] wifi: mt76: mt7915: configure noise floor reporting on reset Sasha Levin
` (9 subsequent siblings)
18 siblings, 0 replies; 20+ messages in thread
From: Sasha Levin @ 2026-10-19 13:47 UTC (permalink / raw)
To: patches, stable
Cc: David Bauer, Felix Fietkau, Sasha Levin, lorenzo, ryder.lee,
matthias.bgg, angelogioacchino.delregno, linux-wireless,
linux-kernel, linux-arm-kernel, linux-mediatek
From: David Bauer <mail@david-bauer.net>
[ Upstream commit 965cbdbdfbd37a659a05ff88e49c216975bd9d2e ]
The SKB containing the generated beacon is not freed when the beacon
queue is deected stuck and scheduled for recovery.
Fixes potential memory leaks in case the beacon queue is detected stuck.
Signed-off-by: David Bauer <mail@david-bauer.net>
Link: https://patch.msgid.link/20260611215658.259324-1-mail@david-bauer.net
Signed-off-by: Felix Fietkau <nbd@nbd.name>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
LLM Generated explanations, may be completely bogus:
The local tree is **6.6.157** (`pending-6.6`). The two-line SKB leak is
present here, was introduced by a commit already in this tree, and
applies cleanly.
===============================================================
PHASE 1: COMMIT MESSAGE FORENSICS
===============================================================
**Step 1.1: PARSE THE SUBJECT LINE**
Record: **[wifi: mt76: mt7603]** **[free]** **[free the generated beacon
SKB when queue-stuck recovery bails out]**
**Step 1.2: PARSE ALL COMMIT MESSAGE TAGS**
Record:
- **Fixes:** none (expected for this pipeline)
- **Reported-by:** none
- **Tested-by:** none
- **Reviewed-by:** none
- **Acked-by:** none
- **Link:**
`https://patch.msgid.link/20260611215658.259324-1-mail@david-
bauer.net`
- **Cc: stable:** none (expected)
- **Signed-off-by:** David Bauer (author); Felix Fietkau (mt76
maintainer). Ignore any Sasha Levin SOB if present in candidate
wrapping.
Mainline SHA (from `origin/master`):
`965cbdbdfbd37a659a05ff88e49c216975bd9d2e`
AuthorDate: 2026-06-11; applied by Felix Fietkau 2026-07-31.
**Step 1.3: ANALYZE THE COMMIT BODY TEXT**
Record:
- **Bug:** After `ieee80211_beacon_get()`, if `mt76_poll()` times out on
`MT_DMA_FQCR0` (beacon/BMC queue flush stuck), the function `goto out`
without freeing the SKB.
- **Symptom:** SKB leak whenever the beacon queue is detected stuck and
recovery is scheduled. Commit message typo: “deected”.
- **Version info:** none in the message.
- **Root cause (author):** beacon SKB not freed on the stuck-queue error
path.
**Step 1.4: DETECT HIDDEN BUG FIXES**
Record: Not a disguised cleanup. Explicit leak fix: two
`dev_kfree_skb(skb)` calls on error paths.
===============================================================
PHASE 2: DIFF ANALYSIS - LINE BY LINE
===============================================================
**Step 2.1: INVENTORY THE CHANGES**
Record:
- File: `drivers/net/wireless/mediatek/mt76/mt7603/beacon.c` (**+2 /
-0**)
- Function: `mt7603_update_beacon_iter()`
- Scope: **single-file surgical fix**
**Step 2.2: UNDERSTAND THE CODE FLOW CHANGE**
Record (both hunks, same pattern):
Before: `ieee80211_beacon_get()` allocates `skb`. Flush BCN or BMC via
`MT_DMA_FQCR0`. If poll times out: set `dev->beacon_check =
MT7603_WATCHDOG_TIMEOUT` and `goto out`. Unlock. **SKB never queued and
never freed.**
After: same, but `dev_kfree_skb(skb)` before `goto out`.
Success path unchanged: `mt76_tx_queue_skb()` still takes ownership.
**Step 2.3: IDENTIFY THE BUG MECHANISM**
Record:
- **Category:** error-path resource leak (SKB)
- **Mechanism:** mac80211 docs: *“The driver is responsible for freeing
the returned skb.”* Error `goto` skipped both queueing and free. Fix
adds the missing free.
**Step 2.4: ASSESS THE FIX QUALITY**
Record:
- Obviously correct; only the two error returns; no API/lock/structure
change.
- **Regression risk:** very low. Success path still hands the SKB to
DMA. `dev_kfree_skb` is `consume_skb` (stats slightly less precise
than `kfree_skb` on a drop); maintainer accepted it. No double-free:
frees only happen before queueing.
===============================================================
PHASE 3: GIT HISTORY INVESTIGATION
===============================================================
**Step 3.1: BLAME THE CHANGED LINES**
Record:
- Leak `goto out` introduced by **`8caa9dd3d1a7c9`** “wifi: mt76:
mt7603: improve stuck beacon handling” (Greg KH, 2023-11-20), stable
rewrite of upstream **`3176205933494`** (Felix Fietkau, 2023-07-28).
- `ieee80211_beacon_get(..., 0)` from `6e8912a503759` (MLO 3-arg API);
already in this tree.
- Driver added in `c8846e1015022` (2018). Pre-2023 code queued the SKB
even if poll failed; the 2023 change moved queueing after the polls
and added the leaky `goto`.
**Step 3.2: FOLLOW THE FIXES: TAG**
Record: No Fixes: tag. Buggy commit in **this** tree is `8caa9dd3d1a7c9`
(`git merge-base --is-ancestor` = yes). Upstream `3176205933494` is not
an ancestor (stable SHA rewrite). No later origin/master commits touch
this file after `965cbdbdfbd37`.
**Step 3.3: CHECK FILE HISTORY FOR RELATED CHANGES**
Record (this tree, path-limited): last functional change on this file is
the stuck-beacon commit itself. Standalone; not patch X/Y.
**Step 3.4: CHECK THE AUTHOR'S OTHER COMMITS**
Record: David Bauer already has mt76 commits in this tree (including
mt7603 EEPROM ID). Felix Fietkau is listed maintainer and applied the
patch.
**Step 3.5: CHECK FOR DEPENDENT/PREREQUISITE COMMITS**
Record: None. Same function, same `ieee80211_beacon_get(hw, vif, 0)`,
same poll/`goto out`. `git apply --check` of `965cbdbdfbd37` succeeded.
Standalone.
===============================================================
PHASE 4: MAILING LIST AND EXTERNAL RESEARCH
===============================================================
**Step 4.1: FIND THE ORIGINAL PATCH DISCUSSION**
Record:
- `b4 dig -c 965cbdbdfbd37` →
https://patch.msgid.link/20260611215658.259324-1-mail@david-bauer.net
- `b4 dig -a`: **v1 only**
- Thread mbox: patch only, **no replies**, no NAK, no reviewer Cc:
stable
- lore.kernel.org WebFetch: **403** (used b4 + openwall/patchew mirrors)
**Step 4.2: CHECK WHO REVIEWED THE PATCH**
Record (`b4 dig -w`): To/Cc included Felix Fietkau, Lorenzo Bianconi,
MediaTek mt76 reviewers, linux-wireless. Applied by Felix with his SOB.
No Reviewed-by.
**Step 4.3: SEARCH FOR THE BUG REPORT**
Record: No Reported-by, syzbot, or bugzilla. Author-found leak on code
inspection. Openwall/Ratatoskr confirm the same v1 text, no discussion.
**Step 4.4: CHECK FOR RELATED PATCHES AND SERIES**
Record: Standalone `[PATCH mt76]`. No series. No follow-up on
`origin/master` for this file.
**Step 4.5: CHECK STABLE MAILING LIST HISTORY**
Record: lore.kernel.org/stable WebFetch **403**. No stable discussion in
the saved thread. UNVERIFIED whether anyone already asked stable@;
absence is not a negative signal.
===============================================================
PHASE 5: CODE SEMANTIC ANALYSIS
===============================================================
semcode MCP: **not available**. Used grep/read.
**Step 5.1: IDENTIFY KEY FUNCTIONS**
Record: `mt7603_update_beacon_iter()` only.
**Step 5.2: TRACE CALLERS**
Record:
- Called from `mt7603_pre_tbtt_tasklet()` via
`ieee80211_iterate_active_interfaces_atomic()`.
- Tasklet scheduled from `mt7603_irq_handler()` on
`MT_HW_INT3_PRE_TBTT0`.
- Reachable whenever the device is an AP with beacons enabled
(`beacon_mask`).
**Step 5.3: TRACE CALLEES**
Record: `ieee80211_beacon_get` (driver owns SKB), `mt76_poll`/`mt76_wr`,
`mt76_tx_queue_skb` → `mt76_dma_tx_queue_skb` (takes SKB; error path
uses `ieee80211_tx_status_ext`).
**Step 5.4: FOLLOW THE CALL CHAIN**
Record: userspace/AP stack enables beaconing → hardware pre-TBTT IRQ →
tasklet → iterator. Unprivileged clients do not trigger it directly;
**any AP/router using this chip in AP mode can**. Stuck DMA/FQCR0 is the
error trigger. `mac_work` runs every `MT7603_WATCHDOG_TIME` (100 ms) and
treats `beacon_check >= 10` as `RESET_CAUSE_BEACON_STUCK`.
**Step 5.5: SEARCH FOR SIMILAR PATTERNS**
Record: Other mt76 chips use `ieee80211_beacon_get_template` /
`mt76x02_mac_set_beacon` and do not share this FQCR0 poll/`goto out`
pattern. mt76x02 has no equivalent leak.
===============================================================
PHASE 6: CROSS-REFERENCING AGAINST THE LOCAL TREE
===============================================================
**Step 6.1: DOES THE BUGGY CODE EXIST IN THIS TREE?**
Record: **Yes.** `drivers/net/wireless/mediatek/mt76/mt7603/beacon.c`
lines 57–66: poll timeout → set watchdog → `goto out` with no free.
Local: `git describe` → `p-6.6-3-g04810563abb71`, `make kernelversion` →
**6.6.157**. Bug since 8caa9dd3d1a7c9 (stuck-beacon handling). Candidate
`965cbdbdfbd37` is **not** an ancestor of HEAD.
**Step 6.2: CHECK FOR BACKPORT COMPLICATIONS**
Record: **Clean apply** (`git show 965cbdbdfbd37 | git apply --check`).
Surrounding function matches mainline hunks.
**Step 6.3: CHECK IF RELATED FIXES ARE ALREADY HERE**
Record: No other “free beacon SKB” commit. Other mt76 leak fixes
(`ec4a608bca405` probe leak, etc.) are unrelated.
===============================================================
PHASE 7: SUBSYSTEM AND MAINTAINER CONTEXT
===============================================================
**Step 7.1: IDENTIFY THE SUBSYSTEM AND ITS CRITICALITY**
Record: **wifi / mt76 / mt7603** (`CONFIG_MT7603E`: MT7603E PCIe and
MT7628/MT7688 SoC WLAN). **IMPORTANT** for those devices (common OpenWrt
APs), not CORE for every 6.6 user.
**Step 7.2: ASSESS SUBSYSTEM ACTIVITY**
Record: Mature driver (2018); this file is quiet. Bug is old (2023
stuck-beacon change), not a new-feature side effect.
===============================================================
PHASE 8: IMPACT AND RISK ASSESSMENT
===============================================================
**Step 8.1: DETERMINE WHO IS AFFECTED**
Record: **Driver-specific / config-specific:** `CONFIG_MT7603E`,
AP/beaconing. MT7628/MT7688 SoCs are widely deployed in consumer
routers.
**Step 8.2: DETERMINE THE TRIGGER CONDITIONS**
Record:
- Trigger: FQCR0 poll timeout (5 ms) while updating beacons — the same
stuck-beacon condition this driver already recovers from.
- Frequency: pre-TBTT (~beacon interval, typically ~100 ms) per AP vif
(up to 4). Watchdog work every 100 ms usually resets after one such
event, so **~1 SKB per vif per stuck incident** if recovery works;
**recurring** if the MAC stays stuck.
- Unprivileged trigger: no (AP beacon path).
**Step 8.3: DETERMINE THE FAILURE MODE SEVERITY**
Record: **SKB leak**, not oops/UAF/corruption. **MEDIUM** (HIGH only if
stuck-beacon storms on a low-RAM AP). Still a real leak on a path
already considered serious enough to backport.
**Step 8.4: CALCULATE RISK-BENEFIT RATIO**
Record:
- **Benefit:** stops leaking beacon frames on a known hardware-stuck
path.
- **Risk:** very low (2 lines, error path only, clean apply).
- **Ratio:** favor backport.
===============================================================
PHASE 9: FINAL SYNTHESIS
===============================================================
**Step 9.1: COMPILE THE EVIDENCE**
FOR:
- Confirmed leak vs mac80211 SKB ownership.
- Buggy code is in this 6.6.157 tree (`8caa9dd3d1a7c9`).
- +2 lines, obviously correct, clean apply, no deps.
- Maintainer-applied.
- Same recovery path that already justified a stable backport.
- MT7603/MT76x8 used on production APs.
AGAINST:
- Error-path leak; volume per incident is small if watchdog resets.
- No crash/CVE/syzbot/user report.
- No Reviewed-by; mailing list silent.
- Not a core-kernel path.
UNRESOLVED:
- lore.kernel.org HTTP 403; stable@ search not fetched (b4/mbox used
instead).
- Exact leak rate if reset fails repeatedly: not measured on hardware.
**Step 9.2: APPLY THE STABLE RULES CHECKLIST**
1. Obviously correct and tested? **PASS** — ownership is documented;
maintainer applied. No extra Tested-by.
2. Fixes a real bug that affects users? **PASS** — SKB leak on stuck-
beacon recovery.
3. Important issue? **PASS** — resource leak on a periodic AP path (not
a one-shot init leak). Severity medium, not a panic.
4. Small and contained? **PASS** — 2 lines, one function.
5. No new features or APIs? **PASS**.
6. Can apply to the local tree? **PASS** — verified with `git apply
--check`.
**Step 9.3: CHECK FOR EXCEPTION CATEGORIES**
Record: Not a device-ID/quirk/DT/build/docs exception. Ordinary small
leak fix.
**Step 9.4: MAKE YOUR DECISION**
This is a two-line error-path `kfree` for a leak that exists in 6.6.157,
introduced by a stuck-beacon change already on this branch. Risk is
negligible; benefit is stopping SKB leaks on MT7603/MT76x8 APs when the
beacon DMA path wedges. That meets stable rules for this tree.
------------------------------------------------
What the commit solves for this tree
------------------------------------------------
In `mt7603_update_beacon_iter()`, `ieee80211_beacon_get()` returns an
SKB the driver must free. On FQCR0 poll timeout the function sets the
beacon watchdog and returns without queueing or freeing. That path is
the stuck-beacon recovery added in `8caa9dd3d1a7c9`, which is already
here. Each timeout leaks one beacon SKB per AP interface. The patch only
adds `dev_kfree_skb(skb)` on those two returns.
Risk vs benefit: almost no regression surface; the leak is real whenever
that recovery runs.
------------------------------------------------
Verification
------------------------------------------------
- [Phase 1] Tags: Link msgid `20260611215658.259324-1-mail@david-
bauer.net`; SOBs David Bauer + Felix Fietkau; no Fixes/Reported-
by/Cc:stable.
- [Phase 1] Mainline commit `965cbdbdfbd37` on `origin/master`.
- [Phase 2] Diff: +2 `dev_kfree_skb(skb)` in `mt7603_update_beacon_iter`
poll-fail paths; success path still `mt76_tx_queue_skb`.
- [Phase 2] `include/net/mac80211.h`: “The driver is responsible for
freeing the returned skb.”
- [Phase 2] `dev_kfree_skb` → `consume_skb` in `include/linux/skbuff.h`.
- [Phase 3] `git blame`: leaky `goto out` from `8caa9dd3d1a7c9` (stable
form of `3176205933494`).
- [Phase 3] `git merge-base --is-ancestor 8caa9dd3d1a7c9 HEAD` → yes;
`965cbdbdfbd37` → no; `3176205933494` → no (rewritten).
- [Phase 3] `git show 8caa9dd3d1a7c9`: moved `mt76_tx_queue_skb` after
polls and added `goto out` without free.
- [Phase 4] `b4 dig -c 965cbdbdfbd37`: v1 only; no replies in mbox.
- [Phase 4] `b4 dig -w`: mt76 maintainers + linux-wireless on To/Cc.
- [Phase 4] lore WebFetch 403; openwall/patchew/ratatoskr match v1, no
review replies.
- [Phase 5] Caller: `mt7603_pre_tbtt_tasklet` ← `mt7603_irq_handler`
PRE_TBTT0.
- [Phase 5] Watchdog: `MT7603_WATCHDOG_TIME` 100 ms, timeout 10;
`mt7603_mac_work` uses `beacon_check` with `check == NULL`.
- [Phase 6] `git describe HEAD` → `p-6.6-3-g04810563abb71`; `make
kernelversion` → 6.6.157.
- [Phase 6] Local `beacon.c` still missing the kfrees (lines 57–66).
- [Phase 6] `git apply --check` of `965cbdbdfbd37` succeeded.
- [Phase 7] `CONFIG_MT7603E`; MAINTAINERS: Felix Fietkau.
- [Phase 8] Failure mode: SKB leak on stuck-beacon recovery; severity
MEDIUM.
- UNVERIFIED: stable@ mailing-list archive (HTTP 403); hardware leak
rate if reset keeps failing.
**YES**
drivers/net/wireless/mediatek/mt76/mt7603/beacon.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/net/wireless/mediatek/mt76/mt7603/beacon.c b/drivers/net/wireless/mediatek/mt76/mt7603/beacon.c
index 6457ee06bb5a1..62e8de6949d1a 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7603/beacon.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7603/beacon.c
@@ -56,6 +56,7 @@ mt7603_update_beacon_iter(void *priv, u8 *mac, struct ieee80211_vif *vif)
FIELD_PREP(MT_DMA_FQCR0_TARGET_QID, MT_TX_HW_QUEUE_BCN));
if (!mt76_poll(dev, MT_DMA_FQCR0, MT_DMA_FQCR0_BUSY, 0, 5000)) {
dev->beacon_check = MT7603_WATCHDOG_TIMEOUT;
+ dev_kfree_skb(skb);
goto out;
}
@@ -63,6 +64,7 @@ mt7603_update_beacon_iter(void *priv, u8 *mac, struct ieee80211_vif *vif)
FIELD_PREP(MT_DMA_FQCR0_TARGET_QID, MT_TX_HW_QUEUE_BMC));
if (!mt76_poll(dev, MT_DMA_FQCR0, MT_DMA_FQCR0_BUSY, 0, 5000)) {
dev->beacon_check = MT7603_WATCHDOG_TIMEOUT;
+ dev_kfree_skb(skb);
goto out;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 20+ messages in thread* [PATCH AUTOSEL 6.18-6.1] wifi: mt76: mt7915: configure noise floor reporting on reset
2026-10-19 13:44 [PATCH AUTOSEL 6.18-6.12] net: dsa: mt7530: check CORE_PLL_GROUP4 access in mt7531_setup() Sasha Levin
` (8 preceding siblings ...)
2026-10-19 13:47 ` [PATCH AUTOSEL 6.18-5.15] wifi: mt76: mt7603: free beacon SKB on error Sasha Levin
@ 2026-10-19 13:47 ` Sasha Levin
2026-10-19 13:48 ` [PATCH AUTOSEL 6.18-6.6] wifi: mt76: mt7603: file buffered frames under the TID reported to mac80211 Sasha Levin
` (8 subsequent siblings)
18 siblings, 0 replies; 20+ messages in thread
From: Sasha Levin @ 2026-10-19 13:47 UTC (permalink / raw)
To: patches, stable
Cc: David Bauer, Felix Fietkau, Sasha Levin, lorenzo, ryder.lee,
matthias.bgg, angelogioacchino.delregno, linux-wireless,
linux-kernel, linux-arm-kernel, linux-mediatek
From: David Bauer <mail@david-bauer.net>
[ Upstream commit a92cd5dd792a63a5d8a72142835382d4edbe9933 ]
When performing a full system recovery of the MCU on a dual-phy
platform, band 0 (usually 2.4GHz) stops reading correct noise floor
data.
This is due to noise floor reporting only being configured correctly
for the second device PHY.
Configure the respective registers correctly after restarting the MCU
firmware to fix reported noise-floor values.
Signed-off-by: David Bauer <mail@david-bauer.net>
Link: https://patch.msgid.link/20260516144944.2574053-1-mail@david-bauer.net
Signed-off-by: Felix Fietkau <nbd@nbd.name>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
LLM Generated explanations, may be completely bogus:
The local tree is **6.6.157** (`pending-6.6`). The buggy dual-PHY
restart path is present here, and this commit should be backported.
===============================================================
PHASE 1: COMMIT MESSAGE FORENSICS
===============================================================
**Step 1.1: PARSE THE SUBJECT LINE**
Record: **[wifi: mt76: mt7915]** **[configure]** configure noise floor
reporting after MCU reset on dual-PHY platforms. “Configure” here is
restoring register state that recovery currently skips, not a new
feature.
**Step 1.2: PARSE ALL COMMIT MESSAGE TAGS**
Record:
- Signed-off-by: David Bauer <mail@david-bauer.net> (author)
- Link: https://patch.msgid.link/20260516144944.2574053-1-mail@david-
bauer.net
- Signed-off-by: Felix Fietkau <nbd@nbd.name> (mt76 maintainer)
- No Fixes:, Reported-by:, Tested-by:, Reviewed-by:, Acked-by:, or Cc:
stable (absence is expected)
- Ignored: any pipeline “Upstream commit” / Sasha Levin SOB markers
**Step 1.3: ANALYZE THE COMMIT BODY TEXT**
Record:
- **Bug:** After full MCU recovery on a dual-PHY (DBDC) device, band 0
(usually 2.4 GHz) stops reporting correct noise floor.
- **Symptom:** Wrong NF / survey noise on the primary PHY; the second
PHY is configured correctly.
- **Root cause (author):** NF enable is only applied for the second PHY
after firmware restart.
- **Version info:** none in the message. The restart path has been in
this tree since before v6.6.
**Step 1.4: DETECT HIDDEN BUG FIXES**
Record: Not disguised cleanup. It is an explicit hardware-init fix. The
mechanism (clear `MT76_STATE_RUNNING` before `mt7915_run()`) also re-
runs the primary PHY’s PM/MAC init that the same `if (!running)` guard
skips, not only NF.
===============================================================
PHASE 2: DIFF ANALYSIS - LINE BY LINE
===============================================================
**Step 2.1: INVENTORY THE CHANGES**
Record:
- File: `drivers/net/wireless/mediatek/mt76/mt7915/mac.c` only
- Scope: ~+6/−2 in `mt7915_mac_restart()` (surgical, single function)
- Adds `bool run_main, run_ext`
- Replaces `test_bit(MT76_STATE_RUNNING)` with `test_and_clear_bit`,
then uses those saved flags to decide whether to call `mt7915_run()`
**Step 2.2: UNDERSTAND THE CODE FLOW CHANGE**
Record:
- **Before:** After firmware reload, `mt7915_run()` is called while both
PHYs still have `MT76_STATE_RUNNING`. `mt7915_dev_running()` is
therefore true.
- In this tree, `mt7915_run()` only programs primary-PHY PM/MAC/NF when
`!running`:
```32:58:drivers/net/wireless/mediatek/mt76/mt7915/main.c
if (!running) {
ret = mt76_connac_mcu_set_pm(&dev->mt76,
dev->phy.mt76->band_idx,
0);
...
mt7915_mac_enable_nf(dev, dev->phy.mt76->band_idx);
}
if (phy != &dev->phy) {
...
mt7915_mac_enable_nf(dev, phy->mt76->band_idx);
}
```
- Primary `mt7915_run()` therefore skips band-0 NF. Ext `mt7915_run()`
still hits `phy != &dev->phy` and enables band-1 NF. That matches the
commit message.
- `ieee80211_restart_hw()` after full reset does not repair this:
starting the main PHY while the ext PHY still has `MT76_STATE_RUNNING`
keeps `running == true`, so band 0 is skipped again; starting the ext
PHY then enables only the ext PHY’s NF.
- **After:** bits are cleared first, so the first `mt7915_run()` sees
`running == false` and programs band 0. Saved flags still prevent
starting a PHY that was never up.
**Step 2.3: IDENTIFY THE BUG MECHANISM**
Record: **Logic / hardware-init.** After MCU reload, IPI/NF registers
(`mt7915_mac_enable_nf`: `MT_WF_PHY_RXTD12_*` and
`MT_WF_PHY_RX_CTRL1_IPI_EN`) are not programmed for band 0.
`mt7915_mac_init_band()` does not enable NF; only `mt7915_run()` does.
**Step 2.4: ASSESS THE FIX QUALITY**
Record: Obviously correct. Same approach the mt76 maintainer asked for
on-list. Minimal. Mutex is already held in `mt7915_mac_full_reset()`;
`MT76_RESET` is already set. Risk is low: if `mt7915_run()` fails, the
RUNNING bits stay clear, but full reset retries and then calls
`ieee80211_restart_hw()`, which stop/start and restores them.
===============================================================
PHASE 3: GIT HISTORY INVESTIGATION
===============================================================
**Step 3.1: BLAME THE CHANGED LINES**
Record: The `test_bit` + `mt7915_run()` sequence was introduced in
`8a55712d124fd8` (“wifi: mt76: mt7915: enable full system reset
support”, Bo Jiao / Ryder Lee, 2022). `git describe --contains` →
`v6.2-rc1~...`. Present in this 6.6 tree (`git merge-base --is-ancestor
8a55712d124fd8 HEAD` succeeded).
**Step 3.2: FOLLOW THE FIXES: TAG**
Record: No Fixes: tag. Not applicable. The introducing commit is in this
tree.
**Step 3.3: CHECK FILE HISTORY FOR RELATED CHANGES**
Record: Related reset work already in this tree:
- `c71d2db21f153` improve hardware restart reliability
- `1e474cbe5db60` fix omac index assignment after hardware reset
- `72eabd4c1986b` firmware restart on devices with a second PCIe link
This patch is standalone; it does not depend on those.
`test_and_clear_bit(MT76_STATE_RUNNING)` is **not** in this tree (`git
grep` found no matches).
**Step 3.4: CHECK THE AUTHOR'S OTHER COMMITS**
Record: David Bauer is an OpenWrt/wireless contributor; in this tree he
already has `b6c39aaa85c4e` (mt7915 MCU re-init). Felix Fietkau (mt76
maintainer) signed off and designed the committed approach.
**Step 3.5: CHECK FOR DEPENDENT/PREREQUISITE COMMITS**
Record: No functional prerequisites. Surrounding `mt7915_init_txpower()`
signature and `napi_enable` placement differ from later mainline; those
are context only. The `run_main`/`run_ext` change applies with a small
context tweak.
===============================================================
PHASE 4: MAILING LIST AND EXTERNAL RESEARCH
===============================================================
**Step 4.1: FIND THE ORIGINAL PATCH DISCUSSION**
Record: `b4 dig -c` was not usable (commit SHA not in this checkout’s
master). `b4 mbox` on msgid `20260516144944.2574053-1-mail@david-
bauer.net` saved a 4-message thread.
- v1 (16 May 2026): 4-line change in `mt7915_run()`: `if (!running ||
(reset && phy == &dev->phy))`
- Felix (27 May): asked to clear `MT76_STATE_RUNNING` in
`mt7915_mac_restart` instead
- David: explained the per-PHY RUNNING guard (don’t start a PHY that was
never up)
- Felix (1 Jun): proposed exactly the committed `test_and_clear_bit`
pattern
No NAK. No reviewer `Cc: stable`. Committed diff is the maintainer
rewrite, still linked to the v1 msgid.
**Step 4.2: CHECK WHO REVIEWED THE PATCH**
Record: Recipients included Felix Fietkau, Lorenzo Bianconi, Ryder Lee,
Shayne Chen, Sean Wang, linux-wireless, linux-mediatek. Felix both
reviewed and applied.
**Step 4.3: SEARCH FOR THE BUG REPORT**
Record: No syzbot/bugzilla. Author describes a real dual-PHY MCU
recovery failure. That is a field observation, not a theoretical report.
**Step 4.4: CHECK FOR RELATED PATCHES AND SERIES**
Record: Single patch, not N/M. v1 vs committed is a maintainer rewrite
of the same fix, not a multi-patch series.
**Step 4.5: CHECK STABLE MAILING LIST HISTORY**
Record: No useful stable-list hit for this subject. No recorded reason
to keep it out of stable.
===============================================================
PHASE 5: CODE SEMANTIC ANALYSIS
===============================================================
**Step 5.1: IDENTIFY KEY FUNCTIONS**
Record: Modified: `mt7915_mac_restart()`. Behavior depends on
`mt7915_run()`, `mt7915_dev_running()`, `mt7915_mac_enable_nf()`.
**Step 5.2: TRACE CALLERS**
Record:
- `mt7915_mac_restart()` ← `mt7915_mac_full_reset()` (only caller in
this tree)
- `mt7915_mac_full_reset()` ← `mt7915_mac_reset_work()` when
`dev->recovery.restart`
- `recovery.restart` set in `mt7915_reset()` on WA/WM watchdog
(`MT_MCU_CMD_WDT_MASK`), which logs “firmware crash, attempting
recovery”
- `mt7915_run()` also from `mt7915_start()` (normal iface start); this
patch does not change that path
**Step 5.3: TRACE CALLEES**
Record: After firmware load: `mt7915_mcu_init_firmware`,
`mt7915_mcu_set_eeprom`, `mt7915_mac_init`, txpower/txbf, then
`mt7915_run()` (PM, `mt7915_mcu_set_mac`, `mt7915_mac_enable_nf`,
thermal, RTS, SKU, RX path).
**Step 5.4: FOLLOW THE CALL CHAIN**
Record: Triggered by firmware watchdog recovery on `CONFIG_MT7915E`
dual-PHY (mt7915/mt7916/mt798x DBDC), common on APs/routers. Not a
generic syscall crash path. Userspace sees bad survey noise
(`mt76_get_survey` → `SURVEY_INFO_NOISE_DBM`) and ACS can use it.
Debugfs can also force full reset (`b662b71`).
**Step 5.5: SEARCH FOR SIMILAR PATTERNS**
Record: No `test_and_clear_bit(MT76_STATE_RUNNING)` in this tree’s mt76.
Sibling chips (mt7615/mt7996) have similar NF helpers; this fix is
mt7915-restart-specific.
===============================================================
PHASE 6: CROSS-REFERENCING AGAINST THE LOCAL TREE
===============================================================
**Step 6.1: DOES THE BUGGY CODE EXIST IN THIS TREE?**
Record: Yes. `mt7915_mac_restart()` at
`drivers/net/wireless/mediatek/mt76/mt7915/mac.c:1397-1407` still uses
`test_bit` without clearing. Introduced v6.2-era (`8a55712d124fd8`),
present since this 6.6 branch.
**Step 6.2: CHECK FOR BACKPORT COMPLICATIONS**
Record: **Minor context.** Mainline hunk context uses
`mt7915_init_txpower(&dev->phy)` / `mt7915_init_txpower(phy2)`; this
tree still has `mt7915_init_txpower(dev, &dev->mphy.sband_* )`.
`napi_enable` vs `local_bh_disable` order in the `out:` path also
differs. The RUNNING-bit change itself matches this tree. Easy manual
backport; not a rewrite.
**Step 6.3: CHECK IF RELATED FIXES ARE ALREADY HERE**
Record: Reset reliability/omac-after-reset fixes are here. This NF re-
init after MCU recovery is not.
===============================================================
PHASE 7: SUBSYSTEM AND MAINTAINER CONTEXT
===============================================================
**Step 7.1: IDENTIFY THE SUBSYSTEM AND ITS CRITICALITY**
Record: **wifi / mt76 mt7915**
(`drivers/net/wireless/mediatek/mt76/mt7915/`). **IMPORTANT** for users
of these radios (filogic/mt7915 DBDC APs), not core mm/net. Not staging.
**Step 7.2: ASSESS SUBSYSTEM ACTIVITY**
Record: Mature driver, still getting reset-path fixes in this 6.6 tree.
Not a newly added subsystem.
===============================================================
PHASE 8: IMPACT AND RISK ASSESSMENT
===============================================================
**Step 8.1: DETERMINE WHO IS AFFECTED**
Record: Driver-specific, dual-PHY `CONFIG_MT7915E` after full MCU
recovery. Widely used on embedded/AP hardware.
**Step 8.2: DETERMINE THE TRIGGER CONDITIONS**
Record: Firmware WA/WM watchdog → full recovery. Unprivileged users
cannot trigger it directly. Timing is the recovery path, not a race.
Debugfs reset can also hit it.
**Step 8.3: DETERMINE THE FAILURE MODE SEVERITY**
Record: Wrong band-0 noise floor / survey after recovery; ACS can pick a
worse channel. Not an oops, deadlock, or corruption. Connectivity was
not reported broken; `mac_init` still runs, so MAC datapath likely
survives. **Severity: MEDIUM.**
**Step 8.4: CALCULATE RISK-BENEFIT RATIO**
Record:
- **Benefit:** Medium. Restores intended PHY register state on a
recovery path this tree already treats as backport-worthy.
- **Risk:** Low. ~8 lines, one function, maintainer-specified, under
existing reset mutex.
- **Ratio:** Favorable.
===============================================================
PHASE 9: FINAL SYNTHESIS
===============================================================
**Step 9.1: COMPILE THE EVIDENCE**
FOR:
- Real dual-PHY bug after MCU full recovery; primary PHY NF registers
never reprogrammed
- Code and introducing commit are in 6.6.157
- Small, obviously correct, maintainer-directed
- Same `!running` skip also omits band-0 `set_pm`/`set_mac` on that path
- This tree already backported other mt7915 reset corrections
- Dual-PHY mt7915/mt798x is common production AP hardware
AGAINST:
- Not a crash, UAF, deadlock, or security issue
- Trigger is firmware watchdog recovery, not a hot path
- User-visible effect is mainly survey/ACS noise, not a reported outage
- Apply needs a trivial context adjustment
UNRESOLVED:
- Upstream SHA is not on this checkout’s `master`, so `b4 dig -c <sha>`
was not run (thread retrieved via msgid instead)
- No independent confirmation that band-0 MAC/PM skip causes traffic
loss (author only reported NF)
**Step 9.2: APPLY THE STABLE RULES CHECKLIST**
1. Obviously correct and tested? **PASS** — logic matches
`mt7915_run()`; maintainer specified this form
2. Fixes a real bug that affects users? **PASS** — wrong NF after
recovery on dual-PHY
3. Important issue? **PASS** (medium) — recovery leaves hardware
misconfigured; not a panic, but it is a real functional failure of
SER
4. Small and contained? **PASS** — one function, few lines
5. No new features or APIs? **PASS**
6. Can apply to the local tree? **PASS** — buggy code present; minor
context only
**Step 9.3: CHECK FOR EXCEPTION CATEGORIES**
Record: Not a new device ID/API. Closest class is hardware re-init after
reset (quirk-like). Qualifies on technical merit, not only via an
exception.
**Step 9.4: MAKE YOUR DECISION**
Backport. The 6.6 tree has the bug, the fix is surgical, and leaving MCU
recovery with band 0 NF unprogrammed is a real driver bug on hardware
this series already ships.
Verification:
- [Phase 1] Parsed tags: author David Bauer, Link to msgid, SOB Felix
Fietkau; no Fixes/Cc stable/Reported-by
- [Phase 1] Body: dual-PHY MCU recovery → band 0 NF wrong because only
PHY1 is configured
- [Phase 2] Diff: `mt7915_mac_restart()` saves/clears RUNNING then calls
`mt7915_run()`
- [Phase 2] Local `mt7915_run()`: primary NF only if
`!mt7915_dev_running()`; ext NF if `phy != &dev->phy`
- [Phase 2] `mt7915_mac_init_band()` does not set IPI/NF; only
`mt7915_mac_enable_nf()` does
- [Phase 3] `git blame` `mac.c:1397-1407` → `8a55712d124fd8` (v6.2-rc1);
ancestor of HEAD
- [Phase 3] `git grep test_and_clear_bit(MT76_STATE_RUNNING)` → no hits
in this tree
- [Phase 3] Related reset fixes already here (`c71d2db21f153`,
`1e474cbe5db60`); this NF fix is not
- [Phase 4] `b4 mbox` msgid → 4-message thread; Felix requested the
committed approach; no NAK
- [Phase 4] lore.kernel.org WebFetch returned 403; used b4 mbox +
openwall/ratatoskr instead
- [Phase 4] No meaningful stable-list discussion found
- [Phase 5] Call chain: WDT → `mt7915_reset()` → dump_work →
`mt7915_mac_reset_work()` → `mt7915_mac_full_reset()` →
`mt7915_mac_restart()`
- [Phase 5] Survey path: `mt7915_update_channel()` → `state->noise` →
`mt76_get_survey()`
- [Phase 6] `git describe HEAD` / `make kernelversion` → p-6.6-3 /
**6.6.157**
- [Phase 6] Local `mt7915_init_txpower()` signature differs from patch
context; RUNNING change still maps 1:1
- [Phase 8] Failure mode: incorrect band-0 noise after firmware crash
recovery; severity MEDIUM
- UNVERIFIED: exact upstream SHA (not on this `master`); whether band-0
`set_mac` skip also breaks traffic (not claimed by author)
The patch is a small, maintainer-reviewed correction of MCU recovery on
dual-PHY mt7915, and the buggy code is in this 6.6 tree.
**YES**
drivers/net/wireless/mediatek/mt76/mt7915/mac.c | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mac.c b/drivers/net/wireless/mediatek/mt76/mt7915/mac.c
index dda4e7d179536..55d2553addb13 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/mac.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/mac.c
@@ -1292,6 +1292,7 @@ mt7915_mac_restart(struct mt7915_dev *dev)
struct mt7915_phy *phy2;
struct mt76_phy *ext_phy;
struct mt76_dev *mdev = &dev->mt76;
+ bool run_main, run_ext;
int i, ret;
ext_phy = dev->mt76.phys[MT_BAND1];
@@ -1387,13 +1388,17 @@ mt7915_mac_restart(struct mt7915_dev *dev)
mt7915_init_txpower(phy2);
ret = mt7915_txbf_init(dev);
- if (test_bit(MT76_STATE_RUNNING, &dev->mphy.state)) {
+ run_main = test_and_clear_bit(MT76_STATE_RUNNING, &dev->mphy.state);
+ run_ext = ext_phy &&
+ test_and_clear_bit(MT76_STATE_RUNNING, &ext_phy->state);
+
+ if (run_main) {
ret = mt7915_run(dev->mphy.hw);
if (ret)
goto out;
}
- if (ext_phy && test_bit(MT76_STATE_RUNNING, &ext_phy->state)) {
+ if (run_ext) {
ret = mt7915_run(ext_phy->hw);
if (ret)
goto out;
--
2.53.0
^ permalink raw reply related [flat|nested] 20+ messages in thread* [PATCH AUTOSEL 6.18-6.6] wifi: mt76: mt7603: file buffered frames under the TID reported to mac80211
2026-10-19 13:44 [PATCH AUTOSEL 6.18-6.12] net: dsa: mt7530: check CORE_PLL_GROUP4 access in mt7531_setup() Sasha Levin
` (9 preceding siblings ...)
2026-10-19 13:47 ` [PATCH AUTOSEL 6.18-6.1] wifi: mt76: mt7915: configure noise floor reporting on reset Sasha Levin
@ 2026-10-19 13:48 ` Sasha Levin
2026-10-19 13:48 ` [PATCH AUTOSEL 6.18-5.10] wifi: mt76: mt7603: fix U-APSD service period termination Sasha Levin
` (7 subsequent siblings)
18 siblings, 0 replies; 20+ messages in thread
From: Sasha Levin @ 2026-10-19 13:48 UTC (permalink / raw)
To: patches, stable
Cc: Felix Fietkau, Sasha Levin, lorenzo, ryder.lee, matthias.bgg,
angelogioacchino.delregno, linux-wireless, linux-kernel,
linux-arm-kernel, linux-mediatek
From: Felix Fietkau <nbd@nbd.name>
[ Upstream commit 0bbd6c52dfff62b319963f54cd9370f9486e59d2 ]
The PS queue filed redirected frames under the TID taken from the TXD,
while mac80211 was told about the TID taken from the QoS header, or TID 0
for anything that is not a QoS data frame. When the two disagree,
mt7603_release_buffered_frames() skips the frame because it does not
match the requested TIDs, so it stays in the PS queue until the station
wakes up. Buffered MMPDUs hit this whenever they were sent on a
non-zero TID.
Use one TID for both.
Link: https://patch.msgid.link/20260801145334.1166751-8-nbd@nbd.name
Signed-off-by: Felix Fietkau <nbd@nbd.name>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
LLM Generated explanations, may be completely bogus:
This tree is **6.12.111** (`p-6.12-2`). The mt7603 PS-queue TID mismatch
is present here, the two-line fix applies cleanly, and it is a real AP-
mode buffering bug.
===============================================================
PHASE 1: COMMIT MESSAGE FORENSICS
===============================================================
**Step 1.1: PARSE THE SUBJECT LINE**
Record: **[wifi: mt76: mt7603]** **[file]** buffered frames under the
TID reported to mac80211. “File” here means enqueue/classify; the body
is a correctness fix so mac80211 and the driver PS queue use the same
TID.
**Step 1.2: PARSE ALL COMMIT MESSAGE TAGS**
Record:
- **Link:**
`https://patch.msgid.link/20260801145334.1166751-8-nbd@nbd.name`
(patch 08/10)
- **Signed-off-by:** Felix Fietkau (mt76 maintainer; ignore any Sasha
Levin SOB)
- **No Fixes:, Reported-by:, Tested-by:, Reviewed-by:, Acked-by:, or Cc:
stable** (absence expected for this review)
**Step 1.3: ANALYZE THE COMMIT BODY TEXT**
Record:
- **Bug:** Redirected PS frames are queued under the TXD TID, while
`ieee80211_sta_set_buffered()` is told the QoS-header TID, or TID 0
for non-QoS data / MMPDUs.
- **Symptom:** `mt7603_release_buffered_frames()` skips the skb (`tids &
BIT(skb->priority)` fails). The frame sits in `msta->psq` until the
station fully wakes (`mt7603_sta_ps()` splices the whole queue).
Buffered MMPDUs hit this whenever the TXD TID is non-zero.
- **Root cause:** Two different TID sources for the same frame.
- **Fix:** Use the same `tid` for both `skb->priority` and
`ieee80211_sta_set_buffered()`.
**Step 1.4: DETECT HIDDEN BUG FIXES**
Record: Not a disguised cleanup. It is an explicit protocol/correctness
fix.
===============================================================
PHASE 2: DIFF ANALYSIS - LINE BY LINE
===============================================================
**Step 2.1: INVENTORY THE CHANGES**
Record:
- **File:** `drivers/net/wireless/mediatek/mt76/mt7603/dma.c` (+1 / −1)
- **Function:** `mt7603_rx_loopback_skb()`
- **Scope:** single-file surgical fix
**Step 2.2: UNDERSTAND THE CODE FLOW CHANGE**
Record:
- **Before:** `skb->priority = FIELD_GET(MT_TXD1_TID, val)` (3-bit TXD
field), then later `ieee80211_sta_set_buffered(sta, tid, true)` with
`tid` from the QoS header or 0.
- **After:** `skb->priority = tid` after that classification.
- **Path:** hardware PS redirect → MCU RX loopback → driver PS queue.
Not an init-only path.
**Step 2.3: IDENTIFY THE BUG MECHANISM**
Record: **Logic / correctness.** Enqueue key (`skb->priority`) and
mac80211 TIM/TID bitmap disagree, so `release_buffered_frames` never
dequeues those skbs during PS-Poll/U-APSD.
**Step 2.4: ASSESS THE FIX QUALITY**
Record: Obviously correct and minimal. `tid` is already 0–7
(`IEEE80211_QOS_CTL_TAG1D_MASK` or 0). No new locks, APIs, or data
structures. Regression risk is very low: release matching becomes
consistent with what mac80211 was already told.
===============================================================
PHASE 3: GIT HISTORY INVESTIGATION
===============================================================
**Step 3.1: BLAME THE CHANGED LINES**
Record:
- `skb->priority = FIELD_GET(MT_TXD1_TID, val)` comes from the original
driver (`c8846e1015022`, 2018).
- Split vs mac80211 TID: `e004b700660025` (2019,
`ieee80211_sta_set_buffered`) and `d55aa5e17461b8` (2019, QoS-only
TID, default 0).
- Current if/else (QoS / data / bufferable MMPDU) is `b473c0e47f04d`
(2024, “fix tx queue of loopback packets”), **already in this 6.12
tree**.
**Step 3.2: FOLLOW THE FIXES: TAG**
Record: No Fixes: tag. Buggy split has been in the driver since 2019;
MMPDU TID-0 reporting since `d55aa5e17461b8` / `b473c0e47f04d`.
**Step 3.3: CHECK FILE HISTORY FOR RELATED CHANGES**
Record: Recent `dma.c` history includes `b473c0e47f04d` and
`9b8d932053b8b`. This commit is **not** in HEAD (`git merge-base --is-
ancestor 0bbd6c52dfff62b319963f54cd9370f9486e59d2 HEAD` → not ancestor).
Standalone vs later 2026 PS series (see 3.5).
**Step 3.4: CHECK THE AUTHOR'S OTHER COMMITS**
Record: Felix Fietkau is the mt76 maintainer. Nearby author work on this
driver is unrelated (chainmask, EEPROM, WPDMA EOF). Same 10-patch series
contains other mt7603 PS fixes he wrote.
**Step 3.5: CHECK FOR DEPENDENT/PREREQUISITE COMMITS**
Record: Upstream SHA `0bbd6c52dfff62b319963f54cd9370f9486e59d2`. Series
08/10. Needed context `b473c0e47f04d` **is** in this tree. Later series
patches are **not** in this tree and are **not** required for this two-
line change:
- `697badc27a9b3` U-APSD EOSP
- `d5001f493fefd` clear buffered-TID when psq empty
- `636a883e2feef` re-arm HW PS after service period
Those fix other PS bugs; this patch only aligns enqueue TID with
`ieee80211_sta_set_buffered()`. It can apply standalone.
===============================================================
PHASE 4: MAILING LIST AND EXTERNAL RESEARCH
===============================================================
**Step 4.1: FIND THE ORIGINAL PATCH DISCUSSION**
Record:
- `b4 dig -c 0bbd6c52dfff6` →
https://patch.msgid.link/20260801145334.1166751-8-nbd@nbd.name
- Single series revision (v1 only; `-a` showed only this series)
- Thread: 11 messages = 10 patches + kernel test robot on **patch 10
only** (mt7996 OOB, unrelated)
- No NAK, no reviewer risk comments, no Cc: stable on this patch
**Step 4.2: CHECK WHO REVIEWED THE PATCH**
Record: `b4 dig -w`: To `linux-wireless@vger.kernel.org`, From Felix
Fietkau. No extra Reviewed-by. Author is the subsystem maintainer and
applied it himself.
**Step 4.3: SEARCH FOR THE BUG REPORT**
Record: No Reported-by / bugzilla / syzbot. Failure mode is code-
derived. Related series patch 07 mentions U-APSD retry storms/packet
loss; that is a **different** bug.
**Step 4.4: CHECK FOR RELATED PATCHES AND SERIES**
Record: `[PATCH 01/10]` adds `MT_DRV_HW_PS_BUFFERING` for firmware-TIM
chips (mt7915/mt7996), not mt7603 loopback. mt7603 patches 05–07 are
sibling PS fixes, not semantic prerequisites of 08.
**Step 4.5: CHECK STABLE MAILING LIST HISTORY**
Record: No useful stable-list hit for this subject (lore.kernel.org
fetch 403; web search returned unrelated archives). UNVERIFIED that
anyone already requested/rejected it for stable.
===============================================================
PHASE 5: CODE SEMANTIC ANALYSIS
===============================================================
**Step 5.1: IDENTIFY KEY FUNCTIONS IN THE DIFF**
Record: `mt7603_rx_loopback_skb()` only.
**Step 5.2: TRACE CALLERS**
Record:
- Called only from `mt7603_queue_rx_skb()` when `q == MT_RXQ_MCU` and
the packet is not `PKT_TYPE_RX_EVENT` (HW-redirected TX).
- `mt7603_queue_rx_skb` is `.rx_skb` in
`drivers/net/wireless/mediatek/mt76/mt7603/init.c`.
- Release path: mac80211 `drv_release_buffered_frames` →
`mt7603_release_buffered_frames()` which filters on
`BIT(skb->priority)` (verified at `main.c:458`).
**Step 5.3: TRACE CALLEES**
Record: `ieee80211_is_data_qos` / `ieee80211_is_data` /
`ieee80211_is_bufferable_mmpdu(skb)` (present in this tree’s
`ieee80211.h`), `ieee80211_sta_set_buffered`, `skb_queue` under
`ps_lock`.
**Step 5.4: FOLLOW THE CALL CHAIN**
Record: Reachable in AP mode when a station is in PS and the PSE
redirects TX. Userspace/network traffic plus sleeping clients trigger
it. Not a syscall crash path; it is a common AP operation on this
hardware.
**Step 5.5: SEARCH FOR SIMILAR PATTERNS**
Record: Other mt76 chips use `mt76_release_buffered_frames()`; mt7603
has its own `psq`. No duplicate of this exact TXD-vs-QoS TID split
elsewhere in this driver.
===============================================================
PHASE 6: CROSS-REFERENCING AGAINST THE LOCAL TREE
===============================================================
**Step 6.1: DOES THE BUGGY CODE EXIST IN THIS TREE?**
Record: **Yes.** `dma.c` still has:
```42:75:drivers/net/wireless/mediatek/mt76/mt7603/dma.c
skb->priority = FIELD_GET(MT_TXD1_TID, val);
...
ieee80211_sta_set_buffered(sta, tid, true);
```
`MT_TXD1_TID` is `GENMASK(22, 20)`. `mt7603_release_buffered_frames()`
still skips on `!(tids & BIT(skb->priority))`. Bug introduced 2019;
still here in 6.12.111. Upstream commit is **not** an ancestor of HEAD.
**Step 6.2: CHECK FOR BACKPORT COMPLICATIONS**
Record: **Clean apply.** `git apply --check` of `0bbd6c52dfff6`
succeeded. This tree still uses `rcu_dereference(dev->mt76.wcid[idx])`
rather than `mt76_wcid_ptr()`; that is unused context, not a conflict.
**Step 6.3: CHECK IF RELATED FIXES ARE ALREADY HERE**
Record: No equivalent TID alignment. `git log --grep='buffered frames
under the TID'` on this path is empty. Sibling 2026 PS series patches
are not in this tree.
===============================================================
PHASE 7: SUBSYSTEM AND MAINTAINER CONTEXT
===============================================================
**Step 7.1: IDENTIFY THE SUBSYSTEM AND ITS CRITICALITY**
Record: **wifi / mt76 / mt7603** (`CONFIG_MT7603E`: MT7603E PCIe and
MT7628/MT7688 SoC WLAN). **IMPORTANT** (widely used AP/router silicon),
not core mm/net.
**Step 7.2: ASSESS SUBSYSTEM ACTIVITY**
Record: Mature driver, still receiving maintainer fixes. Not staging.
===============================================================
PHASE 8: IMPACT AND RISK ASSESSMENT
===============================================================
**Step 8.1: DETERMINE WHO IS AFFECTED**
Record: **Driver-specific:** AP (and any PS-buffering) users of
MT7603/MT7628/MT7688. Not universal.
**Step 8.2: DETERMINE THE TRIGGER CONDITIONS**
Record: Station in power-save; HW redirects frames into the driver PS
queue; mac80211 later releases by TID (PS-Poll / U-APSD). Common on APs
with phones/IoT clients. Unprivileged Wi-Fi clients can trigger it by
sleeping. MMPDUs with non-zero TXD TID are the documented always-hit
case.
**Step 8.3: DETERMINE THE FAILURE MODE SEVERITY**
Record: Frames are not released during the service period. They wait
until the station leaves PS, or they can be dropped if `psq` hits 64.
That delays bufferable management (deauth/disassoc/action) and
mismatched-TID data. **Severity: HIGH** for AP connectivity; not a
kernel oops.
**Step 8.4: CALCULATE RISK-BENEFIT RATIO**
Record: **Benefit: high** for this hardware (PS buffering actually works
for the TIDs mac80211 asked for). **Risk: very low** (2 lines, no
locking/API change, applies cleanly). Ratio strongly favors backport.
===============================================================
PHASE 9: FINAL SYNTHESIS
===============================================================
**Step 9.1: COMPILE THE EVIDENCE**
FOR:
- Real, explained bug; mechanism confirmed in this tree’s `dma.c` and
`main.c`
- User-visible AP PS failure (stuck/delayed frames, possible psq
overflow drops)
- 2-line, obviously correct, maintainer-authored
- Applies cleanly to 6.12.111
- Prerequisite loopback-queue rewrite (`b473c0e47f04d`) already present
- Does not need the rest of the 10-patch series
AGAINST:
- Not a crash, UAF, or CVE
- No reporter / Tested-by / Fixes tag
- Other mt7603 PS bugs in the same series remain unfixed here (does not
make this patch wrong)
UNRESOLVED:
- No stable-list discussion found (lore 403 / search noise)
- No independent user report for this exact TID mismatch
**Step 9.2: APPLY THE STABLE RULES CHECKLIST**
1. Obviously correct and tested? **PASS** — two-line alignment; in
mainline from the maintainer
2. Real bug affecting users? **PASS** — PS-buffered frames not released
until wake
3. Important issue? **PASS** — AP power-save correctness / delayed
MMPDUs; HIGH not panic
4. Small and contained? **PASS** — 2 lines, one function
5. No new features or APIs? **PASS**
6. Can apply to the local tree? **PASS** — clean apply on 6.12.111
**Step 9.3: CHECK FOR EXCEPTION CATEGORIES**
Record: None (not a device ID / quirk / DT / build / docs exception).
Qualifies as a normal contained bugfix.
**Step 9.4: MAKE YOUR DECISION**
Backport. This 6.12 tree has the exact buggy split, the fix is surgical,
and it restores mac80211-driven release of buffered frames (especially
MMPDUs) for a still-deployed wireless SoC.
------------------------------------------------
What the commit solves for stable users
------------------------------------------------
On MT7603/MT7628 APs, hardware-redirected PS frames are advertised to
mac80211 under one TID and stored under another. Service-period release
then skips them, so management and some data stay in the driver queue
until the client fully wakes (or the 64-entry queue drops them). Using
one TID for both makes `release_buffered_frames` find those skbs.
Risk vs benefit: two lines, no API/locking change, clean apply; benefit
is correct PS delivery on real AP hardware.
Concerns: sibling U-APSD/PS-rearm fixes are separate commits and not
required. No backport rewrite needed on this tree.
===============================================================
Verification
===============================================================
- [Phase 1] Tags: Link msgid `20260801145334.1166751-8-nbd@nbd.name`;
SOB Felix Fietkau; no Fixes/Reported-by/Cc stable
- [Phase 2] Diff: move `skb->priority` from `MT_TXD1_TID` to classified
`tid` in `mt7603_rx_loopback_skb` (+1/−1)
- [Phase 3] `git describe` / Makefile: **6.12.111**
(`p-6.12-2-gd38d58a4e0359`)
- [Phase 3] Blame/history: TXD priority from `c8846e1015022`; mac80211
TID from `e004b700660025` / `d55aa5e17461b8`; MMPDU/queue split
`b473c0e47f04d` **is** ancestor of HEAD
- [Phase 3] `git merge-base --is-ancestor
0bbd6c52dfff62b319963f54cd9370f9486e59d2 HEAD` → not present
- [Phase 3] Related series SHAs `697badc27a9b3`, `d5001f493fefd`,
`636a883e2feef` → not in HEAD; not required
- [Phase 4] `b4 dig -c 0bbd6c52dfff6`: lore match, v1 only; `-w`: linux-
wireless + author; robot reply only on patch 10
- [Phase 4] UNVERIFIED: stable@ discussion (lore 403)
- [Phase 5] Caller: `mt7603_queue_rx_skb` MCU loopback; release uses
`BIT(skb->priority)` at `main.c:458`
- [Phase 6] Local `dma.c:42` still assigns priority from TXD; `git apply
--check` of upstream diff **exit 0**
- [Phase 8] Failure mode: PS frames skipped until wake / possible psq
drop; HIGH connectivity, not oops
**YES**
drivers/net/wireless/mediatek/mt76/mt7603/dma.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/wireless/mediatek/mt76/mt7603/dma.c b/drivers/net/wireless/mediatek/mt76/mt7603/dma.c
index e26cc78fff949..25009e49e7771 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7603/dma.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7603/dma.c
@@ -39,7 +39,6 @@ mt7603_rx_loopback_skb(struct mt7603_dev *dev, struct sk_buff *skb)
val = le32_to_cpu(txd[1]);
idx = FIELD_GET(MT_TXD1_WLAN_IDX, val);
- skb->priority = FIELD_GET(MT_TXD1_TID, val);
if (idx >= MT7603_WTBL_STA - 1)
goto free;
@@ -72,6 +71,7 @@ mt7603_rx_loopback_skb(struct mt7603_dev *dev, struct sk_buff *skb)
hwq = MT_TX_HW_QUEUE_MGMT;
}
+ skb->priority = tid;
ieee80211_sta_set_buffered(sta, tid, true);
val = le32_to_cpu(txd[0]);
--
2.53.0
^ permalink raw reply related [flat|nested] 20+ messages in thread* [PATCH AUTOSEL 6.18-5.10] wifi: mt76: mt7603: fix U-APSD service period termination
2026-10-19 13:44 [PATCH AUTOSEL 6.18-6.12] net: dsa: mt7530: check CORE_PLL_GROUP4 access in mt7531_setup() Sasha Levin
` (10 preceding siblings ...)
2026-10-19 13:48 ` [PATCH AUTOSEL 6.18-6.6] wifi: mt76: mt7603: file buffered frames under the TID reported to mac80211 Sasha Levin
@ 2026-10-19 13:48 ` Sasha Levin
2026-10-19 13:49 ` [PATCH AUTOSEL 6.18-5.15] wifi: mt76: mt7603: add 0x7592 EEPROM chip ID Sasha Levin
` (6 subsequent siblings)
18 siblings, 0 replies; 20+ messages in thread
From: Sasha Levin @ 2026-10-19 13:48 UTC (permalink / raw)
To: patches, stable
Cc: Felix Fietkau, Sasha Levin, lorenzo, ryder.lee, matthias.bgg,
angelogioacchino.delregno, linux-wireless, linux-kernel,
linux-arm-kernel, linux-mediatek
From: Felix Fietkau <nbd@nbd.name>
[ Upstream commit 697badc27a9b3b2a8d86092abeed767714f735a2 ]
Frames released from the driver PS queue were all tagged with MORE_DATA
and none of them ever carried the EOSP bit, so from the client's point of
view a U-APSD service period was started but never finished. Clients that
keep their receiver on until EOSP arrives stop sending trigger frames,
and all downlink traffic for that station stalls until they give up.
ieee80211_sta_eosp() only cleared the service period state inside
mac80211, which is why the mismatch went unnoticed.
Assign MORE_DATA per frame and set the wire EOSP bit on the last one. If
the last released frame is a bufferable MMPDU it has no QoS control field
to carry EOSP, so let mac80211 append a QoS-Null frame instead.
Also stop handing the remaining frame budget to
mt76_release_buffered_frames() once frames have been released from the PS
queue: both would signal the end of the same service period. Releasing
fewer frames than requested is allowed, and MORE_DATA tells the client to
trigger again.
Link: https://patch.msgid.link/20260801145334.1166751-5-nbd@nbd.name
Signed-off-by: Felix Fietkau <nbd@nbd.name>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
LLM Generated explanations, may be completely bogus:
The local tree is **5.15.221** (`pending-5.15`). The buggy mt7603 U-APSD
path is present here and matches mainline before `697badc27a9b3`. This
is a real protocol fix for a stall, and it should be backported.
---
## PHASE 1: COMMIT MESSAGE FORENSICS
**Step 1.1: PARSE THE SUBJECT LINE**
Record: **[wifi/mt76/mt7603] [fix] [U-APSD service period never ends on
the wire]**
**Step 1.2: PARSE ALL COMMIT MESSAGE TAGS**
Record:
- `Link: https://patch.msgid.link/20260801145334.1166751-5-nbd@nbd.name`
— patch **05/10** of Felix Fietkau’s series
- `Signed-off-by: Felix Fietkau <nbd@nbd.name>` (mt76 maintainer)
- No `Fixes:`, no `Reported-by:`, no `Tested-by:`, no `Reviewed-by:`, no
`Cc: stable` (absence of the last two is expected in this pipeline)
- Ignore any `Signed-off-by: Sasha Levin` / `[Upstream commit ...]` if
present; they are candidate-prep markers
**Step 1.3: ANALYZE THE COMMIT BODY TEXT**
Record:
- **Bug:** Frames pulled from the driver PS queue all get `MORE_DATA`
and never `EOSP`. A U-APSD SP starts and never ends on the air.
- **Symptom:** Clients that stay awake until EOSP stop sending trigger
frames; **all downlink traffic for that STA stalls** until they give
up.
- **Root cause:** `ieee80211_sta_eosp()` only clears mac80211’s
`WLAN_STA_SP`. mac80211 documents that a driver implementing
`.release_buffered_frames` must set the **wire** EOSP bit itself.
- **Second bug in the same function:** leftover `nframes` is handed to
`mt76_release_buffered_frames()`, which ends the **same** SP a second
time.
- **Fix:** assign `MORE_DATA`/`EOSP` per frame; QoS-Null via
`ieee80211_send_eosp_nullfunc()` if the last frame is a bufferable
MMPDU; do not forward leftover budget once PS-queue frames were
released.
**Step 1.4: DETECT HIDDEN BUG FIXES**
Record: **Not hidden.** Subject and body describe a concrete protocol
failure with a user-visible stall.
---
## PHASE 2: DIFF ANALYSIS
**Step 2.1: INVENTORY THE CHANGES**
Record:
- File: `drivers/net/wireless/mediatek/mt76/mt7603/main.c` (**+63 /
−11**)
- Functions: `mt7603_ps_skb_hdr()` (new), `mt7603_ps_set_more_data` →
`mt7603_ps_set_flags`, `mt7603_release_buffered_frames`
- Scope: **single-file surgical fix**
**Step 2.2: UNDERSTAND THE CODE FLOW CHANGE**
Record:
- **Before:** every released PS-queue frame unconditionally ORs
`IEEE80211_FCTL_MOREDATA`; never sets/clears EOSP;
`ieee80211_sta_eosp()` is called if the list is non-empty, then
leftover `nframes` still go to `mt76_release_buffered_frames()`.
- **After:**
1. Walk remaining PS queue under `ps_lock` and build a pending-TID
bitmap.
2. If nothing was dequeued, fall through to
`mt76_release_buffered_frames()` (unchanged).
3. If anything was dequeued, **do not** also release from mac80211
TXQs.
4. `MORE_DATA` = not-last **or** more frames remain (mac80211
`more_data` or pending matching TIDs).
5. Wire `EOSP` only on the last frame and only for
`IEEE80211_FRAME_RELEASE_UAPSD`.
6. Last frame not QoS data → `ieee80211_send_eosp_nullfunc()`; else
`ieee80211_sta_eosp()`.
**Step 2.3: IDENTIFY THE BUG MECHANISM**
Record:
- **Category:** protocol / correctness (U-APSD SP termination), not
UAF/leak/race.
- **Mechanism:** driver never put EOSP on the air; clients that wait for
EOSP stop triggering; downlink stalls.
- Also: `MORE_DATA` was only set, never cleared. Recycled frames from
`mt7603_filter_tx()` can keep a stale bit; the new helper assigns both
bits.
**Step 2.4: ASSESS THE FIX QUALITY**
Record:
- Matches mac80211’s `.release_buffered_frames` contract
(`include/net/mac80211.h`: driver must set EOSP in the QoS header;
sending fewer frames than requested is allowed).
- `IEEE80211_QOS_CTL_EOSP` (0x0010) on the first QoS-control byte is the
correct on-wire bit.
- `ieee80211_send_eosp_nullfunc()` uses `IEEE80211_TX_STATUS_EOSP` on
the NDP; TX status then clears `WLAN_STA_SP`. iwlwifi already calls
this from BH/TX context; `.release_buffered_frames` must be atomic,
and `ieee80211_send_null_response()` uses `dev_alloc_skb` (GFP_ATOMIC)
+ `ieee80211_xmit`.
- Regression risk: **low–medium**. Logic is contained; PS-Poll does not
set wire EOSP (`uapsd` is false). Companion series patches 06–08 make
TIM / HW buffering / TID filing more complete but are not required for
this EOSP fix to compile or to be correct on its own.
---
## PHASE 3: GIT HISTORY INVESTIGATION
**Step 3.1: BLAME THE CHANGED LINES**
Record:
- `mt7603_release_buffered_frames`: `c8846e101502` (2018-11, **mt76: add
driver for MT7603E and MT7628/7688**)
- Unconditional MORE_DATA: `b126c8897435` (2019-03)
- `ieee80211_sta_eosp()` without wire EOSP: `b7001f46085e` (2019-03)
- All three are ancestors of this 5.15 tree.
**Step 3.2: FOLLOW THE FIXES: TAG**
Record: **No `Fixes:` tag.** Buggy behavior dates to driver introduction
/ 2019 PS-queue helpers, all in this tree.
**Step 3.3: CHECK FILE HISTORY FOR RELATED CHANGES**
Record: Mainline follow-ups on the same function (not in this tree):
- `d5001f493fef` — tell mac80211 when the PS queue is empty
(`ieee80211_sta_set_buffered(..., false)`)
- `636a883e2feef` — restore hardware PS buffering after an SP
These are related U-APSD bugs, not prerequisites for this diff.
**Step 3.4: CHECK THE AUTHOR'S OTHER COMMITS**
Record: Felix Fietkau is the mt76 maintainer and original author of this
driver. This is a maintainer fix.
**Step 3.5: CHECK FOR DEPENDENT/PREREQUISITE COMMITS**
Record: Patch **05/10**. Patches 01–03/09–10 target mt7915/mt7996 / MLO
/ new HW TIM — **not needed**. Patch 04 sets wire EOSP in generic
`mt76_release_buffered_frames()` (`tx.c`); mt7603 has its **own**
`.release_buffered_frames` and only calls the generic helper when the
driver PS queue is empty. This patch does not use new APIs or struct
fields. **Can apply standalone.**
---
## PHASE 4: MAILING LIST AND EXTERNAL RESEARCH
**Step 4.1: FIND THE ORIGINAL PATCH DISCUSSION**
Record:
- `b4 dig -c 697badc27a9b3` →
https://patch.msgid.link/20260801145334.1166751-5-nbd@nbd.name
- **v1 only** (no v2/v3)
- Thread is the 10-patch series plus a kernel-test-robot mail
- Robot error is on **patch 10 / patch 1** (`ieee80211_txq_aql_pending`
missing) — **unrelated** to this patch
- No NAKs, no reviewer risk flags, no `Cc: stable` suggestion in the
thread
**Step 4.2: CHECK WHO REVIEWED THE PATCH**
Record: `b4 dig -w`: To/Cc were **Felix Fietkau** and **linux-
wireless@**. No extra reviewer SOB. Maintainer self-applied into
wireless-next (listed in the 2026-08-06 wireless-next pull).
**Step 4.3: SEARCH FOR THE BUG REPORT**
Record: OpenWrt mt76 users reported U-APSD stalls / **iPhone freezes**
on MT7603 APs (openwrt/mt76#1080 / PR #1084). Testers said an EOSP-
related change made iPhone freezes go away; remaining TX-retry/loss is
the separate HW-buffering bug (series patch 07).
**Step 4.4: CHECK FOR RELATED PATCHES AND SERIES**
Record: Series 01–10 as above. This commit is self-contained. Patch 06
should be considered as a follow-up candidate (TIM never cleared); it is
not required for this hunk.
**Step 4.5: CHECK STABLE MAILING LIST HISTORY**
Record: No evidence this fix was discussed on stable@ or previously
rejected. UNVERIFIED that every stable archive was searchable
(lore.kernel.org returned 403 for some URLs); `b4`/openwall/syzbot CI
were used instead.
---
## PHASE 5: CODE SEMANTIC ANALYSIS
**Step 5.1: IDENTIFY KEY FUNCTIONS**
Record: `mt7603_release_buffered_frames`, `mt7603_ps_set_flags`,
`mt7603_ps_skb_hdr`
**Step 5.2: TRACE CALLERS**
Record: Assigned as `ieee80211_ops.release_buffered_frames` in this
file. mac80211 calls it for **PS-Poll and U-APSD** from the RX/PS path
(atomic). Reachable whenever an AP-mode STA uses power save.
**Step 5.3: TRACE CALLEES**
Record: `mt7603_wtbl_set_ps`, `mt7603_ps_tx_list` /
`mt76_tx_queue_skb_raw`, `mt76_release_buffered_frames` (empty-PS-queue
only), `ieee80211_sta_eosp`, `ieee80211_send_eosp_nullfunc` — all exist
in this tree.
**Step 5.4: FOLLOW THE CALL CHAIN**
Record: Client trigger (QoS-Null/PS-Poll) → mac80211 →
`mt7603_release_buffered_frames`. **Yes, userspace/STA traffic triggers
it.** Typical clients: phones with U-APSD.
**Step 5.5: SEARCH FOR SIMILAR PATTERNS**
Record: Generic `mt76_queue_ps_skb()` in this tree still only sets
`IEEE80211_TX_STATUS_EOSP` + MORE_DATA, not wire EOSP (mainline patch
04). `mt7603_rx_loopback_skb()` sets `ieee80211_sta_set_buffered(...,
true)` and never clears it (mainline patch 06). Same U-APSD family,
different bugs.
---
## PHASE 6: CROSS-REFERENCING AGAINST THE LOCAL TREE
**Step 6.1: DOES THE BUGGY CODE EXIST IN THIS TREE?**
Record: **Yes.** `mt7603_ps_set_more_data` and
`mt7603_release_buffered_frames` in
`drivers/net/wireless/mediatek/mt76/mt7603/main.c` are **byte-for-byte
identical** to the parent of `697badc27a9b3`. Bug since ~2018/2019.
Local tree: `p-5.15-2-g6703e5d2f3a29`, **5.15.221**. `git merge-base
--is-ancestor 697badc27a9b3 HEAD` → **not in this tree**.
**Step 6.2: CHECK FOR BACKPORT COMPLICATIONS**
Record: **Clean apply.** Same function bodies; needed APIs
(`ieee80211_send_eosp_nullfunc`, `ieee80211_get_qos_ctl`,
`IEEE80211_QOS_CTL_EOSP`, `IEEE80211_FRAME_RELEASE_UAPSD`) are in 5.15.
**Step 6.3: CHECK IF RELATED FIXES ARE ALREADY HERE**
Record: No related U-APSD EOSP/TIM/HW-rearm fixes on this file in this
tree.
---
## PHASE 7: SUBSYSTEM AND MAINTAINER CONTEXT
**Step 7.1: IDENTIFY THE SUBSYSTEM AND ITS CRITICALITY**
Record: **wifi / mt76 / mt7603** (`CONFIG_MT7603E`). Criticality:
**IMPORTANT** for users of that hardware (MT7603E / MT7628/MT7688 APs —
very common home routers), not core mm/net.
**Step 7.2: ASSESS SUBSYSTEM ACTIVITY**
Record: Mature driver (since 5.0-era). This is a long-standing bug, not
a regression in new code.
---
## PHASE 8: IMPACT AND RISK ASSESSMENT
**Step 8.1: DETERMINE WHO IS AFFECTED**
Record: **Driver-specific:** AP (or GO) mode on MT7603/MT7628 with
U-APSD (or PS-Poll) clients.
**Step 8.2: DETERMINE THE TRIGGER CONDITIONS**
Record: STA enters power save; hardware redirects frames into
`msta->psq`; STA sends a U-APSD trigger. Common for phones. Unprivileged
wireless clients can trigger it.
**Step 8.3: DETERMINE THE FAILURE MODE SEVERITY**
Record: **Downlink stall / client freeze** until the STA gives up
(disconnect/retry). Not a kernel oops. Severity: **HIGH** for affected
APs (connectivity loss), not CRITICAL kernel crash.
**Step 8.4: CALCULATE RISK-BENEFIT RATIO**
Record:
- **Benefit:** high for MT7603 AP users — restores U-APSD SP completion
so phones keep triggering.
- **Risk:** low–medium (contained ~50-line logic in one ops callback; no
API/lock/core changes).
- **Ratio:** benefit outweighs risk.
---
## PHASE 9: FINAL SYNTHESIS
**Step 9.1: COMPILE THE EVIDENCE**
**FOR:**
- Real, user-visible stall (U-APSD SP never ends on the air)
- Matches mac80211 driver contract
- Present in this 5.15 tree since driver introduction
- Functions identical to mainline parent → clean apply
- Small, one file, no new APIs
- Maintainer-authored, merged to mainline as `697badc27a9b3`
- Corroborated by OpenWrt MT7603/iPhone freeze reports
**AGAINST:**
- Not crash/UAF/security
- Series 05/10 (other patches are separate bugs/chips)
- Follow-ups 06–08 still missing here (incomplete *overall* U-APSD, but
this patch is a complete EOSP fix)
- No extra reviewer tags
**UNRESOLVED:**
- Direct lore.kernel.org HTTP often 403; thread recovered via `b4`
- No explicit stable@ discussion found
**Step 9.2: APPLY THE STABLE RULES CHECKLIST**
1. Obviously correct and tested? **PASS** — protocol-correct; maintainer
merged; consistent with mac80211 docs and iwlwifi’s
`ieee80211_send_eosp_nullfunc` usage
2. Fixes a real bug that affects users? **PASS** — stall / client freeze
on common AP chipsets
3. Important issue? **PASS** — serious connectivity failure for U-APSD
STAs (not a panic, but production-breaking for those devices)
4. Small and contained? **PASS** — one file, +63/−11
5. No new features or APIs? **PASS**
6. Can apply to the local tree? **PASS** — clean; APIs present
**Step 9.3: CHECK FOR EXCEPTION CATEGORIES**
Record: Not a device-ID/quirk/DT/build/docs exception. It is a **driver
protocol bugfix**.
**Step 9.4: DECISION**
Backport to this 5.15 tree. The bug exists here; the fix is self-
contained and applies cleanly. Companion commits `d5001f493fef` and
`636a883e2feef` are worth later evaluation but are not required for this
one.
---
### What the commit solves, and why it matters here
mt7603 implements its own `.release_buffered_frames` because hardware
redirects frames into a driver PS queue. That path tagged every frame
with `MORE_DATA` and never set EOSP on the air. mac80211 only saw
`ieee80211_sta_eosp()`, so the stack thought the SP ended while phones
waiting for EOSP stopped triggering. On 5.15 APs using `CONFIG_MT7603E`,
that is a real stall, not a cleanup.
### Stable rules / risk vs benefit
Surgical, obviously correct vs the documented U-APSD contract, no new
APIs, clean apply. Risk is limited to this driver’s PS release path.
Benefit is restoring downlink for power-save clients on a widely
deployed chipset.
### Concerns
Patches 06–08 (TIM clear, HW PS re-arm, TID filing) address **other**
remaining PS bugs. They are not compile or semantic prerequisites for
this hunk. Patch 04 is the analogous EOSP fix for chips that use generic
`mt76_release_buffered_frames`; mt7603 only hits that when its PS queue
is empty.
---
Verification:
- [Phase 1] Parsed subject/body/tags: Link is 05/10; author Felix
Fietkau; no Fixes/Reported-by/Cc stable
- [Phase 2] Diff: +63/−11 in `mt7603_release_buffered_frames`;
MORE_DATA+EOSP assignment; stop double SP end; QoS-Null for MMPDU
- [Phase 2] Confirmed `IEEE80211_QOS_CTL_EOSP` is 0x0010 and
`ieee80211_get_qos_ctl()` returns `u8 *` to the first QoS byte
- [Phase 2] Confirmed `ieee80211_send_eosp_nullfunc()` in 5.15 sets
`IEEE80211_TX_STATUS_EOSP` on the NDP; TX status clears `WLAN_STA_SP`
- [Phase 3] blame: `c8846e101502` / `b126c8897435` / `b7001f46085e`; all
ancestors of HEAD
- [Phase 3] `git merge-base --is-ancestor 697badc27a9b3 HEAD` → not
present
- [Phase 3] Follow-ups on origin/master: `d5001f493fef`, `636a883e2feef`
only; no revert
- [Phase 4] `b4 dig -c 697badc27a9b3`: v1 series, msgid
`20260801145334.1166751-5-nbd@nbd.name`
- [Phase 4] `b4 dig -w`: linux-wireless@ + author only
- [Phase 4] `b4 mbox`: 11 messages; robot fail is patch
10/`ieee80211_txq_aql_pending`, unrelated
- [Phase 4] OpenWrt mt76#1084: EOSP-related change reported to stop
iPhone freezes
- [Phase 5] ops hook `.release_buffered_frames =
mt7603_release_buffered_frames`; callers are mac80211 PS-Poll/U-APSD
- [Phase 5] `ieee80211_send_eosp_nullfunc` exists and is exported in
this tree; iwlwifi calls it from TX/BH
- [Phase 6] `make kernelversion` → 5.15.221; `git describe HEAD` →
p-5.15-2-g6703e5d2f3a29
- [Phase 6] Byte-for-byte match of both functions vs `697badc27a9b3^`
- [Phase 7] `CONFIG_MT7603E` present for MT7603E/MT7628
- [Phase 8] Failure mode: downlink stall / client freeze, severity HIGH
for that hardware
- UNVERIFIED: exhaustive stable@ archive search (lore HTTP 403); no
evidence of a prior stable rejection
**YES**
.../net/wireless/mediatek/mt76/mt7603/main.c | 74 ++++++++++++++++---
1 file changed, 63 insertions(+), 11 deletions(-)
diff --git a/drivers/net/wireless/mediatek/mt76/mt7603/main.c b/drivers/net/wireless/mediatek/mt76/mt7603/main.c
index 0d7c84941cd0a..f8a43d9f72f95 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7603/main.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7603/main.c
@@ -423,13 +423,33 @@ mt7603_sta_ps(struct mt76_dev *mdev, struct ieee80211_sta *sta, bool ps)
mt7603_ps_tx_list(dev, &list);
}
+static struct ieee80211_hdr *
+mt7603_ps_skb_hdr(struct sk_buff *skb)
+{
+ return (struct ieee80211_hdr *)&skb->data[MT_TXD_SIZE];
+}
+
+/*
+ * Buffered frames can be recycled into the PS queue by mt7603_filter_tx(), so
+ * both bits have to be assigned, not just set.
+ */
static void
-mt7603_ps_set_more_data(struct sk_buff *skb)
+mt7603_ps_set_flags(struct sk_buff *skb, bool more_data, bool eosp)
{
- struct ieee80211_hdr *hdr;
+ struct ieee80211_hdr *hdr = mt7603_ps_skb_hdr(skb);
+
+ if (more_data)
+ hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_MOREDATA);
+ else
+ hdr->frame_control &= ~cpu_to_le16(IEEE80211_FCTL_MOREDATA);
+
+ if (!ieee80211_is_data_qos(hdr->frame_control))
+ return;
- hdr = (struct ieee80211_hdr *)&skb->data[MT_TXD_SIZE];
- hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_MOREDATA);
+ if (eosp)
+ *ieee80211_get_qos_ctl(hdr) |= IEEE80211_QOS_CTL_EOSP;
+ else
+ *ieee80211_get_qos_ctl(hdr) &= ~IEEE80211_QOS_CTL_EOSP;
}
static void
@@ -442,7 +462,10 @@ mt7603_release_buffered_frames(struct ieee80211_hw *hw,
struct mt7603_dev *dev = hw->priv;
struct mt7603_sta *msta = (struct mt7603_sta *)sta->drv_priv;
struct sk_buff_head list;
- struct sk_buff *skb, *tmp;
+ struct sk_buff *skb, *tmp, *last;
+ bool eosp_null, uapsd;
+ u16 pending = 0;
+ u8 last_tid;
__skb_queue_head_init(&list);
@@ -458,20 +481,49 @@ mt7603_release_buffered_frames(struct ieee80211_hw *hw,
skb_set_queue_mapping(skb, MT_TXQ_PSD);
__skb_unlink(skb, &msta->psq);
- mt7603_ps_set_more_data(skb);
__skb_queue_tail(&list, skb);
nframes--;
}
+
+ skb_queue_walk(&msta->psq, skb)
+ pending |= BIT(skb->priority);
spin_unlock_bh(&dev->ps_lock);
- if (!skb_queue_empty(&list))
- ieee80211_sta_eosp(sta);
+ last = skb_peek_tail(&list);
+ if (!last) {
+ mt76_release_buffered_frames(hw, sta, tids, nframes, reason,
+ more_data);
+ return;
+ }
+
+ /*
+ * End the service period here instead of passing the remaining frame
+ * budget on to mt76_release_buffered_frames(), which would signal the
+ * end of the same service period a second time.
+ */
+ uapsd = reason == IEEE80211_FRAME_RELEASE_UAPSD;
+ more_data |= !!(pending & tids);
+
+ skb_queue_walk(&list, skb)
+ mt7603_ps_set_flags(skb, skb != last || more_data,
+ skb == last && uapsd);
+
+ /*
+ * EOSP lives in the QoS control field, so a bufferable MMPDU cannot
+ * terminate a U-APSD service period on its own. In that case mac80211
+ * has to append a QoS-Null frame, which ends the SP through its tx
+ * status.
+ */
+ eosp_null = uapsd &&
+ !ieee80211_is_data_qos(mt7603_ps_skb_hdr(last)->frame_control);
+ last_tid = __fls(tids);
mt7603_ps_tx_list(dev, &list);
- if (nframes)
- mt76_release_buffered_frames(hw, sta, tids, nframes, reason,
- more_data);
+ if (eosp_null)
+ ieee80211_send_eosp_nullfunc(sta, last_tid);
+ else
+ ieee80211_sta_eosp(sta);
}
static int
--
2.53.0
^ permalink raw reply related [flat|nested] 20+ messages in thread* [PATCH AUTOSEL 6.18-5.15] wifi: mt76: mt7603: add 0x7592 EEPROM chip ID
2026-10-19 13:44 [PATCH AUTOSEL 6.18-6.12] net: dsa: mt7530: check CORE_PLL_GROUP4 access in mt7531_setup() Sasha Levin
` (11 preceding siblings ...)
2026-10-19 13:48 ` [PATCH AUTOSEL 6.18-5.10] wifi: mt76: mt7603: fix U-APSD service period termination Sasha Levin
@ 2026-10-19 13:49 ` Sasha Levin
2026-10-19 13:49 ` [PATCH AUTOSEL 6.18-6.1] wifi: mt76: mt7615: fix NULL deref in mt7615_mac_set_rates Sasha Levin
` (5 subsequent siblings)
18 siblings, 0 replies; 20+ messages in thread
From: Sasha Levin @ 2026-10-19 13:49 UTC (permalink / raw)
To: patches, stable
Cc: Ahmed Naseef, Felix Fietkau, Sasha Levin, lorenzo, ryder.lee,
matthias.bgg, angelogioacchino.delregno, linux-wireless,
linux-kernel, linux-arm-kernel, linux-mediatek
From: Ahmed Naseef <naseefkm@gmail.com>
[ Upstream commit d16447d7470502e998d82e806ca7ed49d1baa853 ]
Some EcoNet based routers ship an on-flash EEPROM whose chip-id is
0x7592 instead of the expected 0x7603. The device probes as PCI
14c3:7603 and the hardware MT_HW_CHIPID register reports 0x7603,
independent of the EEPROM value.
This is seen across multiple EcoNet EN751221 and EN7528 based devices
(for example the Genexis Platinum 4410).
Signed-off-by: Ahmed Naseef <naseefkm@gmail.com>
Link: https://patch.msgid.link/20260719082530.3879831-1-naseefkm@gmail.com
Signed-off-by: Felix Fietkau <nbd@nbd.name>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
LLM Generated explanations, may be completely bogus:
The evaluation target is **pending-6.6 (6.6.157)**. The mt7603 driver is
present; the 0x7592 EEPROM ID is not. This is a one-line ID addition to
an existing driver, which is a standard stable exception.
===============================================================
PHASE 1: COMMIT MESSAGE FORENSICS
===============================================================
Step 1.1: PARSE THE SUBJECT LINE
Record: [wifi: mt76: mt7603] [add] [accept EEPROM chip ID 0x7592 in
mt7603_check_eeprom]
Step 1.2: PARSE ALL COMMIT MESSAGE TAGS
Record:
- Signed-off-by: Ahmed Naseef \<naseefkm@gmail.com\> (author)
- Link:
https://patch.msgid.link/20260719082530.3879831-1-naseefkm@gmail.com
- Signed-off-by: Felix Fietkau \<nbd@nbd.name\> (mt76 maintainer,
applied the patch)
- No Fixes: tag (expected for this review queue)
- No Cc: stable (expected)
- No Reported-by / Tested-by / Reviewed-by / Acked-by
- No syzbot / KASAN tags
- Sasha Levin SOB not present on this commit
Step 1.3: ANALYZE THE COMMIT BODY TEXT
Record:
- Bug: EcoNet routers store chip-id 0x7592 in on-flash EEPROM instead of
0x7603/0x7628/0x7600.
- Hardware identity is still MT7603: PCI 14c3:7603, and MT_HW_CHIPID
reads 0x7603.
- Symptom: driver treats a valid factory EEPROM as invalid.
- Devices: EcoNet EN751221 and EN7528, e.g. Genexis Platinum 4410.
- No stack trace; this is hardware recognition, not a crash fix.
- Root cause: mt7603_check_eeprom() whitelist is incomplete.
Step 1.4: DETECT HIDDEN BUG FIXES
Record: Not a disguised cleanup. It is an explicit EEPROM ID addition.
When the ID is rejected and OTP exists, mt7603_eeprom_init() memcpy()s
OTP over the flash EEPROM, so MAC/calibration from flash are discarded.
That is a real functional bug for those boards, not a new API.
===============================================================
PHASE 2: DIFF ANALYSIS - LINE BY LINE
===============================================================
Step 2.1: INVENTORY THE CHANGES
Record:
- File: drivers/net/wireless/mediatek/mt76/mt7603/eeprom.c
- +1 line, 0 removed
- Function: mt7603_check_eeprom()
- Scope: single-file, one-line surgical change
Step 2.2: UNDERSTAND THE CODE FLOW CHANGE
Record:
- Before: switch accepts 0x7628, 0x7603, 0x7600; anything else returns
-EINVAL.
- After: also accepts 0x7592.
- Path: probe → mt7603_register_device() → mt7603_init_hardware() →
mt7603_eeprom_init().
- If check succeeds and OTP exists: apply cal-free OTP overlay onto
flash EEPROM.
- If check fails and OTP exists: overwrite entire flash EEPROM with OTP
(MAC, TX power, xtal data from flash lost).
- Probe does not fail on unknown EEPROM ID.
Step 2.3: IDENTIFY THE BUG MECHANISM
Record: [Hardware ID / quirk] [Whitelist used to decide whether on-flash
EEPROM is trusted. Missing 0x7592 caused valid EcoNet EEPROMs to be
discarded in favor of OTP.]
Step 2.4: ASSESS THE FIX QUALITY
Record:
- Obviously correct: same pattern as the existing 0x7600 case.
- Minimal: one case label.
- Regression risk: very low. A random EEPROM whose first LE16 is 0x7592
would be trusted; that is the same risk as the existing IDs.
- No API or data-structure change.
===============================================================
PHASE 3: GIT HISTORY INVESTIGATION
===============================================================
Step 3.1: BLAME THE CHANGED LINES
Record:
- mt7603_check_eeprom() introduced in c8846e1015022 ("mt76: add driver
for MT7603E and MT7628/7688"), 2018, first released in v5.1-rc1.
- 0x7600 added by bf4a938ab2cf8 ("mt76: mt7603: add additional EEPROM
chip ID"), 2020, same one-line pattern for TP-Link Archer C50 v4.
- Both commits are ancestors of pending-6.6.
Step 3.2: FOLLOW THE FIXES: TAG
Record: No Fixes: tag. Buggy whitelist dates to the original driver
(v5.1), which is in this tree.
Step 3.3: CHECK FILE HISTORY FOR RELATED CHANGES
Record:
- Related: bf4a938ab2cf8 already in 6.6 (precedent).
- Candidate d16447d747050 is not an ancestor of pending-6.6.
- Standalone; not patch X/Y.
Step 3.4: CHECK THE AUTHOR'S OTHER COMMITS
Record:
- Author Ahmed Naseef has no other mt76 commits on pending-6.6.
- Applied by Felix Fietkau, listed maintainer of MEDIATEK MT76.
Step 3.5: CHECK FOR DEPENDENT/PREREQUISITE COMMITS
Record:
- No new helpers or struct fields.
- pending-6.6 vs patch parent only differs in SPDX and later
chainmask/return of mt76_eeprom_override(); the switch hunk is
identical.
- Can apply standalone with a clean hunk.
===============================================================
PHASE 4: MAILING LIST AND EXTERNAL RESEARCH
===============================================================
Step 4.1: FIND THE ORIGINAL PATCH DISCUSSION
Record:
- b4 dig -c d16447d747050 →
https://patch.msgid.link/20260719082530.3879831-1-naseefkm@gmail.com
- b4 dig -a: single v1 series, no v2/v3.
- Thread mbox is the patch only; no replies, no NAK, no Cc: stable in
review.
- Included in wireless-next-2026-08-06 pull (Johannes Berg).
- Syzbot CI: build/boot passed; fuzz skipped.
Step 4.2: CHECK WHO REVIEWED THE PATCH
Record:
- b4 dig -w: Felix Fietkau, Lorenzo Bianconi, Ryder Lee, Shayne Chen,
Sean Wang, linux-wireless, linux-mediatek, linux-kernel.
- Applied by Felix Fietkau (maintainer SOB). No separate Reviewed-by.
Step 4.3: SEARCH FOR THE BUG REPORT
Record:
- No bugzilla/syzbot link.
- Commit cites multiple EcoNet EN751221/EN7528 devices, example Genexis
Platinum 4410.
- OpenWrt mt76 tree already contains case 0x7592.
- No independent public crash report found (UNVERIFIED beyond the commit
text and OpenWrt tree).
Step 4.4: CHECK FOR RELATED PATCHES AND SERIES
Record: Standalone one-patch series. Same pattern as bf4a938ab2cf8.
Step 4.5: CHECK STABLE MAILING LIST HISTORY
Record: lore.kernel.org/stable returned 403. No stable discussion found
via b4/mbox. UNVERIFIED whether anyone requested/rejected this for
stable.
===============================================================
PHASE 5: CODE SEMANTIC ANALYSIS
===============================================================
Step 5.1: IDENTIFY KEY FUNCTIONS IN THE DIFF
Record: mt7603_check_eeprom() only.
Step 5.2: TRACE CALLERS
Record:
- Only caller: mt7603_eeprom_init() (same file).
- mt7603_eeprom_init() ← mt7603_init_hardware() ←
mt7603_register_device()
- mt7603_register_device() ← mt76pci_probe() (PCI 14c3:7603) and
mt76_wmac_probe() (mediatek,mt7628-wmac).
- Probe/init path, not hot path or IRQ.
Step 5.3: TRACE CALLEES
Record: get_unaligned_le16() on eeprom.data[0]. No alloc, lock, or I/O
in the changed function.
Step 5.4: FOLLOW THE CALL CHAIN
Record:
- Reachable when an MT7603 PCI device or MT7628 WMAC probes with
CONFIG_MT7603E.
- Not a syscall-triggered memory bug; firmware/EEPROM contents decide
the branch.
- Unprivileged users cannot trigger it except by plugging/using the
device.
Step 5.5: SEARCH FOR SIMILAR PATTERNS
Record:
- Sibling drivers use the same EEPROM-ID switch (mt7615, mt76x0,
mt76x2).
- This tree already backported other mt76 ID adds, e.g. efd75512e38ac
(mt76x2u TP-Link USB ID).
===============================================================
PHASE 6: CROSS-REFERENCING AGAINST THE LOCAL TREE
===============================================================
Step 6.1: DOES THE BUGGY CODE EXIST IN THIS TREE?
Record:
- Tree under evaluation: pending-6.6, 6.6.157 (git describe
p-6.6-3-g04810563abb71).
- Yes. pending-6.6 eeprom.c switch has 0x7628/0x7603/0x7600 only.
- git merge-base --is-ancestor d16447d747050 pending-6.6 → not present.
- Bug present since v5.1 driver introduction.
Step 6.2: CHECK FOR BACKPORT COMPLICATIONS
Record: Clean apply. Switch context matches. Later chainmask/license
diffs are outside the hunk.
Step 6.3: CHECK IF RELATED FIXES ARE ALREADY HERE
Record: 0x7600 ID is present. 0x7592 is not. No alternate fix.
Note: EcoNet SoC support landed in 6.16 (arch/mips/econet), not in 6.6.
That lowers vanilla-6.6 user count; it does not remove the driver or the
ID check. PCI 14c3:7603 still exists in this tree.
===============================================================
PHASE 7: SUBSYSTEM AND MAINTAINER CONTEXT
===============================================================
Step 7.1: IDENTIFY THE SUBSYSTEM AND ITS CRITICALITY
Record: [drivers/net/wireless/mediatek/mt76/mt7603] [IMPORTANT for
MT7603/MT7628 users; PERIPHERAL relative to core kernel]
Step 7.2: ASSESS SUBSYSTEM ACTIVITY
Record: Mature driver since v5.1. 6.6 still receives mt76 fixes.
Maintainer is Felix Fietkau.
===============================================================
PHASE 8: IMPACT AND RISK ASSESSMENT
===============================================================
Step 8.1: DETERMINE WHO IS AFFECTED
Record: Driver-specific / config-specific (CONFIG_MT7603E). Documented
users are EcoNet EN751221/EN7528 routers with MT7603 PCI WiFi. Vanilla
6.6 cannot boot EcoNet SoCs; downstream 6.6 kernels and any other board
with this EEPROM still benefit.
Step 8.2: DETERMINE THE TRIGGER CONDITIONS
Record:
- Trigger: probe of MT7603 when flash EEPROM starts with 0x7592 and OTP
is present.
- Every boot on those devices, not a race.
- Not exploitable by unprivileged software alone.
Step 8.3: DETERMINE THE FAILURE MODE SEVERITY
Record: [Wrong EEPROM source: factory MAC/calibration replaced by OTP]
[Severity: MEDIUM for those devices — broken/degraded WiFi or wrong MAC,
not oops/corruption]
Step 8.4: CALCULATE RISK-BENEFIT RATIO
Record:
- Benefit: medium for affected hardware (WiFi uses intended EEPROM);
lower on vanilla 6.6 because EcoNet platform is later, but this is the
usual device-ID case.
- Risk: very low (one case label, no locking/API).
- Ratio: favorable. Device-ID additions are accepted in stable for this
reason.
===============================================================
PHASE 9: FINAL SYNTHESIS
===============================================================
Step 9.1: COMPILE THE EVIDENCE
FOR:
- One-line EEPROM/chip ID addition to an existing driver (stable
exception).
- Same pattern as 0x7600, already in 6.6.
- Real boards named; hardware already binds as PCI 14c3:7603.
- Without it, valid flash EEPROM is discarded for OTP (MAC/cal).
- Maintainer applied it; applies cleanly here; no new API.
- This tree already contains similar mt76 ID backports.
AGAINST:
- Not a crash/security/deadlock.
- No Tested-by/Reviewed-by; mailing list had no discussion.
- EcoNet platform is not in 6.6, so vanilla 6.6 user count is small.
- No Fixes:/Cc: stable (expected, not a negative).
UNRESOLVED:
- Could not search lore.kernel.org/stable (403).
- No independent public repro beyond the commit and OpenWrt mt76 tree.
Step 9.2: APPLY THE STABLE RULES CHECKLIST
1. Obviously correct and tested? PASS — one-line whitelist, maintainer-
applied, syzbot CI build/boot passed.
2. Fixes a real bug that affects users? PASS — those boards trust OTP
instead of factory EEPROM.
3. Important issue? PASS under the device-ID/quirk exception (functional
WiFi/MAC on real hardware), even though not a panic.
4. Small and contained? PASS — +1 line, one file.
5. No new features or APIs? PASS — existing driver, additional ID only.
6. Can apply to the local tree? PASS — hunk matches pending-6.6.
Step 9.3: CHECK FOR EXCEPTION CATEGORIES
Record: Device ID addition to an existing driver (EEPROM chip ID,
analogous to PCI/USB ID). Also a hardware quirk for boards whose EEPROM
ID does not match MT_HW_CHIPID.
Step 9.4: MAKE YOUR DECISION
This belongs in 6.6.y. The driver and the incomplete whitelist are in
this tree; the fix is the standard one-line ID addition stable already
takes for mt76. EcoNet SoC support arriving later reduces vanilla-6.6
exposure but does not make the patch a new feature or a dependency-heavy
backport.
What it solves for stable users: MT7603 devices whose flash EEPROM ID is
0x7592 keep factory MAC and calibration instead of having them replaced
by OTP on probe.
Risk vs benefit: essentially no regression risk; benefit is enabling
correct EEPROM use on existing hardware.
Verification:
- [Phase 1] Tags: author SOB, Felix Fietkau SOB, msgid link; no Fixes/Cc
stable/Reported-by
- [Phase 2] Diff: +1 `case 0x7592:` in mt7603_check_eeprom()
- [Phase 2] Confirmed eeprom_init: fail → memcpy OTP over flash; success
→ cal-free overlay only
- [Phase 3] blame: function from c8846e1015022 (v5.1); 0x7600 from
bf4a938ab2cf8; both in pending-6.6
- [Phase 3] git merge-base --is-ancestor d16447d747050 pending-6.6 → not
in 6.6
- [Phase 3] git diff pending-6.6 vs parent: switch identical; only
SPDX/chainmask elsewhere
- [Phase 4] b4 dig -c d16447d747050: lore msgid
20260719082530.3879831-1-naseefkm@gmail.com
- [Phase 4] b4 dig -a: v1 only; mbox has no replies
- [Phase 4] b4 dig -w: mt76 maintainers + linux-wireless CC'd; Felix
applied
- [Phase 4] wireless-next-2026-08-06 pull lists this commit
- [Phase 5] callers: mt7603_eeprom_init → init_hardware →
register_device → pci/soc probe
- [Phase 6] pending-6.6 Makefile 6.6.157; switch lacks 0x7592; would
apply cleanly
- [Phase 6] EcoNet arch not in 6.6 (added ~6.16) — lowers vanilla user
count, code still present
- [Phase 7] MAINTAINERS: Felix Fietkau maintains mt76
- [Phase 8] Failure: OTP replaces flash EEPROM (MAC/cal); not oops
- UNVERIFIED: stable@ lore search (HTTP 403); no independent field crash
report
**YES**
drivers/net/wireless/mediatek/mt76/mt7603/eeprom.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/net/wireless/mediatek/mt76/mt7603/eeprom.c b/drivers/net/wireless/mediatek/mt76/mt7603/eeprom.c
index 88382b537a33b..06f61988655e5 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7603/eeprom.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7603/eeprom.c
@@ -142,6 +142,7 @@ static int mt7603_check_eeprom(struct mt76_dev *dev)
case 0x7628:
case 0x7603:
case 0x7600:
+ case 0x7592:
return 0;
default:
return -EINVAL;
--
2.53.0
^ permalink raw reply related [flat|nested] 20+ messages in thread* [PATCH AUTOSEL 6.18-6.1] wifi: mt76: mt7615: fix NULL deref in mt7615_mac_set_rates
2026-10-19 13:44 [PATCH AUTOSEL 6.18-6.12] net: dsa: mt7530: check CORE_PLL_GROUP4 access in mt7531_setup() Sasha Levin
` (12 preceding siblings ...)
2026-10-19 13:49 ` [PATCH AUTOSEL 6.18-5.15] wifi: mt76: mt7603: add 0x7592 EEPROM chip ID Sasha Levin
@ 2026-10-19 13:49 ` Sasha Levin
2026-10-19 13:51 ` [PATCH AUTOSEL 6.18-5.10] wifi: mt76: mt76x02: report rx FCS errors to mac80211 Sasha Levin
` (4 subsequent siblings)
18 siblings, 0 replies; 20+ messages in thread
From: Sasha Levin @ 2026-10-19 13:49 UTC (permalink / raw)
To: patches, stable
Cc: Felix Fietkau, Chad Monroe, Sasha Levin, lorenzo, ryder.lee,
matthias.bgg, angelogioacchino.delregno, linux-wireless,
linux-kernel, linux-arm-kernel, linux-mediatek
From: Felix Fietkau <nbd@nbd.name>
[ Upstream commit 98aff74779da9f417386c589c36848e9c568f0f9 ]
mt7615_tx() falls back to the vif BSS wcid when mac80211 hands a frame
over without a station, e.g. while a station is being torn down, and to
the global wcid when there is no vif either. Both tx_prepare_skb
implementations derive a mt7615_sta from that wcid unconditionally and,
if the rate control probe flag is set, pass it to mt7615_mac_set_rates(),
which dereferences the NULL vif backpointer of the per-vif embedded sta:
Unable to handle kernel read from unreadable memory at virtual
address 0000000000000002
...
pc : mt7615_mac_set_rates
lr : mt7615_tx_prepare_skb
Neither entry is rate controlled by mac80211: the embedded sta has an
empty rate set, and for the global wcid the container_of does not yield a
valid mt7615_sta at all. Only resolve the sta for wcids that belong to a
station.
Reported-by: Chad Monroe <chad@monroe.io>
Link: https://patch.msgid.link/20260724124813.3961474-23-nbd@nbd.name
Signed-off-by: Felix Fietkau <nbd@nbd.name>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
LLM Generated explanations, may be completely bogus:
## Phase 1: Commit message forensics
**Step 1.1 — Subject**
Record: `[wifi: mt76: mt7615]` `[fix]` `[NULL deref in
mt7615_mac_set_rates when TX uses a non-station wcid]`
**Step 1.2 — Tags**
Record:
- `Reported-by: Chad Monroe <chad@monroe.io>` — real user hit this
- `Link:
https://patch.msgid.link/20260724124813.3961474-23-nbd@nbd.name` —
patch 23/29 of an mt76-next series
- `Signed-off-by: Felix Fietkau <nbd@nbd.name>` — mt76 maintainer
- No `Fixes:`, no `Cc: stable` (expected for this review)
- No `Reviewed-by` / `Tested-by` / `Acked-by` on the commit itself
- Ignore `Signed-off-by: Sasha Levin` / `[Upstream commit ...]` if
present (pipeline)
**Step 1.3 — Body**
Record:
- Bug: `mt7615_tx()` falls back to the vif BSS wcid when mac80211 TX has
no station (e.g. station teardown), and to `global_wcid` if there is
no vif. Both `tx_prepare_skb` paths `container_of` that wcid into
`mt7615_sta` and, if `IEEE80211_TX_CTL_RATE_CTRL_PROBE` is set, call
`mt7615_mac_set_rates()`.
- Symptom: kernel NULL deref / oops:
`Unable to handle kernel read from unreadable memory at virtual
address 0000000000000002`, `pc: mt7615_mac_set_rates`, `lr:
mt7615_tx_prepare_skb`
- Root cause: BSS-embedded sta has a NULL `vif` backpointer;
`global_wcid` is not a `mt7615_sta` at all. Neither is rate-
controlled.
- Fix: only resolve `msta` when `wcid->sta` is set.
**Step 1.4 — Hidden bug fix?**
Record: Not hidden. Explicit crash fix with a stack trace and a
reporter.
## Phase 2: Diff analysis
**Step 2.1 — Inventory**
Record:
- `drivers/net/wireless/mediatek/mt76/mt7615/pci_mac.c`:
`mt7615_tx_prepare_skb` — ~3 lines
- `drivers/net/wireless/mediatek/mt76/mt7615/usb_sdio.c`:
`mt7663_usb_sdio_tx_prepare_skb` — ~3 lines
- Scope: single-driver surgical fix, two TX prepare paths (PCIe/MMIO and
USB/SDIO)
**Step 2.2 — Code flow**
Record: Before, any non-NULL `wcid` was treated as `mt7615_sta`. After,
`msta` is set only if `wcid && wcid->sta`. The existing `if (...
RATE_CTRL_PROBE && msta)` already skips `mt7615_mac_set_rates()` when
`msta` is NULL.
**Step 2.3 — Bug mechanism**
Record: `[NULL pointer dereference]` — `mt7615_mac_set_rates()` does
`sta->vif->mt76.omac_idx`. For the per-vif embedded sta, `vif` is never
set. For `global_wcid`, `container_of` is invalid. The fix uses the
existing `wcid->sta` flag.
**Step 2.4 — Fix quality**
Record: Obviously correct. Same pattern already used in this tree
(`wcid_to_sta()`, `mt76_connac_pm_dequeue_skbs()`,
`mt7615_rx_get_wcid()`). Skipping rate-probe setup for non-station wcids
is intended: those entries are not rate-controlled. Regression risk is
very low. No API change.
## Phase 3: Git history
**Step 3.1 — Blame**
Record: The incomplete NULL check is `8d3cdc1bbb1d3` (“mt76: mt7615: fix
NULL pointer dereference in tx_prepare_skb()”, Lorenzo Bianconi, 2021).
That only handled `wcid == NULL` (then `global_wcid`). The BSS-wcid
fallback in `mt7615_tx()` is from 2019 (`04b8e65922f631` /
`2b8cdfb28d3402`). The bug has been in this lineage since mt7615 TX was
added.
**Step 3.2 — Fixes: tag**
Record: None. The incomplete 2021 fix is already in this tree (`git
merge-base --is-ancestor 8d3cdc1bbb1d3 HEAD` succeeded). This commit
closes the remaining hole.
**Step 3.3 — File history**
Record: Recent mt7615 changes in this tree are unrelated (runtime-pm
timeout, TSF, DMA reset). No prerequisite refactor for this two-line
guard. Standalone.
**Step 3.4 — Author**
Record: Felix Fietkau is the mt76 maintainer. Related earlier NULL-deref
fix was also signed off by him.
**Step 3.5 — Dependencies**
Record: Patch 23/29 of an mt76-next batch, but the other patches are
independent (mt7996/mt7915/scan/WED). This hunk only needs `wcid->sta`
and the existing `msta` NULL check, both present here. Standalone.
## Phase 4: Mailing list / external
**Step 4.1 — Original discussion**
Record: `b4 mbox` saved the thread. Subject: `[PATCH mt76-next 23/29]
wifi: mt76: mt7615: fix NULL deref in mt7615_mac_set_rates`. Sent 24 Jul
2026 by Felix to linux-wireless. 29-message thread is the series itself,
not a v2/v3 of this patch. No NAK. No reviewer `Cc: stable`. Lore HTTP
fetch returned 403; discussion was recovered via `b4`.
**Step 4.2 — Recipients**
Record: To: linux-wireless@vger.kernel.org. Maintainer is the author.
**Step 4.3 — Bug report**
Record: Reported-by Chad Monroe with a concrete oops (`pc:
mt7615_mac_set_rates`, `lr: mt7615_tx_prepare_skb`). Chad also authored
other patches in the same series, so this is a real device user, not a
theoretical report.
**Step 4.4 — Series**
Record: Independent mt76 bug-fix dump. mt7996 patches are irrelevant to
5.15. This patch does not need 1–22 or 24–29.
**Step 4.5 — Stable list**
Record: UNVERIFIED — lore.kernel.org/stable HTTP 403. No evidence it was
rejected for stable.
## Phase 5: Semantic / call-chain
**Step 5.1 — Functions**
Record: `mt7615_tx_prepare_skb`, `mt7663_usb_sdio_tx_prepare_skb`
(callers of `mt7615_mac_set_rates`).
**Step 5.2 — Callers**
Record:
- PCIe/MMIO: `mt7615_tx_prepare_skb` via `mt7615/mmio.c`
`.tx_prepare_skb`, from `mt76_dma_tx_queue_skb` (`dma.c:409`)
- USB: `usb.c:917`; SDIO: `sdio.c:263`
- Upstream of that: `mt7615_tx()` → `mt76_tx()` /
`mt76_connac_pm_queue_skb()`
**Step 5.3 — Callees**
Record: `mt7615_mac_set_rates()` immediately uses
`sta->vif->mt76.omac_idx` (mac.c:1063 in this tree).
**Step 5.4 — Reachability**
Record: Yes, from normal wireless TX. `mt7615_tx()`:
```737:743:drivers/net/wireless/mediatek/mt76/mt7615/main.c
if (vif && !control->sta) {
struct mt7615_vif *mvif;
mvif = (struct mt7615_vif *)vif->drv_priv;
msta = &mvif->sta;
wcid = &msta->wcid;
}
```
mac80211 can pass `control->sta == NULL` while
`IEEE80211_TX_CTL_RATE_CTRL_PROBE` is still set on a previously rate-
controlled skb (station teardown). That is a userspace-reachable
AP/client path.
**Step 5.5 — Similar patterns**
Record: Same `wcid && wcid->sta` guard already exists in
`mt76x02_mac.c`, `mt76_connac_mac.c`, `wcid_to_sta()`.
`mt7615_rx_get_wcid()` already refuses non-station wcids. `wcid.sta = 1`
is set only in `mt7615_mac_sta_add()`, not in `mt7615_add_interface()`.
## Phase 6: Local tree (5.15.221 / pending-5.15)
**Step 6.1 — Buggy code present?**
Record: Yes.
- `pci_mac.c:142`: `msta = wcid ? container_of(wcid, struct mt7615_sta,
wcid) : NULL;`
- `usb_sdio.c:200`: same
- `mac.c:1063`: `u16 idx = sta->vif->mt76.omac_idx;`
- `add_interface` sets `mvif->sta.wcid` but never `mvif->sta.vif` or
`wcid.sta`
- `wcid->sta` exists in `struct mt76_wcid` (`mt76.h:251`)
**Step 6.2 — Backport difficulty**
Record: Minor context mismatch, easy rework. Mainline USB path has extra
locals (`key`, `pktid`) and an in-function `global_wcid` fallback that
5.15 keeps in `mt7663_usb_sdio_write_txwi()`. PCIe path uses
`MT_TX_HW_QUEUE_EXT_PHY` / `mdev->phy2` here vs later `phys[MT_BAND1]`.
The semantic change is the same two-line `wcid->sta` check.
`mt76_vif_link` in the provided hunk context is *not* required.
**Step 6.3 — Related fixes already here?**
Record: `8d3cdc1bbb1d3` is present and is incomplete. No later
`mt7615_mac_set_rates` NULL-deref fix in this tree.
## Phase 7: Subsystem context
**Step 7.1**
Record: `[drivers/net/wireless/mediatek/mt76/mt7615]` `[IMPORTANT]` —
not core kernel, but a widely used 802.11ac chipset (MT7615E/MT7663E
PCIe, MT7663U USB, MT7663S SDIO, MT7622 SoC WMAC). Common on routers and
embedded boards, including 5.15 LTS/Android/OpenWrt-class systems.
**Step 7.2**
Record: Mature driver; this bug is old, not a new-subsystem issue.
## Phase 8: Impact and risk
**Step 8.1 — Who is affected**
Record: Users of MT7615/MT7663/MT7622 (`CONFIG_MT7615E` /
`CONFIG_MT7663U` / `CONFIG_MT7663S` / `CONFIG_MT7622_WMAC`). Driver-
specific, not universal.
**Step 8.2 — Trigger**
Record: TX without a station while `IEEE80211_TX_CTL_RATE_CTRL_PROBE` is
set — typically station teardown / disconnect with a probe rate sample
in flight. Not every packet, but a normal Wi-Fi event. Unprivileged
clients disconnecting from an AP can induce it.
**Step 8.3 — Failure mode**
Record: `[Kernel oops / NULL deref in hard TX path]` `[CRITICAL]`
**Step 8.4 — Risk vs benefit**
Record: Benefit high for that hardware (prevents oops). Risk very low
(~6 lines, existing flag, same pattern as sibling code). Skipping
`mac_set_rates` on BSS/global wcid is the correct behavior.
## Phase 9: Synthesis
**Step 9.1 — Evidence**
FOR:
- Real oops with reporter and stack trace
- Bug and incomplete 2021 fix both exist in this 5.15 tree
- Small, obviously correct guard
- Maintainer-authored
- Matches stable rules (crash, contained, no new API)
- Hardware is common on 5.15-era devices
AGAINST:
- Driver-specific, not core
- Won’t `git am` cleanly (context only)
- Part of a 29-patch series (other patches are unrelated)
- No `Fixes:` / `Cc: stable` (not a negative under these rules)
- No mailing-list review tags on this specific patch
UNRESOLVED:
- Could not fetch lore/stable over HTTP (403); recovered the thread with
`b4`
- Exact crash address `...0002` matches a newer `vif` layout; in 5.15
`omac_idx` is at offset 1. Same NULL `vif` deref either way.
**Step 9.2 — Stable rules**
1. Obviously correct and tested? **PASS** — maintainer fix; user-
reported oops; logic matches existing `wcid->sta` usage
2. Real bug affecting users? **PASS** — Chad Monroe crash
3. Important (crash/security/corruption/deadlock)? **PASS** — kernel
oops in TX
4. Small and contained? **PASS** — two functions, ~6 lines
5. No new features/APIs? **PASS**
6. Can apply to this tree? **PASS** — code is here; needs a trivial
context tweak, not a rewrite
**Step 9.3 — Exceptions**
Record: None (not a device-ID/quirk/DT/build/docs exception). It
qualifies as a normal crash fix.
**Step 9.4 — Decision**
This is a real NULL deref in the mt7615 TX path that 5.15 still has. The
2021 patch only covered a NULL wcid; the BSS-wcid fallback still
crashes. Backport it.
## What the commit solves for this tree
On 5.15.221, `mt7615_tx()` still substitutes the per-vif embedded sta
when mac80211 has no station. `tx_prepare_skb` still `container_of`s
that wcid and can call `mt7615_mac_set_rates()`, which immediately loads
`sta->vif->mt76.omac_idx` while `vif` is NULL. That oopses. Restricting
`msta` to `wcid->sta` stops it. Same change belongs in both PCIe and
USB/SDIO prepare paths.
Risk is a skipped rate-probe update on wcids that were never valid for
rate control. Benefit is avoiding a driver oops during client teardown.
## Verification
- [Phase 1] Parsed tags: Reported-by Chad Monroe; Link to 23/29
mt76-next; SOB Felix Fietkau; no Fixes/Cc stable
- [Phase 2] Diff: two `msta` assignments; require `wcid->sta` before
`container_of`
- [Phase 3] Blame: 8d3cdc1bbb1d3 (2021) only NULL-wcid; BSS fallback
since 2019
- [Phase 3] `git merge-base --is-ancestor 8d3cdc1bbb1d3 HEAD`: yes,
incomplete fix is here
- [Phase 3] `git log --grep="fix NULL deref in mt7615_mac_set_rates" --
mt7615/`: not in this tree
- [Phase 4] `b4 mbox 20260724124813.3961474-23-nbd@nbd.name`: 29-message
independent mt76 series; this patch standalone; no NAK
- [Phase 4] lore HTTP 403; UNVERIFIED stable@ discussion
- [Phase 5] Call chain: mac80211 `drv_tx` → `mt7615_tx` → `mt76_tx` /
DMA `tx_prepare_skb` → `mt7615_mac_set_rates`
- [Phase 5] `mt7615_add_interface` does not set `mvif->sta.vif` or
`wcid.sta`; only `mt7615_mac_sta_add` sets `wcid.sta = 1`
- [Phase 6] `make kernelversion` / Makefile: **5.15.221**, branch
`pending-5.15`
- [Phase 6] Buggy lines present in `pci_mac.c:142` and `usb_sdio.c:200`;
deref at `mac.c:1063`
- [Phase 6] Surrounding context differs (phy2 vs phys[MT_BAND1], USB
locals); semantic apply is still two lines
- [Phase 8] Failure: NULL deref oops in TX; severity CRITICAL for
MT7615/MT7663/MT7622 users
**YES**
drivers/net/wireless/mediatek/mt76/mt7615/pci_mac.c | 5 +++--
drivers/net/wireless/mediatek/mt76/mt7615/usb_sdio.c | 5 +++--
2 files changed, 6 insertions(+), 4 deletions(-)
diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/pci_mac.c b/drivers/net/wireless/mediatek/mt76/mt7615/pci_mac.c
index b795d11d943d0..61efdf59133f5 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7615/pci_mac.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7615/pci_mac.c
@@ -68,10 +68,11 @@ int mt7615_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
int pid, id;
u8 *txwi = (u8 *)txwi_ptr;
struct mt76_txwi_cache *t;
- struct mt7615_sta *msta;
+ struct mt7615_sta *msta = NULL;
void *txp;
- msta = wcid ? container_of(wcid, struct mt7615_sta, wcid) : NULL;
+ if (wcid && wcid->sta)
+ msta = container_of(wcid, struct mt7615_sta, wcid);
if (!wcid)
wcid = &dev->mt76.global_wcid;
diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/usb_sdio.c b/drivers/net/wireless/mediatek/mt76/mt7615/usb_sdio.c
index 820b395900275..01e79f37649c1 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7615/usb_sdio.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7615/usb_sdio.c
@@ -187,10 +187,11 @@ int mt7663_usb_sdio_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
struct sk_buff *skb = tx_info->skb;
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
struct ieee80211_key_conf *key = info->control.hw_key;
- struct mt7615_sta *msta;
+ struct mt7615_sta *msta = NULL;
int pad, err, pktid;
- msta = wcid ? container_of(wcid, struct mt7615_sta, wcid) : NULL;
+ if (wcid && wcid->sta)
+ msta = container_of(wcid, struct mt7615_sta, wcid);
if (!wcid)
wcid = &dev->mt76.global_wcid;
--
2.53.0
^ permalink raw reply related [flat|nested] 20+ messages in thread* [PATCH AUTOSEL 6.18-5.10] wifi: mt76: mt76x02: report rx FCS errors to mac80211
2026-10-19 13:44 [PATCH AUTOSEL 6.18-6.12] net: dsa: mt7530: check CORE_PLL_GROUP4 access in mt7531_setup() Sasha Levin
` (13 preceding siblings ...)
2026-10-19 13:49 ` [PATCH AUTOSEL 6.18-6.1] wifi: mt76: mt7615: fix NULL deref in mt7615_mac_set_rates Sasha Levin
@ 2026-10-19 13:51 ` Sasha Levin
2026-10-19 13:51 ` [PATCH AUTOSEL 6.18] clk: mediatek: mt6735-vdecsys: add missing MODULE_DEVICE_TABLE() Sasha Levin
` (3 subsequent siblings)
18 siblings, 0 replies; 20+ messages in thread
From: Sasha Levin @ 2026-10-19 13:51 UTC (permalink / raw)
To: patches, stable
Cc: Devin Wittmayer, 0072a70, Felix Fietkau, Sasha Levin, lorenzo,
ryder.lee, matthias.bgg, angelogioacchino.delregno,
linux-wireless, linux-kernel, linux-arm-kernel, linux-mediatek
From: Devin Wittmayer <lucid_duck@justthetip.ca>
[ Upstream commit ddae0bcb01e71c1184bb3f526f9622e31dc38f3b ]
When the fcsfail filter is enabled the hardware passes frames with a bad
FCS up to the driver, but mt76x02_mac_process_rx() never checks
MT_RXINFO_CRCERR and hands them to mac80211 without
RX_FLAG_FAILED_FCS_CRC. In monitor mode the radiotap flags byte then
never gets IEEE80211_RADIOTAP_F_BADFCS set and corrupted frames cannot be
told apart from clean ones.
Set RX_FLAG_FAILED_FCS_CRC from the descriptor CRC error bit, matching
mt7603, mt7615, mt7915, mt7921, mt7925 and mt7996.
Reported-by: 0072a70 <90307219+0072a70@users.noreply.github.com>
Closes: https://github.com/morrownr/mt76/issues/38
Tested-by: 0072a70 <90307219+0072a70@users.noreply.github.com>
Signed-off-by: Devin Wittmayer <lucid_duck@justthetip.ca>
Link: https://patch.msgid.link/20260613002544.27750-3-lucid_duck@justthetip.ca
Signed-off-by: Felix Fietkau <nbd@nbd.name>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
LLM Generated explanations, may be completely bogus:
## Phase 1: Commit message forensics
**Step 1.1 — Subject**
- Record: `[wifi: mt76: mt76x02]` `[report]` `[report rx FCS errors to
mac80211]`
- Subsystem is MediaTek mt76, mt76x02 family (mt76x0 / mt76x2 PCI and
USB). “Report” here is a correctness fix: the driver already receives
CRC-failed frames and must mark them.
**Step 1.2 — Tags**
- Record:
- `Reported-by: 0072a70 <90307219+0072a70@users.noreply.github.com>` —
real user hit
- `Closes: https://github.com/morrownr/mt76/issues/38`
- `Tested-by:` same reporter, on real hardware
- `Signed-off-by: Devin Wittmayer` (author)
- `Link: https://patch.msgid.link/20260613002544.27750-3-
lucid_duck@justthetip.ca`
- `Signed-off-by: Felix Fietkau` (mt76 maintainer)
- No `Fixes:` tag (expected for this review)
- No `Cc: stable` (expected; not a negative)
- Ignore any pipeline `Signed-off-by: Sasha Levin` / `[Upstream commit
...]`
**Step 1.3 — Body**
- Record:
- **Bug:** With the `fcsfail` filter enabled, hardware delivers frames
with `MT_RXINFO_CRCERR` set. `mt76x02_mac_process_rx()` never reads
that bit, so mac80211 never gets `RX_FLAG_FAILED_FCS_CRC`.
- **Symptom:** In monitor mode, radiotap never sets
`IEEE80211_RADIOTAP_F_BADFCS`; corrupted frames look identical to
clean ones.
- **Root cause:** Missing descriptor-bit → `rx_status` translation.
Other mt76 chips already do this.
- **Version info in the message:** none. Reporter used kernel 7.0.x;
the code path is much older (see Phase 3).
**Step 1.4 — Hidden bug fix?**
- Record: Not disguised. It is an explicit missing-flag fix that
implements the documented mac80211 contract for `FIF_FCSFAIL`.
## Phase 2: Diff analysis
**Step 2.1 — Inventory**
- Record: one file, `drivers/net/wireless/mediatek/mt76/mt76x02_mac.c`.
Three lines added, none removed. Function: `mt76x02_mac_process_rx()`.
Surgical single-file change.
**Step 2.2 — Flow**
- Record: After the existing `MT_RXINFO_L2PAD` check, if `rxinfo &
MT_RXINFO_CRCERR`, set `status->flag |= RX_FLAG_FAILED_FCS_CRC`.
Normal RX is unchanged for clean frames. Error/monitor path for CRC-
failed frames is now marked.
**Step 2.3 — Bug mechanism**
- Record: **Logic / correctness** (driver contract). Hardware already
passes CRC-failed frames when `FIF_FCSFAIL` is on
(`MT76_FILTER(FCSFAIL, MT_RX_FILTR_CFG_CRC_ERR)` in
`mt76x02_configure_filter()`). The driver failed to set the flag
mac80211 requires (`include/net/mac80211.h`: *“pass frames with failed
FCS (but you need to set RX_FLAG_FAILED_FCS_CRC for them)”*).
Verified mac80211 consequences in this tree:
- `ieee80211_add_rx_radiotap_header()` sets
`IEEE80211_RADIOTAP_F_BADFCS` only if that flag is present
(`net/mac80211/rx.c`).
- `should_drop_frame()` treats `RX_FLAG_FAILED_FCS_CRC` as drop-from-
cooked-path. Without it, `ieee80211_rx_monitor()` copies the frame to
monitor and **returns the original skb** to
`__ieee80211_rx_handle_packet()`. FCS-failed frames can therefore
enter the cooked RX path whenever `fcsfail` is enabled (including
concurrent monitor + STA/AP).
**Step 2.4 — Fix quality**
- Record: Obviously correct; same pattern as
`mt7603`/`mt7615`/`mt7915`/`mt7921`/`mt7996` in this tree. Minimal.
Regression risk is low: only CRCERR frames get a flag they should
already have. Clean frames are untouched. Does not add APIs or change
locking.
## Phase 3: Git history
**Step 3.1 — Blame**
- Record: Insertion point is the 2018 `mt76x02_mac_process_rx()` body
from `d9f8934ed147b3` (“mt76: move mt76x02_mac_process_rx in
mt76x02-lib module”), 2018-10-04, first contained in **v4.20-rc1**.
`MT_RXINFO_CRCERR` is defined in `mt76x02_mac.h:54` since
`5327b5ea13910d` (2018-09-04). The bit has been defined for years and
never consumed in RX processing.
**Step 3.2 — Fixes: tag**
- Record: None. The omission dates to the original mt76x02 RX path, not
a later regression.
**Step 3.3 — File history**
- Record: Same-function sibling from the same series is already in this
tree: `b6e7958602bd1` (“do not WARN on invalid rx descriptor length”).
That is patch 1/2 of `[PATCH 0/2] wifi: mt76: mt76x02: rx fixes for
fcsfail monitor mode`. This candidate is patch 2/2. They touch
different lines; this one does not depend on patch 1. `git apply
--check` of this hunk on HEAD is **clean**. No other FCS reporting
commit exists on this file.
**Step 3.4 — Author**
- Record: Devin Wittmayer; not the subsystem maintainer. Maintainer
Felix Fietkau signed off. Author also submitted the sibling WARN fix.
Related author commits in this tree: `b6e7958602bd1`, plus unrelated
mt7615/mt7921 TXRX_NOTIFY drops.
**Step 3.5 — Prerequisites**
- Record: None beyond symbols already in 6.6: `MT_RXINFO_CRCERR`,
`RX_FLAG_FAILED_FCS_CRC`, `status->flag`. Commit text mentions mt7925;
that chip need not exist here — it is comparison only. Standalone
apply: yes.
## Phase 4: Mailing list / external research
**Step 4.1 — Original discussion**
- Record: `b4 dig -c <sha>` cannot match because this commit is not in
the local history. Fallback: `b4 mbox
20260613002544.27750-3-lucid_duck@justthetip.ca`.
- Cover: https://patch.msgid.link/20260613002544.27750-1-
lucid_duck@justthetip.ca
- Series: v1 only (`b4 am --check-newer-revisions`: no later
revision).
- Two patches; this is 2/2.
- Cover: tested on MT7612U and MT7610U; fcsfail monitor captures get
BADFCS on corrupted frames, clean frames unchanged.
- No NAKs in the retrieved thread (cover + 2 patches, no review
replies). Applied by Felix Fietkau.
- Lore HTTP fetch returned 403; b4 was used instead.
**Step 4.2 — Recipients**
- Record: To Felix Fietkau, Lorenzo Bianconi; Cc Ryder Lee, Shayne Chen,
Sean Wang, linux-wireless, linux-kernel. Right maintainers/lists.
**Step 4.3 — Bug report**
- Record: GitHub issue #38 (closed). Hardware: Alfa AWUS036ACM, mt7612u,
driver mt76x2u. With `iw set monitor fcsfail`, radiotap flags were
always `0x00`; `radiotap.flags.badfcs == 1` matched 0 of 2978 frames.
After this exact three-line change: 956/7353 frames had BADFCS `0x40`,
clean frames stayed `0x00`. Confirmed on-list/issue by the reporter
(`Tested-by`).
**Step 4.4 — Series context**
- Record: Patch 1 (WARN on bogus MPDU length under fcsfail) is already
in this 6.6 tree. Patch 2 is the functional reporting fix.
Independent; both target the same user-visible fcsfail path.
**Step 4.5 — stable@ discussion**
- Record: lore.kernel.org/stable HTTP 403. No separate stable-thread
evidence retrieved. Absence is not a negative for this review.
## Phase 5: Semantic / call-chain analysis
**Step 5.1 — Functions**
- Record: `mt76x02_mac_process_rx()`.
**Step 5.2 — Callers**
- Record: Only `mt76x02_queue_rx_skb()` in `mt76x02_txrx.c` (data RX,
not MCU queue). That is the USB/PCI RX completion path for mt76x0 and
mt76x2.
**Step 5.3 — Callees (relevant)**
- Record: Sets `struct mt76_rx_status` in `skb->cb`, then `mt76_rx()` →
mac80211. `mt76_rx()` already counts `RX_FLAG_FAILED_FCS_CRC` for
testmode FCS stats (`mac80211.c`).
**Step 5.4 — Reachability**
- Record: Userspace-reachable: `iw set type monitor` + `iw set monitor
fcsfail` (nl80211 `NL80211_MNTR_FLAG_FCSFAIL` →
`ieee80211_adjust_monitor_flags()` → `fif_fcsfail` → `FIF_FCSFAIL` →
hardware CRC filter cleared). Common on USB adapters used for capture
(Alfa AWUS036ACM and similar).
**Step 5.5 — Similar patterns**
- Record: Same `status->flag |= RX_FLAG_FAILED_FCS_CRC` already present
in this tree for mt7603, mt7615, mt7915, mt7921, mt7996. mt76x02 is
the gap. `MT_RXINFO_ICVERR` / `MT_RXINFO_MICERR` are also unused here;
out of scope for this patch.
## Phase 6: This tree (6.6.157 / pending-6.6)
**Step 6.1 — Does the buggy code exist?**
- Record: Yes. `mt76x02_mac_process_rx()` at `mt76x02_mac.c:794–797` has
L2PAD then DECRYPT; no CRCERR check. `MT_RXINFO_CRCERR` is defined.
`git merge-base --is-ancestor d9f8934ed147b3 HEAD` succeeded. Bug
present since ~v4.20, so it is in 6.6.y.
Local tree identity:
- `git describe HEAD` → `p-6.6-3-g04810563abb71`
- `make kernelversion` → **6.6.157**
- Branch: `pending-6.6`
**Step 6.2 — Backport difficulty**
- Record: **Clean apply.** Context matches; `git apply --check`
succeeded. Surrounding code is the same as the patch’s index.
**Step 6.3 — Related fixes already here**
- Record: No existing CRCERR → `RX_FLAG_FAILED_FCS_CRC` translation.
Sibling WARN fix `b6e7958602bd1` is present (different hunk).
`63fe66f102837` (mt7996 FCS bit in wrong RXD word) is a different
chip.
## Phase 7: Subsystem context
**Step 7.1**
- Record: `drivers/net/wireless/mediatek/mt76` — **IMPORTANT** (widely
used WiFi, not core mm/vfs). Covers MT76x0U/E and MT76x2U/E (`Kconfig`
MT7610/MT7612 USB and PCIe). Peripheral relative to core kernel, but
these USB NICs are common in the field.
**Step 7.2**
- Record: mt76 is active; mt76x02 RX processing itself has been stable
for years. This is a long-standing omission, not churn from a new
subsystem.
## Phase 8: Impact and risk
**Step 8.1 — Who is affected**
- Record: Users of mt76x0/mt76x2 (USB and PCIe) who enable monitor
`fcsfail`. Normal STA/AP-only operation keeps the hardware CRC filter
on, so those users are not on this path. Mixed monitor+managed on the
same phy is affected for cooked RX.
**Step 8.2 — Trigger**
- Record: Explicit monitor `fcsfail` (and typically a busy channel). Not
every boot. Unprivileged users cannot enable monitor without
privileges, so this is not a generic local-priv-esc path; it is a
privileged capture/correctness bug.
**Step 8.3 — Failure mode**
- Record:
- Monitor: corrupted frames indistinguishable from good ones (broken
advertised filter). **MEDIUM** for dedicated capture.
- Cooked path: FCS-failed frames can be processed as valid 802.11 when
`fcsfail` is on. That is frame-integrity / stack-correctness, not a
panic. **MEDIUM–HIGH** in mixed-iface setups; not a guaranteed oops.
- Overall severity: **MEDIUM**, with a real user-visible functional
break and a documented driver-API violation.
**Step 8.4 — Risk vs benefit**
- Record: **Benefit: medium** (correct FCS reporting; stop garbage
frames leaking into cooked RX). **Risk: very low** (3 lines, same
pattern as sibling chips, no lock/API change). Ratio favors backport.
## Phase 9: Synthesis
**Step 9.1 — Evidence**
For:
- Real, reproduced bug (GitHub #38; Tested-by on MT7612U; author also
tested MT7610U).
- Violates mac80211 `FIF_FCSFAIL` contract; radiotap BADFCS never set.
- FCS-failed frames can continue into `__ieee80211_rx_handle_packet()`
without the flag.
- Three-line, obviously correct, matches every other mt76 MAC in this
tree.
- Applies cleanly to 6.6.157; symbols and call path exist.
- Maintainer SOB (Felix Fietkau).
- Popular USB hardware (e.g. Alfa AWUS036ACM).
Against:
- Not a crash/UAF/deadlock; mainly monitor-mode correctness plus cooked-
path leakage only when `fcsfail` is enabled.
- No `Fixes:` (omission from original driver, not a later regression).
- Affects a subset of mt76x02 users, not all machines.
Unresolved:
- Direct lore.kernel.org HTTP was 403; discussion recovered via b4.
- No independent stable@ thread found.
**Step 9.2 — Stable rules**
1. Obviously correct and tested? **PASS** — 3 lines, hardware-tested,
maintainer-acked.
2. Real bug affecting users? **PASS** — reporter could not tell bad-FCS
frames apart; contract violation is in-tree.
3. Important issue? **PASS** (medium) — broken advertised monitor filter
plus cooked-path delivery of CRC-failed frames. Not a panic, but it
is a real correctness/integrity bug, not a feature.
4. Small and contained? **PASS** — +3 lines, one function.
5. No new features/APIs? **PASS** — sets an existing `rx_status` flag
other mt76 chips already set.
6. Can apply to this tree? **PASS** — clean apply on 6.6.157.
**Step 9.3 — Exception category**
- Record: Not a device-ID/quirk/DT/build/docs exception. Ordinary small
driver correctness fix.
**Step 9.4 — Decision**
This tree is **6.6.157**. The buggy RX path, `MT_RXINFO_CRCERR`, and
mac80211 flag handling are all present. The patch is a tiny, tested,
maintainer-accepted fix for a user-visible bug on hardware this driver
supports. Benefit clearly outweighs risk.
---
### What the commit solves for 6.6 users
mt76x02 already programs the hardware to deliver CRC-failed frames when
monitor `fcsfail` is set, but never tells mac80211. Users of
MT7610/MT7612 USB and PCIe adapters then see every frame as clean in
radiotap, and those frames can also continue into the normal RX
handlers. The fix sets `RX_FLAG_FAILED_FCS_CRC` from `MT_RXINFO_CRCERR`,
which is what this tree already does for later mt76 chips.
### Stable-rule fit
Small, obviously correct, no new API, applies cleanly, real user-visible
bug. Importance is monitor/FCS integrity rather than a panic; that is
still within what stable takes for driver contract bugs of this size.
### Risk vs benefit
Very low risk (three lines, clean frames unchanged). Medium benefit for
mt76x02 monitor users and mixed-iface setups.
### Concerns
No functional dependencies. Series mate (WARN drop) is already in this
tree but is not required for this hunk. mt7925 in the commit message is
comparison only.
---
Verification:
- [Phase 1] Parsed tags: Reported-by/Tested-by 0072a70, Closes
github.com/morrownr/mt76/issues/38, Link msgid `...27750-3...`, SOB
Felix Fietkau; no Fixes/Cc:stable
- [Phase 2] Diff: +3 lines in `mt76x02_mac_process_rx()` after L2PAD;
sets `RX_FLAG_FAILED_FCS_CRC` from `MT_RXINFO_CRCERR`
- [Phase 2] Confirmed `mt76x02_configure_filter()` maps `FIF_FCSFAIL` →
clear `MT_RX_FILTR_CFG_CRC_ERR`
- [Phase 2] Confirmed mac80211 `should_drop_frame()` / radiotap BADFCS /
`ieee80211_rx_monitor()` cooked-path return behavior in this tree
- [Phase 3] `git blame`: insertion region from `d9f8934ed147b3` (2018);
`git merge-base --is-ancestor` true; `git describe --contains` →
v4.20-rc1
- [Phase 3] `MT_RXINFO_CRCERR` defined at `mt76x02_mac.h:54`; `git grep`
shows it is unused in `.c` files in this tree
- [Phase 3] Sibling `b6e7958602bd1` already in HEAD; this hunk
independent; `git apply --check` CLEAN
- [Phase 4] `b4 mbox` saved 3-message series; cover tested
MT7612U/MT7610U; `b4 am --check-newer-revisions` = v1 only, no NAKs
- [Phase 4] WebFetch of GitHub issue #38: reproduced 0 BADFCS; after
patch 956/7353 frames flagged
- [Phase 4] lore.kernel.org WebFetch: 403 — UNVERIFIED via HTTP;
recovered via b4
- [Phase 5] Only caller: `mt76x02_queue_rx_skb()`; chips: MT76x0U/E,
MT76x2U/E
- [Phase 5] Same flag already set in mt7603/mt7615/mt7915/mt7921/mt7996
in this checkout
- [Phase 6] `git describe HEAD` p-6.6-3-g04810563abb71; `make
kernelversion` 6.6.157; buggy code present; fix not applied
- [Phase 8] Failure mode: wrong radiotap + possible cooked-path delivery
of CRC-failed frames; not a panic
- UNVERIFIED: stable@ mailing-list thread content (HTTP 403)
**YES**
drivers/net/wireless/mediatek/mt76/mt76x02_mac.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c
index 06f17da2c0106..17c9782915315 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c
@@ -792,6 +792,9 @@ int mt76x02_mac_process_rx(struct mt76x02_dev *dev, struct sk_buff *skb,
if (rxinfo & MT_RXINFO_L2PAD)
pad_len += 2;
+ if (rxinfo & MT_RXINFO_CRCERR)
+ status->flag |= RX_FLAG_FAILED_FCS_CRC;
+
if (rxinfo & MT_RXINFO_DECRYPT) {
status->flag |= RX_FLAG_DECRYPTED;
status->flag |= RX_FLAG_MMIC_STRIPPED;
--
2.53.0
^ permalink raw reply related [flat|nested] 20+ messages in thread* [PATCH AUTOSEL 6.18] clk: mediatek: mt6735-vdecsys: add missing MODULE_DEVICE_TABLE()
2026-10-19 13:44 [PATCH AUTOSEL 6.18-6.12] net: dsa: mt7530: check CORE_PLL_GROUP4 access in mt7531_setup() Sasha Levin
` (14 preceding siblings ...)
2026-10-19 13:51 ` [PATCH AUTOSEL 6.18-5.10] wifi: mt76: mt76x02: report rx FCS errors to mac80211 Sasha Levin
@ 2026-10-19 13:51 ` Sasha Levin
2026-10-19 13:51 ` [PATCH AUTOSEL 6.18-6.6] net: pcs: mtk-lynxi: check regmap reads in mtk_pcs_lynxi_get_state() Sasha Levin
` (2 subsequent siblings)
18 siblings, 0 replies; 20+ messages in thread
From: Sasha Levin @ 2026-10-19 13:51 UTC (permalink / raw)
To: patches, stable
Cc: Pengpeng Hou, Brian Masney, Sasha Levin, y.oudjana, sboyd,
bmasney+clk, jbrunet+clk, matthias.bgg, angelogioacchino.delregno,
linux-clk, linux-mediatek, linux-kernel, linux-arm-kernel
From: Pengpeng Hou <pengpeng@iscas.ac.cn>
[ Upstream commit 096ab64a0e69460bfb3557d09e17d2933280a1c6 ]
The driver has an OF match table wired to .of_match_table, but does
not export the table with MODULE_DEVICE_TABLE().
Add the missing MODULE_DEVICE_TABLE(of, ...) entry so module alias
information is generated for OF based module autoloading.
This is a source-level fix. It does not claim dynamic hardware
reproduction; the evidence is the driver-owned match table, its use by
the platform driver, and the missing module alias publication.
Signed-off-by: Pengpeng Hou <pengpeng@iscas.ac.cn>
Reviewed-by: Brian Masney <bmasney@redhat.com>
Signed-off-by: Brian Masney <bmasney@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
LLM Generated explanations, may be completely bogus:
The local tree is **7.3.0-rc4** (`v7.3-rc4-27-gf0100363d8c37`). The
vdecsys driver is present here; the change is a one-line
`MODULE_DEVICE_TABLE(of, ...)` so OF module aliases are generated.
===============================================================
PHASE 1: COMMIT MESSAGE FORENSICS
===============================================================
**Step 1.1: PARSE THE SUBJECT LINE**
Record: [clk: mediatek] [add] [missing MODULE_DEVICE_TABLE() for
mt6735-vdecsys]
**Step 1.2: PARSE ALL COMMIT MESSAGE TAGS**
Record:
- Signed-off-by: Pengpeng Hou \<pengpeng@iscas.ac.cn\> (author)
- Reviewed-by: Brian Masney \<bmasney@redhat.com\> (clk co-maintainer;
also committed the patch)
- Signed-off-by: Brian Masney \<bmasney@redhat.com\>
- No Fixes:, Reported-by:, Tested-by:, Link:, or Cc: stable
- Ignore any pipeline-added Sasha Levin SOB (none on this commit)
**Step 1.3: ANALYZE THE COMMIT BODY TEXT**
Record:
- Bug: OF match table is wired to `.of_match_table` but not exported
with `MODULE_DEVICE_TABLE()`, so modpost does not emit `of:` aliases.
- Symptom: when `CONFIG_COMMON_CLK_MT6735_VDECSYS=m`, udev/kmod cannot
autoload `clk-mt6735-vdecsys.ko` from the DT compatible string;
vdecsys clocks/resets never register unless the module is loaded by
hand.
- Version info: none in the message. Driver introduced in
`0bd9b1211f741` (contained in v6.13-rc1); this fix is contained in
v7.3-rc1.
- Root cause: omission at driver introduction, not a later regression.
**Step 1.4: DETECT HIDDEN BUG FIXES**
Record: Not hidden. It is an explicit autoload/alias publication fix.
Author calls it a “source-level fix” with no hardware reproduction; that
is accurate (the missing macro is visible in the file) and does not make
the bug theoretical.
===============================================================
PHASE 2: DIFF ANALYSIS - LINE BY LINE
===============================================================
**Step 2.1: INVENTORY THE CHANGES**
Record:
- File: `drivers/clk/mediatek/clk-mt6735-vdecsys.c` (+1 / -0)
- Function/data: file-scope after `of_match_mt6735_vdecsys[]`
- Scope: single-file, one-line surgical fix
**Step 2.2: UNDERSTAND THE CODE FLOW CHANGE**
Record: Before: match table exists and is used for in-kernel platform
matching, but no module alias is published. After:
`MODULE_DEVICE_TABLE(of, of_match_mt6735_vdecsys)` aliases the table for
`file2alias`/modpost. Affects the modular autoload path only;
probe/remove logic is unchanged.
**Step 2.3: IDENTIFY THE BUG MECHANISM**
Record: [Hardware enablement / module autoload] `MODULE_DEVICE_TABLE` is
the OF analog of exporting PCI/USB IDs. Without it, `modules.alias`
lacks `of:N*T*Cmediatek,mt6735-vdecsys`. Platform matching still works
if the module is already loaded or built-in.
**Step 2.4: ASSESS THE FIX QUALITY**
Record: Obviously correct; matches the established MediaTek clk pattern
(`65c9ad77cbc0e` “Add MODULE_DEVICE_TABLE() where appropriate”).
Compile-time alias generation only; no locking, no API, no runtime path
change. Regression risk is negligible. Sibling `clk-mt6735-imgsys.c` /
`clk-mt6735-mfgcfg.c` still lack the macro in this tree; that does not
make this hunk wrong.
===============================================================
PHASE 3: GIT HISTORY INVESTIGATION
===============================================================
**Step 3.1: BLAME THE CHANGED LINES**
Record: Match table from `0bd9b1211f741` (Yassine Oudjana, 2024-11-06;
contained in v6.13-rc1). `MODULE_DEVICE_TABLE` line is this commit
`096ab64a0e694`. Bug present from first introduction of the driver.
**Step 3.2: FOLLOW THE FIXES: TAG**
Record: No Fixes: tag on this commit. A later unrelated series (`[PATCH
07/32] clk: mediatek: mt6735: Add missing MODULE_DEVICE_TABLE()`) cited
`Fixes: 0bd9b1211f74` for the same omission across four files. Intro
commit is an ancestor of HEAD.
**Step 3.3: CHECK FILE HISTORY FOR RELATED CHANGES**
Record: Only two commits on this file: intro + this fix. Sibling same-
day commit `36cf8d279ff90` does the same for vencsys. Standalone for
vdecsys; no prerequisite refactor.
**Step 3.4: CHECK THE AUTHOR'S OTHER COMMITS**
Record: Pengpeng Hou is not the MT6735 clk maintainer (that is Yassine
Oudjana). Same-day vencsys twin plus several other `MODULE_DEVICE_TABLE`
additions (rtc, vdpa, watchdog). Brian Masney, clk co-maintainer,
reviewed and applied it.
**Step 3.5: CHECK FOR DEPENDENT/PREREQUISITE COMMITS**
Record: None. Macro has long existed in `include/linux/module.h`.
Applies standalone.
===============================================================
PHASE 4: MAILING LIST AND EXTERNAL RESEARCH
===============================================================
**Step 4.1: FIND THE ORIGINAL PATCH DISCUSSION**
Record:
- Lore/msgid:
https://patch.msgid.link/20260704124450.11035-1-pengpeng@iscas.ac.cn
- `b4 dig -a`: v1 only, applied as submitted
- Thread (mbox): author post + Brian Masney `Reviewed-by:` on
2026-07-06. No NAK, no stable nomination, no requested revisions.
- WebFetch of lore/spinics: 403/500; thread recovered via `b4 dig -m`.
**Step 4.2: CHECK WHO REVIEWED THE PATCH**
Record (`b4 dig -w`): linux-clk, linux-mediatek, Stephen Boyd, Brian
Masney, AngeloGioacchino Del Regno, Matthias Brugger, Yassine Oudjana.
Review came from clk co-maintainer Brian Masney.
**Step 4.3: SEARCH FOR THE BUG REPORT**
Record: No Reported-by, no bugzilla/syzbot. Author states source-level
evidence only. No in-tree DTS uses `mediatek,mt6735-vdecsys` (binding
only in `Documentation/devicetree/bindings/clock/mediatek,syscon.yaml`).
**Step 4.4: CHECK FOR RELATED PATCHES AND SERIES**
Record: Twin vencsys patch applied in the same pile. Later 07/32 series
(Akari Tsuyukusa, Aug 2026) would have covered
imgsys+mfgcfg+vdecsys+vencsys together; vdecsys/vencsys were already
fixed here. This commit does not depend on that series.
**Step 4.5: CHECK STABLE MAILING LIST HISTORY**
Record: No dedicated stable thread found for this subject. UNVERIFIED
whether an AUTOSEL pick already exists; that must not drive the verdict.
===============================================================
PHASE 5: CODE SEMANTIC ANALYSIS
===============================================================
**Step 5.1: IDENTIFY KEY FUNCTIONS IN THE DIFF**
Record: No function body changed. Added `MODULE_DEVICE_TABLE` next to
`of_match_mt6735_vdecsys`. Driver uses `mtk_clk_simple_probe` /
`mtk_clk_simple_remove` via `module_platform_driver`.
**Step 5.2: TRACE CALLERS**
Record: Probe is invoked by the platform core when a device matches
`mediatek,mt6735-vdecsys`. Autoload (udev/kmod) is the path that was
broken for `=m`. Built-in (`=y`) matching already worked via
`.of_match_table`.
**Step 5.3: TRACE CALLEES**
Record: `mtk_clk_simple_probe()` (`drivers/clk/mediatek/clk-mtk.c`)
registers the vdecsys gates and resets from `vdecsys_clks`. Unchanged by
this patch.
**Step 5.4: FOLLOW THE CALL CHAIN**
Record: DT node `compatible = "mediatek,mt6735-vdecsys"` → (modular)
udev alias lookup → `clk-mt6735-vdecsys.ko` → platform probe → video-
decoder clocks. Reachable on MT6735 boards that describe that syscon; no
in-tree board DTS. Unprivileged userspace cannot trigger it except by
loading the module.
**Step 5.5: SEARCH FOR SIMILAR PATTERNS**
Record: Most MediaTek clk drivers already have `MODULE_DEVICE_TABLE`.
MT6735 core clocks (apmixedsys/infracfg/pericfg/topckgen) have it;
imgsys and mfgcfg in this tree still do not. Same class of omission as
the 2023 sweep `65c9ad77cbc0e`.
===============================================================
PHASE 6: CROSS-REFERENCING AGAINST THE LOCAL TREE
===============================================================
**Step 6.1: DOES THE BUGGY CODE EXIST IN THIS TREE?**
Record: Yes. File exists; driver from `0bd9b1211f741` (v6.13-rc1).
Kconfig `COMMON_CLK_MT6735_VDECSYS` is **tristate**, Makefile maps it to
`clk-mt6735-vdecsys.o`. HEAD already contains `096ab64a0e694`
(v7.3-rc1); the pre-fix omission is the code this candidate addresses.
**Step 6.2: CHECK FOR BACKPORT COMPLICATIONS**
Record: Clean apply. One added line at a stable match-table site; no
refactor around it.
**Step 6.3: CHECK IF RELATED FIXES ARE ALREADY HERE**
Record: This exact line is present (commit `096ab64a0e694`). No
alternate fix. imgsys/mfgcfg still missing aliases — separate omissions.
===============================================================
PHASE 7: SUBSYSTEM AND MAINTAINER CONTEXT
===============================================================
**Step 7.1: IDENTIFY THE SUBSYSTEM AND ITS CRITICALITY**
Record: [drivers/clk/mediatek] [PERIPHERAL] — SoC-specific video-decoder
clock/reset driver for MT6735 (Helio T1 era). Not core mm/net/fs.
**Step 7.2: ASSESS SUBSYSTEM ACTIVITY**
Record: MediaTek clk is actively developed; this file itself is quiet
(two commits). MT6735 clk is listed Maintained (Yassine Oudjana).
===============================================================
PHASE 8: IMPACT AND RISK ASSESSMENT
===============================================================
**Step 8.1: DETERMINE WHO IS AFFECTED**
Record: Users of MT6735 with `CONFIG_COMMON_CLK_MT6735_VDECSYS=m`. No
in-tree defconfig enables `COMMON_CLK_MT6735`; no in-tree DTS
instantiates the node. Built-in builds are unaffected.
**Step 8.2: DETERMINE THE TRIGGER CONDITIONS**
Record: Boot/enumeration with the DT node while the driver is a module.
Not a race. Not unprivileged-exploitable. Workaround: `modprobe clk-
mt6735-vdecsys` or build `=y`.
**Step 8.3: DETERMINE THE FAILURE MODE SEVERITY**
Record: Video-decoder clocks/resets never appear unless the module is
loaded manually → decode/VPU consumers fail clock lookup. Not
panic/UAF/corruption. Severity: MEDIUM for modular MT6735 vdec; LOW
overall population. Failure is “device feature does not come up,” same
class as missing device IDs.
**Step 8.4: CALCULATE RISK-BENEFIT RATIO**
Record: Benefit: modular autoload for this clock controller. Risk: very
low (one compile-time alias line). Ratio: favorable because risk is
essentially zero.
===============================================================
PHASE 9: FINAL SYNTHESIS
===============================================================
**Step 9.1: COMPILE THE EVIDENCE**
FOR:
- Real autoload bug on a tristate, `module_platform_driver` clock driver
- One-line, obviously correct, clk co-maintainer Reviewed-by + applied
- Same class as device-ID / quirk enablement (OF alias publication)
- Established MediaTek clk precedent (`65c9ad77cbc0e`: “allow auto-load
at boot”)
- Zero runtime/API/locking risk; applies cleanly
- Buggy driver exists in this 7.3 tree (since v6.13)
AGAINST:
- Not crash/security/corruption/deadlock
- No user report or hardware test
- Niche SoC; no in-tree DTS/defconfig
- Built-in configs already work
- Author framed it as source-level only
UNRESOLVED:
- Whether AUTOSEL/stable already discussed this hash (lore.kernel.org
stable search not useful)
- Direct fetch of lore HTML (403)
**Step 9.2: APPLY THE STABLE RULES CHECKLIST**
1. Obviously correct and tested? **PASS** — one-line alias export;
reviewed by clk co-maintainer. No HW test, but correctness does not
depend on runtime.
2. Fixes a real bug that affects users? **PASS** — modular OF autoload
is broken by construction when the table is not exported.
3. Important issue? **PASS** (MEDIUM) — hardware clocks do not come up
on the intended modular path; same practical class as missing device
IDs, not a panic.
4. Small and contained? **PASS** — +1 line, one file.
5. No new features or APIs? **PASS** — publishes an existing match
table.
6. Can apply to the local tree? **PASS** — file and match table exist;
hunk is identical.
**Step 9.3: CHECK FOR EXCEPTION CATEGORIES**
Record: Device-ID / module-alias publication for an existing driver (OF
`MODULE_DEVICE_TABLE`). That exception applies.
**Step 9.4: MAKE YOUR DECISION**
The bug is real for `=m` builds, the fix is trivial and already the
subsystem’s standard pattern, and this tree has the driver. Conservative
stable practice still takes this class because the downside is nil and
the upside is the driver actually binding.
===============================================================
What the commit solves, and why it matters here
===============================================================
Without `MODULE_DEVICE_TABLE(of, of_match_mt6735_vdecsys)`, modpost
never emits the `of:N*T*Cmediatek,mt6735-vdecsys` alias. On this tree
the Kconfig is tristate, so a modular vdecsys driver will not autoload;
video-decoder clocks and resets never register until someone loads the
module by name. Built-in matching via `.of_match_table` was already
fine.
It meets stable rules: obviously correct, one line, no new API, no
dependencies, and it is the OF equivalent of adding a device ID to an
existing driver. Risk is compile-time alias generation only.
Concerns: no in-tree board uses this compatible, no reporter, not a
crash. Those lower breadth of impact; they do not make the hunk unsafe
or non-bugfix.
Verification:
- [Phase 1] Parsed commit `096ab64a0e694`: SOB Pengpeng Hou; Reviewed-
by/SOB Brian Masney; no Fixes/Reported-by/Cc: stable
- [Phase 2] Diff: +1 `MODULE_DEVICE_TABLE(of, of_match_mt6735_vdecsys)`
in `clk-mt6735-vdecsys.c`
- [Phase 3] `git blame`: match table from `0bd9b1211f741`; `git describe
--contains` intro v6.13-rc1, fix v7.3-rc1
- [Phase 3] `git merge-base --is-ancestor 0bd9b1211f741 HEAD` and
`096ab64a0e694 HEAD`: both true
- [Phase 3] `git log --oneline -- drivers/clk/mediatek/clk-
mt6735-vdecsys.c`: only intro + this fix
- [Phase 3] Sibling `36cf8d279ff90` vencsys same change; earlier sweep
`65c9ad77cbc0e`
- [Phase 4] `b4 dig -c 096ab64a0e694`: msgid
`20260704124450.11035-1-pengpeng@iscas.ac.cn`; v1 only
- [Phase 4] `b4 dig -m`: Brian Masney Reviewed-by; no NAK/stable
discussion
- [Phase 4] WebFetch lore/spinics: 403/500; used mbox instead
- [Phase 5] Kconfig `COMMON_CLK_MT6735_VDECSYS` tristate; Makefile
builds `clk-mt6735-vdecsys.o`; probe is `mtk_clk_simple_probe`
- [Phase 5] `MODULE_DEVICE_TABLE` in `include/linux/module.h` creates
file2alias symbol
- [Phase 6] `git describe HEAD` = v7.3-rc4-27-gf0100363d8c37; `make
kernelversion` = 7.3.0-rc4
- [Phase 6] No in-tree dts/dtsi for mt6735-vdecsys; binding listed in
`mediatek,syscon.yaml`
- [Phase 6] No defconfig sets `COMMON_CLK_MT6735`
- [Phase 6] imgsys/mfgcfg still lack MODULE_DEVICE_TABLE (verified by
grep)
- [Phase 7] MAINTAINERS: COMMON CLK FRAMEWORK includes Brian Masney;
MT6735 CLOCK maintained by Yassine Oudjana
- [Phase 8] Failure mode: modular autoload miss → vdec clocks absent;
severity MEDIUM/narrow
- UNVERIFIED: whether stable@ already queued this hash; lore stable
search did not return this commit
**YES**
drivers/clk/mediatek/clk-mt6735-vdecsys.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/clk/mediatek/clk-mt6735-vdecsys.c b/drivers/clk/mediatek/clk-mt6735-vdecsys.c
index 8817085fc1db4..d53ebf92e878d 100644
--- a/drivers/clk/mediatek/clk-mt6735-vdecsys.c
+++ b/drivers/clk/mediatek/clk-mt6735-vdecsys.c
@@ -63,6 +63,7 @@ static const struct of_device_id of_match_mt6735_vdecsys[] = {
{ .compatible = "mediatek,mt6735-vdecsys", .data = &vdecsys_clks },
{ /* sentinel */ }
};
+MODULE_DEVICE_TABLE(of, of_match_mt6735_vdecsys);
static struct platform_driver clk_mt6735_vdecsys = {
.probe = mtk_clk_simple_probe,
--
2.53.0
^ permalink raw reply related [flat|nested] 20+ messages in thread* [PATCH AUTOSEL 6.18-6.6] net: pcs: mtk-lynxi: check regmap reads in mtk_pcs_lynxi_get_state()
2026-10-19 13:44 [PATCH AUTOSEL 6.18-6.12] net: dsa: mt7530: check CORE_PLL_GROUP4 access in mt7531_setup() Sasha Levin
` (15 preceding siblings ...)
2026-10-19 13:51 ` [PATCH AUTOSEL 6.18] clk: mediatek: mt6735-vdecsys: add missing MODULE_DEVICE_TABLE() Sasha Levin
@ 2026-10-19 13:51 ` Sasha Levin
2026-10-19 13:52 ` [PATCH AUTOSEL 6.18] wifi: mt76: mt7603: restore hardware PS buffering after a service period Sasha Levin
2026-10-19 13:53 ` [PATCH AUTOSEL 6.18-6.12] net: ethernet: mtk_wed: increase WED v2 WDMA RESV_BUFF to 0x80 Sasha Levin
18 siblings, 0 replies; 20+ messages in thread
From: Sasha Levin @ 2026-10-19 13:51 UTC (permalink / raw)
To: patches, stable
Cc: Daniel Golle, Andrew Lunn, Jakub Kicinski, Sasha Levin, lynxis,
hkallweit1, davem, edumazet, pabeni, matthias.bgg,
angelogioacchino.delregno, netdev, linux-kernel, linux-arm-kernel,
linux-mediatek
From: Daniel Golle <daniel@makrotopia.org>
[ Upstream commit 5cc65c01cdc577621d1320f4aa03a1382c5a4a45 ]
mtk_pcs_lynxi_get_state() ignores regmap_read()'s return value; a
failed read leaves bm and adv holding uninitialized stack values
which are then decoded into the reported link state. The regmaps
backing the MT7531 SGMII PCS instances sit on an MDIO bus where
reads can fail. Check both reads and report the link as down on
error; phylink presets state->link before the callback, so a bare
return would leave a failed read reported as link-up.
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Link: https://patch.msgid.link/fce70657fc03bbaf60a04c0fbf2f418531135c4f.1785811140.git.daniel@makrotopia.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
LLM Generated explanations, may be completely bogus:
This is a real uninitialized-data bug in MediaTek LynxI PCS link
polling, and the buggy path exists in this 6.12 tree. It should be
backported.
## Phase 1: Commit message forensics
**Step 1.1:** Record: `[net: pcs: mtk-lynxi:]` `[check]` `[validate
regmap_read() in mtk_pcs_lynxi_get_state() so failed MDIO reads are not
decoded as link state]`
**Step 1.2:** Record: tags in the candidate message:
- `Signed-off-by: Daniel Golle <daniel@makrotopia.org>` (author; driver
co-maintainer)
- `Reviewed-by: Andrew Lunn <andrew@lunn.ch>` (netdev/DSA reviewer)
- `Link: https://patch.msgid.link/fce70657fc03bbaf60a04c0fbf2f418531135c
4f.1785811140.git.daniel@makrotopia.org`
- `Signed-off-by: Jakub Kicinski <kuba@kernel.org>` (netdev maintainer)
- No `Reported-by`, `Tested-by`, `Cc: stable` in the candidate text
(absence is expected)
- Original mailing-list submission **did** include `Fixes: 4765a9722e09
("net: pcs: add driver for MediaTek SGMII PCS")`; that tag is not in
the candidate body
**Step 1.3:** Record: `[Bug: ignored regmap_read() errors leave
`bm`/`adv` uninitialized and phylink decodes them as BMSR/LPA]`
`[Symptom: false or garbage link/speed/duplex; failed read can be
reported as link-up because phylink presets `state->link`]` `[Version:
bug dates to driver introduction]` `[Root cause: MDIO-backed MT7531
SGMII PCS regmaps can fail; output is not written on error]`
**Step 1.4:** Record: `[Not a disguised cleanup. This is an explicit
missing-check / uninitialized-use fix. v2 of the patch added
`state->link = false` after review, because a bare return left phylink's
preset link-up.]`
## Phase 2: Diff analysis
**Step 2.1:** Record: `[drivers/net/pcs/pcs-mtk-lynxi.c: +5 / -2 in
`mtk_pcs_lynxi_get_state()`]` `[single-file surgical fix]`
**Step 2.2:** Record: `[Before: two unchecked `regmap_read()`s, then
`phylink_mii_c22_pcs_decode_state()` on `bm`/`adv`. After: if either
read fails, set `state->link = false` and return; otherwise decode as
before. Error path only.]`
**Step 2.3:** Record: `[Category: initialization / missing return-value
check]` `[Mechanism: failed `regmap_read()` does not write `*val`;
`unsigned int bm, adv` stay uninitialized;
`phylink_mii_c22_pcs_decode_state()` does `state->link = !!(bmsr &
BMSR_LSTATUS)` on that garbage. Fix matches
`phylink_mii_c22_pcs_get_state()`, which already treats read errors as
link-down.]`
**Step 2.4:** Record: `[Obviously correct, 5-line change, no
API/locking/refcount changes.]` `[Regression risk: very low. Worst case
is reporting link-down on a failed register read, which is the intended
fail-safe.]`
## Phase 3: Git history
**Step 3.1:** Record: `[Buggy reads introduced in 4765a9722e0976 ("net:
pcs: add driver for MediaTek SGMII PCS", Daniel Golle, 2023-03-19)]`
`[First appeared in v6.4-rc1; present for the life of this driver]`
**Step 3.2:** Record: `[Fixes target 4765a9722e0976 is an ancestor of
HEAD. No later lynxi get_state error-handling in this tree.]`
**Step 3.3:** Record: `[File history on this tree: 4765a9722e097 (add
driver), 3b2de56a146f3 (neg_mode), 90308679c297f (pcs_disable),
be884c15de370 (MODULE_DESCRIPTION).]` `[Standalone functionally; series
patch 1/6, other patches touch `mt7530.c` only.]` `[Prerequisite already
here: 93d46870c5440 ("net: dsa: mt7530: check bus->read() errors in the
MDIO regmap backend") — after that, a failed MDIO read returns an error
and leaves the output unwritten instead of truncated garbage.]`
**Step 3.4:** Record: `[Daniel Golle is listed as maintainer of MEDIATEK
ETHERNET PCS DRIVER. Related MDIO error-propagation work on mt7530 is by
the same author.]`
**Step 3.5:** Record: `[No missing functions. This tree's
`mtk_pcs_lynxi_get_state()` still has the 6.12 signature (no
`neg_mode`); the check itself is independent. Can apply standalone with
a small context adaptation.]`
## Phase 4: Mailing list
**Step 4.1:** Record: `[Lore thread retrieved via b4 mbox: msgid fce7065
7fc03bbaf60a04c0fbf2f418531135c4f.1785811140.git.daniel@makrotopia.org]`
`[v1 of this remaining-errors series was `[PATCH net 1/4]`; v2 is
`[PATCH net v2 1/6]`. Applied version is v2.]` `[v2 change: set
`state->link = false` because phylink presets link-up (Sashiko
review).]` `[Andrew Lunn Reviewed-by on v1; author kept it on v2 for the
small in-spirit change. No NAKs.]` `[Patchwork bot: applied by Jakub
Kicinski as netdev commit 5cc65c01cdc5.]`
**Step 4.2:** Record: `[To/Cc included Andrew Lunn, Vladimir Oltean,
Russell King, netdev, linux-mediatek, DSA and MediaTek maintainers.
Right audience.]`
**Step 4.3:** Record: `[No syzbot/bugzilla user report. Found during
mt7530 MDIO error-handling review. Still a concrete, reachable bug:
`pcs.poll = true` so this runs from phylink's 1 Hz poll.]`
**Step 4.4:** Record: `[Series: "fix remaining swallowed MDIO access
errors". Patch 1 is the only pcs-mtk-lynxi change and does not depend on
patches 2–6.]` `[Earlier companion 93d46870c5440 / 96e0f5184af69 are
already in this tree.]`
**Step 4.5:** Record: `[UNVERIFIED: lore.kernel.org/stable search
blocked by Anubis. No stable-list discussion found via b4.]`
## Phase 5: Semantic analysis
**Step 5.1:** Record: `[Modified: `mtk_pcs_lynxi_get_state`. Wired as
`.pcs_get_state`.]`
**Step 5.2:** Record: `[Callers: `phylink_mac_pcs_get_state()` → in-band
resolve (`MLO_AN_INBAND`), ethtool `phylink_ethtool_ksettings_get()`,
and MII emulation. `mpcs->pcs.poll = true` so `phylink_fixed_poll` runs
`phylink_run_resolve()` every HZ.]`
**Step 5.3:** Record: `[Callees: `regmap_read`,
`phylink_mii_c22_pcs_decode_state`.]`
**Step 5.4:** Record: `[Reachable from userspace: ethtool link settings,
and continuously while the netdev is up in in-band
SGMII/1000Base-X/2500Base-X.]` `[Hardware: MT7531 DSA ports 5/6
(`mt7531_create_sgmii()` uses an MDIO-backed regmap) and MediaTek SoC
SGMII (`mtk_eth_soc` syscon/MMIO, rarely fails). The MDIO path is the
one that matters.]`
**Step 5.5:** Record: `[Same pattern already handled in
`phylink_mii_c22_pcs_get_state()` and `phylink_mii_c45_pcs_get_state()`
in this tree. Lynx PCS uses those helpers; lynxi did not.]`
## Phase 6: Local tree (6.12.111, `pending-6.12`)
**Step 6.1:** Record: `[Yes. `drivers/net/pcs/pcs-mtk-lynxi.c:98-99`
still has unchecked `regmap_read()` into uninitialized `bm`/`adv`.
Introduced v6.4, present here.]` `[Verified: `git describe HEAD` →
p-6.12-4-gbf6fcdf761abd; `make kernelversion` → 6.12.111.]`
**Step 6.2:** Record: `[Minor context rework, not a semantic fork. This
tree has no `mtk_pcs_lynxi_inband_caps`, no `neg_mode` argument, and
`phylink_mii_c22_pcs_decode_state(state, bmsr, lpa)` not the later 4-arg
form. The 5-line check ports 1:1 into the existing function body.]`
**Step 6.3:** Record: `[No lynxi get_state error-check already present.
Prerequisite MDIO backend error propagation is already here, which is
why this follow-up is needed: failed reads no longer write `*val`.]`
## Phase 7: Subsystem context
**Step 7.1:** Record: `[drivers/net/pcs + consumers in net/dsa/mt7530
and net/ethernet/mediatek]` `[IMPORTANT: common OpenWrt/router SGMII CPU
ports, not core mm/VFS, but production networking]`
**Step 7.2:** Record: `[Driver is mature since v6.4; this file has only
a handful of commits on this tree. Bug is long-standing, newly exposed
as true uninitialized use after the MDIO backend fix.]`
## Phase 8: Impact and risk
**Step 8.1:** Record: `[Driver-specific: MT7531 SGMII (MDIO) and
MediaTek SoC SGMII (MMIO).]`
**Step 8.2:** Record: `[Trigger: failed `regmap_read` on the PCS map.
Common on flaky/timeout MDIO; not every boot. Unprivileged userspace can
observe the result via ethtool/carrier; the poll path runs while the
interface is up.]`
**Step 8.3:** Record: `[Failure mode: uninitialized stack decoded as
link/speed/duplex; false carrier possible because phylink presets
`state->link = 1`.]` `[Severity: HIGH for wrong datapath/carrier on MDIO
error; not a panic. Uninitialized use is the same class as KMSAN-class
bugs.]`
**Step 8.4:** Record: `[Benefit: high for MT7531 in-band SGMII — stops
garbage link state after a bus error, especially now that the backend
returns real errors.]` `[Risk: very low — 5 lines, fail-closed to link-
down.]` `[Ratio: strongly favors backport.]`
## Phase 9: Synthesis
**For backporting:**
- Real bug: uninitialized `bm`/`adv` decoded into phylink link state
- User-visible: false/garbage carrier, speed, duplex; ethtool reports it
- Tiny, obviously correct, matches phylink's own C22 helper
- Reviewed by Andrew Lunn, applied by Jakub Kicinski, written by the PCS
maintainer
- Buggy code has been in this driver since v6.4 and is in 6.12.111
- Companion to MDIO error-propagation already in this tree
(93d46870c5440); without this, a failed MT7531 PCS read now leaves
stack garbage instead of even truncated-but-defined data
- No new API/feature
**Against:**
- Not a crash/UAF/deadlock
- Raw upstream hunk will not apply cleanly (later `neg_mode` /
`inband_caps` context)
- No external user/syzbot report
- Series 1/6, but this patch does not need 2–6
**Unresolved:** stable-list discussion (lore/stable fetch blocked)
**Stable rules:**
1. Obviously correct and tested? **PASS** — same pattern as
`phylink_mii_c22_pcs_get_state()`; Reviewed-by Andrew Lunn; merged
2. Fixes a real bug that affects users? **PASS** — wrong link state /
uninitialized data on MDIO failure for MT7531 SGMII
3. Important issue? **PASS** — uninitialized memory used as live link
state on a 1 Hz poll; can keep carrier up after a failed read
4. Small and contained? **PASS** — 5 lines, one function
5. No new features or APIs? **PASS**
6. Can apply to this tree? **PASS** — needs a trivial context backport,
not missing code
**Exception category:** none (normal small correctness fix)
The problem for 6.12 users is that `mtk_pcs_lynxi_get_state()` still
consumes uninitialized stack as BMSR/LPA. Phylink presets `state->link =
1` (`phylink.c:1328`) and this PCS polls every second. After the
already-landed MT7530 MDIO backend fix, a failed read returns an error
and does not fill `*val`, so this is the necessary follow-up. Benefit is
preventing false/garbage link state; risk is a fail-closed link-down on
I/O error.
Verification:
- [Phase 1] Parsed candidate tags; original lore patch had `Fixes:
4765a9722e09`
- [Phase 2] Diff is 5 lines in `mtk_pcs_lynxi_get_state()` wrapping two
`regmap_read()`s
- [Phase 2] Confirmed `phylink_mac_pcs_get_state()` sets `state->link =
1` before the callback
- [Phase 2] Confirmed `phylink_mii_c22_pcs_decode_state()` uses `bmsr`
for `state->link` and that `phylink_mii_c22_pcs_get_state()` already
sets `state->link = false` on read failure
- [Phase 3] `git blame` on lines 98–99: 4765a9722e0976; `git describe
--contains` → v6.4-rc1
- [Phase 3] `git merge-base --is-ancestor 4765a9722e0976 HEAD` succeeded
- [Phase 3] `git merge-base --is-ancestor 93d46870c5440 HEAD` succeeded
(MDIO backend now returns errors without writing `*val`)
- [Phase 4] `b4 mbox` on the msgid: 8-message thread; series v2 1/6;
Andrew Lunn Reviewed-by; no NAK
- [Phase 4] Cover letter: this check was added because a failed read can
now leave output unwritten
- [Phase 4] UNVERIFIED: lore.kernel.org/stable search (Anubis 403)
- [Phase 5] Callers: phylink in-band resolve, ethtool get, 1 Hz
`link_poll`; consumers `mt7530-mdio.c` and `mtk_eth_soc.c`
- [Phase 6] `git describe HEAD` / `make kernelversion`: 6.12.111 on
`pending-6.12`; unchecked reads still at `pcs-mtk-lynxi.c:98-99`
- [Phase 6] Function signature here lacks `neg_mode`; backport is a
local 5-line edit
- [Phase 8] Failure mode: uninitialized link state / possible false
carrier, severity HIGH, not a panic
- UNVERIFIED: whether this SHA is already in some other stable series
(decision is for this tree only)
**YES**
drivers/net/pcs/pcs-mtk-lynxi.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/drivers/net/pcs/pcs-mtk-lynxi.c b/drivers/net/pcs/pcs-mtk-lynxi.c
index 87df3a9dfc9bc..64fb17c189afc 100644
--- a/drivers/net/pcs/pcs-mtk-lynxi.c
+++ b/drivers/net/pcs/pcs-mtk-lynxi.c
@@ -110,8 +110,11 @@ static void mtk_pcs_lynxi_get_state(struct phylink_pcs *pcs,
unsigned int bm, adv;
/* Read the BMSR and LPA */
- regmap_read(mpcs->regmap, SGMSYS_PCS_CONTROL_1, &bm);
- regmap_read(mpcs->regmap, SGMSYS_PCS_ADVERTISE, &adv);
+ if (regmap_read(mpcs->regmap, SGMSYS_PCS_CONTROL_1, &bm) ||
+ regmap_read(mpcs->regmap, SGMSYS_PCS_ADVERTISE, &adv)) {
+ state->link = false;
+ return;
+ }
phylink_mii_c22_pcs_decode_state(state, neg_mode,
FIELD_GET(SGMII_BMSR, bm),
--
2.53.0
^ permalink raw reply related [flat|nested] 20+ messages in thread* [PATCH AUTOSEL 6.18] wifi: mt76: mt7603: restore hardware PS buffering after a service period
2026-10-19 13:44 [PATCH AUTOSEL 6.18-6.12] net: dsa: mt7530: check CORE_PLL_GROUP4 access in mt7531_setup() Sasha Levin
` (16 preceding siblings ...)
2026-10-19 13:51 ` [PATCH AUTOSEL 6.18-6.6] net: pcs: mtk-lynxi: check regmap reads in mtk_pcs_lynxi_get_state() Sasha Levin
@ 2026-10-19 13:52 ` Sasha Levin
2026-10-19 13:53 ` [PATCH AUTOSEL 6.18-6.12] net: ethernet: mtk_wed: increase WED v2 WDMA RESV_BUFF to 0x80 Sasha Levin
18 siblings, 0 replies; 20+ messages in thread
From: Sasha Levin @ 2026-10-19 13:52 UTC (permalink / raw)
To: patches, stable
Cc: Felix Fietkau, Sasha Levin, lorenzo, ryder.lee, matthias.bgg,
angelogioacchino.delregno, linux-wireless, linux-kernel,
linux-arm-kernel, linux-mediatek
From: Felix Fietkau <nbd@nbd.name>
[ Upstream commit 636a883e2feef5e4ff95695d3c372ceff03960f5 ]
Releasing buffered frames has to turn off the PSE redirect for the
station, otherwise the released frames are looped straight back into the
driver PS queue. Nothing ever turns it back on: mt7603_sta_ps() only runs
on an observed PM bit transition, and MT_WCID_FLAG_PS keeps mt76 from
reporting the same state twice. After the first service period the
hardware therefore treats a dozing station as awake and transmits at it
directly, which is where the retry storms and the packet loss reported
against U-APSD clients come from.
Re-arm hardware buffering from mt7603_mac_work() for every station that
is still known to be asleep, once the PSD queue has drained and the
released frames have passed the redirect stage. Frames that are still
queued belong to the service period that was just served, so unlike on a
sleep transition they must not be pulled back with mt7603_filter_tx().
Track the sleep state separately from the WTBL state, so a station that
wakes up while the re-arm is pending is not put back to sleep.
Link: https://patch.msgid.link/20260801145334.1166751-7-nbd@nbd.name
Signed-off-by: Felix Fietkau <nbd@nbd.name>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
LLM Generated explanations, may be completely bogus:
I have enough to judge this against 5.15.221: the bug is in this tree,
the fix is real, and it needs a small mechanical backport rather than
missing code.
---
## PHASE 1: COMMIT MESSAGE FORENSICS
**Step 1.1: PARSE THE SUBJECT LINE**
Record: **[wifi: mt76: mt7603:] [restore] [re-arm hardware PS buffering
after a U-APSD/PS-Poll service period]**
**Step 1.2: PARSE ALL COMMIT MESSAGE TAGS**
Record:
- `Link: https://patch.msgid.link/20260801145334.1166751-7-nbd@nbd.name`
— this is **patch 07/10** of Felix Fietkau’s series
- `Signed-off-by: Felix Fietkau <nbd@nbd.name>` — mt76 maintainer
(ignore any Sasha Levin SOB)
- No `Fixes:`, `Reported-by:`, `Tested-by:`, `Reviewed-by:`, `Acked-
by:`, or `Cc: stable` (absence expected)
**Step 1.3: ANALYZE THE COMMIT BODY TEXT**
Record:
- **Bug:** Releasing buffered frames disables PSE redirect
(`mt7603_wtbl_set_ps(..., false)`). Nothing turns it back on:
`mt7603_sta_ps()` only runs on a PM-bit edge, and `MT_WCID_FLAG_PS`
suppresses duplicate notifications.
- **Symptom:** After the first service period the HW treats a dozing STA
as awake, TX goes to a sleeping radio → **retry storms and packet
loss** on U-APSD clients.
- **Root cause:** Missing re-arm of hardware PS buffering after an SP;
sleep state was conflated with WTBL PS state.
- **Fix:** Re-arm from `mt7603_mac_work()` once the PSD queue has
drained; do not `mt7603_filter_tx()` on that re-arm; track
`ps_sleeping` separately.
**Step 1.4: DETECT HIDDEN BUG FIXES**
Record: Not a disguised cleanup. This is an explicit functional bug fix.
---
## PHASE 2: DIFF ANALYSIS - LINE BY LINE
**Step 2.1: INVENTORY THE CHANGES**
Record:
- `mac.c`: +~70 / −~7 — split `mt7603_wtbl_set_ps`, add
`__mt7603_wtbl_set_ps`, `mt7603_wtbl_sta_ps`,
`mt7603_wtbl_restore_ps`, `mt7603_mac_ps_check`; call it from
`mt7603_mac_work`
- `main.c`: 1 line — `mt7603_sta_ps()` uses `mt7603_wtbl_sta_ps`
- `mt7603.h`: `u8 ps_sleeping` plus two prototypes
- Scope: **single-driver surgical fix** (~72/7, 3 files)
**Step 2.2: UNDERSTAND THE CODE FLOW CHANGE**
Record:
- Before: `mt7603_wtbl_set_ps(true)` enables PSE redirect + `filter_tx`;
`false` disables both. `release_buffered_frames` / PS-response TX
force `false` and never restore.
- After: `sta_ps` also sets `ps_sleeping`. Temporary WTBL-off (SP)
leaves `ps_sleeping` true. `mac_work` (100 ms) walks stations; if `!ps
&& ps_sleeping` and PSD is empty, re-enables redirect **without**
pulling in-flight SP frames back via `filter_tx`.
**Step 2.3: IDENTIFY THE BUG MECHANISM**
Record: **Logic / hardware-state correctness.** HW PS filter left off
after an SP. Not UAF/leak/race in the sanitizer sense; it is a driver
state-machine bug with airtime/retry fallout.
**Step 2.4: ASSESS THE FIX QUALITY**
Record: Quality is high. `ps_sleeping` is updated under `ps_lock`;
`restore_ps` re-checks it under the same lock so a wakeup cannot put the
STA back to sleep. `filter=false` on restore is required so SP frames
are not recycled. Risk: extra WTBL/PSE MMIO from mac_work (low; only
stations that need re-arm). No public API change.
---
## PHASE 3: GIT HISTORY INVESTIGATION
**Step 3.1: BLAME THE CHANGED LINES**
Record:
- `mt7603_wtbl_set_ps` from `c8846e1015022d` (2019-02-26) — initial
MT7603 driver, **in this tree**
- The off-without-restore came from `f25e813bf48dce` (2019-03-07) “clear
ps filtering mode before releasing buffered frames” — **in this tree**
(`git merge-base --is-ancestor` exit 0). That commit is what made SPs
work at all; it never re-armed.
**Step 3.2: FOLLOW THE FIXES: TAG**
Record: No `Fixes:` tag. Bug-introducing commit is `f25e813bf48dce`,
present here.
**Step 3.3: CHECK FILE HISTORY FOR RELATED CHANGES**
Record: Candidate is `636a883e2feef` (not in HEAD). Series around it:
1. `a547b414bf7ea` — **new feature** `MT_DRV_HW_PS_BUFFERING` (other
chips)
2–3. mt7915/mt7996 MCU PS sync
4. EOSP bit in `mt76_release_buffered_frames`
5. `fix U-APSD service period termination` (mt7603 `main.c`)
6. tell mac80211 when PS queue is empty
7. **this commit**
8. file buffered frames under the reported TID
9–10. mt76 link-id / mt7996 OOB
This commit does **not** call anything those others add. Sibling 4–6 fix
other U-APSD bugs; they are complementary, not compile/runtime
prerequisites.
**Step 3.4: CHECK THE AUTHOR'S OTHER COMMITS**
Record: Felix Fietkau is the mt76 maintainer and original mt7603 author.
**Step 3.5: CHECK FOR DEPENDENT/PREREQUISITE COMMITS**
Record: Mainline uses `mt76_wcid_ptr` (`dc66a129adf1f`, 2025, **not
here**) and 4-arg `mt7603_filter_tx(dev, sta->vif->idx, idx, ...)`
(`fe0ea395f0a35`, 2023, **not here**). In 5.15, `msta->vif` is **never
assigned**. A correct backport is: 3-arg `mt7603_filter_tx(dev, idx,
false)` and `rcu_dereference(dev->mt76.wcid[i])`. Logic does not need
those later commits.
---
## PHASE 4: MAILING LIST AND EXTERNAL RESEARCH
**Step 4.1: FIND THE ORIGINAL PATCH DISCUSSION**
Record:
- `b4 dig -c 636a883e2feef` →
https://patch.msgid.link/20260801145334.1166751-7-nbd@nbd.name
- Series v1 only (`b4 dig -a`): `[PATCH 01/10] wifi: mt76: add PS
buffering support for HW-managed TIM drivers`
- Thread: no NAK on patch 07; only kbuild noise on patch 10
(`ieee80211_txq_aql_pending`), unrelated to mt7603
- lore.kernel.org HTTP 403 for WebFetch/curl; discussion recovered via
`b4 dig -m`
**Step 4.2: CHECK WHO REVIEWED THE PATCH**
Record: `b4 dig -w`: Felix Fietkau, `linux-wireless@vger.kernel.org`. No
extra Reviewed-by. Author is the subsystem maintainer.
**Step 4.3: SEARCH FOR THE BUG REPORT**
Record: OpenWrt **mt76#1080** (closed 2026-08-01, same day as this
series): MT7628AN AP, iPhone/U-APSD, Wi-Fi “hangs”, thousands of TX
retries, packet loss; workaround was forcing legacy b/g. Related reports
#865, #576, #390, #841, #375, #26. PR #1084: EOSP helped iPhone freezes;
**retries/loss remained as a separate bug**. Commit text matches that
remaining failure (“retry storms and the packet loss reported against
U-APSD clients”).
**Step 4.4: CHECK FOR RELATED PATCHES AND SERIES**
Record: 10-patch series. 01 is a new mt76 feature; 07 is a standalone
mt7603 HW-PS re-arm. Full iPhone/U-APSD recovery also wants 04–06/08; 07
still fixes a distinct, real bug.
**Step 4.5: CHECK STABLE MAILING LIST HISTORY**
Record: **UNVERIFIED** — lore.kernel.org/stable returned 403.
---
## PHASE 5: CODE SEMANTIC ANALYSIS
**Step 5.1: IDENTIFY KEY FUNCTIONS**
Record: `mt7603_wtbl_set_ps` → `__mt7603_wtbl_set_ps`; added
`mt7603_wtbl_sta_ps`, `mt7603_wtbl_restore_ps`, `mt7603_mac_ps_check`;
`mt7603_sta_ps`; `mt7603_mac_work`.
**Step 5.2: TRACE CALLERS**
Record (this tree):
- `mt7603_sta_ps` ← `mt76_check_sta()` via `drv->sta_ps` on RX PM-bit
change
- `mt7603_wtbl_set_ps(false)` still used by
`mt7603_release_buffered_frames` and `mt7603_tx_prepare_skb` (PS
response) — those are the paths that drop HW buffering
- `mt7603_mac_work` — delayed work every `MT7603_WATCHDOG_TIME` (100 ms)
**Step 5.3: TRACE CALLEES**
Record: PSE_RTA write + poll, optional `mt7603_filter_tx`, WTBL1
POWER_SAVE bit, `ps_lock`. Restore skips `filter_tx`.
**Step 5.4: FOLLOW THE CALL CHAIN**
Record: Userspace-reachable: STA in PS/U-APSD associated to an
mt7603/MT7628 AP → mac80211 `.release_buffered_frames` / PS-Poll. **Yes,
unprivileged clients trigger this.**
**Step 5.5: SEARCH FOR SIMILAR PATTERNS**
Record: Same “turn off PS to release frames” exists in `tx_prepare_skb`;
`ps_sleeping` covers that too because it is only cleared on a real wake.
---
## PHASE 6: CROSS-REFERENCING AGAINST THE LOCAL TREE
**Step 6.1: DOES THE BUGGY CODE EXIST IN THIS TREE?**
Record: **Yes.** Tree is **5.15.221** (`pending-5.15`,
`p-5.15-2-g6703e5d2f3a29`).
- `mt7603_release_buffered_frames` still does `mt7603_wtbl_set_ps(dev,
msta, false)` (`main.c:434`)
- `mt76_check_sta` still uses `MT_WCID_FLAG_PS` to skip duplicate
`sta_ps`
- `636a883e2feef` is **not** an ancestor of HEAD
**Step 6.2: CHECK FOR BACKPORT COMPLICATIONS**
Record: `git show 636a883e2feef | git apply --check` **fails**. Needed
adaptations:
1. `mt7603_filter_tx(dev, sta->vif->idx, idx, false)` →
`mt7603_filter_tx(dev, idx, false)` (3-arg; `msta->vif` unused here)
2. `mt76_wcid_ptr(dev, i)` → `rcu_dereference(dev->mt76.wcid[i])`
3. `mac_work` context differs (`mt76_tx_status_check` arity,
`aggr_stats` location) — insertion after `mt7603_edcca_check` is
still valid
`main.c` hunk and `ps_sleeping` field apply. **Backport difficulty:
minor rework, not a redesign.**
**Step 6.3: CHECK IF RELATED FIXES ARE ALREADY HERE**
Record: No `ps_sleeping` / `mac_ps_check` / `wtbl_restore_ps` in this
tree. Older PS commits here (`e004b70066002`, `9dc27bcbe78c5`,
`d55aa5e17461b`) do not re-arm after an SP.
---
## PHASE 7: SUBSYSTEM AND MAINTAINER CONTEXT
**Step 7.1: IDENTIFY THE SUBSYSTEM AND ITS CRITICALITY**
Record: **drivers/net/wireless/mediatek/mt76/mt7603** —
**PERIPHERAL/IMPORTANT for that hardware.** MT7603E/MT7628 is common on
low-end APs/routers (`CONFIG_MT7603E`). Not core mm/fs, but AP mode with
phones is a primary use.
**Step 7.2: ASSESS SUBSYSTEM ACTIVITY**
Record: Mature driver (landed 2019). Little 5.15-era churn; the bug is
long-lived.
---
## PHASE 8: IMPACT AND RISK ASSESSMENT
**Step 8.1: DETERMINE WHO IS AFFECTED**
Record: **Driver-specific:** mt7603/MT7628 in AP mode with power-
save/U-APSD clients (iPhones and similar).
**Step 8.2: DETERMINE THE TRIGGER CONDITIONS**
Record: First PS-Poll or U-APSD SP after the client dozes. Common on
phones (Instagram/video in #1080). Unprivileged associated STAs trigger
it.
**Step 8.3: DETERMINE THE FAILURE MODE SEVERITY**
Record: **HIGH** (not kernel oops). Retry storms, packet loss, AP
“hangs” vs PS clients; wasted airtime can hurt the whole BSS. Users had
to force legacy b/g.
**Step 8.4: CALCULATE RISK-BENEFIT RATIO**
Record: **Benefit: high** for that hardware. **Risk: low–medium**
(contained MMIO + lock; `ps_sleeping` handles races). Blind 4-arg/`vif`
apply would be wrong here; a 3-arg + `rcu_dereference` backport is safe.
---
## PHASE 9: FINAL SYNTHESIS
**Step 9.1: COMPILE THE EVIDENCE**
**FOR:**
- Real, old bug in this tree (`f25e813bf48dce`, 2019)
- User-visible: retry storms, loss, Wi-Fi hangs with U-APSD/iPhone
(OpenWrt #1080 and several older issues)
- Small, mt7603-only, maintainer-authored, logic is clear
- Standalone vs series patches 01–06
- Trigger is normal AP + phone PS
**AGAINST:**
- 07/10 in a series that also adds a new mt76 feature
- Does not apply cleanly (filter_tx arity, `mt76_wcid_ptr`, mac_work
context)
- Full U-APSD repair also wants 04–06; 07 is not the entire story
- Not a kernel crash/security/corruption bug
**UNRESOLVED:** stable@ lore (HTTP 403). No Tested-by on the commit
itself; OpenWrt #1080 was closed the day the series landed.
**Step 9.2: APPLY THE STABLE RULES CHECKLIST**
1. Obviously correct and tested? **PASS** — maintainer fix; matches a
long-standing user report
2. Fixes a real bug that affects users? **PASS**
3. Important issue? **PASS** — AP unusable with PS phones / BSS retry
storms (HIGH, not oops)
4. Small and contained? **PASS** — ~70 lines, one driver
5. No new features or APIs? **PASS** — internal state + helpers
6. Can apply to the local tree? **PASS** with a small backport (not a
clean cherry-pick)
**Step 9.3: CHECK FOR EXCEPTION CATEGORIES**
Record: None (not a device ID/quirk/DT/build/doc exception). Qualifies
as a normal driver bug fix.
**Step 9.4: MAKE YOUR DECISION**
The buggy “disable PSE redirect on SP, never re-arm” path is in
5.15.221. That is a real AP-mode failure for mt7603/MT7628, not a new-
stack issue. The patch is the right fix and is adaptable without pulling
the HW_PS_BUFFERING feature series.
---
### What the commit solves and why it matters here
After a service period, mt7603 leaves hardware PS buffering off. The AP
then TX’s at a dozing client → retries and loss. That code has been in
this tree since 2019. MT7628 APs with phones hit it in the real world.
### Stable rules
Meets the bar: real bug, contained, no new API. Needs a mechanical
backport (`filter_tx` 3-arg, `rcu_dereference` instead of
`mt76_wcid_ptr`), which is allowed.
### Risk vs benefit
Benefit is high for mt7603 AP users; risk is low if the backport does
**not** use `sta->vif` (unset in 5.15). Sibling EOSP/TIM patches would
help more U-APSD cases but are not required for this re-arm.
### Concerns
Cherry-pick will not apply as-is. Do not copy the 4-argument
`mt7603_filter_tx(..., sta->vif->idx, ...)` call into this tree.
---
Verification:
- [Phase 1] Subject/body/tags: restore HW PS after SP; Link is 07/10;
maintainer SOB only
- [Phase 2] Diff: ~72/7 in mt7603 mac.c/main.c/mt7603.h; `ps_sleeping` +
mac_work re-arm
- [Phase 3] `git describe HEAD` / Makefile: 5.15.221, branch
`pending-5.15`
- [Phase 3] `git merge-base --is-ancestor 636a883e2feef HEAD` → not in
tree
- [Phase 3] blame: `c8846e1015022d` (driver), `f25e813bf48dce` (clear PS
before release) — both ancestors of HEAD
- [Phase 3] Related series commits listed; 01 is new feature; 07 does
not call those APIs
- [Phase 4] `b4 dig -c 636a883e2feef` / `-a` / `-w` / `-m`: lore thread,
v1-only series, wireless list, no NAK on 07
- [Phase 4] OpenWrt mt76#1080 / #1084: retry storms + iPhone U-APSD;
issue closed 2026-08-01
- [Phase 5] Callers verified in 5.15: `sta_ps`,
`release_buffered_frames`, `tx_prepare_skb`, `mac_work` 100 ms
- [Phase 6] Local `mt7603_wtbl_set_ps` / `release_buffered_frames` still
match the bug; `mt76_wcid_ptr` absent; `filter_tx` is 3-arg;
`msta->vif` never set
- [Phase 6] `git apply --check` of 636a883e2feef fails on filter_tx/wcid
helper; main.c hunk would apply
- [Phase 8] Failure mode: retry storms / packet loss / AP hang vs PS
clients, severity HIGH
- UNVERIFIED: stable@ mailing-list discussion (lore 403)
**YES**
.../net/wireless/mediatek/mt76/mt7603/mac.c | 73 +++++++++++++++++--
.../net/wireless/mediatek/mt76/mt7603/main.c | 2 +-
.../wireless/mediatek/mt76/mt7603/mt7603.h | 4 +
3 files changed, 72 insertions(+), 7 deletions(-)
diff --git a/drivers/net/wireless/mediatek/mt76/mt7603/mac.c b/drivers/net/wireless/mediatek/mt76/mt7603/mac.c
index 6387f9e61060a..85c727fc44e6f 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7603/mac.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7603/mac.c
@@ -235,16 +235,17 @@ void mt7603_wtbl_set_smps(struct mt7603_dev *dev, struct mt7603_sta *sta,
sta->smps = enabled;
}
-void mt7603_wtbl_set_ps(struct mt7603_dev *dev, struct mt7603_sta *sta,
- bool enabled)
+static void
+__mt7603_wtbl_set_ps(struct mt7603_dev *dev, struct mt7603_sta *sta,
+ bool enabled, bool filter)
{
int idx = sta->wcid.idx;
u32 addr;
- spin_lock_bh(&dev->ps_lock);
+ lockdep_assert_held(&dev->ps_lock);
if (sta->ps == enabled)
- goto out;
+ return;
mt76_wr(dev, MT_PSE_RTA,
FIELD_PREP(MT_PSE_RTA_TAG_ID, idx) |
@@ -255,7 +256,7 @@ void mt7603_wtbl_set_ps(struct mt7603_dev *dev, struct mt7603_sta *sta,
mt76_poll(dev, MT_PSE_RTA, MT_PSE_RTA_BUSY, 0, 5000);
- if (enabled)
+ if (enabled && filter)
mt7603_filter_tx(dev, sta->vif->idx, idx, false);
addr = mt7603_wtbl1_addr(idx);
@@ -264,8 +265,34 @@ void mt7603_wtbl_set_ps(struct mt7603_dev *dev, struct mt7603_sta *sta,
enabled * MT_WTBL1_W3_POWER_SAVE);
mt76_clear(dev, MT_WTBL1_OR, MT_WTBL1_OR_PSM_WRITE);
sta->ps = enabled;
+}
-out:
+void mt7603_wtbl_set_ps(struct mt7603_dev *dev, struct mt7603_sta *sta,
+ bool enabled)
+{
+ spin_lock_bh(&dev->ps_lock);
+ __mt7603_wtbl_set_ps(dev, sta, enabled, enabled);
+ spin_unlock_bh(&dev->ps_lock);
+}
+
+void mt7603_wtbl_sta_ps(struct mt7603_dev *dev, struct mt7603_sta *sta, bool ps)
+{
+ spin_lock_bh(&dev->ps_lock);
+ sta->ps_sleeping = ps;
+ __mt7603_wtbl_set_ps(dev, sta, ps, ps);
+ spin_unlock_bh(&dev->ps_lock);
+}
+
+void mt7603_wtbl_restore_ps(struct mt7603_dev *dev, struct mt7603_sta *sta)
+{
+ spin_lock_bh(&dev->ps_lock);
+ /*
+ * Frames that are already queued for the station belong to the service
+ * period that has just been served, so unlike on a sleep transition
+ * they must not be pulled back into the PS queue.
+ */
+ if (sta->ps_sleeping)
+ __mt7603_wtbl_set_ps(dev, sta, true, false);
spin_unlock_bh(&dev->ps_lock);
}
@@ -1816,6 +1843,39 @@ mt7603_false_cca_check(struct mt7603_dev *dev)
mt7603_adjust_sensitivity(dev);
}
+/*
+ * Releasing buffered frames turns off the PSE redirect for a station, since
+ * the released frames would otherwise be looped back into the driver PS queue
+ * again. mac80211 never tells us when the service period is over, so hardware
+ * buffering has to be re-armed here for every station that is still known to
+ * be asleep. Waiting for the PSD queue to drain makes sure that the released
+ * frames have already passed the redirect stage.
+ */
+static void
+mt7603_mac_ps_check(struct mt7603_dev *dev)
+{
+ int i;
+
+ if (dev->mphy.q_tx[MT_TXQ_PSD]->queued)
+ return;
+
+ rcu_read_lock();
+ for (i = 0; i < MT7603_WTBL_STA; i++) {
+ struct mt76_wcid *wcid = mt76_wcid_ptr(dev, i);
+ struct mt7603_sta *msta;
+
+ if (!wcid || !wcid->sta)
+ continue;
+
+ msta = container_of(wcid, struct mt7603_sta, wcid);
+ if (msta->ps || !msta->ps_sleeping)
+ continue;
+
+ mt7603_wtbl_restore_ps(dev, msta);
+ }
+ rcu_read_unlock();
+}
+
void mt7603_mac_work(struct work_struct *work)
{
struct mt7603_dev *dev = container_of(work, struct mt7603_dev,
@@ -1830,6 +1890,7 @@ void mt7603_mac_work(struct work_struct *work)
dev->mphy.mac_work_count++;
mt76_update_survey(&dev->mphy);
mt7603_edcca_check(dev);
+ mt7603_mac_ps_check(dev);
for (i = 0, idx = 0; i < 2; i++) {
u32 val = mt76_rr(dev, MT_TX_AGG_CNT(i));
diff --git a/drivers/net/wireless/mediatek/mt76/mt7603/main.c b/drivers/net/wireless/mediatek/mt76/mt7603/main.c
index f8a43d9f72f95..04e3966ab047f 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7603/main.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7603/main.c
@@ -410,7 +410,7 @@ mt7603_sta_ps(struct mt76_dev *mdev, struct ieee80211_sta *sta, bool ps)
struct sk_buff_head list;
mt76_stop_tx_queues(&dev->mphy, sta, true);
- mt7603_wtbl_set_ps(dev, msta, ps);
+ mt7603_wtbl_sta_ps(dev, msta, ps);
if (ps)
return;
diff --git a/drivers/net/wireless/mediatek/mt76/mt7603/mt7603.h b/drivers/net/wireless/mediatek/mt76/mt7603/mt7603.h
index 55a034ccbacd9..c43ddd3e693c0 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7603/mt7603.h
+++ b/drivers/net/wireless/mediatek/mt76/mt7603/mt7603.h
@@ -80,6 +80,7 @@ struct mt7603_sta {
u8 smps;
u8 ps;
+ u8 ps_sleeping;
};
struct mt7603_vif {
@@ -229,6 +230,9 @@ int mt7603_wtbl_set_key(struct mt7603_dev *dev, int wcid,
struct ieee80211_key_conf *key);
void mt7603_wtbl_set_ps(struct mt7603_dev *dev, struct mt7603_sta *sta,
bool enabled);
+void mt7603_wtbl_sta_ps(struct mt7603_dev *dev, struct mt7603_sta *sta,
+ bool ps);
+void mt7603_wtbl_restore_ps(struct mt7603_dev *dev, struct mt7603_sta *sta);
void mt7603_wtbl_set_smps(struct mt7603_dev *dev, struct mt7603_sta *sta,
bool enabled);
void mt7603_filter_tx(struct mt7603_dev *dev, int mac_idx, int idx, bool abort);
--
2.53.0
^ permalink raw reply related [flat|nested] 20+ messages in thread* [PATCH AUTOSEL 6.18-6.12] net: ethernet: mtk_wed: increase WED v2 WDMA RESV_BUFF to 0x80
2026-10-19 13:44 [PATCH AUTOSEL 6.18-6.12] net: dsa: mt7530: check CORE_PLL_GROUP4 access in mt7531_setup() Sasha Levin
` (17 preceding siblings ...)
2026-10-19 13:52 ` [PATCH AUTOSEL 6.18] wifi: mt76: mt7603: restore hardware PS buffering after a service period Sasha Levin
@ 2026-10-19 13:53 ` Sasha Levin
18 siblings, 0 replies; 20+ messages in thread
From: Sasha Levin @ 2026-10-19 13:53 UTC (permalink / raw)
To: patches, stable
Cc: Shiji Yang, Simon Horman, Lorenzo Bianconi, Jakub Kicinski,
Sasha Levin, nbd, andrew+netdev, davem, edumazet, pabeni,
matthias.bgg, angelogioacchino.delregno, netdev, linux-kernel,
linux-arm-kernel, linux-mediatek
From: Shiji Yang <yangshiji66@outlook.com>
[ Upstream commit c0ef04232f9fac083c3d8a77ce58ba32243e6734 ]
Change WDMA RESV_BUFF from 0x40 to 0x80 to avoid CDM TX FIFO overflow.
Without this patch mt7986 and mt7981 may have WDMA TX hang issue. This
patch was pulled from mtk-openwrt-feeds GPL open source project.
Link: https://github.com/mediatek/mtk-openwrt-feeds/commit/07c87502e854b68b48544d101b6fe17ec059b97b
Signed-off-by: Shiji Yang <yangshiji66@outlook.com>
Reviewed-by: Simon Horman <horms@kernel.org>
Acked-by: Lorenzo Bianconi <lorenzo@kernel.org>
Link: https://patch.msgid.link/OSZPR01MB779537889255E2F606E47EABBCA52@OSZPR01MB7795.jpnprd01.prod.outlook.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
LLM Generated explanations, may be completely bogus:
This 6.12.111 tree has the WED v2 DMA path without the RESV_BUFF bump.
The change is a small MediaTek hardware workaround for a WDMA TX hang on
mt7986/mt7981.
## Phase 1: Commit message forensics
**Step 1.1 — Subject**
Record: `[net: ethernet: mtk_wed:] [increase] [WED v2 WDMA RESV_BUFF
0x40 -> 0x80]`
**Step 1.2 — Tags**
Record:
- `Link: https://github.com/mediatek/mtk-openwrt-
feeds/commit/07c87502e854b68b48544d101b6fe17ec059b97b` (vendor source)
- `Signed-off-by: Shiji Yang <yangshiji66@outlook.com>` (author)
- `Reviewed-by: Simon Horman <horms@kernel.org>`
- `Acked-by: Lorenzo Bianconi <lorenzo@kernel.org>` (mtk_wed maintainer)
- `Link: https://patch.msgid.link/OSZPR01MB779...` (netdev submission)
- `Signed-off-by: Jakub Kicinski <kuba@kernel.org>` (applied to
netdev/net)
- No `Fixes:` and no `Cc: stable` on the committed version (expected for
this pipeline)
- No `Reported-by:` / `Tested-by:` / syzbot
**Step 1.3 — Body**
Record:
- Bug: default WDMA `RESV_BUFF` of `0x40` can overflow the CDM TX FIFO
on WED v2.
- Symptom: WDMA TX hang on mt7986 and mt7981.
- Root cause: reserved WDMA buffer too small for v2 hardware.
- Source: MediaTek OpenWrt GPL feeds (`Fix WED 2.0 WDMA TX hang issue`).
- Version info: v2 only (mt7986/mt7981). Rex Lu later said v3 dropped
this register.
**Step 1.4 — Hidden bug fix?**
Record: Not hidden. Explicit hang fix / hardware workaround. Vendor
subject was also a hang fix.
## Phase 2: Diff analysis
**Step 2.1 — Inventory**
Record:
- `drivers/net/ethernet/mediatek/mtk_wed.c`: +5 in
`mtk_wed_dma_enable()`
- `drivers/net/ethernet/mediatek/mtk_wed_regs.h`: +1
(`MTK_WDMA_GLO_CFG_RESV_BUFF` = `GENMASK(23, 16)`)
- Scope: single-driver surgical change (~6 lines)
**Step 2.2 — Flow change**
Record: After the existing v1/v2 vs v3 `MTK_WDMA_GLO_CFG` setup, and
before enabling WED GLO DMA, v2 now RMWs bits 23:16 of
`MTK_WDMA_GLO_CFG` to `0x80`. v1 and v3 are unchanged. Init/enable path
only.
**Step 2.3 — Bug mechanism**
Record: Hardware workaround. Default `RESV_BUFF` is `0x40`; raising it
to `0x80` leaves more WDMA reserved buffer so CDM TX FIFO does not
overflow and stall TX. `wdma_m32()` already does `(read & ~mask) | val`.
**Step 2.4 — Fix quality**
Record: Minimal, gated by `mtk_wed_is_v2()`, uses existing helpers.
Regression risk is low: only WED v2 register bits 23:16. MediaTek
confirmed v3 must not get this write because the field was removed.
## Phase 3: Git history
**Step 3.1 — Blame**
Record: `mtk_wed_dma_enable()` came from `cf26df8833cc` (2022-09-22,
“add mtk_wed_configure_irq and mtk_wed_dma_{enable/disable}”).
Surrounding v2/v3 split is `e2f64db13aa1d` (2023-09-18, MT7988 WED). The
missing programming is a long-standing omission, not new 6.12 code.
**Step 3.2 — Fixes: tag**
Record: Committed patch has none. Simon Horman and Lorenzo Bianconi both
named `cf26df8833cc`. That commit **is** an ancestor of this tree (`git
merge-base --is-ancestor` succeeded).
**Step 3.3 — File history**
Record: Recent 6.12 `mtk_wed.c` work is leaks/UAF/reset, not RESV_BUFF.
No competing local fix. Standalone, not patch N/M.
**Step 3.4 — Author**
Record: Shiji Yang has no other `drivers/net/ethernet/mediatek/` commits
in this tree. Original vendor author is Rex Lu (MediaTek). Lorenzo
(maintainer) acked.
**Step 3.5 — Prerequisites**
Record: Needs `mtk_wed_is_v2()`, `wdma_m32()`, `FIELD_PREP`,
`MTK_WDMA_GLO_CFG`. All present. Upstream SHA `c0ef04232f9f` is **not**
in this tree (ancestor check failed). Can apply standalone.
## Phase 4: Mailing list / external
**Step 4.1 — Original discussion**
Record:
- `b4 dig -c c0ef04232f9f` → https://patch.msgid.link/OSZPR01MB779537889
255E2F606E47EABBCA52@OSZPR01MB7795.jpnprd01.prod.outlook.com
- Single revision (v1). Applied as-is to netdev/net.git.
- Simon: target `net`, **CC stable**, add Fixes; still `Reviewed-by`.
- Jakub asked Lorenzo to review, including the Fixes suggestion.
- Lorenzo asked if v3 needs it; Rex Lu: v2 only, v3 removed the
register.
- Lorenzo: `Acked-by`.
- No NAK.
**Step 4.2 — Recipients (`b4 dig -w`)**
Record: netdev, linux-mediatek, Lorenzo Bianconi, Felix Fietkau, Rex Lu,
netdev maintainers. Right people.
**Step 4.3 — Bug report**
Record: Vendor feeds commit `07c87502e854`: “Fix WED 2.0 WDMA TX hang
issue” / “without this patch mt7986 and mt7981 may have WDMA TX hang”.
Same 6-line change. No public syzbot/bugzilla thread found.
**Step 4.4 — Series**
Record: Standalone 1/1. No companion patches.
**Step 4.5 — Stable list**
Record: UNVERIFIED for lore.kernel.org/stable (HTTP 403). Simon’s review
is an explicit stable nomination. No evidence of a stable NAK.
## Phase 5: Semantic / call graph
**Step 5.1 — Functions**
Record: `mtk_wed_dma_enable()` plus a register `#define`.
**Step 5.2 — Callers**
Record: Only `mtk_wed_start()` → `mtk_wed_dma_enable()`. That is
`wed_ops.start`, invoked as `mtk_wed_device_start()` from mt76
(`mt7915/dma.c`, `mt7996/dma.c`). mt7915 is the usual WiFi partner for
mt7986/mt7981 (WED v2).
**Step 5.3 — Callees**
Record: `wdma_m32` → `wdma_r32`/`wdma_w32` (MMIO RMW). No alloc, no
locks.
**Step 5.4 — Reachability**
Record: Yes. Bringing WiFi up with WED offload on Filogic 820/830 hits
this. Not a rare debug path.
**Step 5.5 — Similar patterns**
Record: No other `RESV_BUFF` users. Nearby `wdma_set(MTK_WDMA_GLO_CFG,
...)` already programs this register for TX enable / prerest bits.
## Phase 6: This tree (6.12.111)
**Step 6.1 — Buggy code present?**
Record: Yes. `make kernelversion` / `git describe` → **6.12.111**
(`p-6.12-3-gc504cf0baa3d8`). `mtk_wed_dma_enable()` has the v2/v3 split
and does **not** set RESV_BUFF. `mt7981_data` / `mt7986_data` have
`.version = 2`. `hw->version = eth->soc->version`. Bug dates to WED
dma_enable (2022), well before 6.12.
**Step 6.2 — Backport difficulty**
Record: Clean apply. Insertion context around the v3 `else` branch and
`MTK_WDMA_GLO_CFG` bit defines matches the upstream hunk.
**Step 6.3 — Already fixed?**
Record: No. `git log --grep=RESV_BUFF` / `WDMA TX hang` / `increase WED
v2` on these files is empty. `c0ef04232f9f` is not an ancestor.
## Phase 7: Subsystem
**Step 7.1**
Record: MediaTek ethernet WED (WiFi/Ethernet dispatch offload).
**IMPORTANT** for Filogic routers, not core-mm/VFS. OpenWrt 6.12 devices
(BPI-R3, GL-MT6000, many AX3000/AX6000 boards) use this.
**Step 7.2**
Record: Mature driver; v2 support is years old. This is a vendor hang
workaround, not churn from a new API.
## Phase 8: Impact / risk
**Step 8.1 — Who**
Record: Driver/SoC specific: `CONFIG_NET_MEDIATEK_SOC` + WED,
mt7981/mt7986, WiFi WED offload.
**Step 8.2 — Trigger**
Record: WED DMA enable when WiFi starts. Can be common on those APs.
Unprivileged users do not poke the register; they can trigger it by
using the AP. Timing-dependent FIFO overflow under TX load is plausible.
**Step 8.3 — Severity**
Record: WDMA TX hang → WiFi/Ethernet TX stall. **HIGH** (hang / loss of
forwarding). Not a KASAN UAF, but a real production hang on shipping
routers.
**Step 8.4 — Benefit vs risk**
Record: Benefit high for Filogic v2 users (fixes hang). Risk very low (6
lines, v2-only, maintainer + MediaTek + netdev review). Ratio strongly
favors backport.
## Phase 9: Synthesis
**For backporting**
- Real hang: CDM TX FIFO overflow → WDMA TX stall on mt7986/mt7981.
- Hardware quirk/workaround (stable exception).
- Tiny, obviously correct RMW of a documented field.
- Code and helpers exist in 6.12; applies cleanly.
- Simon Horman asked for `Cc: stable`; Lorenzo acked; MediaTek confirmed
v2-only.
- Vendor already shipped the same change in OpenWrt feeds.
**Against**
- No kernel.org `Reported-by` / crash log (vendor description only).
- Affects one SoC family, not all machines.
- Committed patch omitted `Fixes:` / `Cc: stable` (Simon noted that; not
a technical reason to skip).
**Unresolved**
- Could not query lore.kernel.org/stable (403). No sign it was rejected.
**Stable rules**
1. Obviously correct and tested — **PASS** (review + vendor feeds +
MediaTek confirmation)
2. Real user bug — **PASS** (TX hang)
3. Important (hang) — **PASS** (HIGH)
4. Small/contained — **PASS** (6 lines, two files)
5. No new features/APIs — **PASS** (register programming)
6. Applies to this tree — **PASS** (clean context on 6.12.111)
**Exception:** hardware workaround / quirk.
This should be backported to this 6.12.y tree.
Verification:
- [Phase 1] Parsed tags: vendor GitHub link, Reviewed-by Horman, Acked-
by Bianconi, applied by Kicinski; no Fixes/Cc: stable on the commit
- [Phase 2] Diff: +5 in `mtk_wed_dma_enable()`, +1 GENMASK; v2-only
`wdma_m32` of bits 23:16 to 0x80
- [Phase 2] `wdma_m32()` in this tree is `(read & ~mask) | val` at
`mtk_wed.c:111-114`
- [Phase 3] Blame: `mtk_wed_dma_enable` from `cf26df8833cc`
(2022-09-22); v2/v3 split from `e2f64db13aa1d`
- [Phase 3] `git merge-base --is-ancestor cf26df8833cc HEAD` succeeded;
`c0ef04232f9f` is not in this tree
- [Phase 3] `mtk_wed_is_v2` from `d274d523c71c82` is in this tree
- [Phase 4] `b4 dig -c c0ef04232f9f`: v1 only; lore msgid
OSZPR01MB7795...
- [Phase 4] Horman review (openwall 2026/08/21/128): “Be CCed to
stable”, Fixes `cf26df8833cc`, Reviewed-by
- [Phase 4] Rex Lu: v2 only; v3 removed RESV_BUFF
- [Phase 4] Lorenzo Acked-by after that confirmation
- [Phase 4] GitHub `07c87502e854`: same 6-line hang fix
- [Phase 4] lore.kernel.org/stable: UNVERIFIED (403)
- [Phase 5] Caller: `mtk_wed_start` → `mtk_wed_dma_enable`;
`mtk_wed_device_start` from mt76 mt7915/mt7996
- [Phase 6] `git describe HEAD` / `make kernelversion`: 6.12.111;
RESV_BUFF define absent; insertion context matches
- [Phase 6] `mt7981_data`/`mt7986_data`.version = 2; `hw->version =
eth->soc->version`
- [Phase 8] Failure mode: WDMA TX hang, severity HIGH
- UNVERIFIED: whether anyone already requested this on stable@ (lore
403)
The hang is real on WED v2 hardware this tree supports, the fix is a
six-line register quirk, and it applies cleanly here.
**YES**
drivers/net/ethernet/mediatek/mtk_wed.c | 5 +++++
drivers/net/ethernet/mediatek/mtk_wed_regs.h | 1 +
2 files changed, 6 insertions(+)
diff --git a/drivers/net/ethernet/mediatek/mtk_wed.c b/drivers/net/ethernet/mediatek/mtk_wed.c
index 1ed1f88dd7f8b..fdb487e5d46e1 100644
--- a/drivers/net/ethernet/mediatek/mtk_wed.c
+++ b/drivers/net/ethernet/mediatek/mtk_wed.c
@@ -2071,6 +2071,11 @@ mtk_wed_dma_enable(struct mtk_wed_device *dev)
wdma_set(dev, MTK_WDMA_GLO_CFG, MTK_WDMA_GLO_CFG_TX_DMA_EN);
}
+ if (mtk_wed_is_v2(dev->hw))
+ wdma_m32(dev, MTK_WDMA_GLO_CFG,
+ MTK_WDMA_GLO_CFG_RESV_BUFF,
+ FIELD_PREP(MTK_WDMA_GLO_CFG_RESV_BUFF, 0x80));
+
wed_set(dev, MTK_WED_GLO_CFG,
MTK_WED_GLO_CFG_TX_DMA_EN |
MTK_WED_GLO_CFG_RX_DMA_EN);
diff --git a/drivers/net/ethernet/mediatek/mtk_wed_regs.h b/drivers/net/ethernet/mediatek/mtk_wed_regs.h
index c71190924816c..e5f83100ded52 100644
--- a/drivers/net/ethernet/mediatek/mtk_wed_regs.h
+++ b/drivers/net/ethernet/mediatek/mtk_wed_regs.h
@@ -433,6 +433,7 @@ struct mtk_wdma_desc {
#define MTK_WDMA_GLO_CFG_TX_DMA_BUSY BIT(1)
#define MTK_WDMA_GLO_CFG_RX_DMA_EN BIT(2)
#define MTK_WDMA_GLO_CFG_RX_DMA_BUSY BIT(3)
+#define MTK_WDMA_GLO_CFG_RESV_BUFF GENMASK(23, 16)
#define MTK_WDMA_GLO_CFG_RX_INFO3_PRERES BIT(26)
#define MTK_WDMA_GLO_CFG_RX_INFO2_PRERES BIT(27)
#define MTK_WDMA_GLO_CFG_RX_INFO1_PRERES BIT(28)
--
2.53.0
^ permalink raw reply related [flat|nested] 20+ messages in thread