Skip to content

mac80211 CSA finalize failure on EKH01 REPEATER — single radio AP+STA disconnects all clients #5

Description

@AsafTv

Describe the bug

Hi Morse Micro Support,

We're seeing a reproducible kernel-level bug on the EKH01 that breaks CSA propagation in REPEATER mode. Every time the upstream AP announces a channel switch, the REPEATER's downstream AP kicks all its associated clients off. This is blocking REPEATER deployments for us; would appreciate a workaround or a confirmation that a fix is in flight.

Setup

Hardware: MM8108-EKH01 (RPi 4 + Morse SDIO)
Firmware: official openwrt-morse-2.9.3-mmx108-ekh01-sdio-squashfs-sysupgrade.img.gz
Stack: OpenWrt 23.05.5, kernel 5.15.167, backports-6.1.110-1, morse_driver 1.17.8, hostapd_s1g 2.12-rel_1_16_4
Topology: shared-radio REPEATER — wlan0 = STA uplink to a root AP, wlan1 = AP downlink serving clients
The bug

When the upstream root AP announces CSA, mac80211 correctly auto-propagates the channel switch to the AP vif (wlan1) on the same wiphy. Because hostapd never initiated this CSA, it never populated sdata->deflink.u.ap.next_beacon. In __ieee80211_csa_finalize() → ieee80211_set_after_csa_beacon() (net/mac80211/cfg.c around line 3565):

case NL80211_IFTYPE_AP:
if (!sdata->deflink.u.ap.next_beacon)
return -EINVAL;
…returns -EINVAL → __ieee80211_csa_finalize propagates the error → cfg80211_stop_iface(wlan1) runs → every STA associated to the downstream AP is force-disconnected.

Observed in logread on the REPEATER:

hostapd_s1g: wlan1: CTRL-EVENT-STARTED-CHANNEL-SWITCH freq=5250 ht_enabled=0 ...
kernel: morse: pre_channel_switch: count=10, target_freq=5250 MHz, blockTX=0
kernel: morse: channel_switch_beacon: target_freq=5250 MHz
kernel: wlan1: failed to finalize CSA, disconnecting
kernel: wlan1: failed to finalize CSA, disconnecting
Net effect: instead of the zero-handoff CSA should deliver, every downstream STA loses link for 2–10 s while it scans + reassociates. For deployments with multiple hops, the disruption multiplies.

Reproducer

Two EKH01 boards on the same SSID — one root AP (wlan0 mode=ap), one REPEATER (wlan0 mode=sta + wlan1 mode=ap, both bound to the same radio0)
A third board (any HaLow STA) associated to the REPEATER's wlan1
On the root AP:

hostapd_cli_s1g -i wlan0 chan_switch 10 5250
On the REPEATER, logread shows the failed to finalize CSA, disconnecting lines above.
The STA client on wlan1 loses association and re-scans.
What we tried

Patched ieee80211_set_after_csa_beacon to handle the NULL-next_beacon case without returning -EINVAL: set *changed |= BSS_CHANGED_BEACON and break so the finalize flow continues normally. The patch builds cleanly and the marker shows up in the compiled mac80211.ko, but the resulting image kernel-panics at boot. Side effects of the auto-propagation path beyond set_after_csa_beacon clearly need handling we don't fully grok — we're not deep enough in your __ieee80211_csa_finalize consumers to know what else needs to be initialized when the AP vif gets here without hostapd having driven the CSA.

We also rebuilt your release source (MorseMicro/openwrt @ 2.9.3 tag) with no patches and the resulting image still boots into a kernel panic, which makes us think our build environment isn't fully reproducing your release pipeline. If you can share the exact build script / config used to produce the official openwrt-morse-2.9.3-mmx108-ekh01-sdio-squashfs-sysupgrade.img.gz, that alone would unblock us to iterate on a fix locally.

Asks

Is this bug known? Is there a patch already in flight (a later 2.x release, an internal branch)?
Any workaround at the hostapd or uci layer to avoid the auto-propagation finalize path?
The build instructions / config used to produce the 2.9.3 EKH01 release image, so we can reproduce it locally and iterate on patches against your exact baseline.
Timeline for an official fix in a release if one isn't ready yet.
Happy to share full dmesg, logread capture, the patch we attempted, or jump on a call. This is the gating issue for our REPEATER deployments, so we'd appreciate it being prioritised.

Thanks!

Best,
Asaf Tov
asaf@guardian7.co
Guardian7

OpenWrt version

openwrt-morse-2.9.3-mmx108-ekh01-sdio-squashfs-sysupgrade.img.gz

OpenWrt target/subtarget

bcm27xx/bcm2711

Device

EKH01

Image kind

Official downloaded image

Steps to reproduce

Hardware: Two MM8108-EKH01 boards (root AP + REPEATER) + one HaLow STA client.
Firmware: official openwrt-morse-2.9.3-mmx108-ekh01-sdio-squashfs-sysupgrade.img.gz
(kernel 5.15.167, backports-6.1.110-1, morse_driver 1.17.8,
hostapd_s1g 2.12-rel_1_16_4)

  1. Flash the official Morse 2.9.3 sysupgrade image to two EKH01 boards.
    Label them: AP (will be root AP) and REPEATER.

  2. Configure the AP board — single AP vif on radio0:
    wireless.default_radio0.mode='ap'
    wireless.default_radio0.ssid='test-halow'
    wireless.default_radio0.encryption='sae'
    wireless.default_radio0.key='<any 32-char key>'
    wireless.default_radio0.network='lan'
    uci commit wireless && wifi up

  3. Configure the REPEATER board — disable default_radio0, add two ifaces
    bound to the same radio0:
    wireless.repeater_uplink = wifi-iface (mode=sta, 4addr=on,
    ssid='test-halow',
    encryption=sae,
    key='',
    network=lan)
    wireless.repeater_downlink = wifi-iface (mode=ap, wds=1,
    ssid='test-halow',
    encryption=sae,
    key='',
    network=lan)
    uci commit wireless && wifi up
    → Verify iw dev shows wlan0 type managed (uplink to AP) + wlan1
    type AP (serving downstream).

  4. Bring a third HaLow STA client up against the REPEATER:
    iw dev link → must show "Connected to "

  5. Trigger CSA from the root AP (move from CH_28 to CH_12 at 8 MHz):
    ssh root@
    hostapd_cli_s1g -i wlan0 chan_switch 10 5250

EXPECTED:

  • Root AP announces CSA in beacons (counter 10 → 0).
  • REPEATER's wlan0 (STA) follows the switch.
  • REPEATER's wlan1 (AP, same wiphy, same radio) updates beacons
    and the third-board client stays associated through the switch.
  • Result: clean zero-handoff CSA across the chain.

ACTUAL:

  • Root AP CSA works fine for its directly-associated STAs.
  • REPEATER's wlan0 follows.
  • REPEATER's wlan1 raises "failed to finalize CSA, disconnecting"
    (see logread excerpt below) and force-disconnects all its
    associated STAs.
  • Third-board client loses link for ~2–10 s while it rescans and
    reassociates.

REPEATER logread excerpt at time of CSA:
hostapd_s1g: wlan1: CTRL-EVENT-STARTED-CHANNEL-SWITCH freq=5250 ht_enabled=0 ch_width=20 MHz cf1=5250 cf2=0
kernel: morse: pre_channel_switch: count=10, target_freq=5250 MHz, blockTX=0
kernel: morse: channel_switch_beacon: target_freq=5250 MHz
kernel: wlan1: failed to finalize CSA, disconnecting
kernel: wlan1: failed to finalize CSA, disconnecting

ROOT CAUSE (confirmed by code inspection — net/mac80211/cfg.c
in __ieee80211_csa_finalize() → ieee80211_set_after_csa_beacon()):

case NL80211_IFTYPE_AP:
if (!sdata->deflink.u.ap.next_beacon)
return -EINVAL; // ← fires here

When mac80211 auto-propagates CSA from the STA vif (wlan0) to the
sibling AP vif (wlan1) on the same wiphy, hostapd never received an
NL80211_CMD_CHANNEL_SWITCH for wlan1, so next_beacon is NULL.
The -EINVAL then trips cfg80211_stop_iface() on the AP vif, killing
every downstream STA.

Actual behaviour

No response

Expected behaviour

No response

Additional info

No response

Diffconfig

N/A — running the official, unmodified Morse 2.9.3 release image:
openwrt-morse-2.9.3-mmx108-ekh01-sdio-squashfs-sysupgrade.img.gz

No custom build, no patches, no diffconfig modifications. The bug
reproduces with the released binary as-is. Standard `wifi-iface`
configurations for repeater_uplink + repeater_downlink (both on
radio0), defaults otherwise.

Terms

  • I am reporting an issue for OpenWrt, not an unsupported fork.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions