# ast STA roaming (802.11r FT) between two HaLow APs — handoff fails: "lands then deauths" within 3s

**URL:** <https://community.morsemicro.com/t/ast-sta-roaming-802-11r-ft-between-two-halow-aps-handoff-fails-lands-then-deauths-within-3s/1707>\
**Category:** General\
**Created:** [June 2, 2026, 11:35am UTC](https://community.morsemicro.com/t/ast-sta-roaming-802-11r-ft-between-two-halow-aps-handoff-fails-lands-then-deauths-within-3s/1707 "2026-06-02T11:35:39Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![Asaftv](https://avatars.discourse-cdn.com/v4/letter/a/8491ac/32.png) [@Asaftv](https://community.morsemicro.com/u/Asaftv)\
**Post date:** [June 2, 2026, 11:35am UTC](https://community.morsemicro.com/t/ast-sta-roaming-802-11r-ft-between-two-halow-aps-handoff-fails-lands-then-deauths-within-3s/1707/1 "2026-06-02T11:35:39Z")

</div>

Hello Morse Micro Support,

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

- **Software** (from STA `g7-sta-00000001`):

$ uname -r  
5.15.167  
$ cat /etc/openwrt\_release  
DISTRIB\_ID=‘OpenWrt’  
DISTRIB\_RELEASE=‘23.05.5’  
DISTRIB\_REVISION=‘r0+24325-747fb9b5e1’  
DISTRIB\_TARGET=‘bcm27xx/bcm2711’  
DISTRIB\_ARCH=‘aarch64\_cortex-a72’  
DISTRIB\_DESCRIPTION=‘OpenWrt 23.05.5 Morse-2.9.3’  
$ wpa\_cli\_s1g -v  
wpa\_cli v2.12-morse\_micro-rel\_1\_16\_4\_2025\_Sep\_18  
$ hostapd\_s1g -v  
hostapd v2.12-morse\_micro-rel\_1\_16\_4\_2025\_Sep\_18

- 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)

1. **`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).

2. **`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.

3. **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

1. **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?

2. If FT is supported, what is the **correct `hostapd_s1g` configuration** to enable it across two HaLow APs? Specifically:

3. What `key_mgmt=` should the **STA supplicant** advertise? `FT-SAE` only, or `FT-SAE SAE` for fallback?

4. 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?

5. 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?)

6. 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.

Best regards,

---

<div class="post-metadata">

**Author:** ![ajudge](https://avatars.discourse-cdn.com/v4/letter/a/c2a13f/32.png) [@ajudge](https://community.morsemicro.com/u/ajudge)\
**Post date:** [June 12, 2026, 1:12am UTC](https://community.morsemicro.com/t/ast-sta-roaming-802-11r-ft-between-two-halow-aps-handoff-fails-lands-then-deauths-within-3s/1707/2 "2026-06-12T01:12:30Z")

</div>

Hey @Asaftv

Sorry for the late reply here.

> [@Asaftv](#):
>
> 1. **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?

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.

You will also want to configure the r0kh and r1kh fields as per the OpenWrt [/etc/config/wireless documentation](https://openwrt.org/docs/guide-user/network/wifi/basic#fast_bss_transition_options_80211r)

> [@Asaftv](#):
>
> 1. What `key_mgmt=` should the **STA supplicant** advertise? `FT-SAE` only, or `FT-SAE SAE` for fallback?

Please try with `key_mgmt = PSK ` first. I would be interested to know if FT-SAE works when you adjust the pwe as below.

> [@Asaftv](#):
>
> 1. 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?

In /etc/config/wireless, try setting `option sae_pwe '0'` for the HaLow interface.

> [@Asaftv](#):
>
> 1. 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?

A sniffer capture would be very, very beneficial [https://www.morsemicro.com/resources/appnotes/MM\_APPNOTE-36\_How\_to\_do\_a\_Sniffer\_Capture.pdf](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:

```auto
ctrl_interface=/var/run/hostapd_s1g

interface=wlan0
driver=nl80211
hw_mode=a
ieee80211ah=1
channel=42
op_class=69
country_code=AU
s1g_prim_chwidth=1
s1g_prim_1mhz_chan_index=0

ssid=MorseMicroSamC
beacon_int=100
dtim_period=1
ap_max_inactivity=65536
s1g_capab=[SHORT-GI-ALL]

wpa=2
wpa_key_mgmt=FT-PSK
rsn_pairwise=CCMP

wpa_passphrase=12345678
ieee80211w=1

# Low priority / AC_BK = background
tx_queue_data3_aifs=7
tx_queue_data3_cwmin=15
tx_queue_data3_cwmax=1023
tx_queue_data3_burst=15.0

# Normal priority / AC_BE = best effort
tx_queue_data2_aifs=3
tx_queue_data2_cwmin=15
tx_queue_data2_cwmax=1023
tx_queue_data2_burst=15.0

# High priority / AC_VI = video
tx_queue_data1_aifs=2
tx_queue_data1_cwmin=7
tx_queue_data1_cwmax=15
tx_queue_data1_burst=15.0

# Highest priority / AC_VO = voice
tx_queue_data0_aifs=2
tx_queue_data0_cwmin=3
tx_queue_data0_cwmax=7
tx_queue_data0_burst=15.0

# Low priority / AC_BK = background
wmm_ac_bk_aifs=7
wmm_ac_bk_cwmin=4
wmm_ac_bk_cwmax=10
wmm_ac_bk_txop_limit=469
wmm_ac_bk_acm=0

# Normal priority / AC_BE = best effort
wmm_ac_be_aifs=3
wmm_ac_be_cwmin=4
wmm_ac_be_cwmax=10
wmm_ac_be_txop_limit=469
wmm_ac_be_acm=0

# High priority / AC_VI = video
wmm_ac_vi_aifs=2
wmm_ac_vi_cwmin=3
wmm_ac_vi_cwmax=4
wmm_ac_vi_txop_limit=469
wmm_ac_vi_acm=0

# Highest priority / AC_VO = voice
wmm_ac_vo_aifs=2
wmm_ac_vo_cwmin=2
wmm_ac_vo_cwmax=3
wmm_ac_vo_txop_limit=469
wmm_ac_vo_acm=0
wnm_sleep_mode=1

mobility_domain=a1b2
ft_psk_generate_local=1

r1_key_holder=0CBF7400017C
nas_identifier=0CBF7400017C

r0_key_lifetime=10000

r0kh=<mac addr1> <nasid1> <256 bit key>
r1kh=<mac addr2> <r1khid1> <256 bit key>
r0kh=<mac addr1> <nasid2> <256 bit key>
r1kh=<mac addr2> <r1khid2> <256 bit key>

```

---

<div class="post-metadata">

**Author:** ![Asaftv](https://avatars.discourse-cdn.com/v4/letter/a/8491ac/32.png) [@Asaftv](https://community.morsemicro.com/u/Asaftv)\
**Post date:** [June 12, 2026, 2:32pm UTC](https://community.morsemicro.com/t/ast-sta-roaming-802-11r-ft-between-two-halow-aps-handoff-fails-lands-then-deauths-within-3s/1707/3 "2026-06-12T14:32:03Z")

</div>

CSA (Channel Switch Announcement) on MM8108 — hostapd\_fill\_csa\_settings  
emits IE with op\_bw=0, prim\_bw=0 — workaround / fixed release?

Setup:  
Hardware: MM8108 EKH01 module  
Software: 2.12-morse-rel\_1\_16\_4\_2025\_Sep\_18 hostapd\_s1g / wpa\_supplicant\_s1g  
(OpenWrt 2.9.3 release, kernel 5.15.167)  
Mode: 8 MHz HaLow AP @ CH\_28 (916 MHz HaLow / 5570 MHz mapped) with  
WDS+SAE+sae\_pwe=1 (default)

Symptom:  
Issuing `hostapd_cli_s1g -i wlan0 chan_switch 5 916 sec_channel_offset=0 center_freq1=916 bandwidth=8 op_class=68` returns success at the API,  
but `logread -e hostapd_s1g` shows:

hostapd\_s1g: IEEE 802.11 CHAN\_SWITCH EHT/HE/VHT config 0x2  
hostapd\_s1g: hostapd\_fill\_csa\_settings : ECSA info op\_bw=0,  
prim\_bw=0, vht=0, ht=0

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:

1. 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?

2. 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?

3. 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](http://upgrade.morsemicro.com)?

4. 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.

Thanks,

---

<div class="post-metadata">

**Author:** ![ajudge](https://avatars.discourse-cdn.com/v4/letter/a/c2a13f/32.png) [@ajudge](https://community.morsemicro.com/u/ajudge)\
**Post date:** [June 12, 2026, 3:02pm UTC](https://community.morsemicro.com/t/ast-sta-roaming-802-11r-ft-between-two-halow-aps-handoff-fails-lands-then-deauths-within-3s/1707/4 "2026-06-12T15:02:13Z")

</div>

This sounds like a separate set of questions to the fast roaming and should be a new topic.

Were you able to get 802.11r working as per my response? Were you able to capture a sniffer trace?

---

<div class="post-metadata">

**Author:** ![ajudge](https://avatars.discourse-cdn.com/v4/letter/a/c2a13f/32.png) [@ajudge](https://community.morsemicro.com/u/ajudge)\
**Post date:** [June 12, 2026, 4:55pm UTC](https://community.morsemicro.com/t/ast-sta-roaming-802-11r-ft-between-two-halow-aps-handoff-fails-lands-then-deauths-within-3s/1707/5 "2026-06-12T16:55:00Z")

</div>

Regarding csa, check this thread for a command which worked: [ECSA - Extended Channel Switch Announcement is not working](https://community.morsemicro.com/t/ecsa-extended-channel-switch-announcement-is-not-working/217)

---

<div class="post-metadata">

**Author:** ![Asaftv](https://avatars.discourse-cdn.com/v4/letter/a/8491ac/32.png) [@Asaftv](https://community.morsemicro.com/u/Asaftv)\
**Post date:** [June 14, 2026, 7:51am UTC](https://community.morsemicro.com/t/ast-sta-roaming-802-11r-ft-between-two-halow-aps-handoff-fails-lands-then-deauths-within-3s/1707/6 "2026-06-14T07:51:33Z")

</div>

Hi,  
Thank you for your Help!

Hi Morse team,

Following up on the community thread:

> [@ECSA - Extended Channel Switch Announcement is not working](https://community.morsemicro.com/t/ecsa-extended-channel-switch-announcement-is-not-working/217):
>
> I am currently using the Morse Micro MM6108 HaLow in mesh mode. I am searching for a tool that can modify the channel and bandwidth through CSA (wireless beacons). We came across the ecsa\_info command with the ‘morsectrl/morse\_clil’ utility, which is intended to change the channel and bandwidth via the CSA beacon. However, when I tried using the ecsa\_info command, it did not change the channel and bandwidth as expected. ‘ecsa\_info’ help, morsectrl -i morse1 ecsa\_info --help ecsa\_info…

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.

== Hardware / firmware (both AP and STA) ==

Hardware: MM8108 EKH01  
Build: rel\_1\_17\_8\_2026\_Mar\_24

- hostapd\_s1g rel\_1\_17\_8\_2026\_Mar\_24-1
- wpa\_supplicant\_s1g rel\_1\_17\_8\_2026\_Mar\_24-1
- kmod-morse 5.15.189+rel\_1\_17\_8\_2026\_Mar\_24-1
- morse-fw-8108 rel\_1\_17\_8\_2026\_Mar\_24-1
- morsectrl rel\_1\_17\_8\_2026\_Mar\_24-1
- wpad-openssl 2023-09-08-e5ccbfc6-8
- morse-regdb v2.7.0-1
- kernel 5.15.189
- iw 5.19  
Regulatory: country=US, 8 MHz HaLow

== Test setup ==

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)

== chan\_switch command ==

$ hostapd\_cli\_s1g -i wlan0 chan\_switch 10 920500   
prim\_bandwidth=1 sec\_channel\_offset=1   
center\_freq1=924000 bandwidth=8  
OK

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:

channel 149 (5745 MHz), width: 160 MHz, center1: 5815 MHz

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

immediately followed by:

wpa\_supplicant\_s1g: wlan0: CTRL-EVENT-DISCONNECTED  
bssid=0c:bf:74:00:1f:05 reason=4  
locally\_generated=1

`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 ==

1. 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?

2. 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?

3. 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 ─────────────────

driver=nl80211  
logger\_syslog=127  
logger\_syslog\_level=2  
logger\_stdout=127  
logger\_stdout\_level=2  
country\_code=US  
hw\_mode=a  
channel=28  
chanlist=28  
op\_class=4  
s1g\_capab=[SHORT-GI-ALL]  
s1g\_prim\_chwidth=1  
s1g\_prim\_1mhz\_chan\_index=3

ieee80211ah=1

# anti-clogging does not work and creates issues in high station count networks (100+)

# This effectively disables it

anti\_clogging\_threshold=99999

interface=wlan0  
ctrl\_interface=/var/run/hostapd\_s1g  
ap\_isolate=1  
bss\_load\_update\_period=60  
chan\_util\_avg\_period=600  
disassoc\_low\_ack=0  
skip\_inactivity\_poll=0  
preamble=1  
wmm\_enabled=1  
ignore\_broadcast\_ssid=0  
uapsd\_advertisement\_enabled=1  
utf8\_ssid=1  
multi\_ap=0  
beacon\_int=100  
wpa\_group\_rekey=604800  
nas\_identifier=0cbf74001f05  
sae\_require\_mfp=1  
wpa\_passphrase=  
sae\_password=  
wpa\_psk\_file=/var/run/hostapd-wlan0.psk  
auth\_algs=1  
wpa=2  
wpa\_pairwise=CCMP  
ssid=g7-AP-00000001  
bridge=br-lan  
wds\_bridge=  
wnm\_sleep\_mode=1  
bss\_transition=1  
rrm\_neighbor\_report=1  
rrm\_beacon\_report=1  
mobility\_domain=a1b2  
ft\_psk\_generate\_local=0  
ft\_over\_ds=0  
reassociation\_deadline=20000  
r1\_key\_holder=0cbf74001f05  
r0\_key\_lifetime=10000  
pmk\_r1\_push=0  
r0kh=ff:ff:ff:ff:ff:ff \* 80ab93aff49137476a8acededb853f3a  
r1kh=00:00:00:00:00:00 00:00:00:00:00:00 80ab93aff49137476a8acededb853f3a  
wpa\_disable\_eapol\_key\_retries=0  
wpa\_key\_mgmt=SAE FT-SAE  
okc=1  
ieee80211w=2  
group\_mgmt\_cipher=AES-128-CMAC  
qos\_map\_set=0,0,2,16,1,1,255,255,18,22,24,38,40,40,44,46,48,56

# (TX queue / WMM blocks omitted for brevity — defaults)

wds\_sta=1  
bssid=0c:bf:74:00:1f:05  
sae\_pwe=0  
dpp\_configurator\_connectivity=1  
raw=0

───────────────── 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

Thanks,

---

<div class="post-metadata">

**Author:** ![Asaftv](https://avatars.discourse-cdn.com/v4/letter/a/8491ac/32.png) [@Asaftv](https://community.morsemicro.com/u/Asaftv)\
**Post date:** [June 14, 2026, 3:36pm UTC](https://community.morsemicro.com/t/ast-sta-roaming-802-11r-ft-between-two-halow-aps-handoff-fails-lands-then-deauths-within-3s/1707/7 "2026-06-14T15:36:17Z")

</div>

Hi Ajudge,  
Thank you for your support.

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.

```auto

# 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:

1. `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`.

2. `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

> Role  
> |   
> IP  
> |   
> Board  
> |   
> Kernel  
> |   
> Driver  
> |
> 
> - | - | - | - | - |  
>   
> STA  
> |   
> 192.168.1.201  
> |   
> EKH01 (MM8108)  
> |   
> `5.15.189` `aarch64`  
> |   
> `morse.ko` 678376 B, dated Apr 2 2026 (stock, identical to `/rom/`)  
> |  
>   
> AP  
> |   
> 192.168.1.203  
> |   
> EKH01 (MM8108)  
> |   
> `5.15.167` `aarch64`  
> |   
> `morse.ko` stock 641280 B, dated Sep 19 2025  
> |  
>   
> AP  
> |   
> 192.168.1.200  
> |   
> Older MM6108 carrier  
> |   
> `5.15.189` `MIPS32`  
> |   
> morse.ko stock  
> |  
>   
> AP  
> |   
> 192.168.1.202  
> |   
> Older MM6108 carrier  
> |   
> `5.15.189` `MIPS32`  
> |   
> morse.ko stock  
> |

`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`)

```auto

wpa_key_mgmt = WPA-PSK FT-PSK # we also tried SAE FT-SAE - same result
ieee80211r = 1
mobility_domain = a1b2
r1_key_holder = <AP-MAC-no-colons>
nas_identifier = <AP-MAC-no-colons>
r0_key_lifetime = 10000
reassociation_deadline = 20000
ft_psk_generate_local = 1 # 1 for FT-PSK (your sample); 0 for FT-SAE
pmk_r1_push = 0
ft_over_ds = 0
sae_require_mfp = 1
sae_pwe = 0 # your 2026-06 fix
disable_pmksa_caching = 0
okc = 1
bss_transition = 1
ieee80211k = 1
rrm_neighbor_report = 1
rrm_beacon_report = 1
disassoc_low_ack = 0

```

STA side (supplicant.conf, generated by netifd from uci)

```auto

country = US
sae_pwe = 0
network = {
    key_mgmt = WPA-PSK FT-PSK
    psk = "<32-char>"
    pairwise = CCMP
    proto = RSN
    ieee80211w = 2
    bssid = <target>
    scan_ssid = 1
    ...
}

```

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:

```auto

hostapd_cli_s1g -i wlan0 chan_switch 30 921000 \
    prim_bandwidth=2 sec_channel_offset=1 \
    center_freq1=924000 bandwidth=8
→ FAIL

```

`logread` on the AP:

```auto

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:

```auto

phy#0 (self-managed)
country US: DFS-invalid
    (920 - 928 @ 8), (N/A, 36), (N/A), AUTO-BW <-- CH_44 block, 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

1. 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.

2. `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.

3. 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.

4. `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](mailto:asaf@guardian7.co) Guardian7 — EKH01 deployment  
Appendix A — Full STA logread (.201) around the FT failure

```auto

# 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

```auto

[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.

```auto

driver=nl80211
country_code=US
hw_mode=a
channel=28
op_class=71
s1g_capab=[SHORT-GI-ALL]
s1g_prim_chwidth=1
s1g_prim_1mhz_chan_index=3
ieee80211ah=1
anti_clogging_threshold=99999

interface=wlan0
ctrl_interface=/var/run/hostapd_s1g
ap_isolate=1
disassoc_low_ack=0
ignore_broadcast_ssid=0
utf8_ssid=1
beacon_int=100
wpa_group_rekey=604800
nas_identifier=502e91d2c659
wpa_passphrase=8Fk7Tq2RmZ9pVnXc4HsLwB6jNyU3DeYa
sae_password=8Fk7Tq2RmZ9pVnXc4HsLwB6jNyU3DeYa
wpa_psk_file=/var/run/hostapd-wlan0.psk
auth_algs=1
wpa=2
wpa_pairwise=CCMP
ssid=g7-AP
bridge=br-lan
wnm_sleep_mode=1
bss_transition=1
rrm_neighbor_report=1
rrm_beacon_report=1
mobility_domain=a1b2
ft_psk_generate_local=1
ft_over_ds=0
reassociation_deadline=20000
wpa_disable_eapol_key_retries=0
wpa_key_mgmt=WPA-PSK FT-PSK
okc=0
disable_pmksa_caching=1
bssid=50:2e:91:d2:c6:59
sae_pwe=0

```

(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)

```auto

country=US
ctrl_interface=/var/run/wpa_supplicant_s1g
sae_pwe=0

network={
    scan_ssid=1
    ssid="g7-AP"
    key_mgmt=WPA-PSK FT-PSK
    psk="8Fk7Tq2RmZ9pVnXc4HsLwB6jNyU3DeYa"
    pairwise=CCMP
    proto=RSN
    bssid=50:2e:91:d2:c6:59
}

```

The STA uci sets `ieee80211r=1`, which netifd translates into the `WPA-PSK FT-PSK` `key_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
