MediaTek MT7927 (MT6639) WiFi + Bluetooth on Ubuntu — ASUS ROG CROSSHAIR X870E HERO
Getting both WiFi and Bluetooth working on the MediaTek MT7927 (Filogic 380) combo chip on Ubuntu 24.04 with kernel 6.17+.
- Board: ASUS ROG CROSSHAIR X870E HERO
- Chip: MediaTek MT6639 (PCI
14c3:6639), marketed as MT7927 (WiFi 7, Filogic 380) - WiFi: PCIe — works via patched
mt7925edriver - Bluetooth: USB
13d3:3588(IMC Networks / MediaTek) — requires btusb patch - OS: Ubuntu 24.04.4 LTS, kernel 6.17.0-14-generic
- WiFi: The MT6639/MT7927 chip is not supported by the stock kernel mt76 driver (no
0x6639chip ID handling) - Bluetooth: The BT half of the chip appears as a USB device (
13d3:3588) butbtusbdoesn't recognize the USB ID as a MediaTek device, so it never loads firmware — HCI reset fails with-16(EBUSY) - Boot timing race: The BT USB device needs the WiFi driver to initialize CONNINFRA first. If USB enumeration happens before WiFi init, the BT device hangs and needs a full PSU power cycle to recover
- WiFi: jetm's mediatek-mt7927-dkms package with patched mt76/mt7925e driver
- Bluetooth: Patch
btusb/btmtkto add0x6639device support + USB ID13d3:3588(based on max-prtsr's gist) - Boot timing: initramfs early loading + systemd xHCI rescan service
sudo apt update
sudo apt install -y build-essential dkms linux-headers-$(uname -r) git curl python3 zstd iw# Clone jetm's DKMS package
cd ~
git clone https://github.com/jetm/mediatek-mt7927-dkms.git
cd mediatek-mt7927-dkms
# Copy DKMS source to /usr/src
sudo cp -r mediatek-mt7927-2.1 /usr/src/
# If kernel < 6.19: copy missing stub header needed by mt76
KVER=$(uname -r)
if [ ! -f /usr/src/linux-headers-${KVER}/include/linux/soc/airoha/airoha_offload.h ]; then
sudo mkdir -p /usr/src/linux-headers-${KVER}/include/linux/soc/airoha/
curl -sL "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/plain/include/linux/soc/airoha/airoha_offload.h?h=v6.19" \
| sudo tee /usr/src/linux-headers-${KVER}/include/linux/soc/airoha/airoha_offload.h > /dev/null
echo "Stub header installed"
fi
# Build and install DKMS modules
sudo dkms add mediatek-mt7927/2.1
sudo dkms build mediatek-mt7927/2.1 -k $(uname -r)
sudo dkms install mediatek-mt7927/2.1 -k $(uname -r)# Create firmware directories
sudo mkdir -p /lib/firmware/mediatek/mt6639
sudo mkdir -p /lib/firmware/mediatek/mt7927
# Download WiFi firmware from jetm's repo (or copy from the cloned repo)
sudo cp ~/mediatek-mt7927-dkms/firmware/WIFI_MT6639_PATCH_MCU_2_1_hdr.bin /lib/firmware/mediatek/mt7927/
sudo cp ~/mediatek-mt7927-dkms/firmware/WIFI_RAM_CODE_MT6639_2_1.bin /lib/firmware/mediatek/mt7927/Download the official MediaTek Bluetooth driver from your motherboard's ASUS support page (Drivers → Windows 11 → Bluetooth). Extract the zip.
# Extract BT firmware from the Windows driver's mtkbt.dat file
# Replace 'path/to/BT/mtkbt.dat' with the actual path to the extracted file
python3 -c "
import struct, sys
data = open(sys.argv[1], 'rb').read()
offset = 0x10
name = data[offset:offset+48].split(b'\x00')[0].decode()
data_offset = struct.unpack_from('<I', data, offset + 64)[0]
data_size = struct.unpack_from('<I', data, offset + 68)[0]
fw = data[data_offset:data_offset + data_size]
open('BT_RAM_CODE_MT6639_2_1_hdr.bin', 'wb').write(fw)
print(f'Extracted {name}: {len(fw)} bytes')
" path/to/BT/mtkbt.dat
# Install to firmware directory
sudo cp BT_RAM_CODE_MT6639_2_1_hdr.bin /lib/firmware/mediatek/mt6639/IMPORTANT: btusb has TWO device tables. New USB IDs must go in
quirks_table(around line 733), NOT inbtusb_table(around line 70). The genericUSB_INTERFACE_INFO(0xe0,0x01,0x01)entry inbtusb_tablematches ALL Bluetooth USB devices first withdriver_info=0. Thenbtusb_probe()does a second lookup inquirks_tablefor vendor-specific flags. If your entry is in the wrong table,BTUSB_MEDIATEKis never set,btmtk_usb_setupnever runs, no firmware is downloaded, and HCI_Reset fails with status0x0c(Command Disallowed) / errno-16.
The DKMS BT patch includes 0489:e13a by default. The ASUS ROG CROSSHAIR X870E HERO uses 13d3:3588 instead. Check yours:
# Find your BT USB ID (run after cold boot if device isn't visible)
lsusb | grep -iE 'mediatek|wireless_device'If your ID is already in the patch, skip this step. Otherwise add it to the quirks_table section of the patch:
# This command adds USB ID 13d3:3588 to the btusb patch (quirks_table section)
# Change 0x13d3 and 0x3588 to match YOUR device if different
sudo python3 -c "
import re
with open('/usr/src/mediatek-mt7927-2.1/mt6639-bt-6.19.patch', 'r') as f:
content = f.read()
# Check if already present
if '0x13d3, 0x3588' in content:
print('USB ID 13d3:3588 already in patch, skipping')
exit(0)
# Add new USB ID in the quirks_table section (after e0fa entry)
old = '''+\t{ USB_DEVICE(0x0489, 0xe0fa), .driver_info = BTUSB_MEDIATEK |
+\t\t\t\t\t\t BTUSB_WIDEBAND_SPEECH },'''
new = '''+\t{ USB_DEVICE(0x0489, 0xe0fa), .driver_info = BTUSB_MEDIATEK |
+\t\t\t\t\t\t BTUSB_WIDEBAND_SPEECH },
+\t{ USB_DEVICE(0x13d3, 0x3588), .driver_info = BTUSB_MEDIATEK |
+\t\t\t\t\t\t BTUSB_WIDEBAND_SPEECH },'''
content = content.replace(old, new)
# Update hunk header line count (+2 lines added)
content = re.sub(
r'@@ -733,6 \+733,(\d+) @@',
lambda m: f'@@ -733,6 +733,{int(m.group(1))+2} @@',
content
)
with open('/usr/src/mediatek-mt7927-2.1/mt6639-bt-6.19.patch', 'w') as f:
f.write(content)
print('Added USB ID 13d3:3588 to btusb patch (quirks_table)')
"Now rebuild the DKMS modules with the updated patch:
sudo dkms remove mediatek-mt7927/2.1 -k $(uname -r) --force
sudo dkms build mediatek-mt7927/2.1 -k $(uname -r)
sudo dkms install mediatek-mt7927/2.1 -k $(uname -r) --forceThe BT USB device needs CONNINFRA (initialized by the WiFi driver) before it can enumerate. These commands set up early loading and USB bus re-scan.
# 6a. Load WiFi driver early in initramfs
echo "mt7925e" | sudo tee -a /etc/initramfs-tools/modules
# 6b. Auto-load BT modules at boot
cat <<EOF | sudo tee /etc/modules-load.d/mt7927.conf
mt7925e
btmtk
btusb
EOF
# 6c. Include BT firmware in initramfs
cat <<'EOF' | sudo tee /etc/initramfs-tools/hooks/mt6639-bt-firmware
#!/bin/sh
PREREQ=""
prereqs() { echo "$PREREQ"; }
case $1 in prereqs) prereqs; exit 0;; esac
. /usr/share/initramfs-tools/hook-functions
copy_file firmware /lib/firmware/mediatek/mt6639/BT_RAM_CODE_MT6639_2_1_hdr.bin
EOF
sudo chmod +x /etc/initramfs-tools/hooks/mt6639-bt-firmwareThis service re-scans the USB bus after WiFi has initialized CONNINFRA, giving BT a fresh enumeration attempt.
First, find your xHCI PCI address:
# Find which xHCI controller hosts the BT USB device (usually bus 1)
readlink -f /sys/bus/usb/devices/usb1 | grep -oP 'pci[0-9:]+/\K[0-9a-f:.]+(?=/usb)'
# Example output: 0000:0e:00.0Then create the service (replace 0000:0e:00.0 with your address):
# Replace 0000:0e:00.0 with YOUR xHCI PCI address from above!
XHCI_ADDR="0000:0e:00.0"
cat <<EOF | sudo tee /etc/systemd/system/mt7927-bt-rescan.service
[Unit]
Description=Rescan USB bus for MT7927 Bluetooth after WiFi init
After=network-pre.target
Wants=network-pre.target
[Service]
Type=oneshot
ExecStartPre=/bin/sleep 5
ExecStart=/bin/bash -c 'echo "${XHCI_ADDR}" > /sys/bus/pci/drivers/xhci_hcd/unbind; sleep 3; echo "${XHCI_ADDR}" > /sys/bus/pci/drivers/xhci_hcd/bind'
RemainAfterExit=yes
[Install]
WantedBy=multi-user.target
EOF
sudo systemctl daemon-reload
sudo systemctl enable mt7927-bt-rescan.service# Rebuild initramfs with all changes
sudo update-initramfs -u
# Power off completely (NOT reboot — warm reboot won't clear hung BT state)
sudo poweroffAfter poweroff:
- Turn off the PSU switch (back of the PC)
- Wait 10+ seconds (clears hung MT6639 BT state)
- Turn PSU back on and power up
# Check WiFi
iw dev
# Expected: wlp9s0 interface listed
# Check BT USB device is visible
lsusb | grep -iE 'mediatek|wireless_device|13d3'
# Expected: Bus 001 Device 003: ID 13d3:3588 IMC Networks Wireless_Device
# Check Bluetooth controller
hciconfig -a
# Expected: hci0 UP RUNNING, real BD address (not 00:00:00:00:00:00)
# Check bluetoothctl
bluetoothctl show
# Expected: Controller with Powered: yes
# Check rescan service ran
systemctl status mt7927-bt-rescan
# Expected: active (exited)
# If BT not working, check kernel messages:
sudo dmesg | grep -iE 'btusb|btmtk|mt6639|hci|bluetooth|usb 1-6' | tail -20If you just rebuilt DKMS and want to test without rebooting:
sudo modprobe -r btusb
sudo modprobe -r btmtk
sudo modprobe btmtk
sudo modprobe btusb
sudo rfkill unblock bluetooth
# Wait ~20 seconds for firmware to load, then check:
sleep 20 && hciconfig -a && bluetoothctl showDifferent board manufacturers use different USB IDs for the same chip:
| USB ID | OEM | Boards |
|---|---|---|
0489:e13a |
Foxconn/Hon Hai | ASUS ROG STRIX X870-I |
0489:e0fa |
Foxconn/Hon Hai | Various |
0489:e116 |
Foxconn/Hon Hai | Various |
0489:e110 |
Foxconn/Hon Hai | MSI X870E Ace Max |
13d3:3588 |
IMC Networks | ASUS ROG CROSSHAIR X870E HERO, ASUS ProArt X870E |
If yours isn't listed, add it to the patch as shown in Step 5.
| Problem | Solution |
|---|---|
BT USB not in lsusb |
Cold boot required: sudo poweroff → PSU off 10s → power on |
hci0 BD address all zeros |
USB ID not in btusb quirks_table — see Step 5 |
Opcode 0x0c03 failed: -16 |
USB ID in wrong table or missing — must be in quirks_table, see Step 5 |
| WiFi slow / drops | Disable ASPM: echo 0 | sudo tee /sys/bus/pci/devices/0000:09:00.0/link/l1_aspm |
| CHIPID reads 0x0000 | Normal — driver forces it to 0x7927 |
| Build fails kernel < 6.19 | Copy stub header — see Step 2 |
setting interface failed (22) |
Harmless warning, ignore |
ISO intf not support (-19) |
Harmless warning, ignore |
btusb.c has two USB device ID tables:
btusb_table(line ~70) — Used for driver binding. Contains generic entries likeUSB_INTERFACE_INFO(0xe0, 0x01, 0x01)that match ALL Bluetooth USB devices withdriver_info=0.quirks_table(line ~179) — Contains vendor-specific entries with flags likeBTUSB_MEDIATEK. Looked up insidebtusb_probe()when the initialdriver_infois 0.
USB matching is first-match (not best-match). The generic entry always wins in btusb_table. New MT7927 USB IDs must go in quirks_table so btusb_probe() finds them on the second lookup and sets BTUSB_MEDIATEK, which triggers btmtk_usb_setup() for firmware download.
- Board: ASUS ROG CROSSHAIR X870E HERO
- Chip: MediaTek MT6639 / MT7927 (Filogic 380)
- Kernel: 6.17.0-14-generic
- OS: Ubuntu 24.04.4 LTS (Noble)
- WiFi: Working (wlp9s0, 2.4/5GHz)
- Bluetooth: Working (hci0, BT 5.4, BD F8:3D:C6:94:CE:A9)
- jetm/mediatek-mt7927-dkms — DKMS package for WiFi + BT (v2.4-1)
- max-prtsr's gist — BT btusb/btmtk patches for kernel 6.18+
- jfmarliere/linux-driver-mediatek-mt7927-bluetooth — original BT driver work
- openwrt/mt76#927 — upstream MT6639 tracking issue
- morrownr/usb-wifi#517 — MT7927 Linux support discussion
- ASUS ROG forum BT thread
- WiFi driver upstream submission: patchwork series 1062894 (18 patches by Javier Tia, 2026-03-07)
好复杂...要不还是把mt7927拆了换ax210?