[PR #62] [MERGED] core: rtw_xmit: gate scan_state TX-block by _FW_UNDER_SURVEY to prevent permanent TX stall #63

Closed
opened 2026-10-13 19:33:49 +00:00 by bsakaguchi · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/morrownr/8812au-20210820/pull/62
Author: @breakneck-git
Created: 4/25/2026
Status: ✅ Merged
Merged: 4/25/2026
Merged by: @morrownr

Base: main ← Head: fix-tx-stall-scan-state-desync


📝 Commits (1)

  • 9e91355 core: rtw_xmit: gate scan_state TX-block by _FW_UNDER_SURVEY to prevent permanent TX stall

📊 Changes

1 file changed (+10 additions, -3 deletions)

View changed files

📝 core/rtw_xmit.c (+10 -3)

📄 Description

Summary

Fixes a permanent TX stall caused by a race between the upper-level (mlmepriv._FW_UNDER_SURVEY) and low-level (mlmeextpriv.scan_state) MLME state when a scan times out.

Same root cause and identical patch shape was also submitted to:

Root cause

rtw_scan_timeout_handler() (core/rtw_mlme.c) clears the upper-level _FW_UNDER_SURVEY flag and notifies cfg80211, but does not reset mlmeext->scan_state. The only place that resets scan_state to SCAN_DISABLE in the normal completion path is the SCAN_COMPLETE handler in core/rtw_mlme_ext.c, which a stalled scan never reaches.

After this race, rtw_xmit_ac_blocked() (core/rtw_xmit.c) permanently returns _TRUE for the scan-state check, blocking all TX. RX continues unaffected (no scan gate on the RX path), beacons arrive, the station stays associated — wpa_supplicant reports COMPLETED, signal is fine, but no traffic flows.

wpa_cli reconnect is the user-visible workaround because a full re-assoc goes through init_mlme_ext_priv() which unconditionally resets scan_state to SCAN_DISABLE.

Fix

Gate the scan-state TX-block check by _FW_UNDER_SURVEY. If the upper layer no longer thinks a scan is in progress, do not block TX even if the low-level scan_state is stuck.

The new condition is strictly a subset of the old one — when both layers agree a scan is in progress, behaviour is unchanged. Defensive: doesn't touch the state machine, doesn't risk HW init inconsistency.

Test environment

Tested on the 8821AU sister chip (8821au-20210708 fork). The 8812AU and 8821AU share core/rtw_xmit.c verbatim, so the fix applies identically. If a maintainer of this repo wants to verify on actual 8812AU hardware before merging, that's reasonable — the change is small and the code path identical.

Layer state Old behaviour New behaviour
_FW_UNDER_SURVEY=1, scan_state ∉ {DISABLE, BACKOP} block TX block TX (unchanged)
_FW_UNDER_SURVEY=0, scan_state ∉ {DISABLE, BACKOP} (the desync) block TX (forever) don't block TX
_FW_UNDER_SURVEY=1, scan_state ∈ {DISABLE, BACKOP} don't block TX don't block TX (unchanged)
_FW_UNDER_SURVEY=0, scan_state = DISABLE don't block TX don't block TX (unchanged)

🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/morrownr/8812au-20210820/pull/62 **Author:** [@breakneck-git](https://github.com/breakneck-git) **Created:** 4/25/2026 **Status:** ✅ Merged **Merged:** 4/25/2026 **Merged by:** [@morrownr](https://github.com/morrownr) **Base:** `main` ← **Head:** `fix-tx-stall-scan-state-desync` --- ### 📝 Commits (1) - [`9e91355`](https://github.com/morrownr/8812au-20210820/commit/9e91355f90936fda2d804b2944e9643157eb1663) core: rtw_xmit: gate scan_state TX-block by _FW_UNDER_SURVEY to prevent permanent TX stall ### 📊 Changes **1 file changed** (+10 additions, -3 deletions) <details> <summary>View changed files</summary> 📝 `core/rtw_xmit.c` (+10 -3) </details> ### 📄 Description ## Summary Fixes a permanent TX stall caused by a race between the upper-level (`mlmepriv._FW_UNDER_SURVEY`) and low-level (`mlmeextpriv.scan_state`) MLME state when a scan times out. Same root cause and identical patch shape was also submitted to: - [`aircrack-ng/rtl8812au`](https://github.com/aircrack-ng/rtl8812au) (referencing their open issue [#778](https://github.com/aircrack-ng/rtl8812au/issues/778) — "Radio scans introduce lag spikes") - [`morrownr/8821au-20210708`](https://github.com/morrownr/8821au-20210708) (sister repo with shared MLME code) ## Root cause `rtw_scan_timeout_handler()` (`core/rtw_mlme.c`) clears the upper-level `_FW_UNDER_SURVEY` flag and notifies cfg80211, but does **not** reset `mlmeext->scan_state`. The only place that resets `scan_state` to `SCAN_DISABLE` in the normal completion path is the `SCAN_COMPLETE` handler in `core/rtw_mlme_ext.c`, which a stalled scan never reaches. After this race, `rtw_xmit_ac_blocked()` (`core/rtw_xmit.c`) permanently returns `_TRUE` for the scan-state check, blocking all TX. RX continues unaffected (no scan gate on the RX path), beacons arrive, the station stays associated — `wpa_supplicant` reports `COMPLETED`, signal is fine, but no traffic flows. `wpa_cli reconnect` is the user-visible workaround because a full re-assoc goes through `init_mlme_ext_priv()` which unconditionally resets `scan_state` to `SCAN_DISABLE`. ## Fix Gate the scan-state TX-block check by `_FW_UNDER_SURVEY`. If the upper layer no longer thinks a scan is in progress, do not block TX even if the low-level `scan_state` is stuck. The new condition is **strictly a subset** of the old one — when both layers agree a scan is in progress, behaviour is unchanged. Defensive: doesn't touch the state machine, doesn't risk HW init inconsistency. ## Test environment Tested on the 8821AU sister chip (8821au-20210708 fork). The 8812AU and 8821AU share `core/rtw_xmit.c` verbatim, so the fix applies identically. If a maintainer of this repo wants to verify on actual 8812AU hardware before merging, that's reasonable — the change is small and the code path identical. | Layer state | Old behaviour | New behaviour | | -------------------------------------------------- | ------------- | ------------- | | `_FW_UNDER_SURVEY=1`, `scan_state` ∉ {DISABLE, BACKOP} | block TX | block TX (unchanged) | | `_FW_UNDER_SURVEY=0`, `scan_state` ∉ {DISABLE, BACKOP} (the desync) | block TX (forever) | **don't block TX** | | `_FW_UNDER_SURVEY=1`, `scan_state ∈ {DISABLE, BACKOP}` | don't block TX | don't block TX (unchanged) | | `_FW_UNDER_SURVEY=0`, `scan_state = DISABLE` | don't block TX | don't block TX (unchanged) | --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
bsakaguchi 2026-10-13 19:33:49 +00:00
Sign in to join this conversation.
No labels
bug
bug
pull-request
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
morrownr/8812au-20210820#63
No description provided.