Gentoo Linux在MacBook Air配置Wifi

备注

所有淘宝上售卖的不同品牌 AX300 免驱动WiFi6无线网卡 ,实际上都是 RealTek 开发芯片 aic8800 , BrostTrend 代工的 AX5L WiFi6 USB无线网卡。

aic8800 可能是 Realtek RTL8188EU 芯片的改进型号,但是驱动没有进入Linux主线内核,需要独立编译安装

支持WiFi标准:

  • WiFi 4: 802.11n

  • WiFi 6: 802.11ax

备注

Tenda(腾达)公司 AX300 Wi-Fi 6 高增益USB无线网卡(U2 v5.0) 产品介绍,以及 U2v5.0 Linux系统驱动- X86架构 (Ubuntu/UOS/kylin OS) 内核3.10~6.2 提供了源代码安装包。我在 Ubuntu AIC8800驱动(Tenda无线网卡AX300) 实践中完成Ubuntu平台的编译安装。

我的 MacBook Air 13" Early 2014MacBook Pro 15" Late 2013 配置的是完全一样的 Boradcom BCM4360 蓝牙无线网卡,这款网卡对开源非常不兼容,导致 Gentoo Linux在MacBook Pro配置Wifi 实践遇到很多波折。

虽然最终能够通过hack方式使用 Boradcom BCM4360 ,但是性能损失和kernel的特性损失导致得不偿失。所以我分别采用了不同的方法来解决这两台MacBook的无线网络问题:

硬件

  • 选了一款 WiFi6 的USB网卡 - COMFAST CF-940AX 免驱动WiFi6无线网卡

    • 主要考虑露出USB接口部分比较小,比较便携

    • WiFi6现在逐渐普及,这样在 2.4GHz 频率下能够速率翻倍(比原先WiFi4),达到300Mbps

    • 比较担心Linux兼容性 真没想到非常巧,原来AX300是Realtek开发BrosTrend代工的Linux的无线网卡 ,广告宣传是免驱动,实际上只有Win10/11是内置驱动,其他是通过插入USB无线网卡后默认内置一个小容量U盘提供驱动安装

../../_images/cf-940ax.png
  • 插入 CF-940AX USB无线网卡后,执行 lsusb 可以看到这款网卡设备显示:

COMFAST CF-940AX 显示设备名
Bus 001 Device 010: ID a69c:5721 aicsemi Aic MSC

好奇怪的设备名字,居然没有型号

看起来,这款USB无线网卡是 爱科微 公司的WiFi6无线芯片 aic8800

这款 aic8800 驱动没有进入Linux内核,所以要通过 out-of-tree 方式编译安装:

根据 BrosTrend官方Linux文档 ,从 Kernel 6.2 开始,已经包含 AC1L, AC3L, AC5L :

  • AC1L,AC3L 使用 Realtek rtl88x2bu 驱动

  • AC5L 使用 Realtek rtl8821cu 驱动

  • AX5L 是最新Realtek为BrosTrend 开发的 aic8800 芯片,尚未进入Linux内核

在 Gentoo 中也提供了这个驱动的ebulid net-wireless/aic8800 ,源代码是从 brostrend公司Linux源代码网站 获取。在官方Linux源代码网站说明:

安装包实际上提供了源代码以及将源代码注册到 动态内核模块支持(DKMS) 系统,这样在新内核安装时会自动重新编译。

../../_images/AX300-Linux-WiFi-6-USB-Adapter-Supports.webp

AX300 ( BrosTrend AX5L )支持众多Linux发行版以及Windows和macOS

根据腾达公司 和 爱科微公司(似乎是BrosTrend的国内公司名) 提供的编译安装文档,看起来这款设备的文档都是2023年10月发布的,应该都是 brostrend 代工产品(Realtek公司开发)。BrosTrend官方文档 BrosTrend AX300 WiFi 6 Linux Compatible WiFi Adapter, 2.4GHz Only, Nano Linux WiFi Adapter for PC, Raspberry Pi 2+, for Ubuntu, Mint, Debian, Kubuntu, Mate, Zorin, PureOS etc, USB WiFi Dongle 286Mbps 介绍这款AX300 Linux WiFi 6 USB Adapter对Linux兼容和支持较好:

安装

  • 安装 net-wireless/aic8800 :

安装 aic8800 驱动
emerge --ask net-wireless/aic8800
  • 识别设备

编译很顺利,安装完成后,在 /lib/modules/$(uname -r) 目录下可以通过 tree 命令找到安装的内核模块和firmware,通过 ls 检查:

tree 找到对应驱动,通过 ls 检查
ls -lh /lib/modules/$(uname -r)/kernel/drivers/net/wireless/aic8800

输出可以看到以下两个文件:

aic8800 内核模块和firmware
total 1.1M
-rw-r--r-- 1 root root 907K Jan  5 15:04 aic8800_fdrv.ko
-rw-r--r-- 1 root root 133K Jan  5 15:04 aic_load_fw.ko

但是,很奇怪,为何没有像网上所说的那样能够自动加载内核模块呢?而且再次使用 lsusb 看到的USB口插入的无线网卡依然没有显示出详细的品牌和型号信息,依然是:

安装了 aic8800 内核模块和firmware,却没有看到设备输出信息有任何变化
Bus 001 Device 010: ID a69c:5721 aicsemi Aic MSC

根据 BrosTrend Source code: install.sh 提供了 install.sh 脚本中段落:

BrosTrend Source code 安装脚本 install.sh 有关 aic8800
            a69c:5721)
                _DRIVER=aic8800
                bold "Switching the adapter from storage to WLAN mode"
                # Background it as it can take up to 30 seconds in a VM
                rw usb_modeswitch -KQ -v a69c -p 5721 &
                ;;

原来如此

这个无线网卡默认是存储模式,需要通过一个工具 usb_modeswitch 工具来转换工作模式

在Gentoo上安装 usb_modeswitch
emerge --ask usb_modeswitch
  • 参考官方提供的 install.sh 脚本片段的实际命令,执行:

执行 usb_modeswitch 命令将 AX5L 从存储模式切换到WLAN模式
usb_modeswitch -KQ -v a69c -p 5721

注意: 在转换前设备ID是 a69c:5721 ,这个参数就是 usb_modeswitch 需要的参数

  • 执行完成后,再次执行 lsusb 就会看到设备显示信息,可以看到该USB设备的ID和名称都发生了变化:

a69c:5721 ( aicsemi Aic MSC ) 在切换模式之后,改变成 a69c:88dc ( AICSemi AIC8800DC )
Bus 001 Device 008: ID a69c:88dc AICSemi AIC8800DC

此时检查 ifconfig 会看到系统中增加了一个 wlan0 设备

并且系统日志中会记录模式切换的数据信息:

aicsemi USB设备切换模式时系统日志
[Fri Jan  5 17:08:31 2024] usb 1-2: USB disconnect, device number 2
[Fri Jan  5 17:08:32 2024] usb 1-2: new high-speed USB device number 8 using xhci_hcd
[Fri Jan  5 17:08:32 2024] usb 1-2: New USB device found, idVendor=a69c, idProduct=88dc, bcdDevice= 1.00
[Fri Jan  5 17:08:32 2024] usb 1-2: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[Fri Jan  5 17:08:32 2024] usb 1-2: Product: AIC8800DC
[Fri Jan  5 17:08:32 2024] usb 1-2: Manufacturer: AICSemi
[Fri Jan  5 17:08:32 2024] usb 1-2: SerialNumber: 20220127
[Fri Jan  5 17:08:32 2024] AICWFDBG(LOGINFO)    aicwf_usb_chipmatch USE AIC8800DC
[Fri Jan  5 17:08:32 2024] AICWFDBG(LOGINFO)    aicwf_parse_usb endpoints = 4
[Fri Jan  5 17:08:32 2024] AICWFDBG(LOGERROR)   Number of interfaces: 1 not supported
[Fri Jan  5 17:08:32 2024] AICWFDBG(LOGERROR)   AIC8800DC change to AIC8800DW
[Fri Jan  5 17:08:32 2024] AICWFDBG(LOGINFO)    Aic high speed USB device detected
[Fri Jan  5 17:08:32 2024] AICWFDBG(LOGINFO)    aicwf_usb_alloc_rx_urb AICWF_USB_RX_URBS:200
[Fri Jan  5 17:08:32 2024] AICWFDBG(LOGINFO)    aicwf_usb_alloc_tx_urb AICWF_USB_TX_URBS:200
[Fri Jan  5 17:08:32 2024] AICWFDBG(LOGINFO)    aicwf_usb_alloc_msg_rx_urb AICWF_USB_MSG_RX_URBS:100
[Fri Jan  5 17:08:32 2024] AICWFDBG(LOGINFO)    usb_busrx_thread the policy of current thread is:0
[Fri Jan  5 17:08:32 2024] AICWFDBG(LOGINFO)    usb_busrx_thread the rt_priority of current thread is:0
[Fri Jan  5 17:08:32 2024] AICWFDBG(LOGINFO)    usb_busrx_thread the current pid is:6924
[Fri Jan  5 17:08:32 2024] AICWFDBG(LOGINFO)    usb_bustx_thread the policy of current thread is:0
[Fri Jan  5 17:08:32 2024] AICWFDBG(LOGINFO)    usb_bustx_thread the rt_priority of current thread is:0
[Fri Jan  5 17:08:32 2024] AICWFDBG(LOGINFO)    usb_bustx_thread the current pid is:6925
[Fri Jan  5 17:08:32 2024] AICWFDBG(LOGINFO)    usb_msg_busrx_thread the policy of current thread is:0
[Fri Jan  5 17:08:32 2024] AICWFDBG(LOGINFO)    usb_msg_busrx_thread the rt_priority of current thread is:0
[Fri Jan  5 17:08:32 2024] AICWFDBG(LOGINFO)    usb_msg_busrx_thread the current pid is:6926
[Fri Jan  5 17:08:32 2024] AICWFDBG(LOGINFO)    rwnx_platform_init rwnx_cfg80211_init enter
[Fri Jan  5 17:08:32 2024] AICWFDBG(LOGINFO)    rwnx_cfg80211_init sizeof(struct rwnx_hw):14288
[Fri Jan  5 17:08:32 2024] AICWFDBG(LOGINFO)    aicwf_prealloc_txq_alloc size is diff will to be kzalloc
[Fri Jan  5 17:08:32 2024] AICWFDBG(LOGINFO)    aicwf_prealloc_txq_alloc txq kzalloc successful
[Fri Jan  5 17:08:32 2024] AICWFDBG(LOGINFO)    usb config read 11d
[Fri Jan  5 17:08:32 2024] AICWFDBG(LOGINFO)    chip_id=7, chip_sub_id=1
[Fri Jan  5 17:08:32 2024] [0x40500010]=e
[Fri Jan  5 17:08:32 2024] AICWFDBG(LOGINFO)    ### Upload fmacfw_patch_8800dc_u02.bin firmware, @ = 180000
[Fri Jan  5 17:08:32 2024] AICWFDBG(LOGINFO)    ### Load file fmacfw_patch_8800dc_u02.bin
[Fri Jan  5 17:08:32 2024] AICWFDBG(LOGINFO)    rwnx_load_firmware :firmware path = /lib/firmware//aic8800DC/fmacfw_patch_8800dc_u02.bin
[Fri Jan  5 17:08:32 2024] AICWFDBG(LOGINFO)    file md5:e3ca44de3ff9489eea9da4c69a01088a
[Fri Jan  5 17:08:32 2024] AICWFDBG(LOGINFO)    size=27592, dst[0]=7a00edd0
[Fri Jan  5 17:08:32 2024] AICWFDBG(LOGINFO)    wifisetting_cfg_addr=11019c, ldpc_cfg_addr=120980, agc_cfg_addr=120180, txgain_cfg_addr=120000
[Fri Jan  5 17:08:32 2024] patch 11022c = 13fc00
[Fri Jan  5 17:08:32 2024] patch 11024c = ad180100
[Fri Jan  5 17:08:32 2024] patch 110220 = 40
[Fri Jan  5 17:08:32 2024] AICWFDBG(LOGINFO)    ### Upload fmacfw_patch_tbl_8800dc_u02.bin
[Fri Jan  5 17:08:32 2024] AICWFDBG(LOGINFO)    ### Load file fmacfw_patch_tbl_8800dc_u02.bin
[Fri Jan  5 17:08:32 2024] AICWFDBG(LOGINFO)    rwnx_load_firmware :firmware path = /lib/firmware//aic8800DC/fmacfw_patch_tbl_8800dc_u02.bin
[Fri Jan  5 17:08:32 2024] AICWFDBG(LOGINFO)    file md5:d8e2db863a24e4654745159f18f992ad
[Fri Jan  5 17:08:32 2024] AICWFDBG(LOGINFO)    tbl size = 432
[Fri Jan  5 17:08:32 2024] AICWFDBG(LOGINFO)    FMACFW_PATCH_TBL_8800DC_U02_DESCRIBE_BASE = 186e00
[Fri Jan  5 17:08:32 2024] AICWFDBG(LOGINFO)    li Aug 26 2023 16:25:25 - g2f2e258m
[Fri Jan  5 17:08:32 2024] AICWFDBG(LOGERROR)   patch_tbl:  110888  180ea9
[Fri Jan  5 17:08:32 2024] AICWFDBG(LOGERROR)   patch_tbl:  1108ec  185cd1
[Fri Jan  5 17:08:32 2024] AICWFDBG(LOGERROR)   patch_tbl:  110874  180ee9
...
[Fri Jan  5 17:08:32 2024] ieee80211 phy0:
                           *******************************************************
                           ** CAUTION: USING PERMISSIVE CUSTOM REGULATORY RULES **
                           *******************************************************
[Fri Jan  5 17:08:32 2024] AICWFDBG(LOGINFO)    rwnx_interface_add: wlan%d, 2, 10
[Fri Jan  5 17:08:32 2024] AICWFDBG(LOGINFO)    interface add:40 a5 ef 22 58 37
[Fri Jan  5 17:08:32 2024] AICWFDBG(LOGINFO)    New interface create wlan0
[Fri Jan  5 17:08:32 2024] AICWFDBG(LOGINFO)    rwnx_platform_init rwnx_cfg80211_init exit
[Fri Jan  5 17:08:33 2024] usb 1-2 wlan0: Current addr:  40 a5 ef 22 58 37 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
[Fri Jan  5 17:08:33 2024] usb 1-2 wlan0: Expected addr: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
[Fri Jan  5 17:08:33 2024] ------------[ cut here ]------------
[Fri Jan  5 17:08:33 2024] netdevice: wlan0: Incorrect netdev->dev_addr
[Fri Jan  5 17:08:33 2024] WARNING: CPU: 2 PID: 5555 at net/core/dev_addr_lists.c:519 dev_addr_check+0x9b/0x100
[Fri Jan  5 17:08:33 2024] Modules linked in: aic8800_fdrv(OE) aic_load_fw(OE) rndis_host cdc_ether usbnet mii xt_conntrack xt_MASQUERADE nf_conntrack_netlink nfnetlink iptable_nat nf_nat nf_conntrack nf_defrag_ipv6 nf_defrag_ipv4 xt_addrtype iptable_filter ip_tables br_netfilter bridge 8021q garp mrp stp llc vfat fat btusb btrtl btintel btbcm bluetooth intel_rapl_msr intel_rapl_common x86_pkg_temp_thermal intel_powerclamp coretemp kvm_intel ecdh_generic snd_hda_codec_hdmi ecc apple_mfi_fastcharge kvm irqbypass cfg80211 snd_hda_codec_cirrus rfkill i915 crct10dif_pclmul snd_hda_codec_generic ledtrig_audio ghash_clmulni_intel i2c_algo_bit drm_buddy snd_hda_intel sha512_ssse3 ttm zfs(POE) snd_intel_dspcfg sha256_ssse3 snd_intel_sdw_acpi drm_display_helper snd_hda_codec sha1_ssse3 cec rapl snd_hwdep spl(OE) intel_cstate drm_kms_helper snd_hda_core mei_hdcp intel_uncore snd_pcm drm i2c_i801 i2c_smbus snd_timer efi_pstore lpc_ich snd mei_me mfd_core i2c_core mei soundcore spi_pxa2xx_pci dw_dmac_pci acpi_als industrialio_triggered_buffer
[Fri Jan  5 17:08:33 2024]  kfifo_buf spi_pxa2xx_platform industrialio dw_dmac dw_dmac_core video efivarfs xfs libcrc32c uas hid_apple usb_storage sd_mod t10_pi crc64_rocksoft crc32_pclmul crc64 crc32c_intel aesni_intel xhci_pci xhci_pci_renesas crypto_simd ahci cryptd xhci_hcd libahci
...

udev 配置自动切换WLAN模式

上述 aic8800 配置完成后,如果重启操作系统或者重新插入 AX5L USB WiFi设备,初始状态都是USB存储模式。每次手工输入 usb_modeswitch 命令切换显然太笨拙了。这就需要结合 OpenRC udev 来完成自动切换:

配置 aic8800 (AX5L)无线网卡插入时自动将存储模式切换为WLAN模式
# own udev rule USB LTE 
# switch from mass storage mode to modem modem
ACTION=="add", SUBSYSTEM=="usb", ATTRS{idVendor}=="a69c", ATTRS{idProduct}=="5721", RUN+="/usr/sbin/usb_modeswitch usb_modeswitch -KQ -v a69c -p 5721"
# load driver for modem mode
ACTION=="add", SUBSYSTEM=="usb", ATTRS{idVendor}=="a69c", ATTRS{idProduct}=="5721", RUN+="/bin/bash -c 'modprobe aic8800_fdrv && modprobe aic_load_fw'"

完成配置后,触发 udev 重新加载规则:

udevadm 控制重新加载 udev 规则
udevadm control --reload-rules

使用wpa_supplicant连接无线网络

接下来就是常规操作,通过 使用wpa_supplicant连接无线网络 配置无线认证和接入WiFi

参考