Host-side proof tool for changes that must not alter what the WTLWireless core does to the hardware, such as moving chip constants
into the table in MtkChip.cpp. It compiles the driver's real sources on the Mac
(plain user space, clang, UBSan), runs the bring-up against a fake MT7925 and records every register access, MCU
message, firmware chunk, DMA ring setup and TX frame as one text line. Two versions of the driver source give the same
trace if and only if they do the same thing to the hardware (as far as the fake device can tell).
tests/hwtrace/run.sh # build, run twice, fail if the runs differ; trace in out/tests/hwtrace/trace.txt
tests/hwtrace/compare.sh [ref] # driver sources at ref (default HEAD, temporary git worktree) vs the working tree
tests/hwtrace/selftest.sh # mutates a scratch copy and checks each change shows up in the trace
All paths are relative to the driver folder (the one with the Makefile). Output goes to out/tests/hwtrace/. No sudo, no kernel, no network.
compare.sh prints hwtrace: identical (N events) or a unified diff and exits 1. The harness always comes from the
working tree; only the driver sources differ. The driver source list is read from the Makefile SRCS, so a new driver
file is picked up without touching the harness (WTLWirelessEth.cpp and MtkUserClient.cpp are left out).
W 0x0d4208 0x00000001, R 0x0e0010 -> 0x00000004 (BAR0 offsets, after the driver's own remapping),
MCU legacy|uni cid .. seq .. len .. hdr .. fnv .. (payload hashed), FWDL off .. len .. fnv .. (firmware chunk),
RING tx 15 base 0x.. cnt 32, SLEEP 1ms, DELAY 100us, PCI .., STEP <driver step text>, PHASE ..,
TXDATA (TX descriptor and frame hashes), RXMCU / RXDATA (what the model hands back). Device addresses come from a
fixed bump allocator. No host pointers, no timestamps. hwtrace <file> --props adds PROP lines (the registry
properties the driver publishes) for debugging. --pcidev 7927 makes the fake card report another PCI device ID;
run.sh uses it to check that a card without a chip table row gets no register access at all.
--oldset pretends the class of the older kext set (MtkWlan) is in the kernel too: the core must then publish
MtkConflict on the PCI device and touch nothing. compare.sh works across the rename from MtkWlan to WTLWireless (the
harness takes whichever class the tree under test has); against 0.13.0 the only changed line is the status text that
names the native front end.
Start (PCI command bits, BAR0, driver/firmware ownership, CHIPID gate), hwStart (WFSYS reset, DMA disable, five
rings, prefetch table, GLO_CFG, IRQ masks), patch and RAM download with the real firmware, hwInit (NIC capability,
EFUSE mode, MDP, per-band MAC init, DEV_INFO, domain, CLC, per-rate power, RTS, RX filter), one firmware scan, a join
of an open 5 GHz HT+VHT AP through the connection manager (BSS_INFO, STA_REC, EDCA, ROC, auth, assoc, link up), the
disconnect, a country change (non-FCC domain, CLC, SKU), the fixed register windows and the L1/L2 remap paths through
rr/wr, the supervisor reload (second hwStart over existing rings), quiesce and stop.
WPA2 (key code, 4-way handshake, staKey), data TX/RX and block ack (needs mbufs and a front end), the Ethernet and
native front ends and the user client (IOKit networking, not compiled), interrupt delivery, FLR, TX-free tokens,
timing and the real tick rate. Registry properties are not part of the default trace.
Listed as GUESS in model.cpp: BAR0 size (2 MB), chip id and revision values, handshake latency (OWN_SYNC, WFSYS
reset done and N9 ready each flip on the second read), DMA engines never busy, plain registers read back what was
written, every UNI command accepted with a bare result event, EFUSE all zero (HW_TYPE encap 0), the AP always accepts
(AID 1), event layouts for NIC capability, ROC grant and scan done, three made-up networks. The engine only fetches
TX descriptors while TX_DMA_EN is set and only fills RX buffers while RX_DMA_EN is set.
The real firmware: out/gen/MtkFirmware.c (generated by the kext build, git-ignored). If it is missing, build.sh
generates it into out/tests/hwtrace/fw/. Firmware bytes appear only as hashes.
shim/ kernel and IOKit stand-ins (first on the include path, so the SDK kernel headers are never used; prelude.h
opens private so the harness can call driver internals), model.* the fake chip, host_shim.cpp trace sink, DMA
space and register routing, trace_main.cpp the scenario and function coverage (functions-run.txt,
functions-not-run.txt), regmap_probe.inc the register window probes.