mt7996: after firmware SER, MLO stations lose management-frame TX - repeated deauth of MLO clients (sa_query send failed)

Open
#1,139 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Assessment

Difficulty
4/5
Estimated time
3-5 days
Newbie friendliness
35/100
Issue type
Bug
Clarity
Mostly clear
Activity status
Active
Tech stack
c, linux

Research direction

Start with mt7996_mac_reset_sta_iter(), its caller mt7996_mac_full_reset(), and the surrounding station-reset paths to trace how MLO per-link state is handled during SER. Reproduce the reset on the affected hardware and verify that SA-query and data-poll management frames transmit afterward, with the MLO client remaining associated instead of being deauthenticated.

Written by the indexing model from the issue text.

Description

Environment
  • Hardware: Airoha AN7581 (Econet XR1710G retail tri-band router), MT7996 (2.4 + 5 + 6 GHz)
  • Software: Linux 6.18.53, backports 7.2, mt76 = be5ce791 (current HEAD of this mirror, package r10), hostapd 831364bf (2026-08-07)
  • AP configuration: two AP-MLDs (2.4+5 GHz and 5+6 GHz, SAE, PMF required by MLO) plus a 6 GHz 802.11s mesh link on the same radio set; Apple MacBook as MLO client
  • Two identical devices running the same build
Symptom

A Wi-Fi 7 client in MLO mode associates to the 5+6 GHz ap-mld interface. Around/after a firmware SER event, hostapd can no longer deliver management frames to the MLO station:

  1. At (re)association of the MLO station, hostapd logs ieee802_11_send_sa_query_req: send failed four times in a row — the SA query request to the ML station never makes it out.
  2. ~20-30 s later the station is removed: deauthenticated due to inactivity (timer DEAUTH/REMOVE), even though ap_max_inactivity=86400 is configured (so this is not the idle timer actually firing — the data poll/management frames simply cannot be delivered to the ML station).
  3. Every subsequent MLO association on the affected device repeats the same sequence. The same client falling back to a legacy (non-MLO) association is then stable for many hours, so the breakage is specific to the per-link (MLD) station state.

On a second identical device running the same build and the same configuration, the MLO client stays associated for hours without being kicked — the behaviour is not universal, which matches it being tied to a SER event having occurred on that particular radio.

Kernel evidence that SER happened

dmesg on the affected unit, boot+69 s:

WARNING: CPU: ... mt7996_mac_reset_sta_iter ... 
Call trace:
 mt7996_mac_reset_sta_iter
 mt7996_queue_rx_skb
 mt76_npu_rx_poll

mt7996_mac_reset_sta_iter() has a single caller: mt7996_mac_full_reset(), i.e. a chip-level system error recovery (firmware SER) ran on that radio. This unit is also the one where the MLO station keep-alive/TX failures occur afterwards.

Interpretation / question

mt7996_mac_reset_sta_iter() walks all stations during full reset. For MLO stations (an MLD station with per-link station entries on multiple links) some per-link state — WTBL entries and/or firmware link records for the non-primary links — does not appear to be restored correctly after the reset: afterwards hostapd's management frames to the ML station (SA query, QoS data polls) fail to transmit, and hostapd's inactivity logic eventually removes the station.

Is mt7996_mac_reset_sta_iter() fully MLO-aware? Should it skip MLD stations (letting mac80211/hostapd re-create the link state), or additionally reset the per-link WTBL entries of MLD stations? We could not find any existing report of this, so this may simply be the first report.

Happy to provide hostapd debug logs and further dmesg, and to test candidate patches on the hardware.

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

Getting set up

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

First steps

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

More from openwrt/mt76

All issues in openwrt/mt76

Similar issues

More C issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.