Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 11 additions & 17 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@ OpenIPC project for long-range video links.
Targets the Realtek "Jaguar" 1st-gen 802.11ac family: **RTL8812AU** (2T2R,
reference), **RTL8811AU** (1T1R cut of 8812 silicon — rides the 8812 code
path with `RFType=RF_TYPE_1T1R` selected via `REG_SYS_CFG` bit 27),
**RTL8814AU** (4T4R RF / 3-SS baseband; RX solid, TX validated on
fresh-chip single-cell runs but unstable after USB passthrough cycles
issue #36), and **RTL8821AU** (1T1R AC + BT combo; proper 8821-specific
init flow landed in PR #42, Android hotplug confirmed end-to-end).
**RTL8814AU** (4T4R RF / 3-SS baseband; host-pushed TX requires the
on-chip 3081 MCU, which devourer boots during firmware download
a failed FW-boot poll means dead TX while RX still works), and
**RTL8821AU** (1T1R AC + BT combo).

NOT 8821AU's family confusion: it IS Jaguar wave 1 (CHIP_8821 = 7 in
Realtek's HalVerDef, shares the enum with CHIP_8812), not Jaguar2 as
Expand Down Expand Up @@ -54,12 +54,13 @@ sudo python3 tests/regress.py \
--vm-name devourer-testrig --vm-ssh <user>@<VM-IP>
```

Default channel is `6` (2.4GHz). Devourer's 5GHz path has known broken
cells for 8814 RX, 8821 TX, and 8821 RX — at 2.4GHz every chip combo
except 8814 TX works. Pass `--channel 36` / `--channel 100` to exercise
5GHz; do not assume a single-band matrix is comprehensive. (The repo
history's matrix tables in PR bodies #34/#42/#49 were all captured at
`--channel 100` and document the 5GHz state.)
Default channel is `6` (2.4GHz). Pass `--channel 36` / `--channel 100`
to exercise 5GHz; do not assume a single-band matrix is comprehensive.
Matrix-interpretation caveat: with the 8814 as TX, the `kernel`-TX cells
read 0 at every channel — `aircrack-ng/88XXau` host-push *beacon*
injection (what `inject_beacon.py` does) doesn't emit on that driver,
even though its probe-request injection does. Judge 8814 TX by the
devourer-TX cells.

Three specialised modes layered on top of the default 4-cell matrix:

Expand Down Expand Up @@ -163,13 +164,6 @@ phydm parser.
Windows installer, then re-enumerate as the NIC after a mode switch. If
`libusb_open_device_with_vid_pid` returns NULL, check `lsusb` — may need
`usb_modeswitch` first.
- **RTL8814AU TX is flaky after USB passthrough cycles** (issue #36):
fresh-chip single-cell runs send ~4000 frames with 0 submit failures,
but after one or more virsh attach/detach cycles `libusb_bulk_transfer`
starts returning `LIBUSB_ERROR_IO` on 90%+ of submits. Every full-
matrix run since #34 has reproduced this. `RX = devourer` 8814 cells
are also still 0 (RX path itself is separately broken — not in scope
for #36).
- **rmmod/sysfs-unbind actively de-inits the chip** (RF off, MAC DMA off).
After detaching a kernel driver, expect to re-init from cold, not warm.
`DEVOURER_SKIP_RESET=1` only helps when firmware state is still intact.
Expand Down
15 changes: 7 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,11 @@
The Realtek 11ac driver that simply devours its competitors.

Devourer is a userspace re-implementation of Realtek's RTL88xxAU Wi-Fi
driver (Jaguar family: RTL8812AU and RTL8821AU shipping on every band,
RTL8811AU supported via the 8812 code path, RTL8814AU with band-
specific gaps — see table below), speaking to the chip directly
through libusb. No kernel module, no `rtl8812au` DKMS tree — just a
C++20 static library (`WiFiDriver`) plus two demo executables for RX
and TX. It is the OpenIPC project's driver of choice for long-range
driver (Jaguar family: RTL8812AU, RTL8814AU, and RTL8821AU shipping on
every band, RTL8811AU supported via the 8812 code path), speaking to
the chip directly through libusb. No kernel module, no `rtl8812au`
DKMS tree — just a C++20 static library (`WiFiDriver`) plus two demo
executables for RX and TX. It is the OpenIPC project's driver of choice for long-range
video links built on top of cheap Realtek 11ac USB radios.

## Hardware landscape
Expand All @@ -23,9 +22,9 @@ layered on top.

| Part | RF / streams | 2.4 GHz | 5 GHz UNII-1 (ch36-48) | 5 GHz UNII-2/3 (ch52+) | Notes |
| -------------- | --------------- | ------------- | ---------------------- | ---------------------- | ------------------------------------------- |
| **RTL8812AU** | 2T2R | TX + RX | TX + RX | TX + RX | VID/PID `0bda:8812`; reference part — works on every channel/band combo |
| **RTL8812AU** | 2T2R | TX + RX | TX + RX | TX + RX | VID/PID `0bda:8812`; reference part |
| **RTL8811AU** | 1T1R | TX + RX | TX + RX | TX + RX | 1T1R cut of 8812 silicon; rides 8812 code path with `RFType=RF_TYPE_1T1R` selected from `REG_SYS_CFG` bit 27. Status mirrored from 8812 — not separately exercised |
| **RTL8814AU** | 4T4R, 3-SS max | RX only | RX only | TX + RX | VID/PID `0bda:8813`; 2-SS effective on USB-2. 5 GHz UNII-2/3 TX produces on-air frames after the 8814A-specific band-switch + channel-set chain. 2.4 GHz TX still doesn't reach receivers |
| **RTL8814AU** | 4T4R, 3-SS max | TX + RX | TX + RX | TX + RX | VID/PID `0bda:8813`; 2-SS effective on USB-2 |
| **RTL8821AU** | 1T1R AC + BT | TX + RX | TX + RX | TX + RX | OEM-rebadged as TP-Link Archer T2U Plus (`2357:0120`) etc. UNII-2/3 TX has cross-receiver asymmetry against 8812AU peers |

Successor families (`Jaguar2` / `Jaguar+` — 8812BU, 8822BU/BE, etc., and
Expand Down
16 changes: 16 additions & 0 deletions docs/8814-port-audit.md
Original file line number Diff line number Diff line change
Expand Up @@ -150,3 +150,19 @@ symptom.
4. `sudo python3 tests/regress.py --vm-name devourer-testrig --vm-ssh …`
default matrix; `--channel 36` spot-check; full matrix + encoding-matrix if
8814 TX goes green.

## Resolution: FW-boot / TX-silence axis (2026-06-11)

The smoking gun fired exactly as predicted by finding #3: on a virgin chip the
`CPU_DL_READY` poll failed (`REG_MCUFWDL` stuck at `0x00606078`) and TX was
0 on-air. Replacing the rtw88-mimic fwdl *bracket* with a verbatim port of the
vendor kernel's `FirmwareDownload8814A` + `HalROMDownloadFWRSVDPage8814A`
(keeping the mimic's power-on prefix, which remains devourer's only 8814
power-on) makes the 3081 boot: trajectory `0x...2079` (per-section
DL_RDY/CHKSUM_OK RMW) → `0x...6079` (FW_DW_RDY) → `0x...E078`
(`CPU_DL_READY`, asserted instantly on `_3081Enable`). With the FW running,
TX emits on-air: ch6 12.8k / ch36 10.7k / ch100 10.8k canonical-SA frames at
the kernel-monitor witness; RX unaffected. The legacy sequence is preserved
bit-for-bit behind `DEVOURER_8814_FWDL=rtw88` and still reproduces the
failure — a clean causal A/B. Residual-risk items #1 (blanket `0x79/0x6078`
kick) and the FW-boot arm of #5 are thereby resolved.
Loading
Loading