Skip to content

WiFi Advanced: MLO switch, on FLWRT 2.0's X_LINKSYS_Mesh (ref FWDEV#201) #1692

Description

@AustinChangLinksys

Ref linksys/FWDEV#201 (FW's contract of 2026-10-09). Parity row: linksys/Architecture#210, WiFi — MLO (fronthaul + backhaul, SLO fallback).

This is the MLO part of #856, split out the way steering was (#1661). The MLO client display, MLO (<bands>) on a device, is a different change and lives in #1686.

FW contract

Leaf Access Meaning
Device.X_LINKSYS_Mesh.MLOEnabled writable bool, default off one switch for the whole mesh, set on the controller only
Device.X_LINKSYS_Mesh.MLOStatus read-only Disabled / Active / Inactive (on, but the bands' SSID, password or security are not compatible)

A change restarts Wi-Fi for about 60 s. Read MLOStatus again after that.

Measured on the bench

FW 2.0.3.26101472 (HW1, single node), 2026-10-15, through the app's WASM client and usp-bridge.

  • Read: MLOEnabled is xsd:boolean, writable, and reads 0. MLOStatus is xsd:string, read-only, and reads Disabled. Both are served by dm-reflector, like the steering leaves.
  • MLO + DFS in one Set ({MLOEnabled: 1, Radio.1/2.IEEE80211hEnabled: 1}, allowPartial: true): accepted, all three applied, and Wi-Fi reloaded once. The reply came after 19.9 s. MLOStatus read Inactive 10 s later and stayed there, which is expected: the bench's two main bands share an SSID but are WPA2-Personal.
  • The same leaves in two Sets (MLO, then DFS) also reloaded once. But the MLO Set was answered in 166 ms, and its reload started 71 s later.

Not measured: Active (needs the same password and WPA3 on both bands), MLO together with steering, and why the reload after the MLO-only Set came 71 s late.

To do

  1. A definition of its own (wifi/mesh_mlo.yaml, linksys/usp_framework branch feat/mlo-switch-definition), not in mesh_steering.yaml. Its two leaves are required, and its header says a write does not restart Wi-Fi. With MLO in it, firmware without MLO would make the steering switches fail to read too. In PrivacyGUI, generate only this definition with the vendored 0.17.0, as feat(advanced, wifi): UPnP switch and client/node steering switches (#1660, #1661) #1674 did for steering.
  2. One Set for the whole tab. Steering, MLO and DFS go out in one Set with allowPartial: true. Today steering and DFS are two Sets (feat(advanced, wifi): UPnP switch and client/node steering switches (#1660, #1661) #1674), and DFS uses allowPartial: false.
  3. A save that restarts Wi-Fi waits for the restart. feat(advanced, wifi): UPnP switch and client/node steering switches (#1660, #1661) #1674's changesDfs grows into "does this save restart Wi-Fi?", true when MLO or DFS changes. Such a save goes the DFS way (Wi-Fi restart, then reconnect), not the steering way (applies at once). Because the reload can start long after the reply (71 s above), the read-back must not finish before it.
  4. Show MLOStatus. On Inactive, say why. FW suggests: "Use the same Wi-Fi name, password and WPA3 security on 2.4 GHz and 5 GHz."

Depends on

  • FW: linksys/FWDEV#201's PRs merged on 2026-10-14 (linksys/targets#269, linksys/feed_core#36, linksys/feed_premium#55, linksys/feed_usp#49, linksys/feed_uspapi#40). Local build 2.0.3.26101472 carries them.
  • linksys/usp_framework: the mesh_mlo.yaml PR.
  • One node is enough to verify. Switching restarts Wi-Fi, so measure over a cable.

Acceptance criteria

  • The switch turns MLO on and off, and the status is right after the restart.
  • Inactive shows its hint. With the same SSID, password and WPA3 on both bands, the status reads Active.
  • A save that changes MLO, DFS and steering together sends one Set and restarts Wi-Fi once.
  • A part refused within that Set shows as a failed save, not as saved.
  • On firmware without MLO, steering and DFS still read and write.

Post-merge recheck

Activity

  1. added
    enhancementNew feature or request
    feature:wifiWiFi configuration and management
    blocked:fw-supportBlocked — requires firmware team support
    2.xLabeled for 2.x version
    FLWRT-2.0Labeled belonging on FLWRT-2.0
    and removed
    blocked:fw-supportBlocked — requires firmware team support
    on Oct 15, 2026
  2. AustinChangLinksys commented on Oct 15, 2026

    @AustinChangLinksys
    CollaboratorAuthor

    Automated triage

    Classification: enhancement (feature:wifi), USP/TR-181 protocol-layer change → 2.x line. The line is decidable here because the ticket reads/writes Device.X_LINKSYS_Mesh.* (TR-181 / generated USP code, which 1.x does not have). (author=Austin — self-filed tracking item, may already be in progress)

    Codebase findings (checked on origin/dev-2.7.3, the newest line):

    • No MLO switch exists yet: grep MLO over lib/page/wifi_settings and lib/generated/mesh_steering.g.dart returns nothing. The only MLO hit in generated code is the unrelated Device.WiFi.Templates.APMLDTemplate.{i}.MLOEnable (lib/generated/tr181_paths.g.dart:18825).
    • Only lib/generated/mesh_steering.g.dart exists under lib/generated/mesh*, so mesh_mlo.g.dart has to be generated (To-do 1).
    • usp_wifi_advanced_provider.dart:109: if (!state.changesDfs) return;, with changesDfs at wifi_advanced_feature_state.dart:44. This is the flag the ticket wants widened to "does this save restart Wi-Fi?" (To-do 3).
    • usp_wifi_advanced_service.dart:65: the comment says the DFS write is not allowPartial, which matches the ticket's "DFS uses allowPartial: false". Moving to one Set with allowPartial: true (To-do 2) changes that contract.
    • wifiWriteConfirmProvider exists (wifi_write_confirm_provider.dart:114) and is used in usp_wifi_advanced_provider.dart:256, so the read-back mentioned in To-do 2 is reachable.
    • usp-definitions/wifi/mesh_steering.yaml:7 says a write does not restart Wi-Fi, which supports keeping MLO in its own definition.
    • Not verified: the feat/mlo-switch-definition branch in usp_framework, and anything about MLOStatus on firmware without MLO.

    Blockers / open questions:

    Suggested roles: 2x-dev, 2x-verify

    Automated triage by gate.py. Dispatch requires Austin's authorization.

  3. added
    triagedAutomated diagnosis complete; root cause investigated (bug lane entry)
    on Oct 15, 2026
  4. AustinChangLinksys commented on Oct 18, 2026

    @AustinChangLinksys
    CollaboratorAuthor

    Implemented on feat/1692-mlo-switch (PR to follow). The definition is linksys/usp_framework#86. Bench results and the ticket corrections below.

    Bench, 2026-10-16 (FW 2.0.3.26101472, single node, Mac on Ethernet)

    Save Answer Radios MLOStatus
    MLO on, bands WPA2 2.2 s not restarted (110 s watched) Inactive at once
    MLO off, bands WPA2 3.2 s not restarted Disabled at once
    MLO on, both bands WPA3-Personal with one password 3.3 s both restarted, up 4.7 s / 8.8 s after the Set Active at 9.8 s
    MLO off + DFS on + client steering on, one Set 30.4 s one Wi-Fi reload, both up within 11 s Disabled
    • The 71 s reload was not the MLO Set's. With WPA2 bands an MLO change restarts nothing: lsmesh logs "-> wifi reload", but the MLO hook finds the grouping unchanged and returns. That reload came from the DFS Set sent 70 s after the MLO one.
    • When MLO does restart the radios (the grouping changes, as with WPA3 bands), the restart ends after the answer, so a read-back taken on the answer reads the old status. The app waits FW's 60 s before reading back; on one node the restart was over in about 10 s. Not measured with agents.
    • One Set restarts Wi-Fi once (acceptance criterion 3).
    • Not measured here: a part refused inside the Set (no part was refused), and firmware without MLO (this one has it).

    Decided: every MLO change is treated as restarting Wi-Fi. The save enters recovery even when the router will not restart (WPA2 bands): the app cannot tell the two apart without the firmware's grouping rule. If nothing drops, recovery's first probe, sent as soon as the write settles, finds the router and ends it.

    Corrections to the description

    These lines attribute the 71 s reload to the MLO Set. Per the bench above, it was the DFS Set's:

    • Measured on the bench: "But the MLO Set was answered in 166 ms, and its reload started 71 s later."
    • Not measured: "why the reload after the MLO-only Set came 71 s late".
    • To-do 3: "Because the reload can start long after the reply (71 s above)". To-do 3 still holds, for another reason: the MLOEnabled setter only schedules the restart and returns, so the answer comes before the restart ends.

    Post-merge recheck (additions)

    • Once linksys/usp_framework#86 merges, regenerate lib/generated/mesh_mlo.g.dart from merged main and diff it. PrivacyGUI generated it contract-first from [Screenshot testing] #86's branch with the vendored 0.17.0. Format the regenerated file from the repo root before diffing: the package's language version picks the short style, a temp directory picks the tall one.
    • Check that MLOEnabled and MLOStatus are still both required in the merged definition. The app relies on that: a router that offers MLO but answers without one of them must fail the read, not show "off".
  5. added this to the 2.7.3 milestone on Oct 19, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

2.xLabeled for 2.x versionFLWRT-2.0Labeled belonging on FLWRT-2.0enhancementNew feature or requestfeature:wifiWiFi configuration and managementtriagedAutomated diagnosis complete; root cause investigated (bug lane entry)

Projects

No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions