OpenWiFi roam matrix — 188n-flush-roamback

67 trials · roam mode · 2026-09-15 17:54 · 12 min

What this measured

A single client was driven between every pair of BSSIDs in the testbed and each transition timed from the ROAM command to the CTRL-EVENT-CONNECTED event. Trials were interleaved across pairs rather than run in blocks, so anything drifting over the run spreads across all groups instead of loading onto one.

The comparison that matters is a cross-radio roam within one AP against the same 2.4↔ 5 GHz transition between two APs. The client does identical work either way; the only difference is whether the two radios share one ath11k_base.

ipq6018

Cross-radio roams on the same AP are not materially worse than the same transition between two APs (median 0.98s vs 1.03s, completion 95% vs 100%). On this chipset the shared peer table is not costing anything measurable.

Dataplane after the roam

Every completed roam is followed by a real DHCP exchange from the client. This is a forwarding test, not a DHCP test: sdan drops a downstream frame whose destination MAC is absent from the MAC table for that VLAN, so a station that is associated and authorized but missing from the table receives nothing — the server answers every message and the client keeps asking. That failure is only visible from the client.

11 of 66 completed roams could not get a lease

These stations finished the 802.11 transition and then had no working dataplane. That is the reported symptom, reproduced.

Chipset / classRoamsGot a leaseNo leasemedian DHCPmax DHCP
ipq6018 / inter-ap-cross-band2015 (75%)50.30s0.40s
ipq6018 / intra-ap-cross-radio1919 (100%)00.30s0.40s
ipq6018 / inter-ap-same-band-diff-channel107 (70%)30.30s0.40s
ipq6018 / inter-ap-same-channel107 (70%)30.30s0.40s
ipq6018 / static-control77 (100%)00.30s0.30s

Roams that completed but had no dataplane

#ClassFromToRoamReason
11inter-ap-cross-band188n-96/5188n-99/2.41.78sno-lease(rc=1)
12inter-ap-cross-band188n-99/2.4188n-96/51.76sno-lease(rc=1)
20inter-ap-same-band-diff-channel188n-96/5188n-99/52.00sno-lease(rc=1)
25inter-ap-cross-band188n-99/5188n-96/2.41.80sno-lease(rc=1)
26inter-ap-cross-band188n-96/2.4188n-99/51.79sno-lease(rc=1)
28inter-ap-same-channel188n-96/2.4188n-99/2.41.79sno-lease(rc=1)
29inter-ap-same-channel188n-99/2.4188n-96/2.41.77sno-lease(rc=1)
36inter-ap-same-band-diff-channel188n-99/5188n-96/52.03sno-lease(rc=1)
39inter-ap-cross-band188n-99/5188n-96/2.41.80sno-lease(rc=1)
54inter-ap-same-band-diff-channel188n-99/5188n-96/51.99sno-lease(rc=1)
60inter-ap-same-channel188n-96/2.4188n-99/2.41.80sno-lease(rc=1)

By roam class

GroupTrialsCompleted≤2s≤5smedianp90max
inter-ap-cross-band
The same 2.4↔ 5 GHz transition, but between two APs — separate ath11k instances, so no shared peer table. The control that matters.
2020 (100%)20 (100%)20 (100%)1.03s1.80s1.80s
intra-ap-cross-radio
Both radios of one AP. On a shared-peer-table SoC this is the only path where a cross-radio peer delete can be attributed to the wrong radio.
2019 (95%)19 (95%)19 (95%)0.98s1.19s1.24s
inter-ap-same-band-diff-channel
Two APs, same band, different channel. A re-tune without a band change.
1010 (100%)9 (90%)10 (100%)1.03s2.03s2.03s
inter-ap-same-channel
Two APs on one channel. No re-tune at all, so it answers “does roaming between these APs work” without isolating anything.
1010 (100%)10 (100%)10 (100%)0.87s1.80s1.80s
static-control70 (0%)0 (0%)0 (0%)———

By BSSID pair

GroupTrialsCompleted≤2s≤5smedianp90max
(none) → 188n-96/2.430 (0%)0 (0%)0 (0%)———
(none) → 188n-96/520 (0%)0 (0%)0 (0%)———
(none) → 188n-99/520 (0%)0 (0%)0 (0%)———
188n-96/2.4 → 188n-96/555 (100%)5 (100%)5 (100%)1.01s1.05s1.05s
188n-96/2.4 → 188n-99/2.455 (100%)5 (100%)5 (100%)0.76s1.80s1.80s
188n-96/2.4 → 188n-99/555 (100%)5 (100%)5 (100%)1.09s1.79s1.79s
188n-96/5 → 188n-96/2.454 (80%)4 (80%)4 (80%)0.93s1.00s1.00s
188n-96/5 → 188n-99/2.455 (100%)5 (100%)5 (100%)0.75s1.78s1.78s
188n-96/5 → 188n-99/555 (100%)5 (100%)5 (100%)1.03s2.00s2.00s
188n-99/2.4 → 188n-96/2.455 (100%)5 (100%)5 (100%)0.87s1.77s1.77s
188n-99/2.4 → 188n-96/555 (100%)5 (100%)5 (100%)1.03s1.76s1.76s
188n-99/2.4 → 188n-99/555 (100%)5 (100%)5 (100%)1.11s1.24s1.24s
188n-99/5 → 188n-96/2.455 (100%)5 (100%)5 (100%)0.89s1.80s1.80s
188n-99/5 → 188n-96/555 (100%)4 (80%)5 (100%)1.03s2.03s2.03s
188n-99/5 → 188n-99/2.455 (100%)5 (100%)5 (100%)0.97s0.99s0.99s

Failures

ModeCountShare of all trials
landed_on_other(d4:ba:ba:a3:db:fb)11.5%

stayed_on_source the client never left the old BSS. landed_on_other it moved somewhere unasked. ended_disconnected it fell off entirely. roam_rejected wpa_supplicant refused the command, usually a target missing from the scan cache.

Testbed

BSSIDAPChipsetBandFreq
d4:ba:ba:ab:ba:ab188n-99ipq60182.4 GHz2437 MHz
d4:ba:ba:ab:ba:aa188n-99ipq60185 GHz5785 MHz
d4:ba:ba:ab:ce:6d188n-96ipq60182.4 GHz2437 MHz
d4:ba:ba:ab:ce:6c188n-96ipq60185 GHz5180 MHz
SSID
OW mPSK WPA2
Client MAC
02:03:7f:12:97:21
Client iface
sta0
Trials per pair
5
Shuffle seed
1
Roam cap (s)
25.0

Chipset topology is read from sysfs, not inferred from the model name: on IPQ6018 both phy0 and phy1 resolve to soc/c000000.wifi, while on IPQ5018 phy1 resolves to soc:wifi1@c000000 — a separate device with its own peer table.

Method

All trials

Expand 67 trials
#RoundClassFromToLatencyOutcome
11inter-ap-cross-band188n-96/2.4188n-99/51.06scompleted
21intra-ap-cross-radio188n-96/5188n-96/2.40.68scompleted
31intra-ap-cross-radio188n-99/2.4188n-99/51.19scompleted
41intra-ap-cross-radio188n-96/2.4188n-96/51.01scompleted
51inter-ap-same-band-diff-channel188n-99/5188n-96/51.03scompleted
61inter-ap-same-channel188n-96/2.4188n-99/2.40.74scompleted
71intra-ap-cross-radio188n-99/5188n-99/2.40.99scompleted
81inter-ap-same-band-diff-channel188n-96/5188n-99/51.03scompleted
91static-control(none)188n-99/5—completed
101inter-ap-cross-band188n-99/5188n-96/2.40.71scompleted
111inter-ap-same-channel188n-99/2.4188n-96/2.40.97scompleted
121inter-ap-cross-band188n-96/5188n-99/2.41.78scompleted
131inter-ap-cross-band188n-99/2.4188n-96/51.76scompleted
142intra-ap-cross-radio188n-96/2.4188n-96/50.93scompleted
152intra-ap-cross-radio188n-96/5188n-96/2.40.64scompleted
162inter-ap-cross-band188n-99/5188n-96/2.40.89scompleted
172inter-ap-same-channel188n-99/2.4188n-96/2.40.74scompleted
182static-control(none)188n-96/2.4—completed
192inter-ap-cross-band188n-99/2.4188n-96/51.00scompleted
202intra-ap-cross-radio188n-99/5188n-99/2.40.75scompleted
212inter-ap-same-band-diff-channel188n-99/5188n-96/51.00scompleted
222inter-ap-same-band-diff-channel188n-96/5188n-99/52.00scompleted
232inter-ap-cross-band188n-96/5188n-99/2.40.75scompleted
242inter-ap-same-channel188n-96/2.4188n-99/2.40.69scompleted
252intra-ap-cross-radio188n-99/2.4188n-99/51.24scompleted
262inter-ap-cross-band188n-96/2.4188n-99/50.76scompleted
272static-control(none)188n-99/5—completed
283inter-ap-cross-band188n-99/5188n-96/2.41.80scompleted
293inter-ap-cross-band188n-96/2.4188n-99/51.79scompleted
303inter-ap-cross-band188n-99/2.4188n-96/51.21scompleted
313inter-ap-same-channel188n-96/2.4188n-99/2.41.79scompleted
323inter-ap-same-channel188n-99/2.4188n-96/2.41.77scompleted
333intra-ap-cross-radio188n-96/5188n-96/2.41.00scompleted
343intra-ap-cross-radio188n-99/5188n-99/2.40.73scompleted
353intra-ap-cross-radio188n-96/2.4188n-96/51.03scompleted
363static-control(none)188n-96/5—completed
373inter-ap-cross-band188n-96/5188n-99/2.40.78scompleted
383inter-ap-same-band-diff-channel188n-96/5188n-99/50.93scompleted
393intra-ap-cross-radio188n-99/2.4188n-99/51.02scompleted
403inter-ap-same-band-diff-channel188n-99/5188n-96/52.03scompleted
414inter-ap-same-channel188n-96/2.4188n-99/2.40.76scompleted
424intra-ap-cross-radio188n-99/2.4188n-99/50.97scompleted
434inter-ap-cross-band188n-99/5188n-96/2.41.80scompleted
444intra-ap-cross-radio188n-96/5188n-96/2.40.93scompleted
454static-control(none)188n-96/2.4—completed
464inter-ap-same-band-diff-channel188n-99/5188n-96/50.92scompleted
474inter-ap-same-channel188n-99/2.4188n-96/2.40.87scompleted
484inter-ap-cross-band188n-99/2.4188n-96/50.93scompleted
494inter-ap-same-band-diff-channel188n-96/5188n-99/51.05scompleted
504inter-ap-cross-band188n-96/5188n-99/2.40.61scompleted
514inter-ap-cross-band188n-96/2.4188n-99/51.09scompleted
524intra-ap-cross-radio188n-99/5188n-99/2.40.97scompleted
534intra-ap-cross-radio188n-96/2.4188n-96/51.05scompleted
544static-control(none)188n-96/5—completed
555inter-ap-cross-band188n-96/5188n-99/2.40.71scompleted
565intra-ap-cross-radio188n-96/5188n-96/2.4—landed_on_other(d4:ba:ba:a3:db:fb)
575inter-ap-cross-band188n-96/2.4188n-99/51.17scompleted
585intra-ap-cross-radio188n-99/5188n-99/2.40.98scompleted
595inter-ap-same-band-diff-channel188n-96/5188n-99/50.91scompleted
605inter-ap-same-band-diff-channel188n-99/5188n-96/51.99scompleted
615intra-ap-cross-radio188n-99/2.4188n-99/51.11scompleted
625inter-ap-cross-band188n-99/5188n-96/2.40.61scompleted
635static-control(none)188n-96/2.4—completed
645inter-ap-cross-band188n-99/2.4188n-96/51.03scompleted
655inter-ap-same-channel188n-99/2.4188n-96/2.40.73scompleted
665intra-ap-cross-radio188n-96/2.4188n-96/50.92scompleted
675inter-ap-same-channel188n-96/2.4188n-99/2.41.80scompleted