Theoretically, the PCE-AC88 pci wifi card is capable of 1000MB over 802.11n, and 2167MB over 802.11ac. In other words — apart from some latency — no need to run a cable for normal work. That is, when it has a working driver. Without, it's not even a worthy as a paperweight.

Even though ASUS doesn't really provide Linux drivers, they seem to be using this exact hardware in their AC3100 router. Since routers usually run some kind of minimised version of Linux, there might just be a way to get the driver out of the routers latest firmware, at least that's what Tabre and n3roj2 thought.

Even though this idea originates from 2017, the problem remains unresolved: no working drivers by default. Therefore, I wrote a script to extract the firmware from the AC3100 firmware and tested that against all other firmware I could find.

Extracting driver from AC3100 router firmware

As stated before, the main idea to extract the driver came from Tabre and n3roj2, I coudn't have ever tought of that myself. Nonetheless, I've created a simple script that extracts the driver from the firmware package. Have a look at their posts, or this visual post, to find how it exactly works. Mainly, it extracts the binary driver from the trx file by looking for matching start and end bytes.

First, download the latest firmware from the AC3100 download page by choosing "Others" in the dropdown and extract the zip file, this result in a .trx file

# Extract trx file as firmware.trx from zip
unzip -p FW_RT_AC88U_300438643129.zip *.trx > firmware.trx

# Extract all files from firmware.trx, this create _firmware.trx.extracted folder
binwalk -e firmware.trx

# Find dhd.ko file in extracted files
dhdpath=$(find _firmware.trx.extracted -name 'dhd.ko')

# Get the size of the driver binary file from dhd.ko
sizehex=$(readelf -s $dhdpath | grep dlarray_4366c0 | awk '{print $3}' | cut -dx -f2 | tr '[:lower:]' '[:upper:]')
size=$(echo "ibase=16; $sizehex" | bc)

# Using an existing firmware binary, find start bits, e.g. "\x00\xF2\x3E\xB9"
start=$(xxd -u -c4 -g1 /lib/firmware/brcm/brcmfmac4366b-pcie.bin | head -n1 | awk '{ print "\\x" $2 "\\x" $3 "\\x" $4 "\\x" $5 }')

# Find the position of these start bits in the dhd file
offset=$(LANG=C grep -obUaP "$start" $dhdpath | head -n1 | cut -d: -f1)

# Now we have the start and the end positins, lets extract the binary
dd if=$dhdpath skip=$offset ibs=1 count=$size of=brcmfmac4366c-pcie.bin.fromtrx

This results in a file named brcmfmac4366c-pcie.bin.fromtrx, which should be the working driver. Using the script below we can load the driver without restarting your computer to see if it actually works.

Loading drivers without restarting

Installing the driver is actually not much more than copying the file to the firmware directory and telling the kernel to reload the brcmfmac module:

# Copy driver binary to firmware dir
sudo cp -v brcmfmac4366c-pcie.bin.fromtrx /lib/firmware/brcm/brcmfmac4366c-pcie.bin

# Unload brcmfmac module
sudo modprobe -vr brcmfmac

# Load / reload brcmfmac module
sudo modprobe -v brcmfmac

Your system should automatically reload the Wifi network card, otherwise manually restarting the network manager might help:

systemctl restart network-manager

If it doesn't work, have a look at the comparison results below, there might be a driver that actually works for you.

Firmware comparison results

Extracting a binary driver using the method from above feels janky at best, so I tried all other sources I could find for a working replacement. First, I made a simple script to load a specific driver, connect to Wifi and test the speed:

#!/bin/bash

firmware="$1"

if [ ! -f "$firmware" ]; then
echo "Usage: $0 brcmfmac4366c-pcie.bin"
exit 1
fi

echo
echo "Firmware version in file:"
strings $firmware | grep -i --color version

echo
echo "Installing firmware:"
sudo cp -v $firmware /lib/firmware/brcm/brcmfmac4366c-pcie.bin

echo
echo "Re-loading module:"
sudo modprobe -vr brcmfmac
sudo modprobe -v brcmfmac
sleep 1

echo
echo "New firware version:"
lshw -c network 2>&1 | grep -i --color driverversion

echo
echo "Restart network manager:"
sudo systemctl restart network-manager
sleep 1

echo
echo "Connect to default network:"
nmcli dev connect wlp1s0

echo
echo "And test working speed:"
curl -s https://raw.githubusercontent.com/sivel/speedtest-cli/master/speedtest.py | python -

I did this for every bin file I could find on the web, these are my findings. your mileage may vary:

File(s)Md5sumVersion2G Down/Up (Mbit/s)5G Down/Up (Mbit/s)Comments
brcmfmac4366c-pcie.bin.20210710f0442510.10.122.1876/4273/21extracted version 3.0.0.4_386
brcmfmac4366c-pcie.bin.6902718eeff10.10.69.1650/2579/30doesn't load on boot
brcmfmac4366c-pcie.bin_ac88
brcmfmac4366c-pcie.bin.ac88u
brcmfmac4366c-pcie.bin.tabre

b95d65

10.10.69.2667/4479/30doesn't load on boot
brcmfmac4366c-pcie.bin_ac88_2cad5e4
10.10.122.1881/4979/39doesn't load on boot
brcmfmac4366c-pcie.bin_ac88_332e0e810.10.122.1865/2477/40doesn't load on boot
brcmfmac4366c-pcie.bin.asus-dhd242cb1d410.10.69.1668/3775/33unstable
brcmfmac4366c-pcie.bin.ea9500
brcmfmac4366c-pcie.bin_u_da_third
647bee10.10.69.6992/6178/29 
brcmfmac4366c-pcie.bin_ea95005bbefc10.10.122.1890/6180/36 
brcmfmac4366c-pcie.bin.20210312cad5e410.10.122.1887/5179/39extracted version 3.0.0.4_384
brcmfmac4366c-pcie.bin.k3
brcmfmac4366c-pcie.bin_k3
7efed0n/an/an/adoesn't work
brcmfmac4366c-pcie.bin.picchietti8dbff4n/an/an/adoesn't work
brcmfmac4366c-pcie.bin_u_da_first5efe8f10.10.69.11781/5377/32 
brcmfmac4366c-pcie.bin.v10.28.2
brcmfmac4366c-pcie.bin.kernel_org
e3bb4410.28.2n/an/alatest from kernel.org, doesn't work

Current situation

Even though there has been some recent activity by the kernel developers trying to solve the wifi driver issues, the problem still remains. Some kernel updates even break the driver you manually installed. So, my advice is to keep some binary driver files on your harddisk so you'll be able to try a few if it all breaks again.

Sometimes 5Ghz, always 2Ghz: check your channels

Long story short, check if you're WiFi is on an Indoors-only channel, avoid DFS channels.

The 5Ghz band uses DFS to share it's vast amount of channels with multiple purposes. Even though your router supports these shared channels, it has to drop connectivity or switch to a different channel if it detects other activity on these frequencies, to ensure there's no interference. The exact channels differ per country, Linux uses the wireless-regdb package to determine what channels are allowed and not. Currently it seems you can only connect using channels specifically designated for Indoor use.

Check which channels your card supports here, even though usually crowded, try to stick to the lower channels (32-46).

iwconfig
iwlist wlp1s0 freq
iw phy

Finally, ensure there's no conflicting packages running on your machine:

sudo apt purge bcmwl-kernel-source broadcom-sta-dkms broadcom-sta-common broadcom-sta-source
sudo apt autoremove

Will Linux ever be ready for consumers?

More and more device manufacturers slowly start to understand there is a growing Linux user base who desperately need working drivers, preferably open source. But this realisation seems slow. The result is that 5G for this Wifi card is unstable and 2G only is stable if you manually find the drivers somewhere.

This'll keep users in bloated and spying Windows and OS X land, because Linux is just too difficult for them. I'll put my bets on Steam OS for now :)

Sources

Finding hardware / Firmware id

The brcmfmac module should support the AC88 device using bcm4366 driver.

lspci -nn | grep network -i
# 01:00.0 Network controller [0280]: Broadcom Inc. and subsidiaries Device [14e4:43c3] (rev 04)