Skip to content

WCN3990 wifi: advertise mfp in firmware-5.bin - #133

Open
shunnag wants to merge 1 commit into
commaai:masterfrom
shunnag:wcn3990-mfp
Open

shunnag wants to merge 1 commit into
commaai:masterfrom
shunnag:wcn3990-mfp

Conversation

@shunnag

@shunnag shunnag commented Sep 26, 2026 •

Copy link
Copy Markdown

Sets the mfp feature bit (ATH10K_FW_FEATURE_MFP_SUPPORT, bit 12) in kernel/firmware/ath10k/WCN3990/hw1.0/firmware-5.bin. Fixes the PMF reconnect problem in #131.

Why

  • ath10k only sets the WMI peer PMF flag when the firmware advertises mfp (ath10k_peer_assoc_h_crypto()). Without the flag, the firmware does not treat PMF peers as protected.
    • The protected Deauth that mac80211 sends on disconnect leaves the air with PN 0. The host queued it with PN 1, so the firmware rewrote the CCMP header.
    • The AP drops that Deauth as a replay and keeps the old association. The next connect then gets status 30 (association comeback), and recovery takes 20 s or more.
  • The firmware's own ADDBA Requests are also sent unprotected.
  • qcacld on AGNOS sets the peer PMF flag with the same firmware family and does not show the problem.
  • sargo: declare WCN3990 management-frame protection support samcday/pocketfed#27 is the same bit on another WCN3990 device.

Change

  • 1 byte, offset 0x21 (the FW_FEATURES IE bitmap): 0x00 → 0x10.
  • The file stays 60 bytes. sha256 changes from fef6539e… to 5a2be7e7…, and the ath10k crc32 from b3d4b790 to eda01cc5.
  • dmesg then shows features wowlan,mfp,mgmt-tx-by-reference,non-bmi.
-00000020: 4000 0c77 0500 0000 0400 0000 0400 0000
+00000020: 4010 0c77 0500 0000 0400 0000 0400 0000

Testing (comma four, LD 7.2)

  • Setup:
    • The new file was bind-mounted over /lib/firmware/ath10k/WCN3990/hw1.0/firmware-5.bin, followed by an ath10k_snoc unbind/bind.
    • AP: Deco BE85, WPA3-only SSID with SAE and PMF required, BSSID pinned.
    • Each trial used a fresh MAC and ran connect, 20 s of traffic, nmcli connection down, 3 s wait, nmcli connection up.
    • A macOS sniffer captured each trial.
Deauth PN on air status 30 reconnect
stock firmware-5.bin 0 (3/3) 3/3 21, 21, 25 s
this PR 17-88 (7/7) 0/7 1-5 s (6/7), 28 s (1/7)
  • The 28 s run: the AP stopped ACKing the STA for 26 s after accepting the Deauth. It did not happen again in the other 6 runs.
  • With the bit set, the firmware's own ADDBA frames are protected. Data, DHCP and ping were normal in every run. The WPA2-PSK SSID without PMF was unaffected (sta->mfp is false there).
  • Not tested with this bit: the hostapd SAE hotspot, and a full image build (only the file was swapped at runtime).

Not fixed by this PR (details in #131)

  • If a stale association exists anyway, for example after a power cut, reconnecting still takes about 20 s:
    • mac80211 retries the association after the comeback without re-authenticating.
    • After that, the firmware holds the next Auth frames without sending them, then discards them.
  • The bundled mgmt TX completion handler in wmi.c reads the status from desc_ids[i] instead of status[i]. This firmware uses bundled completions, so discarded frames can be reported as ACKed.

Note: I worked through this together with Claude (AI). English is hard for me, so the English was written with AI help. I ran the device tests myself on my comma four, and the results above come from those runs.

@github-actions

github-actions Bot commented Sep 26, 2026 •

Copy link
Copy Markdown

vamOS System Profile

Changes vs master

Metric Change
Used space 3438.4MB → 3439.8MB (+1.4MB)
Sparse image 3392.5MB → 3394.0MB (+1.5MB)
Package count 526 → 526

Added packages: cmake-4.2.2_3, dhcpcd-10.3.2_2, expat-2.8.4_1, expat-devel-2.8.4_1, jsoncpp-1.9.8_1, libharfbuzz-14.4.0_1, python3-3.14.7_1, python3-Mako-1.4.1_1, python3-Pygments-2.21.0_1, texinfo-7.3_2, vim-9.2.1031_1, vim-common-9.2.1031_1, xxd-9.2.1031_1

Removed packages: cmake-4.2.2_2, dhcpcd-10.3.2_1, expat-2.8.3_1, expat-devel-2.8.3_1, jsoncpp-1.9.6_1, libharfbuzz-14.3.1_1, python3-3.14.6_1, python3-Mako-1.3.2_3, python3-Pygments-2.20.0_1, texinfo-7.3_1, vim-9.2.0506_1, vim-common-9.2.0506_1, xxd-9.2.0506_1

Directory size changes (>1MB)
Directory Change

Metric Value
Used space 3439.8MB / 5959.5MB
Files 56307
Directories 4774
Symlinks 3602
Packages 526

Top 10 Directories

Directory Size

Category Breakdown

Category Size %
xbps packages 2516.5MB 73.1%
Python venv 591.8MB 17.2%
Firmware 11.2MB .3%
Other 320.2MB 9.3%

Top 10 Packages by Size

Package Size
mit-krb5-libs-1.21.3_1 270.4MB
gawk-5.3.2_1 210.3MB
llvm-21_3 148.6MB
libldns-1.9.2_1 124.3MB
pd-mapper-1.0_1 74MB
libclang21-21.1.7_1 70.2MB
glib-2.88.0_1 67.4MB
gcc-14.2.1+20250405_4 66.6MB
libcap-progs-2.78_1 56MB
cmake-4.2.2_3 53.2MB

Top 30 Files by Size

File Size
/usr/lib/llvm/21/lib/libLLVM.so.21.1 124.3MB
/usr/lib/llvm/21/lib/libMLIR.so.21.1 89.7MB
/usr/lib/llvm/21/bin/mlir-transform-opt 82.9MB
/usr/lib/llvm/21/lib/libclang-cpp.so.21.1 56MB
/usr/lib/llvm/21/bin/mlir-translate 53.2MB
/usr/lib/llvm/21/bin/llvm-exegesis 52MB
/usr/lib/llvm/21/bin/llvm-bolt-binary-analysis 50.6MB
/usr/bin/uv 41.6MB
/usr/lib/gcc/aarch64-linux-gnu/14.2/gnat1 40.1MB
/usr/bin/gdb 39.1MB
/usr/lib/libgallium-26.1.8.so 37.7MB
/usr/lib/gcc/aarch64-linux-gnu/14.2/cc1plus 37.3MB
/usr/lib/libllvm-qcom.so 35.2MB
/usr/lib/gcc/aarch64-linux-gnu/14.2/cc1 35.2MB
/usr/lib/libRusticlOpenCL.so.1.0.0 34.4MB
/usr/lib/gcc/aarch64-linux-gnu/14.2/lto1 33.9MB
/usr/bin/lto-dump 33.9MB
/usr/local/venv/bin/ruff 31.8MB
/usr/share/icu/78.3/icudt78l.dat 31.5MB
/usr/lib/llvm/21/lib/libclang.so.21.1.7 30.2MB
/usr/lib/libz3.so 28.8MB
/usr/lib/llvm/21/bin/c-index-test 28.6MB
/usr/local/venv/lib/python3.12/site-packages/gcc_arm_none_eabi/toolchain/libexec/gcc/arm-none-eabi/13.2.1/cc1 28.2MB
/usr/bin/run 26.7MB
/usr/local/venv/lib/python3.12/site-packages/numpy.libs/libscipy_openblas64_-71e1b124.so 23.6MB
/usr/comma/updater 23.5MB
/usr/comma/setup 23.5MB
/usr/comma/reset 23.5MB
/usr/local/uv/python/cpython-3.12.14-linux-aarch64-gnu/bin/python3.12 22.1MB
/usr/local/uv/python/cpython-3.12.14-linux-aarch64-gnu/lib/libpython3.12.so.1.0 22MB

@shunnag

shunnag commented Sep 27, 2026

Copy link
Copy Markdown
Author

More device results for this change, from a new session on the same comma four and AP.

Setup

  • Liberation Day 7.2 with my debug build of the kernel: extra logging and the one-line wmi.c bundled-status fix. The other debug switches were off.
  • Both firmware-5.bin files were tested in the same session, on the same WPA3-only SSID and BSSID. The file was swapped at runtime (bind mount, then ath10k_snoc unbind/bind).
  • Each run used a new MAC: connect, ping, nmcli connection down, wait 3 s, nmcli connection up.

Reconnect after a local disconnect

firmware-5.bin runs status 30 on reconnect reconnect
stock 9 9/9 21.1-24.6 s
this PR (mfp bit) 2 0/2 4.2 s, 4.2 s

AP mode with the mfp bit
The PR body lists the hostapd SAE hotspot as untested. I tried wpa_supplicant's AP mode instead:

  • A standalone wpa_supplicant AP (my own config, not hostapd and not the NetworkManager hotspot) came up (AP-ENABLED) with key_mgmt=WPA-PSK SAE, ieee80211w=1, channel 6.
  • An iPhone joined with SAE (AKM 00-0f-ac-8), CCMP and PMF. The 4-way handshake completed.
  • Still not tested: hostapd, the NetworkManager hotspot (PMF required), traffic through the AP, and a full image build.

Note: I worked through this together with Claude (AI). English is hard for me, so the English was written with AI help. I ran the device tests myself on my comma four, and the results above come from those runs.

Set the mfp feature bit (ATH10K_FW_FEATURE_MFP_SUPPORT, bit 12) in the
WCN3990 firmware-5.bin. Without it, ath10k never sets the WMI peer PMF
flag, and the firmware sends the protected Deauth from mac80211 with
PN 0. The AP drops it as a replay and keeps the old association, so the
next connect gets status 30 and recovery takes 20 s or more (commaai#131).
The firmware's own ADDBA Requests also go out unprotected.

One byte changes (offset 0x21, 0x00 -> 0x10). Tested on a comma four
with LD 7.2 by bind-mounting the new file over the old one. The
reconnect after a local disconnect on a WPA3-only (PMF required) AP
went from 21-25 s (3/3, status 30) to 1-5 s in 6/7 runs, with no
status 30 in any of them.
@shunnag

shunnag commented Sep 29, 2026

Copy link
Copy Markdown
Author

Throughput results for this change, this time on the stock Liberation Day 7.2 kernel (release boot.img, no debug build).

Setup

  • Same comma four and AP (Deco BE85), 5 GHz channel 48, 80 MHz. iperf3 to a wired host on the same LAN, 30 s each way.
  • Both firmware-5.bin files in one session, swapped at runtime as before (bind mount, then ath10k_snoc unbind/bind). A new MAC for each connection (the reconnect test reuses one MAC).

Results (Mbit/s, device → host / host → device)

SSID and NM profile stock firmware-5.bin this PR
WPA3-only (sae, PMF required) 31.6 / 21.6, 22.6 / 21.7 273.8 / 242.5, 287.7 / 243.7
WPA2/WPA3 mixed (wpa-psk, pmf default) 23.4 / 22.7 285.4 / 226.9
WPA3-only, 4 streams (-P 4 -S 0x20) 21.2 / 24.1 248.7 / 235.5
WPA2-only (wpa-psk, PMF disabled) 283.0 / 264.5, 280.2 / 272.3 275.9 / 264.5, 270.9 / 261.2
WPA3-only reconnect after nmcli connection down 24.4 s, 24.3 s (status 30) 4.2 s, 1.0 s
  • Sniffer: with the stock file, the device sent 146-176 unprotected ADDBA Requests in each PMF iperf3 connection. The AP answered none, and there were no BlockAck frames, so no A-MPDU aggregation. With this PR there were no unprotected ADDBA frames, and 11k-22k BlockAck frames each way.
  • The mixed SSID is affected too. The profile had the same security settings that openpilot's WifiManager uses (wpa-psk, auth-alg open, no pmf). It connected with SAE and PMF, and it was as slow as WPA3-only.
  • WPA2 without PMF is the same with both files. No ath10k warnings in dmesg.
  • firmware-5.bin is the same file on master and liberation-day-7.2, so this change applies to both.

The run log, the iperf3 per-second summary and the per-connection sniffer counts are attached. SSIDs and AP addresses are removed.

Note: I worked through this together with Claude (AI). English is hard for me, so the English was written with AI help. I ran the device tests myself on my comma four, and the results above come from those runs.
pr133_throughput_stock_kernel.txt
pr133_sniffer_counts.txt

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.

1 participant