We are seeing slow STA->STA handoffs (~2 seconds) on MM8108-EKH01 and would like to confirm whether 802.11r FT is supported on the current OpenWrt/driver stack, and if so the correct configuration to achieve sub-200 ms cross-channel STA roams.
Setup
Hardware: 2× MM8108-EKH01 boards configured as HaLow APs + 1× MM8108-EKH01 board as HaLow STA, all on Raspberry Pi 4
Driver: morse_driver from the 2.9.3 release tarball (/usr/sbin daemons dated 2025-Sep-18).
Security: WPA3-Personal (SAE), same SSID (g7-AP), same PSK on both APs
Channels: AP1 on CH_28 (S1G ch 28, mapped to 5570 MHz cfg80211), AP2 on CH_12 (mapped to 5250 MHz cfg80211) — cross-channel ESS
What we tried (and what failed)
wpa_cli_s1g -i wlan0 roam <target_bssid> — the link lands on the target AP momentarily (wlan0: associated to <new_bssid> in dmesg), but within ~3 seconds the AP sends a deauth and the STA falls back. Pattern repeats regardless of signal strength (tested at −40 / −50 dBm to both APs).
wpa_cli_s1g -i wlan0 reassociate after set_network 0 bssid <target> + set_network 0 scan_freq <freq> — works reliably but performs a full WPA3-SAE handshake. End-to-end handoff takes ~2 s.
PMKSA / OKC caching via pmksa_caching=1 okc=1 in the supplicant network block — set but observed minimal effect; the full handshake still seems to happen on every roam (likely because we are roaming between two different BSSIDs in different cells — we need OKC support on both APs and a shared PMK-R1 distribution mechanism, which we have not configured).
Questions
Is 802.11r FT supported on MM8108 with morse_driver + hostapd_s1g/wpa_supplicant_s1g 2.12-morse-rel_1_16_4_2025_Sep_18 in the 2.9.3 OpenWrt release? If supported in a newer release (driver 1.17.x?), which one?
If FT is supported, what is the correct hostapd_s1g configuration to enable it across two HaLow APs? Specifically:
mobility_domain=XXXX requirements
r0_key_holder / r1_key_holder MAC selection
ft_psk_generate_local=1 vs static r0kh/r1kh entries
PMK-R1 distribution requirement — do both APs need to be on the same wired LAN, or does FT-over-DS work over the air?
What key_mgmt= should the STA supplicant advertise? FT-SAE only, or FT-SAE SAE for fallback?
Is the “lands then deauths within ~3 s” symptom a known issue on a specific firmware/driver version? Is there a known fix or workaround?
If FT is not supported on 2.9.3, what is the recommended fast-roam mechanism for sub-200 ms STA handoffs between two HaLow APs in an ESS on this platform? (Plain PMKSA + OKC, or 802.11v BTM?)
Are there any driver/firmware logs we should capture (e.g., dmesg | grep morse, wpa_supplicant -dd, or a debug-enabled morse_driver build) that would help diagnose the wpa_cli roam failure mode?
Our current fallback (full reassociate + 2 s settle to detect the deauth) gives ~2 s total handoff. We need to reduce this significantly for streaming use cases that cannot tolerate 2 s gaps.
Yes. Strictly speaking, for Wi-Fi HaLow you should be using FT-SAE. However, our internal documentation - which might be a little out of date - is recommending to use FT-PSK for fast roaming support.
Enabling ieee80211r should be as simple as setting option ieee80211r 1 in /etc/config/wireless for the HaLow interface. This will set up some defaults for the configuration you have described in question 2.
Please try with key_mgmt = PSK first. I would be interested to know if FT-SAE works when you adjust the pwe as below.
In /etc/config/wireless, try setting option sae_pwe '0' for the HaLow interface.
A sniffer capture would be very, very beneficial https://www.morsemicro.com/resources/appnotes/MM_APPNOTE-36_How_to_do_a_Sniffer_Capture.pdf, as would hostap logs from the two access points. Easiest way to configure debug logging in OpenWrt is to set option log_level '0' in /etc/config/wireless on the wifi-device of type ‘morse’. Read back these logs with logread -e hostapd_s1g.
I haven’t had a chance to experiment with this myself, but it has been documented as functional internally in the past. If all else fails, compare the generated hostap configuration - see /var/run/hostapd-phy#-wlan0.conf with the following configuration below:
The CSA IE in the subsequent beacons is therefore emitted with
zero-filled bandwidth fields. Downstream STAs (MM8108 with the same
build, in managed mode) do NOT follow the announcement — empirically
they wait the full natural beacon-loss timeout (~12-15 s on this build
with listen_interval=5) before discovering the AP on the new channel.
As a result the only reliable way we have found to move the radio is uci set wireless.radio0.channel=<X>; uci commit wireless; wifi reload,
which causes a 5-7 s wifi reload window during which the STA has no
way of knowing where the AP is going — total downtime 18-22 s on
affected STAs.
Questions:
Is the op_bw=0/prim_bw=0/vht=0/ht=0 path through hostapd_fill_csa_settings() a known bug in
2.12-morse-rel_1_16_4_2025_Sep_18 hostapd_s1g for S1G mode?
What is the recommended invocation of chan_switch (or any other
CLI / netlink path) for an S1G AP such that the emitted CSA IE
contains correct bandwidth information AND downstream MM8108 STAs
follow the announcement?
Has this been fixed in any newer driver / hostapd_s1g release
(1.17.x source line)? If so, which release, and is there a build
available from the OpenWrt feed at upgrade.morsemicro.com?
Are there hostapd_s1g build / log options that would surface
additional diagnostics for the CSA IE path beyond option log_level '0' on the wifi-device?
We currently work around the bug by broadcasting a UDP CSA-OOB
announcement on the bridged LAN before issuing the channel change,
but this only helps STAs that run our custom listener and adds an
out-of-band failure mode (broadcast lost during the wifi reload
window). A working in-band CSA via the standard 802.11h flow would
obsolete the workaround.
We applied ajudge’s recommended chan_switch syntax (freq in kHz,
prim_bandwidth, sec_channel_offset, no op_class) and the AP-side
behaviour is now correct — the ECSA IE is filled properly. However,
the STA-side mac80211 rejects the announcement at the kernel level
and disconnects.
Snippets of evidence below; full hostapd-phy0-wlan0.conf and full
logread excerpts are at the end of this mail.
AP wlan0 mode=ap, S1G op_chan 28 (HaLow center 916 MHz, 8 MHz BW),
SAE encryption with sae_pwe=0, FT-SAE enabled
(ieee80211r=1, mobility_domain=a1b2, ft_psk_generate_local=0,
nas_identifier=, r1_key_holder=,
reassociation_deadline=20000, ieee80211k=1,
rrm_neighbor_report=1, rrm_beacon_report=1)
STA wlan0 mode=managed, associated to the AP via SAE / FT-SAE
(auth_alg=ft observed for reassociations - FT itself works)
Switching from S1G op_chan 28 (HaLow center 916 MHz)
to S1G op_chan 44 (HaLow center 924 MHz).
Lower-edge 1 MHz subchannel for CH_44 is at 920.5 MHz =
920500 kHz, per the rule “<freq_kHz> = <center_kHz> -
(bw_MHz - 1) × 500” we derived from your community example.
== AP-side: WORKS as expected ==
hostapd_s1g: wlan0: IEEE 802.11 CHAN_SWITCH EHT config 0x2
HE config 0x2 VHT config 0x1
hostapd_s1g: hostapd_fill_csa_settings : ECSA info op_bw=160,
prim_bw=1, vht=1, ht=1, change to oldconfig:
ht=1, vht=1
ECSA IE bandwidth fields are non-zero. The radio moves in place
and iw dev wlan0 info post-switch shows:
This is the fix for the original “op_bw=0 prim_bw=0” report — that
was our wrong invocation (freq in MHz, omitted prim_bandwidth,
extra op_class). Your community example’s syntax is correct.
== STA-side: REJECTED by mac80211 ==
With CSA-OOB workaround DISABLED (so the STA only sees the in-band
CSA, no application-layer pre-arm), the STA kernel logs:
[4414.171472] wlan0: AP 0c:bf:74:00:1f:05 switches to
unsupported channel (5745.000 MHz, width:5,
CF1/2: 5815.000/0 MHz), disconnecting
width:5 is NL80211_CHAN_WIDTH_160. Our reading: the same
cfg80211 compat shim that maps the S1G 8 MHz block to a 5 GHz
160 MHz channel for IE generation also drives the STA-side
validation - and mac80211 then rejects the channel under the
US 5 GHz regulatory domain (which doesn’t permit this 160 MHz
pair), even though the S1G regdom that actually applies on the
wire DOES permit it.
Net effect: STA disconnects, falls into beacon-loss timeout,
full-scans, reassociates ~28 s later (measured). We work
around it with an application-layer UDP “CSA-OOB” pre-arm that
pushes the new freq to the STA before the radio moves; with
that, recovery drops to ~5-8 s. The workaround is what we’re
shipping now.
== Questions ==
Is the STA-side “switches to unsupported channel …
width:5” rejection a known issue on rel_1_17_8_2026_Mar_24?
Does a newer build let the STA’s mac80211 follow the in-band
CSA on an S1G 8 MHz block without flagging it as 5 GHz /
160 MHz?
Is there a driver / kernel flag (morse driver side, or a
regulatory option at boot) that makes the STA’s regdomain
check happen against the S1G plan rather than the
cfg80211-mapped 5 GHz plan?
If cfg80211 compat is the long-term plan, is there a
mac80211 / cfg80211 patch in your tree that accepts the
mapped 160 MHz width under regdom=US for the S1G channel
range during a CSA follow?
== What we’d appreciate ==
Confirmation that our AP-side ECSA invocation is correct
(we’re sending the IE with non-zero bandwidth fields).
Status on the STA-side rejection (known issue / fix planned
/ fix shipped after rel_1_17_8_2026_Mar_24).
Pointer to release notes if the STA-side fix is in a newer
build we haven’t picked up.
Sniffer capture available on request - the snippets above are the
load-bearing lines but a 60-second pcap around the chan_switch is
ready to share.
Thanks,
───────────────── APPENDIX A: AP hostapd-phy0-wlan0.conf ─────────────────
───────────────── APPENDIX B: STA kernel + supplicant log ─────────────────
(captured with CSA-OOB workaround DISABLED so only the in-band CSA path
is exercised; T0 = chan_switch issued on the AP)
[T0]
kern.info kernel: [4390.369166] wlan0: deauthenticating from
0c:bf:74:00:1f:05 by local choice
(Reason: 2=PREV_AUTH_NOT_VALID)
daemon.notice wpa_supplicant_s1g[7177]: wlan0: SME: Deauth request to
the driver failed
[T0 + ~23 s — STA receives the CSA IE and tries to follow]
kern.info kernel: [4414.171472] wlan0: AP 0c:bf:74:00:1f:05 switches to
unsupported channel (5745.000 MHz, width:5,
CF1/2: 5815.000/0 MHz), disconnecting
daemon.notice wpa_supplicant_s1g[7177]: wlan0: CTRL-EVENT-DISCONNECTED
bssid=0c:bf:74:00:1f:05 reason=4 locally_generated=1
daemon.notice wpa_supplicant_s1g[7177]: wlan0: Added BSSID
0c:bf:74:00:1f:05 into ignore list, ignoring for
10 seconds
[T0 + ~28 s — STA full-scans and reassociates from scratch]
daemon.notice wpa_supplicant_s1g[8014]: wlan0: Associated with
0c:bf:74:00:1f:05
daemon.notice wpa_supplicant_s1g[8014]: wlan0: CTRL-EVENT-CONNECTED -
Connection to 0c:bf:74:00:1f:05 completed [id=0]
───────────────── APPENDIX C: AP hostapd log (chan_switch path) ─────────────────
daemon.info hostapd_s1g: wlan0: IEEE 802.11 CHAN_SWITCH EHT config 0x2
HE config 0x2 VHT config 0x1
daemon.notice hostapd_s1g: hostapd_fill_csa_settings : ECSA info
op_bw=160, prim_bw=1, vht=1, ht=1,
change to oldconfig: ht=1, vht=1
802.11r FT — “Failed to set PTK to the driver” on MM8108 aarch64 build (FT-PSK + FT-SAE both affected)
Hi Morse Micro Support Team,
Following your 2026-06 reply confirming 802.11r FT is supported on MM8108 with hostapd_s1g/wpa_supplicant_s1g 2.12-morse-rel_1_16_4_2025_Sep_18 + sae_pwe=0, we worked through the recommended FT config in a multi-AP HaLow deployment. The sae_pwe=0 fix resolved the original ~3-s post-roam deauth we reported. However, we are now blocked by a second, deeper problem: the FT auth completes over-the-air but the FT-derived PTK cannot be installed into the driver via nl80211 SET_KEY — both FT-PSK and FT-SAE are affected.
Summary
Test | Result |
| - |
FT-SAE with sae_pwe=0 + your full recommended config | FT: Failed to set PTK to the driver → fallback to plain SAE |
FT-PSK (exact recipe from your 2026-06 sample: wpa_key_mgmt=FT-PSK, ft_psk_generate_local=1, mobility_domain, r0_key_lifetime, r1_key_holder, nas_identifier) | Same FT: Failed to set PTK to the driver → fallback to plain PSK |
Plain SAE / plain PSK without FT (control) | works, roam takes ~1.5–5 s (full 4-way each time) |
Both FT variants fail at the same step in the supplicant. Switching FT-SAE → FT-PSK changed nothing — the error is at the nl80211 SET_KEY layer, not the over-the-air handshake.
Reproduction — exact kernel error: nl80211: kernel reports: key not allowed
The full logread capture below makes the failure unambiguous: wpa_supplicant_s1g requests the FT-derived PTK via nl80211 SET_KEY, the kernel returns key not allowed, and wpa_supplicant_s1g logs FT: Failed to set PTK to the driver and tears the connection down. The next-AP reassoc is then rejected by that AP with status_code=55 (“Auth rejected”) because the FT-MD context from the prior failure is stale, and after one retry the STA falls back to plain PSK and the link comes up.
# STA .201 — single end-to-end roam attempt, FT-PSK config, no edits
# (Sun Jun 14 18:25:43 — see appendix A for the full capture)
[10687.907649] kernel: wlan0: authenticate with 50:2e:91:d2:c6:59
[10687.924135] kernel: wlan0: send auth to 50:2e:91:d2:c6:59 (try 1/3)
[18:25:43] wpa_supplicant_s1g: nl80211: kernel reports: key not allowed <-- KERNEL <===
[18:25:43] wpa_supplicant_s1g: FT: Failed to set PTK to the driver <-- SUPPLICANT
[18:25:43] wpa_supplicant_s1g: Trying to associate with 50:2e:91:d2:c6:59
[10687.941434] kernel: wlan0: authenticated
[10687.954733] kernel: wlan0: associate with 50:2e:91:d2:c6:59 (try 1/3)
[10687.975458] kernel: wlan0: RX ReassocResp from 50:2e:91:d2:c6:59 (capab=0x1011 status=0 aid=1)
↑ first AP accepted plain reassoc
[18:25:43] wpa_supplicant_s1g: Associated with 50:2e:91:d2:c6:59
[18:25:43] wpa_supplicant_s1g: WPA: Key negotiation completed [PTK=CCMP GTK=CCMP]
[18:25:43] wpa_supplicant_s1g: CTRL-EVENT-CONNECTED
# 0.1 s later — STA tries to roam to the next AP. FT path same failure:
[10688.105163] kernel: wlan0: disconnect from AP 50:2e:91:d2:c6:59 for new auth to 50:2e:91:d2:ce:54
[10688.237350] kernel: wlan0: authenticate with 50:2e:91:d2:ce:54
[10688.253749] kernel: wlan0: send auth (try 1/3)
[10688.364684] kernel: wlan0: send auth (try 2/3)
[10688.474685] kernel: wlan0: send auth (try 3/3)
[18:25:44] wpa_supplicant_s1g: nl80211: kernel reports: key not allowed <-- KERNEL <===
[18:25:44] wpa_supplicant_s1g: FT: Failed to set PTK to the driver <-- SUPPLICANT
[10688.498864] kernel: wlan0: authenticated
[10688.504714] kernel: wlan0: associate (try 1/3)
[10688.525432] kernel: wlan0: RX ReassocResp ... status=55 aid=1 <-- AP REJECTS
[10688.533458] kernel: wlan0: 50:2e:91:d2:ce:54 denied association (code=55)
[18:25:44] wpa_supplicant_s1g: CTRL-EVENT-ASSOC-REJECT status_code=55
[18:25:44] wpa_supplicant_s1g: SME: Deauth request to the driver failed
[18:25:44] wpa_supplicant_s1g: Added BSSID 50:2e:91:d2:ce:54 into ignore list, 10 seconds
# 1 s later supplicant retries from scratch (non-FT) — and succeeds:
[18:25:45] wpa_supplicant_s1g: Trying to authenticate with 50:2e:91:d2:ce:54
[18:25:45] wpa_supplicant_s1g: RX AssocResp ... status=0 aid=1
[18:25:45] wpa_supplicant_s1g: WPA: Key negotiation completed [PTK=CCMP GTK=CCMP]
[18:25:45] wpa_supplicant_s1g: CTRL-EVENT-CONNECTED
Two distinct symptoms in one trace, both rooted at the same kernel reply:
nl80211: kernel reports: key not allowed — wpa_supplicant_s1g issues NL80211_CMD_NEW_KEY (or SET_KEY) for the FT-derived PTK; mac80211 hands it to morse.ko’s .set_key() callback; the driver returns -EPERM (“Operation not permitted”). The supplicant prints Failed to set PTK to the driver.
status=55 (“Auth rejected”) on the AP-side ReassocResp — the second AP refuses the FT ReassocReq, which suggests the AP-side hostapd hits the same kernel error when it tries to install the PMK-R1 it derived from our FT request. Same code path, mirrored.
The same key not allowed → Failed to set PTK pattern reproduces on every FT-PSK roam, regardless of which of the three APs is the target. Plain PSK association (no FT) never hits this — the post-association 4-way SET_KEY works fine.
Hardware / software baseline
hostapd_s1g / wpa_supplicant_s1g packaged build (visible in logread): rel_1_17_8_2026_Mar_24.
The “Failed to set PTK to the driver” reproduces on the STA (.201, aarch64). All three APs are configured identically with the FT options below; the same STA roaming between the three APs (.200, .202, .203) produces the same error in every direction.
Config in use
AP side (hostapd via uci → /var/run/hostapd-phy*.conf)
Netifd patch applied hostapd_s1g rejects netifd’s auto-added ft_iface=br-lan with 1 errors found in configuration file '/var/run/hostapd-phy0-wlan0.conf' and hostapd dies. We had to comment out the ft_iface= line in both:
/lib/netifd/hostapd.sh line 934 / 941 (depending on package version)
/lib/netifd/morse/morse_overrides.sh line 432 / 434
Without these patches hostapd_s1g cannot come up at all when ieee80211r=1. We assume this is a known netifd-vs-hostapd_s1g mismatch — please let us know if there is an official fix or supported way to disable the ft_iface= line.
Secondary issue — chan_switch to CH_44 (US 8 MHz) fails on aarch64 build only
While testing channel switching with the same boards:
hostapd_s1g: nl80211: kernel reports: (extension) channel is disabled
hostapd_s1g: Channel 44 not found for s1g/global operating class 1/68
hostapd_s1g: Failed to derive class from s1g primary bandwidth
The exact same command on the MIPS AP (.200) returns OK and the radio retunes correctly to CH_44 (5815 MHz mapped). On the aarch64 APs (.203 / EKH01) the kernel rejects it with the “extension channel is disabled” / “Channel 44 not found in operating class 1/68” pair.
The Morse self-managed regdom shows the channel as allowed:
CH_12 and CH_28 chan_switch commands work fine on the same aarch64 board with identical syntax. Only CH_44 is rejected.
Note that the s1g_freq / cfg80211 freq state on aarch64 hostapd_cli status sometimes returns inconsistent values after a failed chan_switch (e.g. s1g_freq=916000 but channel=100 freq=5500) until wifi down && wifi up resets it — suggesting hostapd’s internal state isn’t being cleaned up when the kernel rejects the switch.
What we’d like from you
The PTK install error. Is FT: Failed to set PTK to the driver a known issue in the aarch64 morse.ko build? Is there a driver build that addresses it? If the issue is in our config, what is wrong — the wpa_supplicant_s1g derives the FT PTK successfully (it just can’t install it via nl80211 SET_KEY), so this looks driver-side to us.
ft_iface= — what is the supported way to disable netifd’s auto-add of this option on Morse builds? Our patch works but is invasive.
CH_44 chan_switch — is the aarch64 hostapd_s1g operating class table out of sync with the Morse regdom for the upper 8 MHz US block? Channel 44 not found for s1g/global operating class 1/68 looks like a missing entry rather than a regulatory restriction.
status=55 from the AP on the FT ReassocResp — does the AP-side hostapd also fail to install the FT-derived PMK-R1, mirroring the STA-side Failed to set PTK? If yes, the bug is symmetric and pointing at a common morse.ko code path.
We can provide:
Full logread from STA + AP from a single reproduction
dmesg from the STA at the time of the failed SET_KEY
The exact /var/run/hostapd-phy*.conf and /var/run/wpa_supplicant-wlan0.conf produced by netifd
A packet capture from a third radio if useful (we’d need guidance on what frames to focus on)
Happy to schedule a call or share a sniffer trace. Thanks in advance for any pointers.
Best regards, asaf@guardian7.co Guardian7 — EKH01 deployment
Appendix A — Full STA logread (.201) around the FT failure
# STA .201 — wpa_supplicant_s1g + kernel mac80211 — single ROAM attempt
# Sun Jun 14 18:25:43–48 2026
Sun Jun 14 18:25:43 daemon.notice wpa_supplicant_s1g[30240]: wlan0: SME: Trying to authenticate with 50:2e:91:d2:c6:59 (SSID='g7-AP' chan=37)
Sun Jun 14 18:25:43 kern.info kernel: [10687.885622] wlan0: disconnect from AP 50:2e:91:d2:ce:54 for new auth to 50:2e:91:d2:c6:59
Sun Jun 14 18:25:43 kern.info kernel: [10687.907649] wlan0: authenticate with 50:2e:91:d2:c6:59
Sun Jun 14 18:25:43 daemon.notice netifd: Network device 'wlan0' link is down
Sun Jun 14 18:25:43 kern.info kernel: [10687.924135] wlan0: send auth to 50:2e:91:d2:c6:59 (try 1/3)
Sun Jun 14 18:25:43 daemon.err wpa_supplicant_s1g[30240]: nl80211: kernel reports: key not allowed
Sun Jun 14 18:25:43 daemon.warn wpa_supplicant_s1g[30240]: FT: Failed to set PTK to the driver
Sun Jun 14 18:25:43 daemon.notice wpa_supplicant_s1g[30240]: wlan0: Trying to associate with 50:2e:91:d2:c6:59 (SSID='g7-AP' chan=37)
Sun Jun 14 18:25:43 kern.info kernel: [10687.941434] wlan0: authenticated
Sun Jun 14 18:25:43 kern.info kernel: [10687.954733] wlan0: associate with 50:2e:91:d2:c6:59 (try 1/3)
Sun Jun 14 18:25:43 kern.info kernel: [10687.975458] wlan0: RX ReassocResp from 50:2e:91:d2:c6:59 (capab=0x1011 status=0 aid=1)
Sun Jun 14 18:25:43 daemon.notice netifd: Network device 'wlan0' link is up
Sun Jun 14 18:25:43 daemon.notice wpa_supplicant_s1g[30240]: wlan0: Associated with 50:2e:91:d2:c6:59
Sun Jun 14 18:25:43 daemon.notice wpa_supplicant_s1g[30240]: wlan0: WPA: Key negotiation completed with 50:2e:91:d2:c6:59 [PTK=CCMP GTK=CCMP]
Sun Jun 14 18:25:43 daemon.notice wpa_supplicant_s1g[30240]: wlan0: CTRL-EVENT-CONNECTED - Connection to 50:2e:91:d2:c6:59 completed [id=0 id_str=]
Sun Jun 14 18:25:43 daemon.notice wpa_supplicant_s1g[30240]: wlan0: CTRL-EVENT-SUBNET-STATUS-UPDATE status=0
Sun Jun 14 18:25:43 kern.info kernel: [10687.986874] wlan0: associated
# 100 ms later — roam to the next AP
Sun Jun 14 18:25:43 daemon.notice wpa_supplicant_s1g[30240]: wlan0: SME: Trying to authenticate with 50:2e:91:d2:ce:54 (SSID='g7-AP' chan=11)
Sun Jun 14 18:25:43 kern.info kernel: [10688.105163] wlan0: disconnect from AP 50:2e:91:d2:c6:59 for new auth to 50:2e:91:d2:ce:54
Sun Jun 14 18:25:43 kern.info kernel: [10688.237350] wlan0: authenticate with 50:2e:91:d2:ce:54
Sun Jun 14 18:25:43 kern.info kernel: [10688.253749] wlan0: send auth to 50:2e:91:d2:ce:54 (try 1/3)
Sun Jun 14 18:25:44 kern.info kernel: [10688.364684] wlan0: send auth to 50:2e:91:d2:ce:54 (try 2/3)
Sun Jun 14 18:25:44 kern.info kernel: [10688.474685] wlan0: send auth to 50:2e:91:d2:ce:54 (try 3/3)
Sun Jun 14 18:25:44 daemon.err wpa_supplicant_s1g[30240]: nl80211: kernel reports: key not allowed
Sun Jun 14 18:25:44 daemon.warn wpa_supplicant_s1g[30240]: FT: Failed to set PTK to the driver
Sun Jun 14 18:25:44 daemon.notice wpa_supplicant_s1g[30240]: wlan0: Trying to associate with 50:2e:91:d2:ce:54 (SSID='g7-AP' chan=11)
Sun Jun 14 18:25:44 daemon.notice netifd: Network device 'wlan0' link is down
Sun Jun 14 18:25:44 kern.info kernel: [10688.498864] wlan0: authenticated
Sun Jun 14 18:25:44 kern.info kernel: [10688.504714] wlan0: associate with 50:2e:91:d2:ce:54 (try 1/3)
Sun Jun 14 18:25:44 kern.info kernel: [10688.525432] wlan0: RX ReassocResp from 50:2e:91:d2:ce:54 (capab=0x1011 status=55 aid=1)
Sun Jun 14 18:25:44 kern.info kernel: [10688.533458] wlan0: 50:2e:91:d2:ce:54 denied association (code=55)
Sun Jun 14 18:25:44 daemon.notice wpa_supplicant_s1g[30240]: wlan0: CTRL-EVENT-ASSOC-REJECT bssid=50:2e:91:d2:ce:54 status_code=55
Sun Jun 14 18:25:44 daemon.notice wpa_supplicant_s1g[30240]: wlan0: SME: Deauth request to the driver failed
Sun Jun 14 18:25:44 daemon.notice wpa_supplicant_s1g[30240]: wlan0: Added BSSID 50:2e:91:d2:ce:54 into ignore list, ignoring for 10 seconds
# 1 second later — supplicant retries non-FT, succeeds with plain PSK:
Sun Jun 14 18:25:45 daemon.notice wpa_supplicant_s1g[30240]: wlan0: Removed BSSID 50:2e:91:d2:ce:54 from ignore list (clear)
Sun Jun 14 18:25:45 daemon.notice wpa_supplicant_s1g[30240]: wlan0: SME: Trying to authenticate with 50:2e:91:d2:ce:54 (SSID='g7-AP' chan=11)
Sun Jun 14 18:25:45 kern.info kernel: [10689.606109] wlan0: authenticate with 50:2e:91:d2:ce:54
Sun Jun 14 18:25:45 kern.info kernel: [10689.622725] wlan0: send auth to 50:2e:91:d2:ce:54 (try 1/3)
Sun Jun 14 18:25:45 kern.info kernel: [10689.633984] wlan0: authenticated
Sun Jun 14 18:25:45 daemon.notice wpa_supplicant_s1g[30240]: wlan0: Trying to associate with 50:2e:91:d2:ce:54 (SSID='g7-AP' chan=11)
Sun Jun 14 18:25:45 kern.info kernel: [10689.644678] wlan0: associate with 50:2e:91:d2:ce:54 (try 1/3)
Sun Jun 14 18:25:45 daemon.notice netifd: Network device 'wlan0' link is up
Sun Jun 14 18:25:45 kern.info kernel: [10689.662664] wlan0: RX AssocResp from 50:2e:91:d2:ce:54 (capab=0x1011 status=0 aid=1)
Sun Jun 14 18:25:45 kern.info kernel: [10689.673898] wlan0: associated
Sun Jun 14 18:25:45 daemon.notice wpa_supplicant_s1g[30240]: wlan0: Associated with 50:2e:91:d2:ce:54
Sun Jun 14 18:25:45 daemon.notice wpa_supplicant_s1g[30240]: wlan0: WPA: Key negotiation completed with 50:2e:91:d2:ce:54 [PTK=CCMP GTK=CCMP]
Sun Jun 14 18:25:45 daemon.notice wpa_supplicant_s1g[30240]: wlan0: CTRL-EVENT-CONNECTED - Connection to 50:2e:91:d2:ce:54 completed
Appendix B — STA dmesg (.201) for the same window
[10657.896165] wlan0: authenticate with 50:2e:91:d2:ce:54
[10657.915153] wlan0: send auth to 50:2e:91:d2:ce:54 (try 1/3)
[10657.925915] wlan0: authenticated
[10657.934703] wlan0: associate with 50:2e:91:d2:ce:54 (try 1/3)
[10657.951413] wlan0: RX AssocResp from 50:2e:91:d2:ce:54 (capab=0x1011 status=0 aid=1)
[10657.962648] wlan0: associated
[10658.036240] IPv6: ADDRCONF(NETDEV_CHANGE): wlan0: link becomes ready
[10687.885622] wlan0: disconnect from AP 50:2e:91:d2:ce:54 for new auth to 50:2e:91:d2:c6:59
[10687.907649] wlan0: authenticate with 50:2e:91:d2:c6:59
[10687.924135] wlan0: send auth to 50:2e:91:d2:c6:59 (try 1/3)
[10687.941434] wlan0: authenticated
[10687.954733] wlan0: associate with 50:2e:91:d2:c6:59 (try 1/3)
[10687.975458] wlan0: RX ReassocResp from 50:2e:91:d2:c6:59 (capab=0x1011 status=0 aid=1)
[10687.986874] wlan0: associated
[10688.105163] wlan0: disconnect from AP 50:2e:91:d2:c6:59 for new auth to 50:2e:91:d2:ce:54
[10688.237350] wlan0: authenticate with 50:2e:91:d2:ce:54
[10688.253749] wlan0: send auth to 50:2e:91:d2:ce:54 (try 1/3)
[10688.364684] wlan0: send auth to 50:2e:91:d2:ce:54 (try 2/3)
[10688.474685] wlan0: send auth to 50:2e:91:d2:ce:54 (try 3/3)
[10688.498864] wlan0: authenticated
[10688.504714] wlan0: associate with 50:2e:91:d2:ce:54 (try 1/3)
[10688.525432] wlan0: RX ReassocResp from 50:2e:91:d2:ce:54 (capab=0x1011 status=55 aid=1)
[10688.533458] wlan0: 50:2e:91:d2:ce:54 denied association (code=55)
[10689.606109] wlan0: authenticate with 50:2e:91:d2:ce:54
[10689.622725] wlan0: send auth to 50:2e:91:d2:ce:54 (try 1/3)
[10689.633984] wlan0: authenticated
[10689.644678] wlan0: associate with 50:2e:91:d2:ce:54 (try 1/3)
[10689.662664] wlan0: RX AssocResp from 50:2e:91:d2:ce:54 (capab=0x1011 status=0 aid=1)
[10689.673898] wlan0: associated
Appendix C — full hostapd-phy1-wlan0.conf (.200 AP)
Generated by netifd from the uci config shown in the main body. The AP is currently broadcasting ssid=g7-AP on channel=28 (US 8 MHz HaLow, mapped to 5570 MHz center). wpa_key_mgmt=WPA-PSK FT-PSK, mobility_domain=a1b2, ft_psk_generate_local=1, sae_pwe=0 — exactly the recipe from your 2026-06 reply.
(WMM / TX queue / qos_map_set lines elided for brevity — they are the netifd defaults.)
Note: ft_iface= is NOT present in this file — we patched both /lib/netifd/hostapd.sh and /lib/netifd/morse/morse_overrides.sh to drop the auto-added ft_iface=$network_ifname line. Without that patch hostapd_s1g aborts with 1 errors found in configuration file and never reaches state=ENABLED.
Appendix D — full /var/run/wpa_supplicant-wlan0.conf (.201 STA)
The STA uci sets ieee80211r=1, which netifd translates into the WPA-PSK FT-PSKkey_mgmt line above. ieee80211w (MFP) is intentionally not pinned — under FT-PSK it is optional and not advertised. The bssid= field is set per-roam by our Python orchestrator before each wpa_cli reassociate; the supplicant’s own bgscan would otherwise pick the strongest match in the BSS cache.
Appendix E — driver / firmware versions