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

Hi,
Thank you for your Help!

Hi Morse team,

Following up on the community thread:

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,