Skip to content

Band downsteer - #24

Open
rdmitry0911 wants to merge 6 commits into
openwrt:masterfrom
rdmitry0911:band-downsteer
Open

Band downsteer#24
rdmitry0911 wants to merge 6 commits into
openwrt:masterfrom
rdmitry0911:band-downsteer

Conversation

@rdmitry0911

Copy link
Copy Markdown

No description provided.

rdmitry0911 and others added 6 commits September 5, 2026 11:00
usteer's band steering only moves clients UP (2.4 -> 5/6 GHz). A client that
camps on a weak 6 GHz signal is never moved down, even when the same AP's
5 GHz would be far stronger, because roaming only steers to candidates whose
per-STA signal usteer has measured, and a client glued to 6 GHz is not heard
on the lower bands.

Add an opt-in fallback: when the roam state machine reaches SCAN_DONE with no
measured better candidate and the client sits on an upper band (freq > 4000)
below the new band_downsteer_snr threshold, send a directed BSS-TM request to
the next-lower band of the SAME AP (6->5, then 5->2.4). Measured roaming to
another AP keeps priority; down-steering only runs when usteer would otherwise
give up. min_snr / min_connect_snr on the upper band prevent an immediate
bounce back.

Also wire the new option through the OpenWrt init script and document it in
the sample config and README.

Verified on a 4x Airoha AN7581 (MT7996) mesh with an iPhone that otherwise
clung to 6 GHz at -85 dBm: the client is moved to the same AP's 5 GHz and
streams normally.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FT9j3wHzwrFbMaxRdn5x3T
On a fluctuating signal a down-steered client could bounce straight back up to
the weak band as soon as its signal briefly peaked above the threshold. Add a
time-based hold: for band_downsteer_hold ms after a down-steer, refuse
probe/assoc for any band higher than the one the client was moved to. This is
hysteresis independent of the instantaneous signal, so brief peaks no longer
pull the client back up.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FT9j3wHzwrFbMaxRdn5x3T
Refuse association to an upper band (>2.4 GHz) on ANY node when the client
signal is below assoc_min_snr; 2.4 GHz is exempt so a client that is weak on
all upper bands still has a landing band and cannot be locked out. Enforced
independently of assoc_steering. Admission-only: never kicks a connected
client, so unlike min_snr it cannot cause an assoc/kick storm.

Closes the cross-AP gap that per-AP band_downsteer_hold cannot: the hold stops
bounce-back to the SAME AP upper band, assoc_min_snr stops a jump to another
node upper band that is equally weak.
After a down-steer BSS-TM, if band_downsteer_disassoc (ms) is set and the client
is still on the upper band after that delay, kick it. Handles clients (notably
iOS) that ignore the gentle BSS-TM and cling to a dying upper band. Safe with
assoc_min_snr: the kicked client cannot reassociate to the weak upper band, so
it lands on 2.4/5 GHz and cannot bounce back -- no kick storm (unlike min_snr).
0 = gentle (suggestion only, previous behaviour).
When a client rejects a BSS-TM (status_code != 0), keep the already-scheduled
fallback kick instead of cancelling it. Cancelling left stubborn clients
(notably iPhones) stuck for minutes on soft-steering retries and defeated the
forced band-downsteer, which relies on kick_time. Ask nicely first, deauth if
the client refuses.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JWdWhnrgq2Mq8nuuMmtsNL
The band_steering_signal_threshold field existed in the config struct,
was referenced by band_steering.c, listed in the init.d option loop and
documented in config/usteer -- but it was MISSING from the ubus.c _cfg
config table. So set_config silently dropped it: uci could never change
it and the daemon always used the hardcoded main.c default of 5.

With threshold=5 the up-steer (band_steering) only fires when a client's
signal has risen >5 dB above its tracked minimum (i.e. it is physically
approaching the AP); a client that connected already-strong on 2.4 GHz
and stays put is never steered up. Exposing the knob lets it be set to 0,
which disables that "signal must be improving" gate and up-steers any
BSS-TM-capable client whose 2.4 GHz signal is >= band_steering_min_snr.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JWdWhnrgq2Mq8nuuMmtsNL
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