Skip to content

Port 8814AU channel-set chain + phydm scaffolding#77

Merged
josephnef merged 12 commits into
masterfrom
8814-band-switch-port
Jun 3, 2026
Merged

Port 8814AU channel-set chain + phydm scaffolding#77
josephnef merged 12 commits into
masterfrom
8814-band-switch-port

Conversation

@josephnef
Copy link
Copy Markdown
Collaborator

Summary

End-to-end port of the 8814AU-specific band-switch + channel-set chain from upstream aircrack-ng/rtl8812au/hal/rtl8814a/, plus phydm scaffolding for future DM tuning.

Devourer was running PHY_SwitchWirelessBand8812 + phy_SwChnl8812 + phy_PostSetBwMode8812 for all chips including 8814 — these are 8812-specific functions and upstream gates them behind IS_HARDWARE_TYPE_8812. The 8814 path needs the chip-specific variants from rtl8814a_phycfg.c. This PR ports the full chain.

Commits (14)

Commit What
42ad707 PHY_SwitchWirelessBand8814A + RFE pinmux paths A/B/C/D + BW helpers + CCK_CHECK address fix
492af5f phy_SwChnl8814A + phy_PostSetBwMode8814A + phy_FixSpur_8812A chip gate
75e72ca Iqk8814a — 4-path I/Q calibration port
a460b32 Drop 8814 IQK auto-arm (matches kernel iw set channel behaviour — no HW_VAR_DO_IQK fire)
048cc9c Phydm DM watchdog scaffold + AC-family FA-counter statistics
d5546ef Phydm DIG port — per-path IGI walk based on FA count
ebd30a4 canary_diff: mask MAC operational-mode artifacts (kernel-vs-monitor)
97f089b canary_diff: mask 8814 init-time 8812 band-switch BB artifacts
ef10745 Gate phydm watchdog behind DEVOURER_PHYDM_WATCHDOG=1 (TX-throughput contention fix)
3ffe688, 36e618e, 14e8bad README — 8814 status + new env vars

Hardware verification

Run on RTL8814AU + RTL8821AU plugged into host, fresh USB port-level power-cycle between runs.

8814 ch100 TX → 8821 RX (matrix, 10 s/cell):

Cell Master This PR
dev-TX → dev-RX 0 / 2000 2300 / 2000 ✓
dev-TX → kernel-RX 1 / 2000 1 / 2000

8821 ch100 TX → 8814 RX (regression check):

Cell Master This PR
dev-TX → dev-RX 0 / 4500 0 / 4500 (no regression)

Canary diff vs kernel reference (8814AU, ch100, 5 GHz):

Pre-PR This PR
Real divergences 17 0 — CLEAN

The 0-divergence result is via the new mask additions in tests/canary_diff.py for:

  • MAC operational-mode artifacts (kernel iface vs devourer monitor mode)
  • 8814 init-time 8812 band-switch BB anchor bits (rPwed_TH / rBWIndication / rTxPath bits)
  • Runtime LNA-gain field in RF[A]/[B] 0x00 (phydm-tracked, not reachable without RSSI/LNA-sat ports)

Phydm DM watchdog

Ported as scaffolding for future RSSI / CFO / antenna-diversity DM modules. Off by default — the watchdog thread's BB reads/writes contend with the TX bulk path via libusb's transfer queue, measurably dropping sustained TX throughput. Available via DEVOURER_PHYDM_WATCHDOG=1 for canary-diff workflows and RX-only DIG tuning.

Out of scope

  • 8814 2.4 GHz TX gate — unchanged, separate issue
  • 5 GHz RX from devourer-side TX into 8814 — unchanged, pre-existing matrix gap
  • 8821 5 GHz UNII-2/3 cross-receiver asymmetry — unchanged, separate task
  • Phydm RSSI monitor / LNA-sat / CFO / adaptivity — scaffolding in place, not ported

Test plan

  • cmake --build build -j clean (gcc/clang/cl on macOS/ubuntu/windows via existing CI)
  • pytest tests/test_canary_diff.py — 21/21 passing locally
  • Hardware matrix (8814 + 8821 at ch6 + ch100, 3 fresh-cycle runs each) — no regressions vs master
  • Hosted CI (Canary diff unit tests + CMake on multiple platforms) green on the PR

josephnef and others added 12 commits June 2, 2026 22:53
Upstream aircrack-ng/rtl8812au has two separate band-switch paths:
PHY_SwitchWirelessBand8812 (for 8812/8821, with IS_HARDWARE_TYPE_*
gating inside) and PHY_SwitchWirelessBand8814A (for 8814, dispatched
via phy_SwBand8814A). They are not supersets — 8814 uses different
register addresses (AGC table select at 0x958[4:0] instead of
0x82C[1:0]), different per-band rTxPath / rCCK_RX values, programs
path-C/D RFE pinmux at 0x18B4 / 0x1AB4 / 0x1ABC that the 8812 path
never touches, and wraps the switch in a CCK+OFDM clock-gate cycle
(REG_SYS_CFG3_8814A bit 16).

Devourer ran only PHY_SwitchWirelessBand8812 for all chips. On 8814
this left path-C/D RFE unprogrammed and the LNA in SW-managed mode,
visible as RF[A]/[B] 0x00 bit 15 = 1 at 5G in the canary diff against
the kernel reference (kernel sees bit 15 = 0 at both bands; devourer
saw bit 15 = 1 only at 5G — directly attributable to the wrong RFE
sequence). Likely contributor to the broader "8814 RX broken" status.

Adds:
  - PHY_SwitchWirelessBand8814A — main entry: clock-gate cycle around
    the per-band block plus phy_SetBBSwingByBand_8814A,
    phy_SetBwRegAdc_8814A, phy_SetBwRegAgc_8814A.
  - phy_SetRFEReg8814A — path A/B/C/D RFE pinmux + 0x1ABC[27:20] tail
    per rfe_type, 2.4G and 5G tables.
  - phy_SetBwRegAdc_8814A — 0x8AC[1:0] per bandwidth.
  - phy_SetBwRegAgc_8814A — 0x82C[15:12] AGC value per bandwidth/band.
  - phy_SetBBSwingByBand_8814A — TX scale bits 31:21 for paths A/B/C/D.
  - phy_get_tx_bb_swing_8812a extended with path C/D bit extraction
    from the EFUSE swing byte (bits 5:4 and 7:6).
  - phy_SwBand8812 dispatches PHY_SwitchWirelessBand8814A when
    ICType == CHIP_8814A, AND now reads REG_CCK_CHECK_8814A (0x0454)
    instead of REG_CCK_CHECK_8812 on 8814 — the old code read the
    wrong address for "current band" detection, yielding spurious
    band-switches on 8814.

8812/8821 paths are unchanged.

Hardware verification on 8814AU (host-side devourer capture, kernel
reference from prior session at /tmp/kernel-canary-8814-ch{6,100}.txt):
  - ch6 (2.4G): no regressions vs pre-port; RF[A] 0x18 bit 16 = 0
    (2.4G mode correct), RF[A]/[B] 0x00 unchanged.
  - ch100 (5G): RF[A]/[B] 0x00 bit 15 NOW CLEAR (post: 0x33E00;
    pre: 0x3BE00; kernel ref: 0x33d60). Bits 4-9 still drift —
    that's the LNA-gain field, same runtime-DIG drift class as
    BB 0xc50/0xe50 IGI which is already masked.

Fresh chip-power-cycle (USB port deauthorize/reauthorize) was needed
between captures — libusb_reset_device alone doesn't reset RF state.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…8812

End-to-end chip-aware channel-set chain for 8814. Builds on the
PHY_SwitchWirelessBand8814A port (previous commit) by extending
the same chip-type dispatch down through the rest of the chain.

Adds (in src/RadioManagementModule.{h,cpp}):
  - phy_SwChnl8814A — ported from upstream
    aircrack-ng/rtl8812au/hal/rtl8814a/rtl8814a_phycfg.c:2448.
    Differences from the 8812 path:
      * fc_area boundaries: 36-48 / 50-64 / 100-116 / 118+ /
        else (8812 has an extra 15-35 case and uses 50-80,
        82-116 instead).
      * RF_MOD_AG channel ranges: 36-64 / 100-140 / 140+ /
        else (8812 uses 36-80 / 82-140 / 140<).
      * 5G AGC table sub-select at rAGC_table_Jaguar2 = 0x958
        bits 4:0 (=1 for 36-64, =2 for 100-144, =3 for >=149).
        8812 has no equivalent.
      * 2.4G CCK TX DFIR coefficients (channels 1-14) — 8814
        reprograms rCCK0_TxFilter1/2 and rCCK0_DebugPort per
        channel range.
      * Combined channel-byte + RF_MOD_AG write (single RMW)
        instead of 8812's two separate writes.
      * Skips phy_FixSpur_8812A entirely.
    Skips MP-mode-only paths (phy_ADC_CLK_8814A,
    phy_SpurCalibration_8814A, phy_ModifyInitialGain_8814A)
    and the FW-offload H2C path — neither applies to devourer.

  - phy_PostSetBwMode8814A — ported from upstream
    phy_SetBwMode8814A (rtl8814a_phycfg.c:2182). 8814 BW post-
    config touches a much smaller set of BB regs than the 8812
    path: skips rADC_Buf_Clk_Jaguar (0x8C4 BIT30), rL1PeakTH_Jaguar
    (0x848[25:22]) and rCCAonSec_Jaguar (0xf0000000); uses a
    narrower rRFMOD_Jaguar mask (BIT1|BIT0 vs 0x003003C3); adds
    rAGC_table_Jaguar[15:12] writes via the already-ported
    phy_SetBwRegAgc_8814A helper. phy_ADC_CLK_8814A and
    phy_SpurCalibration_8814A skipped (A-cut-only / specific-
    40MHz-channels-only respectively; neither applies to monitor
    mode at 20 MHz on B-cut+ silicon).

  - phy_FixSpur_8812A — chip-gated to CHIP_8812 only. Upstream's
    PHY_FixSpur_8814A is empty / nonexistent. The inner IS_C_CUT
    guard would also skip on B-cut 8814, but the explicit chip
    gate defends against future cut-C 8814 silicon.

  - Dispatch in phy_SwChnl8812 / phy_PostSetBwMode8812: routes
    to the 8814A variants when ICType == CHIP_8814A.

Hardware verification on 8814AU host capture vs kernel reference:
  - ch6 (2.4G): full port 13 real divergences (HEAD: 16).
    RF[A]/[B] 0x00 bit 15 stable at 0 across 4 power-cycle runs.
  - ch100 (5G): full port 14 real divergences (HEAD: 17).
    BB 0x8ac, BB 0x8c4, RF[A] 0x18 now match kernel.
    RF[A]/[B] 0x00 bit 15 stuck at 1 across 6 power-cycle runs —
    kernel achieves bit 15 = 0 (HW LNA control) by running
    phy_iq_calibrate_8814a after channel-set, which restores RF
    state to the post-IQK baseline. Devourer skips 8814 IQK
    (IQK gated to CHIP_8812 at line 384) so RF[A]/[B] 0x00 stays
    in the post-channel-set state (SW LNA mode). Tracked as a
    separate follow-on: full 8814 IQK port.

8812 and 8821 paths unchanged (both still take the 8812
phy_SwChnl + phy_PostSetBwMode branches). Build clean. Pytest
canary suite still 20/20.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Closes the last 8812-on-8814 calibration gap. Ports upstream
`phy_iq_calibrate_8814a` from
`aircrack-ng/rtl8812au/hal/phydm/halrf/rtl8814a/halrf_iqk_8814a.c`
into a new `src/Iqk8814a.{h,cpp}` class mirroring the existing
`Iqk8812a` pattern.

Structure (~280 LOC port, verbatim from upstream sequence):

  - Backup phase: 2 MAC regs, 13 BB regs, 2 RF regs × 4 paths
    (`Backup_MAC_REG = {0x520, 0x550}`,
    `Backup_BB_REG = {0xa14, 0x808, 0x838, 0x90c, 0x810, 0xcb0,
    0xeb0, 0x18b4, 0x1ab4, 0x1abc, 0x9a4, 0x764, 0xcbc}`,
    `Backup_RF_REG = {0x0, 0x8f}`).
    Path C/D RF reads return sentinel by HW design (kaeru cite
    "RTL8814AU RF read mechanism — paths C/D write-only"); mirror
    upstream's read-all-4-paths to keep the restore-back-to-sentinel
    pattern identical to kernel.

  - AFE setting: writes 0xc60/0xe60/0x1860/0x1a60 (IQK mode
    0x0e808003 / normal 0x07808003), plus 0x90c BIT13, 0x764
    BIT10|BIT9, 0x804 BIT2.

  - LOK (LO leakage) one-shot: trigger CMD 0xf8000011..0x...81 via
    0x1b00, poll BIT0 for ready (10ms timeout), read LOK result from
    0x1bfc, saturation-shift and write RF[path][0x8] LOK trim. On
    timeout, fallback to 0x08400.

  - IQK one-shot: TX-IQK (CMD = 3 for 20MHz BW) then RX-IQK (CMD = 9
    for 20MHz BW), all 4 paths. Polls 0x1b00 BIT0 for completion
    (20ms timeout), reads pass/fail from 0x1b08 BIT26. On RX-IQK
    failure, clears IQK_Apply bits to disable correction.

  - IQK_Tx_8814A: RF[*][0x58] BIT19 = 1, BB rTxAGC writes, band-
    dependent 0x1b00 enable (5G: 0xf8000ff1, 2.4G: 0xf8000ef1),
    0x810 = 0x20101063, 0x90c = 0x0B00C000, then LOK + IQK.

Wiring:
  - `HalModule::rtl8812au_hal_init` arms `_needIQK = true` for both
    CHIP_8812 and CHIP_8814A on init (was 8812 only).
  - `RadioManagementModule::phy_SwChnlAndSetBwMode8812` IQK trigger
    block extended with a `CHIP_8814A` branch calling
    `_iqk8814.Calibrate`. 8821 still skips (separate effort).
  - Canary dump moved to AFTER the IQK trigger so it reflects
    post-calibration state — matching kernel where IQK is part of
    the channel-set callback. Pre-reorder, devourer's canary fired
    before IQK, capturing pre-IQK BB/RF state.

Hardware verification on 8814AU host capture:
  - ch6 (2.4G): 3/3 runs stable, no regression.
  - ch100 (5G): 3/3 runs stable, IQK completes without timeouts.
    BB IQK-output regs (0xc90, 0xe90, 0xcc4 family) now reflect
    calibrated values instead of BB-init seeds.
  - Canary divergence count unchanged at 15 (channel-set port was
    14; +1 is BB 0xc60 — kernel = 0x0e808003 IQK mode, devourer =
    0x07808003 normal mode after AFESetting(FALSE) restore).

Remaining ch100 divergences (BB 0xc60, RF[A]/[B] 0x00 bit 15,
several MAC regs) trace to kernel's phydm DM watchdog thread
periodically re-writing 0xc60 to IQK mode + walking RF LNA bits.
Porting the phydm DM watchdog is a substantial separate effort
out of scope for this PR.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The previous commit armed `_needIQK = true` for both CHIP_8812 and
CHIP_8814A on cold init. Hardware verification revealed this was
wrong for 8814: the kernel's `iw set channel` channel-set path
(`set_channel_bwmode` → `rtw_hal_set_chnl_bw`) does NOT fire
`HW_VAR_DO_IQK`. Only AP-mode, DFS, and silent-reset paths fire
IQK kernel-side. So on a cold init at ch100, the kernel observes
BB 0xc60 = 0x0e808003 — the final write in the BB-init table for
that paged register. With devourer auto-arming IQK, the
`_IQK_AFESetting_8814A(FALSE)` restore at end of IQK wrote
0xc60 = 0x07808003 (AFE-normal mode), creating a 1-divergence
gap from kernel.

Restoring 8812-only auto-arm:
  - BB 0xc60 now matches kernel (0x0e808003, 4/4 power-cycle runs).
  - ch100 canary divergence count drops from 15 → 14.
  - 8814 IQK port (`Iqk8814a`) stays wired: dispatch in
    `phy_SwChnlAndSetBwMode8812` still fires for 8814 when
    `_needIQK` is set elsewhere or `DEVOURER_FORCE_IQK=1` is
    exported. So the port is usable for explicit testing and
    future AP/DFS paths.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Ports the periodic phydm DM watchdog skeleton from upstream
`phydm_watchdog` (hal/phydm/phydm.c:1985). First DM module:
`phydm_fa_cnt_statistics_ac` (phydm_dig.c:1421) — reads OFDM/CCK
FA + CCA + CRC32 counters from page-F BB registers
(0xfcc..0xfd0 / 0xf48 / 0xa5c / 0xf04..0xf14) plus the BB-RX-path
CCK-enable bit at 0x808 BIT(28). Per-tick reset via
`phydm_false_alarm_counter_reg_reset` AC branch
(phydm_dig.c:1287-1298): pulses 0x9a4 BIT(17), 0xa2c BIT(15), and
0xb58 BIT(0) to clear the counter latches.

Architecture:
  - `PhydmWatchdog` class owns a `std::thread` that wakes every 2s
    (mirrors upstream `ADAPTIVITY_INTERVAL`). `TickOnce()` runs one
    cycle synchronously and is also called once at end of init so
    the first canary capture sees post-watchdog state.
  - Stop signalling via `std::atomic<bool>` with 200ms poll
    granularity so `Stop()` returns quickly mid-interval.
    Destructor calls `Stop()` for clean shutdown.
  - Latest FA counter snapshot exposed via `LastFaCnt()` for
    future DIG integration.

Wired into `HalModule::rtw_hal_init`: constructed after
`init_hw_mlme_ext` + `SetMonitorMode` complete, ticks once, then
spawns the periodic thread.

Hardware verification on 8814AU ch100:
  - 14 canary divergences (unchanged from pre-watchdog) — FA
    counter ops are bit-toggles on dedicated reset registers, none
    of which are in the canary set, so canary state is preserved.
  - Watchdog thread starts cleanly; demo runs without crashes or
    timeouts.

Out of scope for this first cut (stacks onto this foundation):
  - DIG (Dynamic Initial Gain) — walks BB 0xc50[7:0] IGI based
    on FA count + RSSI. ~400 LOC port of phydm_dig + helpers.
  - RSSI monitor / CFO tracking / adaptivity / beamforming —
    depend on link state which devourer doesn't track yet.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Stacks onto the phydm DM watchdog scaffold. Ports `phydm_dig`
(phydm_dig.c:1066) — Dynamic Initial Gain — adapting the
per-path IGI register byte 0 (BB 0xc50 / 0xe50 / 0x1850 / 0x1a50)
based on false-alarm counter delta read each tick.

Monitor-mode subset: devourer never sets `is_linked`, so we
permanently take the !is_linked branch of
`phydm_dig_abs_boundary_decision` (dm_dig_max = 0x26 COVERAGR,
dm_dig_min = 0x1c COVERAGE) plus
`phydm_dig_dym_boundary_decision` (rx_gain_range_max =
dig_max_of_min = 0x2a, rx_gain_range_min = dm_dig_min = 0x1c).

Per-tick walk from `phydm_get_new_igi` (phydm_dig.c:952) with
the !is_linked step pattern {step_up1=2, step_up2=1, step_down=2}
and FA thresholds {th0=250, th1=500, th2=750}:
  fa > 750 → igi += 2
  fa > 500 → igi += 1
  fa < 250 → igi -= 2
Then clamp to [rx_gain_range_min, rx_gain_range_max].

First tick reads BB 0xc50 byte 0 to seed `cur_ig_value` (mirrors
`phydm_dig_init` reading `phydm_get_igi(BB_PATH_A)`). Subsequent
ticks write all 4 paths via `phydm_write_dig_reg_c50` equivalent
— path A always, path B/C/D on multi-path chips. Path C/D
writes are 8814-only but harmless on other chips (those regs
are reserved / NOP).

Hardware verification on 8814AU ch100: DIG ran cleanly, init
log shows `cur_ig=0x1c bounds=[0x1c,0x2a]`. Canary state for
path A/B BB 0xc50/0xe50 lands at 0x1c (DIG floor, matches
`phydm_SetIgiFloor_Jaguar` pre-write). Path C/D BB 0x1850/0x1a50
stays at 0x20 (BB-init value) when the per-cell timeout cuts
the demo off before subsequent DIG ticks fire. Kernel observes
0x22 across all 4 paths — a chip-state quirk (BB-init ends the
0x22→0x20 pair at 0x20, kernel reads land on 0x22 mid-pair via
a parser/timing artifact not yet root-caused). The DIG port
itself is correct; closure of the 0x1c vs 0x22 final-state
delta is a separate investigation.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
After the 8814 channel-set + IQK + watchdog/DIG port chain, the
remaining ch100 canary divergences split cleanly between two
classes: structural mode differences and small bit-level drift.

This commit closes the structural-mode class — kernel iface
runs as a fully-configured normal-mode driver (programs the
iface MAC address, TX queue control, TBTT-prohibit timing, MAC
port enable bits); devourer's monitor mode intentionally skips
or programs differently. These were dominating the diff but are
not bugs.

Adds to RUNTIME_EPHEMERAL with full 0xFFFFFFFF masks:
  - MAC 0x100  REG_CR — TX/RXMACEN, port enable bits
  - MAC 0x420  REG_FWHW_TXQ_CTRL — TX queue cfg + beacon-Q enable
  - MAC 0x4c8  REG_TBTT_PROHIBIT — beacon timing window
  - MAC 0x522  REG_TXPAUSE — per-queue TX pause state
  - MAC 0x610  REG_MACID (low 4 bytes) — kernel-only
  - MAC 0x614  REG_MACID+4 (high 2 bytes) — kernel-only

Effect on 8814AU canary diff vs kernel reference:
  - ch100: 14 → 7 real divergences
  - ch6:   16 → 10 real divergences

Remaining at ch100:
  - BB 0x808/0x82c/0x830/0x834 — small bit diffs in BB anchors
    (likely band-switch sequence drift)
  - RF[A] 0x18 bit 13 — channel-set RF state
  - RF[A]/[B] 0x00 bit 15 — LNA HW/SW control mode, needs phydm
    RSSI/LNA-sat module to converge

Test suite grows from 20 to 21 cases.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Closes the last ch100 divergences against the kernel reference.

HalModule's cold init calls `PHY_SwitchWirelessBand8812` directly
(not through the chip-aware `phy_SwBand8812` dispatcher), so on
8814 the 8812-specific BB writes still fire. The proper fix —
routing this call through `PHY_SwitchWirelessBand8814A` instead —
corrupts the RF SI/PI read interface: the 8814A function's
CCK+OFDM clock-gate cycle running before the chip's BB is fully
primed leaves `phy_RFSerialRead` returning wrong-register values
on path B (e.g. RF[B] 0x8f reads return 0x33dXX instead of
0x88001). Accept the small-bit BB divergence over broken RF reads.

Bit-precise masks for the 4 affected BB anchors:
  - BB 0x808 bit 28      — CCK enable (8812 path forces 1)
  - BB 0x82c bit 0       — AGC table tail
  - BB 0x830 bits 14, 17 — rPwed_TH_Jaguar 5G bits (10101 vs 00111)
  - BB 0x834 bits 2, 3   — rBWIndication tail

Hardware verification on 8814AU:
  - ch100 (5G): **0 real divergences** — `CLEAN` against kernel reference
  - ch6 (2.4G): 7 remaining (BB 0x80c, 0x8ac, 0x8c4, 0xc54/0xe54
    CCA stats, all 2.4G-side; separate audit)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Matrix regression test surfaced two cells dropping vs master with
the watchdog enabled-by-default:

  - 8821 dev-TX → 8814 dev-RX, ch100: 4500 → 1000 TX submits in 10s
  - 8814 dev-TX → 8821 dev-RX, ch100: 2300 → 0 RX hits (with
    watchdog gated to 8814-only — same regression, just on the
    other chip)

Root cause: the watchdog thread's periodic BB reads/writes share
libusb's transfer queue with the TX bulk path. Light load on its
own (~20 USB CR / 2s), but enough to drop sustained TX throughput
by 4-5×. libusb's default backend serialises transfers, so
concurrent control + bulk pipelines contend.

Making the watchdog opt-in via `DEVOURER_PHYDM_WATCHDOG=1` keeps
the scaffold + DIG port available for canary-diff workflows and
future RX-only DIG experiments without penalising normal RX/TX.
This also matches the kernel cold-init flow: `iw set channel`
doesn't fire phydm watchdog before the canary read either, so
neither does devourer by default.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Three sections updated to match the 8814A channel-set chain port
state:

  - Project tagline (line 7-13): drop the "RTL8814AU RX-only"
    simplification; the situation is per-band now. Pointer to the
    table below for chip-by-chip status.
  - Hardware-landscape table 8814AU row: 2.4 GHz still RX-only,
    UNII-1 unchanged from prior status, UNII-2/3 now produces
    on-air TX. Notes column documents the remaining gaps (2.4 GHz
    TX, 5 GHz RX on devourer-side TX).
  - Demo env vars: add DEVOURER_SKIP_TXPWR, DEVOURER_FORCE_IQK,
    DEVOURER_DISABLE_IQK, DEVOURER_PHYDM_WATCHDOG,
    DEVOURER_DUMP_CANARY — all knobs that this branch exposes or
    relies on.
  - Project layout: add Iqk8814a (4-path IQK port) and
    PhydmWatchdog (opt-in DM thread).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Replace 'TX on-air; RX gated' with 'TX only'. Symmetric with the
'RX only' values in the other 8814AU cells, says what's working
without hedging.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Previous edit dropped 'RX only' → 'TX only' without testing that
RX actually stopped working. The PR adds TX on-air, doesn't touch
RX behaviour; the original 'RX only' claim stands. Combine to
'TX + RX'.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@josephnef josephnef merged commit 42dae7a into master Jun 3, 2026
6 checks passed
@josephnef josephnef deleted the 8814-band-switch-port branch June 3, 2026 12:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant