feat: runtime Wi-Fi AP/STA mode switch for AIC8800 on SG2002 (LicheeRV Nano)#1266
Conversation
Add runtime Wi-Fi mode switching for the aic8800 SoftAP/STA on sg2002, driven through the standard Linux wireless-extensions ioctl path. The network stack stays link-agnostic (PR rcore-os#1185 design): all wireless specifics stay behind the WifiControl trait. - aic8800: MM_REMOVE_IF teardown + teardown_vif() before re-creating the VIF, so repeated STA/AP switches reuse one vif_idx cleanly. - rd-net: WifiControlHandle clones the device's Arc<NetInner> before the Net is consumed into the data-plane driver, keeping the control plane reachable from a separate task/syscall context. - ax-net: name-indexed WIFI_CONTROLS registry + reconfigure_wifi() entry point; Service::reconfigure_as_{ap,sta} swap IPv4/DHCP role only. - StarryOS: wext.rs handles SIOCSIW{MODE,ESSID,ENCODEEXT,FREQ} (staged) + SIOCSIWCOMMIT (atomic apply via ax_net::reconfigure_wifi). - demo: wifi_switch.c userspace tool + WIFI_SWITCH_DEMO.md. STA association performs a real WPA2-PSK 4-way handshake; WPA3/SAE is not implemented yet.
CI 'Check formatting / run_host' failed on the mode-switch commit: rustfmt reformats the WifiControlHandle .then() closure (rd-net) and the reconfigure_wifi() call sites + byte-collect chain (wext.rs). No logic change. sync-lint passed locally (182 packages); its CI failure was a fail-fast cancellation triggered by the fmt failure, not a real lint.
There was a problem hiding this comment.
PR 审查总结
变更概述
本 PR 在 #1185(SG2002 AIC8800 Wi-Fi SoftAP)基础上,为 wlan0 增加运行时 AP↔STA 模式切换能力。通过标准 Linux wireless-extensions ioctl 路径驱动,采用「先暂存、后提交」两阶段操作模型:SIOCSIWMODE/ESSID/ENCODEEXT/FREQ 只暂存参数到内核侧 PENDING 表,SIOCSIWCOMMIT 原子应用全部变更。
变更涉及 13 个文件(+842/-6),涵盖四层:
- 驱动层(aic8800 / rd-net):新增
MM_REMOVE_IF拆除 +teardown_vif(),WifiControlHandle在Net消费前克隆Arc<NetInner> - 网络栈(ax-net):
WIFI_CONTROLS注册表 +reconfigure_wifi()入口 +Service::reconfigure_as_{ap,sta} - 内核(StarryOS wext.rs):wireless-extensions ioctl 处理
- 演示工具:
wifi_switch.c+WIFI_SWITCH_DEMO.md
实现逻辑评价
分层设计延续 #1185 的 link-agnostic 边界,网络栈不感知具体芯片。teardown_vif() 的 VIF 生命周期管理正确(先尽力 disconnect,再 REMOVE_IF,最后复位 vif_idx/sta_idx 到 0xFF)。WIFI_CONTROLS 在 Net 消费前捕获控制面句柄的设计合理。Service 的 AP/STA 重配正确处理了 DHCP 客户端/服务器状态转换。
本地验证
cargo fmt --check✅ 通过cargo fmt --check✅ 无格式问题[patch.crates-io]检查 ✅ 未引入 crates.io patchgit diff --stat origin/dev...HEAD✅ 变更范围与 PR 描述一致
CI 状态
CI workflow run: 27527190735
实际运行的检查全部通过:
- Check formatting / run_host: ✅
- Run sync-lint / run_container: ✅
- Run clippy / run_host: ✅
- Test with std / run_host: ✅
- Test starry x86_64/aarch64/loongarch64 qemu: ✅
- Test axvisor riscv64/aarch64/loongarch64 qemu: ✅
- Test axvisor self-hosted x86_64: ✅
- Test axvisor board roc-rk3568-pc-linux/orangepi-5-plus-linux: ✅
跳过的检查属于预期的 CI 矩阵路径过滤(run_host/run_container 互斥对、container publish 等),非 PR 引入的 CI 问题。workflow 级别显示 failure 是 GitHub Actions 对跳过矩阵条目的汇总行为,不影响实际通过状态。
重复/重叠分析
- 前序 PR #1185(已合并):添加了 AIC8800 SoftAP 基础支持,本 PR 在其之上扩展运行时模式切换,不重复
- 其他 open PR(#1265 串口 IRQ 重构等):与本 PR 改动范围无重叠
- 本 PR 是 #1185 的自然延续,无冲突风险
无阻塞发现
- 代码质量良好,分层清晰
- 无 crates.io patch
- 无合并冲突(
mergeable: true) - CI 全部实际检查通过
- 无未解决的 review thread
- 作者已在 SG2002 实板验证 AP→STA→AP 往返、WPA2 关联、开放网络关联、DHCP 等
Wi-Fi 硬件行为仅能在物理板上验证(SG2002/LicheeRV Nano),这是驱动代码的合理限制。共享的内核和网络栈代码已由 CI QEMU 测试覆盖。
Powered by mimo-v2.5-pro
ZR233
left a comment
There was a problem hiding this comment.
变更内容
本 PR 在 #1185(SG2002 AIC8800 SoftAP)的基础上,为 wlan0 增加运行时 AP↔STA 模式切换,走标准 Linux wireless-extensions ioctl 路径,网络栈保持 link-agnostic:
- aic8800:新增
teardown_vif()+MM_REMOVE_IF_REQ,在重建 VIF 前拆除旧 VIF,使反复 STA/AP 切换能干净复用同一个vif_idx(复位vif_idx/sta_idx/缓存 MAC,避免固件侧 VIF 泄漏)。 - rd-net:新增
WifiControlHandle,在Net被数据面消费前克隆同一份Arc<NetInner>,使控制面在独立 task/syscall 上下文仍可达。 - ax-net:新增按名索引的
WIFI_CONTROLS注册表 +reconfigure_wifi()入口;Service::reconfigure_as_{ap,sta}仅切换 IPv4/DHCP 角色,不触碰链路细节。 - StarryOS:
wext.rs处理SIOCSIW{MODE,ESSID,ENCODEEXT,FREQ}(暂存)+SIOCSIWCOMMIT(原子应用)。 - demo:
wifi_switch.c+WIFI_SWITCH_DEMO.md。
实现逻辑评价
分层清晰,延续 #1185 的 link-agnostic 边界。几个并发/所有权点已确认合理:
reconfigure_wifi先释放注册表锁再做阻塞的WifiControl调用(lib.rs:380-396),不会在阻塞固件命令路径上同时持有WIFI_CONTROLS与SERVICE两把锁。WifiControlHandle的&mut别名:wifi_control()经&mut **interface.get()拿到&mut dyn WifiControl,与 IRQ handler / OOB poll task / 数据面 TX/RX 队列共享同一份Arc<NetInner>::UnsafeCell<Interface>。这正是 base #1185 既有路径(irq_handler、receive、prepare_send)的既有别名模型,本 PR 没有引入新的别名来源;模式切换由 syscall/task 上下文发起且与poll_interfaces()串行,符合 handle 注释所述约束。teardown_vif状态机:先尽力disconnect(失败不阻断),再MM_REMOVE_IF_REQ,最后复位驱动侧vif_idx=0xFF/sta_idx=0xFF/ap_mac=None;无有效 VIF 时为安全空操作。逻辑自洽。- wext 暂存-提交两阶段:setter 只写 per-ifname 的
PENDING,只有COMMIT才下发;ifname取自iwreq.ifrn_name,与register_wifi_control(name, ...)(devices.rs 用&'static str)的命名一致。
验证
- 构建/clippy:
cargo xtask starry build -c os/StarryOS/configs/board/licheerv-nano-sg2002-wifi.toml在本地通过(riscv64,产出.uimg,含 starry-kernel + ax-net + aic8800)。cargo xtask clippy --package ax-net/rd-net/aic8800全部通过,cargo fmt --check通过。无[patch.crates-io]。 - demo 工具:按文档
riscv64-linux-musl-gcc -static -O2 -o wifi_switch wifi_switch.c编译通过(static-PIE riscv64 ELF);WIFI_SWITCH_DEMO.md的准备工作/上板命令/成功判据完整可执行。 - CI 状态(head
c03c9a9):本次唯一真实失败是Test starry riscv64 qemu / run_container,失败发生在qemu-smp4/system的bug-sched-affinity-pid(TEST START: sched affinity respects pid)挂起到 1800s 超时 —— 属调度器 affinity 测试,与本 PR 的 Wi-Fi/wext/ax-net/aic8800 改动面无关,且与既有 issue #1215(ci(starry): riscv64 qemu-smp4 system hangs in bug-sched-affinity-pid)描述完全一致。已在 #1215 追加本 PR 的复现证据(run/job 链接 + 失败模式)。其余 starry x86_64/aarch64/loongarch64 qemu、ax-net/aic8800 clippy、axvisor/board 各 job 均通过。Test starry self-hosted board licheerv-nano-sg2002显示 fail 实为 step 5cancelled(运行被取消),非真实失败。 - 运行时行为:真实模式切换(WPA2-PSK 四次握手、AP↔STA 往返)依赖 AIC8800 芯片与真实 AP,只能在 SG2002 实板验证,QEMU 无 Wi-Fi 设备无法复现。PR 正文已提供板级证据(AP↔STA 往返、STA WPA2/开放网络关联+DHCP、AP 被 DHCP
.2),作为 board-only 验证可接受。
重复/重叠
已用 WifiControlHandle/reconfigure_wifi/wext/aic8800 wext 多组关键词检索 base dev 与全部 open PR:base 无任何运行时模式切换/reconfigure_wifi/WifiControlHandle 实现,open PR 中也无重叠项,本 PR 是该能力的首次引入,与 #1185(SoftAP bring-up)互补而非重复。
非阻断建议(供后续)
- 栈侧
Service::reconfigure_as_{ap,sta}的 IPv4/DHCP 角色切换理论上可借助既有test_support/LoopbackDevice补一个 host 侧单测(不依赖芯片),目前 ax-net 无对应单测。非阻断,因该面由设备驱动触发且已在板级验证。 _write_iwreq_data带#[allow(dead_code)]是未来回写型 setter 的占位,可接受。
结论
分层合理、所有权/锁模型自洽、文档命令可复现、构建与 clippy 通过;唯一 CI 失败为既有 riscv64 bug-sched-affinity-pid 超时(issue #1215),与本 PR 无关。真实 Wi-Fi 切换为 board-only 能力,PR 已提供板级证据。准予合入。
…V Nano) (rcore-os#1266) * feat(wifi): runtime AP<->STA mode switch via wireless-extensions ioctl Add runtime Wi-Fi mode switching for the aic8800 SoftAP/STA on sg2002, driven through the standard Linux wireless-extensions ioctl path. The network stack stays link-agnostic (PR rcore-os#1185 design): all wireless specifics stay behind the WifiControl trait. - aic8800: MM_REMOVE_IF teardown + teardown_vif() before re-creating the VIF, so repeated STA/AP switches reuse one vif_idx cleanly. - rd-net: WifiControlHandle clones the device's Arc<NetInner> before the Net is consumed into the data-plane driver, keeping the control plane reachable from a separate task/syscall context. - ax-net: name-indexed WIFI_CONTROLS registry + reconfigure_wifi() entry point; Service::reconfigure_as_{ap,sta} swap IPv4/DHCP role only. - StarryOS: wext.rs handles SIOCSIW{MODE,ESSID,ENCODEEXT,FREQ} (staged) + SIOCSIWCOMMIT (atomic apply via ax_net::reconfigure_wifi). - demo: wifi_switch.c userspace tool + WIFI_SWITCH_DEMO.md. STA association performs a real WPA2-PSK 4-way handshake; WPA3/SAE is not implemented yet. * style(wifi): apply rustfmt to mode-switch changes CI 'Check formatting / run_host' failed on the mode-switch commit: rustfmt reformats the WifiControlHandle .then() closure (rd-net) and the reconfigure_wifi() call sites + byte-collect chain (wext.rs). No logic change. sync-lint passed locally (182 packages); its CI failure was a fail-fast cancellation triggered by the fmt failure, not a real lint.
…V Nano) (#1266) * feat(wifi): runtime AP<->STA mode switch via wireless-extensions ioctl Add runtime Wi-Fi mode switching for the aic8800 SoftAP/STA on sg2002, driven through the standard Linux wireless-extensions ioctl path. The network stack stays link-agnostic (PR #1185 design): all wireless specifics stay behind the WifiControl trait. - aic8800: MM_REMOVE_IF teardown + teardown_vif() before re-creating the VIF, so repeated STA/AP switches reuse one vif_idx cleanly. - rd-net: WifiControlHandle clones the device's Arc<NetInner> before the Net is consumed into the data-plane driver, keeping the control plane reachable from a separate task/syscall context. - ax-net: name-indexed WIFI_CONTROLS registry + reconfigure_wifi() entry point; Service::reconfigure_as_{ap,sta} swap IPv4/DHCP role only. - StarryOS: wext.rs handles SIOCSIW{MODE,ESSID,ENCODEEXT,FREQ} (staged) + SIOCSIWCOMMIT (atomic apply via ax_net::reconfigure_wifi). - demo: wifi_switch.c userspace tool + WIFI_SWITCH_DEMO.md. STA association performs a real WPA2-PSK 4-way handshake; WPA3/SAE is not implemented yet. * style(wifi): apply rustfmt to mode-switch changes CI 'Check formatting / run_host' failed on the mode-switch commit: rustfmt reformats the WifiControlHandle .then() closure (rd-net) and the reconfigure_wifi() call sites + byte-collect chain (wext.rs). No logic change. sync-lint passed locally (182 packages); its CI failure was a fail-fast cancellation triggered by the fmt failure, not a real lint.
背景
本 PR 在 #1185(SG2002 AIC8800 Wi-Fi SoftAP)的基础上,为
wlan0增加运行时AP↔STA 模式切换能力:无需重启,即可在 SoftAP 与 Station 之间切换。切换通过标准
Linux wireless-extensions
ioctl路径驱动,网络栈保持 link-agnostic——所有无线相关细节仍收敛在
WifiControltrait 之后,延续 #1185 的分层设计。一次切换的完整控制面链路:
变更内容
驱动层(aic8800 / rd-net)
aic8800:在重建 VIF 前执行MM_REMOVE_IF拆除 +teardown_vif(),使反复STA/AP 切换能干净复用同一个
vif_idx。rd-net:WifiControlHandle在Net被数据面驱动接管之前克隆设备的Arc<NetInner>,使控制面在独立的 task/syscall 上下文中仍可达。网络栈集成(ax-net)
WIFI_CONTROLS注册表与reconfigure_wifi()入口。Service::reconfigure_as_{ap,sta}仅切换 IPv4/DHCP 角色,不触碰链路细节。系统调用(StarryOS)
wext.rs处理SIOCSIW{MODE,ESSID,ENCODEEXT,FREQ}(暂存)+SIOCSIWCOMMIT(经
ax_net::reconfigure_wifi原子应用)。演示工具
wifi_switch.c用户态工具 +WIFI_SWITCH_DEMO.md。实现逻辑
模式切换被建模为"先暂存、后提交"的两阶段操作:
SIOCSIWMODE/ESSID/ENCODEEXT/FREQ只把目标参数暂存在内核侧,直到
SIOCSIWCOMMIT才真正下发。提交时reconfigure_wifi先经
WifiControl让 aic8800 拆除当前 VIF 并按新模式重建(STA 走真实 WPA2-PSK四次握手,AP 则
APM_START),再由Service切换网络栈的 IPv4/DHCP 角色(STA 转DHCP client,AP 恢复
192.168.50.1/24+ 单客户端 DHCP server)。整个过程网络栈不感知具体芯片,延续 #1185 的 link-agnostic 边界。
构建与验证
已在 SG2002 / LicheeRV Nano 实板验证(默认启动态为 SoftAP
PicoClaw-Car,192.168.50.1/24,单客户端 DHCP server 分配.2):无
vif_idx泄漏。client 获取地址,可 ping 通网关。
PicoClaw-Car,经 DHCP 获得.2,可 ping 通
192.168.50.1。已知限制