Build Story
1. The Machine and the Symptom
ASUS laptop, Ryzen 7 7730U, Linux Mint on kernel 6.14, MediaTek MT7902 Wi-Fi chip. No upstream Linux support — Windows driver only.
The driver loaded without crashing. The chip showed up on the PCI bus. Firmware upload appeared to complete. But dmesg had one damning line: the WM firmware version field was ____000000 — placeholder garbage instead of real digits. The firmware uploaded, but the driver never received the completion event. The handshake never happened.
2. Mapping the Hardware
Before touching code the first job was understanding what the MT7902 actually looks like from the host side. Read register dumps through BAR0 using devmem2. Traced the WFDMA layout. Documented the interrupt architecture.
MT7902 uses a single WFDMA engine with 4 TX rings and 4 RX rings. The command ring — how the host sends firmware commands — is hardware ring 15.
3. Reading the Windows Driver and Firmware Blobs
Extracted the ASUS OEM Windows driver package and catalogued every .sys, .inf, .bin, and .dat file with checksums. Fed the firmware blobs through binwalk, strings, and hexdump.
Cross-referenced string tables, register constants, and interrupt field names across the vendor source. The key finding: the MT7902 command TX ring doesn't fire on interrupt bit 15 or bit 2 — it fires on bit 17, called wfdma0_tx_done_17. Explicitly called out in the vendor source as a chip-specific quirk. No clean explanation. That's just what this chip does.
4. The Root Cause
The Linux driver base was written for the MT7921. That chip uses HOST_TX_DONE_INT_ENA13 = BIT(27) for its command ring interrupt. MT7902 requires BIT(17) in the same position.
The mask was wrong. When the firmware finished initializing and fired the CMD TX done interrupt on bit 17, the driver's interrupt handler was masked against bit 27 and saw nothing. The handshake never completed. Hence: ____000000.
5. The Patch and Verification
Two files needed fixing: regs.h to correct the constant, and pci.c to fix the interrupt enable mask written to WF_WFDMA_HOST_DMA0_HOST_INT_ENA_ADDR. Recompiled with make -j$(nproc).
Verification in progress: confirm the patch in the binary via objdump, then read the hardware register at 0xe0302204 with devmem2 to verify the mask programs correctly into silicon. Then rmmod the old module, insmod the new one, and watch dmesg to see whether the CMD TX done interrupt arrives and the firmware version field shows real digits.