SM8550: fix slow WiFi reconnect, ath12k never sends its scan priority - #3189
SM8550: fix slow WiFi reconnect, ath12k never sends its scan priority#3189xiaodoudou wants to merge 1 commit into
Conversation
|
My automated test and real test give me not the same result, I'm putting in draft for now. I will investigate this more. |
|
这个问题在我的设备上有复现。我在提交的#3177 添加 AYANEO Pocket S Mini 支持- # 3177 有提到,修复针对 ath12k 的 11d 扫描竞争;上游资料也说明 11d 扫描可能取消普通硬件扫描。芯片最终识别出的监管域已经是 CN,但系统启动时全局监管域仍是 00,于是 ath12k 会先启动一次固件 11d 国家扫描;上游驱动明确说明 11d 扫描会抢占普通扫描。这个固件组合很可能在停止 11d 后没有正确释放扫描引擎。好像是这个全局监管冲突导致我们连接C N的Wi Fi的时候呢,通道被它占用了,失败一定次数以后,它就会停止 5G 的扫描,导致只能扫描到 2.4G,所以就只能连接到 2.4G 了。我在我的设备上能复现并且也修复了这个问题。 |
Translation for anyone following the issue:
|
ath12k computes a priority for every hardware scan, LOW as the baseline and MEDIUM while its 11d regulatory scan is about to run, so host scans are not starved by the 11d service the firmware runs at MEDIUM priority in its single scan queue. The value never leaves the driver: cmd->scan_priority is never assigned, so every hardware scan reaches the firmware as priority 0, VERY_LOW. ath11k sends the same computation with the command; the copy was lost in the ath12k rework. On the WCN7850 every radio bring-up therefore opens with a refusal storm. The first hardware scan arms and starts the 11d scan, and every scan submitted while that MEDIUM scan is pending fails with WMI_SCAN_REASON_INTERNAL_FAILURE. iwd sees aborted scans, abandons its quick reconnect plan and falls back to full sweeps with growing backoff. Reconnecting after the suspend hooks toggle rfkill takes 4.4 to 8 seconds and degrades as refusals accumulate. With the priority on the wire, ten fresh-boot rfkill cycles on an AYN Odin 2 reconnect 10/10 with zero scan refusals, nine of them between 1021 and 1041 ms, reconnecting from the first quick scan every time. This replaces the earlier attempt that moved the 11d arming to the interface: an A/B on the real resume path measured identical refusal counts with and without it, which is what pointed away from the 11d churn and at the scan request itself.
6b870a0 to
8638e1d
Compare
|
Rework: this PR now carries a different, one-line fix. The 11d patch that used to be here is gone. What happened: when I retested the 11d patch on the real resume path (what the sleep hooks actually run, not my earlier synthetic harness), it made no measurable difference. Same number of firmware scan refusals with it as without it. The diagnosis in the old body was describing something real, but it was not what refused the scans. Debug traces found the actual cause. A refused scan stays refused if you resend it unchanged, even on a freshly recreated vdev, yet a different scan submitted right after goes through fine. That pointed at the scan request itself, and the request has a bug: ath12k computes a priority for every hardware scan but never sends it. The assignment is simply missing, so every scan reaches the firmware as priority 0, the lowest there is. The firmware runs its 11d country scan at MEDIUM priority in the same queue, so after every radio bring-up, everything iwd submits while 11d is pending gets refused. Each refusal makes iwd fall back to slow full scans with backoff, and that is the whole slowdown. ath11k computes the same priority and does send it; the copy was lost somewhere in the ath12k rework. The fix is restoring that one line: cmd->scan_priority = cpu_to_le32(arg->scan_priority);Results on the Odin 2, fresh boot each time, real resume path:
The PR body has been rewritten to match the new patch. One more thing, for #3177: the Pocket S Mini patch that disables 11d entirely ( |
Summary
WiFi reconnects slowly and erratically after the radio is taken down and brought back up on the Odin 2, which is what the suspend hooks do around every sleep cycle. On a stock image, five off/on cycles reconnect in 4.4 to 8 seconds, degrading as cycles accumulate, with bursts of firmware scan refusals along the way.
The cause is a one-line regression in ath12k. The driver computes a priority for every hardware scan and then never sends it:
ath12k_wmi_send_scan_start_cmd()fillsarg->scan_priority(LOW as the baseline, MEDIUM when its own 11d regulatory scan is about to run, precisely so host scans do not get starved by it) butcmd->scan_priorityis never assigned, so every hardware scan reaches the firmware as priority 0,WMI_SCAN_PRIORITY_VERY_LOW. ath11k computes the same value and does send it; the copy was lost in the ath12k rework. The firmware schedules all scans through one queue and runs the 11d scan at MEDIUM, so after every bring-up the first hardware scan starts the 11d scan and every further scan submitted while it is pending is refused:Reason 4 is
WMI_SCAN_REASON_INTERNAL_FAILURE. The driver reports each refused scan to iwd as an aborted scan, iwd abandons its quick reconnect plan and falls back to full sweeps with growing backoff, and that is the whole slowdown.The fix sends the priority the driver already computes:
Testing
AYN Odin 2 (SM8550, WCN7850 hw2.0), linux 7.1.2, shipped c5 firmware, everything from a fresh boot, timing from radio unblock to carrier plus an IPv4 address.
Ten rfkill off/on cycles through the real resume path (
wifictl disable, thenwifi-resume):Nine of ten cycles land within 20 ms of each other. The starred outlier shows zero refusals and matches a NetworkManager-level stall that exists on stock as well (where it produces the 8 s cycles and occasional 40 s timeouts); the driver side stayed clean through it.
On top of the rfkill cycles, real suspend/resume endurance: deep suspend entered via
systemctl suspendwith an RTC wake, about 25 seconds asleep per cycle, WiFi remeasured after every wake. 36 consecutive cycles before the run was ended manually, every one a verified real suspend (suspend_statsincremented), every reconnect between 2.0 and 3.2 seconds, zero scan refusals across the entire run. The same pattern on the unfixed driver produces refusal bursts from the second or third cycle and degrades from there.Additional context
How this was found. The earlier version of this PR moved the 11d arming from the per-scan vdev to the interface, based on the observation that ath12k churns an 11d scan start/stop around every hardware scan. The churn is real, but an A/B on the real resume path measured identical refusal counts with and without that patch, which meant the refusals had another cause. Debug traces then showed refused scans staying refused when resent as-is (same vdev or a recycled one, up to 660 ms later) while any different scan submitted moments later sailed through; that ruled out timing and vdev state and left the request itself, and the missing priority assignment accounts for everything, including why a wedged 11d scan used to block every scan for minutes.
This likely fixes the Pocket S Mini workaround target too. #3177 carries
0507-wifi-ath12k-skip-11d-scan-on-ayaneo-pocket-s-mini.patchfor the same symptom on the same chip (scans permanently refused after 11d starts and stops, until power cycle). That is the priority starvation in its hardest form. With this fix, host scans coexist with the 11d scan instead of losing to it, so the per-device 11d amputation (and the regulatory blind spot it brings) should no longer be needed; worth a retest on that hardware.Upstream. This is a mechanical divergence from ath11k and worth sending to linux-wireless. The ath12k 11d-offload commit message documents the MEDIUM/LOW queue model this restores. A related patch in review upstream ("wifi: ath12k: restore country code during resume") fixes country loss across a full firmware reload; complementary, no overlap.
AI Usage
Did you use AI tools to help write this code? YES