Skip to content

mac80211: improve ath12k recovery and link handling - #2

Open
KakatkarAkshay wants to merge 5 commits into
perceival:flint3-be9300from
KakatkarAkshay:fix/flint3-ath12k-recovery
Open

mac80211: improve ath12k recovery and link handling#2
KakatkarAkshay wants to merge 5 commits into
perceival:flint3-be9300from
KakatkarAkshay:fix/flint3-ath12k-recovery

Conversation

@KakatkarAkshay

Copy link
Copy Markdown
Contributor

Summary

  • detect Q6/rootPD crashes and recover the complete ath12k WSI group without rebooting
  • retry wireless setup when late PHY registration completes
  • read ath12k MAC addresses from device tree NVMEM definitions
  • select an active driver-backed link when the TX link is unspecified

Validation

  • all five commits apply cleanly to the latest flint3-be9300 branch
  • git diff --check passes
  • the patches have been verified on the source branch

KakatkarAkshay and others added 5 commits August 2, 2026 20:30
The AHB driver currently uses the Qualcomm SSR notifier only to wait for
rootPD startup. Handle crash shutdown notifications as well so the actual
failure is visible instead of only its later effects.

Release an SCM-authenticated userPD before the remoteproc core collects the
rootPD dump. This mirrors the ordering used by Qualcomm's rootPD crash
handling without importing its downstream group reset and panic machinery.

Adapted from Qualcomm's downstream rootPD crash handling by Sowmiya Sree
Elavalagan and Avula Sri Charan.

Link: https://github.com/Telecominfraproject/wlan-ap/blob/4dda11dcf7455828e03a753079c520701f2f7a7c/feeds/qca-wifi-7/mac80211/patches-qca/ath12k/0111-0017-QSDK-PLATFORM-wifi-ath12k-Register-and-handle-rootPD-crash.patch
Signed-off-by: Akshay Kakatkar <me@kakatkarakshay.dev>
The rootPD crash notifier releases the AHB userPD so remoteproc can collect
the complete q6wcss dump, but no ath12k recovery is started. The AHB userPD
remains down and PCIe partners stay attached to the stale WSI group.

Mark the AHB device crashed before releasing its userPD. Once rootPD power-up
completes, queue the existing reset work for every registered device in the
WSI group so wireless service recovers without a reboot.

Avoid sending an unacknowledgeable userPD stop request after a rootPD crash.
Reinitialize userPD completions before each request and always clear the spawn
request bit to prevent stale acknowledgements from satisfying a restart.

Adapt Qualcomm's downstream recovery ordering without its panic, forced
partner assert, or direct remoteproc state manipulation.

Signed-off-by: Sowmiya Sree Elavalagan <quic_ssreeela@quicinc.com>
Signed-off-by: Avula Sri Charan <quic_asrichar@quicinc.com>
Signed-off-by: Akshay Kakatkar <me@kakatkarakshay.dev>
An ieee80211 add event can arrive while a failed wireless setup is still running or teardown is active. Record the retry until teardown completes and reset the retry budget afterward. Devices already down still start immediately.

This replaces the IPQ53xx-specific polling hook with the generic event-driven path.

Signed-off-by: Akshay Kakatkar <me@kakatkarakshay.dev>
Most embedded devices with integrated ath12k radios store the MAC address in an NVMEM partition. Fetch it through the standard of_get_mac_address API and prefer it over firmware-provided addresses.

Use the factory Wi-Fi MAC from the Flint 3 ART partition for its integrated and PCI radios.

Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
Group addressed frames reach ath12k_mac_op_tx() with no STA and with the
TX control link field set to IEEE80211_LINK_UNSPECIFIED, so
ath12k_mac_get_tx_link() falls back to ahvif->deflink.link_id.

deflink is preallocated storage reused for whichever link of an ML VIF
comes up first, and ath12k_mac_unassign_link_vif() memsets it when that
link goes away. Its link_id is then zero while the remaining links keep
their own ids, so the fallback selects link zero. On an MLD that does not
include link zero, for example one covering only 5 GHz and 6 GHz,
ahvif->link[0] is NULL and every such frame is warned about and dropped.

Select the first driver-backed active link instead. The set of live links
is the only valid source for this decision; deflink.link_id describes a
storage slot, not a link.

The check added in 113-wifi-ath12k-select-valid-link-when-link-zero-is-
missing.patch matches an explicit zero in the TX control field and does
not cover this path.

Signed-off-by: Akshay Kakatkar <me@kakatkarakshay.dev>
@KakatkarAkshay

Copy link
Copy Markdown
Contributor Author

I have tested all of these changes on the GL-BE9300, and they work as intended to resolve the corresponding issues.

perceival added a commit that referenced this pull request Aug 6, 2026
Patch by Akshay Kakatkar, taken from PR #2. Group-addressed and other
management frames reach ath12k_mac_op_tx() with no STA and with the TX control
link set to IEEE80211_LINK_UNSPECIFIED, so ath12k_mac_get_tx_link() falls back
to ahvif->deflink.link_id. deflink is preallocated storage reused by whichever
link comes up first, and ath12k_mac_unassign_link_vif() memsets it when that
link goes away, leaving link_id == 0 while the surviving links keep their own
ids. On an MLD without link 0 every such frame is warned about and dropped.

Verified on hardware here rather than by inspection. The trigger is a *partial*
teardown - remove the link that owns deflink while another stays up:

    wifi down radio1 ; sleep 10 ; wifi up radio1

Two negative results pin the mechanism down: `wifi reload` does not reproduce it
(both links go away, links_map reaches 0, deflink is legitimately reused), and
removing link 2 does not either (link 1 owns deflink, being created first). That
is why one of our APs sat at 0 occurrences for 16 hours while the other flooded
on the same build.

Same trigger, both units:

    ap2  ch36 non-DFS  unpatched   6257 events (760 printed + 5497 suppressed),
                                   link id 0, still climbing
    ap2  ch36 non-DFS  patched     0
    ap1  ch100 DFS     patched     10, all link id 1, one 0.3 s burst, then zero

The link-0 flood is gone. The residual on the DFS unit is a different and
narrower race: it requests link 1, a real link, during the window that the 60 s
CAC opens between the link entering links_map/active_links and its arvif being
installed. Bounded and self-limiting, but the read side still trusts the
selected link without checking ahvif->link[id] is populated - reported upstream
in issue #6.

Note when re-testing: a fresh reboot proves nothing, because it clears the stale
deflink and a patched and unpatched unit both read zero. And rebuilding the
mac80211 package does not change the kernel build stamp, so `uname -v` is not
proof the new module is running - compare the ath12k_wifi7.ko hash.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013Yv2jeo6zrG622qSnuUC9M
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants