Getting a clone AIC8800D80 Wi-Fi dongle working on Linux
Cheap AX900 and AX300 class Wi-Fi 6 USB dongles built on AICSemi's AIC8800D80 are everywhere on Temu, AliExpress, and eBay. Some of the unbranded ones plug into Linux and show up as a USB CD-ROM instead of a network interface, and no existing driver package recognizes them. This is how I got one working, and how the repo packages it so it keeps working.
The problem
Branded AIC8800D80 adapters (Tenda U11, Cudy, UGREEN, and others) also start out as USB mass storage. They enumerate as a69c:5721 through a69c:572f, appear as a virtual disc, and switch into Wi-Fi mode when that disc is ejected. Existing packages handle this with a udev rule that runs eject on the block device.
The unbranded "Pandora" clones are different. They enumerate as 1111:1111, a placeholder vendor and product ID that matches no known device. Because of that:
- no driver package lists that ID, so nothing claims the device
usb_modeswitchhas no entry for it- the eject trick that works for the Tenda units does nothing
The device just sits there as storage.
The mode switch
The clone needs a vendor-specific 16-byte SCSI command descriptor block:
FD 00 00 00 00 00 00 00 00 00 00 00 00 00 00 F2It's sent as an ordinary USB mass-storage command, wrapped in the standard 31-byte Command Block Wrapper (CBW). After it lands, the device drops off the bus and re-enumerates as a69c:8d80, the ID the AIC8800 driver already knows.
usb_modeswitch can send arbitrary CBWs, so the fix is a config entry:
DefaultVendor=0x1111
DefaultProduct=0x1111
TargetVendor=0xa69c
TargetProduct=0x8d80
MessageContent="555342438765432100000000000010fd0000000000000000000000000000f2"Here is that MessageContent byte by byte:
| Bytes | Field | Value |
|---|---|---|
55 53 42 43 | dCBWSignature | "USBC", fixed |
87 65 43 21 | dCBWTag | Arbitrary tag, echoed back in the status reply |
00 00 00 00 | dCBWDataTransferLength | 0, no data phase |
00 | bmCBWFlags | Direction bit unused with no data |
00 | bCBWLUN | LUN 0 |
10 | bCBWCBLength | 16-byte command |
fd 00 … 00 f2 | CBWCB | The vendor command |
Making it automatic
A mode switch you have to run by hand on every plug-in isn't a fix. A udev rule fires it on hotplug:
ACTION=="add", ATTRS{idVendor}=="1111", ATTRS{idProduct}=="1111", \
RUN+="/bin/sh -c 'if [ -x /usr/sbin/usb_modeswitch ]; then exec /usr/sbin/usb_modeswitch -c /etc/usb_modeswitch.d/1111:1111; elif [ -x /usr/bin/usb_modeswitch ]; then exec /usr/bin/usb_modeswitch -c /etc/usb_modeswitch.d/1111:1111; fi'"It checks both /usr/sbin and /usr/bin because distros disagree on where usb_modeswitch lives. A few more rules handle firmware variants that re-enumerate as a69c:8d81, a69c:8d83, or 368b:8d81. If the driver doesn't bind those on its own, they write the ID to the driver's new_id in sysfs, and they clear any rfkill soft block on Bluetooth.
One small trap: the config has to be installed as /etc/usb_modeswitch.d/1111:1111, with a colon in the filename. Windows can't check out filenames containing colons, so the repo stores it as 1111_1111 and the installer renames it.
Packaging
The AIC8800 driver isn't in mainline, so it has to be built out of tree for every kernel. The repo's install.sh is a multi-distro DKMS installer. It:
- detects the package manager (apt, dnf, yum, pacman, zypper) and installs the build dependencies
- removes any existing
aic8800*firmware directories under/lib/firmware, because mismatched firmware versions can hard-freeze the machine - installs the firmware, udev rules, and mode-switch config
- registers the tree with DKMS so the modules rebuild automatically on kernel updates
Bluetooth needs no custom module. Once aic_load_fw uploads the firmware patch, the stock btusb driver handles the HCI interface. Upstream's diagnose_bt.sh checks the usual failure points: missing firmware patch files, a leftover aic_btusb module from another package, and rfkill.
What's mine and what isn't
The driver itself is AICSemi's. It reached me by way of the Tenda U11 vendor drop and shenmintao/aic8800d80, which carried it forward to modern kernels and established that Bluetooth works through stock btusb. My part is the clone-dongle support: the mode-switch config and the udev rules that fire it.
The driver source is GPL-2.0. That isn't a choice I made: it descends from GPL vendor source and its modules declare MODULE_LICENSE("GPL"). Upstream shipped no license file, so the repo adds one. The firmware under fw/ is a proprietary AICSemi binary with no explicit redistribution grant. The repo's NOTICE.md spells out that posture rather than pretending it's a permission.
Tested on
| Distro | Kernel | Arch | Result |
|---|---|---|---|
| Debian 13 (trixie) | 6.12.95, 6.12.96, 6.12.100 | x86_64 | Wi-Fi and Bluetooth working |
| Ubuntu 25.04 | 6.16 | x86_64 | Reported upstream |
| Debian 12 | 6.1.0-27 | x86_64 | Reported upstream |
The repo also has notes for installing on a 2008-era polycarbonate MacBook. USB 2.0 caps real throughput there at roughly 150 to 250 Mb/s whatever the radio negotiates, but it still adds WPA3 and more reliable association with modern access points than the built-in Broadcom card manages.