AIC8800M80 是一款常见的 USB WiFi 6 / 蓝牙二合一网卡芯片(2.4/5GHz 双频、802.11ax、WPA3),但它没有进入 Linux 内核主线,只能依赖厂商外流、社区维护的开源驱动。本作品是社区仓库 ronnyf/AIC8800-Linux-Driver 的 fork,目标只有一个:让这块网卡在 StarFive VisionFive 2(昉星光 2,JH7110 RISC-V SoC,内核 6.12.5-starfive)上真正用起来

适配结果已在真机验证:固件下载成功 → 生成 wlan0 → NetworkManager 自动关联并联网正常。相对上游的改动极小——3 个文件、7 行,无任何功能变更,分支保持干净,随时可以向上游回馈。

这块网卡的“三段变身“

AIC8800M80 插上电脑后不是一张现成的网卡,而是一台会变身的设备,USB ID 随状态流转:

阶段VID:PID状态
插入瞬间a69c:5721伪装成 U 盘(存放 Windows 驱动安装包)
eject 之后a69c:8d80ROM 引导模式,等待主机下载固件
固件就绪a69c:8d83真正的 WiFi 工作模式

所以驱动加载前必须先对设备执行 eject(注意不是 usb_modeswitch),把 U 盘“弹出“成固件下载模式。这一步用一条 udev 规则即可自动化。蓝牙部分则无需操心,固件就绪后由内核自带的 btusb 接管。

核心难题:320KB 的固件下载窗口

适配过程中最耗时的不是写代码,而是定位一个隐蔽的硬件限制。最初的现象是驱动日志卡在 bin upload fail: 170400,随后芯片彻底失去响应。

排查一度误入歧途——因为问题只在这块 RISC-V 开发板上出现,很容易怀疑是 JH7110 平台的 USB 兼容性缺陷。直到在 Deepin x86 PC 上完整复现了同样的故障,才推翻平台假设(教训:疑似平台问题,应尽早做跨平台对照实验)。

真正的根因是:AIC8800M80 的 boot ROM 为固件下载预留的 RAM 窗口只有 320KB,写入超过偏移 0x170000 会确定性挂死 ROM。而社区流传的 D80 固件体积在 347~358KB,全部超窗,没有一个能用。

最终在上游仓库的 fw/aic8800D80/ 目录里找到了 fmacfw_8800d80_u02.bin(324720 字节,md5 01acfbebdfb15755e3fe853e7bc95c7d)——这是目前已知唯一在 320KB 窗口之内的公开固件。换上它之后,固件一次下载成功。

内核 6.12 编译修复:3 文件 7 行

上游驱动的 cfg80211 API 版本门控有 3 处判断错误——它误以为某些 API 在内核 6.0 就已引入,实际上它们分别落地于 6.13 和 6.15,导致在 6.12 上编译失败。修复全部是预处理条件的版本号校正:

文件修改
drivers/aic8800/aic8800_fdrv/rwnx_main.hrwnx_cfg80211_set_monitor_channel_() 声明门控改为 >= 6.13
rwnx_compat.hcfg80211_rx_spurious_frame 宏门控 6.0 → 6.13
rwnx_main.cset_tx_powerparent 参数门控 6.0 → 6.15

交叉编译(对已编译的 RISC-V 内核源码树):

# 先编固件加载模块,再编主驱动(依赖前者的符号表)
make -C $K M=$SRC/aic_load_fw ARCH=riscv CROSS_COMPILE=$CROSS KBUILD_MODPOST_WARN=1 modules
make -C $K M=$SRC/aic8800_fdrv ARCH=riscv CROSS_COMPILE=$CROSS \
     KBUILD_EXTRA_SYMBOLS=$SRC/aic_load_fw/Module.symvers KBUILD_MODPOST_WARN=1 modules

部署时两个 .ko 拷入模块目录后 depmod -a,固件放入 /lib/firmware/aic8800D80/,加载顺序固定为modprobe aic_load_fw,再 modprobe aic8800_fdrv

开箱即用的自动化

fork 仓库附带一套已在 VisionFive 2 上验证的开机自动化链条:

  • udev 规则 99-aic8800.rules:插入网卡自动 eject,触发身份切换;
  • systemd 服务 aic8800-load.service:按序加载两个内核模块;
  • NetworkManager autoconnect + wifi-setup 命令行工具:首次配置后开机自动联网。

整个流程从插卡到联网无需人工干预。

过程中的两个教训

  1. rmmod 会死锁:在网卡仍处于绑定状态时卸载驱动模块,会导致引用计数错乱(-1)并卡死内核——调试期间因此搞挂过两次设备。正确顺序是先解除绑定再卸载。
  2. 不要试图从 Windows 驱动里抠固件:曾尝试从 Windows .sys 文件中提取固件,因边界错位得到损坏镜像,白费功夫;公开仓库里的固件才是正路。

分支与开源

  • 默认分支 starfive-visionfive2-k6.12:适配版,README 为中文,含 VisionFive 2 专属的英文适配文档 STARFIVE_VISIONFIVE2.md
  • main 分支保留上游原版(x86 原生编译可参考它);
  • 编译产物(.ko/.o)未入库,diff 干净,遵循上游原许可证。