Adapter capabilities API + extended out-of-band 5 GHz tuning#215
Merged
Conversation
Two coupled additions for dependent apps (OpenIPC-FPV tooling, link managers, test harnesses): AdapterCaps API. New src/AdapterCaps.h aggregates what the opened radio IS and can do — chip identity (name/generation/variant/transport/id), TX/RX chain counts, the composed TxCaps + TxPowerCaps, the supported channel-width set, per-band tunable + characterized frequency spans, and per-family feature flags (per-packet TX power, narrowband, fast retune, per-chain RSSI). Surfaced via IRtlDevice::GetAdapterCaps() (static, thread-safe, callable pre-Init), overridden per generation. GetActiveRxPaths() is the live companion — a best-effort per-chain-RSSI estimate of which antennas actually carry signal (RxPathActivityAccumulator + classify_active_paths in RxQuality.h, fed from all three RX loops). The demos emit the static caps as the adapter.caps JSONL event via the shared examples/common/caps_event.h; rxdemo emits adapter.rxpaths for the live hint. Extended tuning. The 5 GHz synthesizer tunes past the UNII channels (~5080-6165 MHz, chan up to 253, freq = 5000 + 5*chan — the vendor rtl88x2bu monitor_chan_override range). ChannelFreq.h lifts the 5895 MHz cap; the per-generation channel-programming buckets (fc/AGC/RF18/SCO/VCO band, IQK/TXGAPK calibration bands) are opened at both edges so ch 15-35 and >177 tune instead of falling through. TX power for uncharacterized channels falls back to the nearest characterized channel's index (never the near-zero index 0), with a one-shot diagnostic. No regulatory enforcement — the caller owns compliance, as in monitor mode generally. Validated on-air across all three generations: adapter.caps correct on 8812AU/8814AU/8822C/8821C/8822E/8822B; TX+RX confirmed at ch180 = 5900 MHz (75 MHz past the ch165 edge) on cross-generation pairs; ctest 13/13 with the new adapter_caps_derive selftest. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The build-mingw job builds a hand-listed set of targets (its demo binaries aren't mingw targets), and every ctest-registered selftest binary must be in it or the Test step fails it as Not Run. Add the new AdapterCapsSelftest. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
josephnef
added a commit
that referenced
this pull request
Jul 8, 2026
## What PR #215 left 5/10 MHz narrowband as Jaguar3-only. Investigating the in-repo reference drivers showed **Jaguar2 has real vendor narrowband support** (`config_phydm_switch_bandwidth_8822b/_8821c`) — same "RF stays in 20 MHz mode, underclock the baseband" concept as Jaguar3, packed into the BB `0x8ac` clock word (small-BW `[7:6]` + ADC/DAC fields, `0x8c4[30]=0`, `0x8c8[31]=1`) instead of Jaguar3's `0x9b0/0x9b4` dividers. **Jaguar1 has no vendor narrowband anywhere** (enum-only dead code in every rtl8812au tree) — documented out of scope. ## The three pieces the vendor registers alone don't give (hardware-bisected) 1. **BB reset after the re-clock** — MAC `0x0` BIT16 toggle (the `_iqk_bb_reset` mechanism) so the DAC/DFE relatch at the new sample rate; the Jaguar3 port learned the same lesson. 2. **NB as an end-of-bring-up retune** — the vendor NB switch only ever runs on an initialized interface (`iw`/OpenHD `monitor_chan_override`); re-clocking mid-bring-up before IQK leaves the chip deaf both directions. 3. **The `config_phydm_switch_band` CCK-block trio** (5G: `0x808[28]=0`, `0x454[7]=1`, `0xa80[18]=1`) — the 8821C path had it, the 8822B path never ported it; a CCK engine left enabled under the NB re-clock breaks the OFDM demod. Fixed en route: 8821C RX-DFIR `0xc20[31]` was wrong for bw 5/6, and `apply_tx_power` read raw ChannelWidth 5/6 as HT40 **and missed the regulatory `txpwr_lmt` lookup entirely** (unclamped 63) — narrowband now folds to the 20 MHz power column like Jaguar3. ## Hardware validation **8821C (RTL8811CU / RTL8821CU / RTL8821CE) — fully working:** - SDR occupied bandwidth (c811, differential PSD): **16.71 / 8.55 / 4.41 MHz** → ratios **1.95** (10M) and **3.79** (5M) - Cross-generation vs Jaguar3 c812, both directions, both widths, at 20 MHz-control parity (10M: 44–58 hits, 5M: 56–106 vs control 57–67) - NB survives FastRetune (175 hits across sweep dwells — the re-clock state is bandwidth-keyed and the NB RF18 equals the 20 MHz encoding) - 2.4 GHz + efuse/regulatory power path verified (134 hits ch6, no flat override) - 20/40/80 regression smokes pass on both variants; `ctest` 13/13 **8822B (RTL8822BU) — gated off (`narrowband_ok=false`, `bw_mask` clears 5/10):** with the same recipe it syncs ~10% of NB frames and airs no NB TX, while the OpenHD kernel module decodes **5000/5000** of our Jaguar3 NB frames on the same dongle with a **byte-identical firmware blob** and identical page-8 BB state (proven by a `write_reg` reverse-bisect on the working kernel). The kernel's own 20→10 MHz self-diff leaves exactly one unexplained delta: an RF-internal RXBB LPF retune (RF `0x82`/`0xf2`) driven by a runtime FW interaction devourer doesn't reproduce yet — documented in the NB branch comment, with `DEVOURER_NB_ADC`/`DEVOURER_NB_DAC` divider-override knobs left in as the debugging levers for that follow-up. ## Tests - `tests/jaguar2_narrowband_sdr.sh` — differential-PSD occupied-BW check (Jaguar3 script's twin, `CHIP=8821c` default) - `tests/narrowband_cross_rx.sh` — both-ends-re-clocked demod proof across generations (20M control + 10/5 MHz cells, DLFW-flake retry) 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Two coupled additions requested for dependent apps (OpenIPC-FPV tooling, link managers, test harnesses) — modeled on the vendor rtl88x2bu
monitor_chan_overrideprocfs hack, but as a first-class library API.A. Adapter capabilities API
New
src/AdapterCaps.haggregates what the opened radio is and can do:ChipVarianton Jaguar2/3)TxCaps+TxPowerCaps(single source of truth)Surfaced via
IRtlDevice::GetAdapterCaps()— static, thread-safe, callable beforeInit, mirroring the existingGetTxCaps/GetTxPowerCapsprecedent.GetActiveRxPaths()is the live companion: a best-effort per-chain-RSSI estimate of which antennas actually carry signal (RxPathActivityAccumulator+classify_active_pathsinRxQuality.h, fed from all three RX loops). Demos emit the static caps as theadapter.capsJSONL event via sharedexamples/common/caps_event.h; rxdemo emitsadapter.rxpathsfor the live hint.B. Extended out-of-band 5 GHz tuning
The synthesizer tunes past the UNII channels (~5080–6165 MHz, chan up to 253,
freq = 5000 + 5·chan).ChannelFreq.hlifts the 5895 MHz cap; the per-generation channel-programming buckets (fc / AGC / RF18 / SCO / VCO band, IQK/TXGAPK calibration bands) are opened at both edges so ch 15–35 and >177 tune instead of falling through. TX power for uncharacterized channels falls back to the nearest characterized channel's index (never the near-zero index 0), with a one-shot diagnostic. No regulatory enforcement — the caller owns compliance, as in monitor mode generally.Validation (on-air, all three generations)
tests/adapter_caps_probe.sh— correct caps on 8812AU, 8814AU (4T4R), 8822C, 8821C (1T1R), 8822E, 8822Btests/extended_freq_smoke.sh— TX+RX confirmed at ch180 = 5900 MHz (75 MHz past the ch165 edge): 8812AU→8822C and 8822B→8822E, matching in-band control hit countsadapter.rxpaths= 4/4 chains active, balanced RSSIctest13/13, incl. the newadapter_caps_deriveselftestOFF/unbuilt-chip configs are unaffected (additive API, no existing-event changes).
🤖 Generated with Claude Code