Skip to content

Kestrel: compose-cache FastRetune (44→25 ms) + dwell-1 data plane on AX#326

Merged
josephnef merged 1 commit into
masterfrom
kestrel-fastretune-opt
Jul 20, 2026
Merged

Kestrel: compose-cache FastRetune (44→25 ms) + dwell-1 data plane on AX#326
josephnef merged 1 commit into
masterfrom
kestrel-fastretune-opt

Conversation

@josephnef

@josephnef josephnef commented Jul 20, 2026

Copy link
Copy Markdown
Collaborator

Answers "can the tested FHSS features come up on Kestrel?" — yes, and the FastRetune hop nearly halves.

Data plane: runs on AX unchanged

The dwell-1 / N-channel data plane (examples/dwelltx, exp 4/5) is caller-side (send_packet + FastRetune), both of which Kestrel has. Validated on-air on an 8852B DUT: 3-channel dwell-1, zero wrong-channel, ~97% delivery. No library change for the data plane itself.

FastRetune: 44 → 25 ms via the compose-cache

Kestrel's fast_retune started at ~44 ms/hop (vs ~2 ms on the 8822B). Per-stage profiling put the cost in the vendored halrf channel setting — and the same compose-cache recipe the 11ac retunes use applies here:

  • fast_rf_channel_8852b is a write-only port of halrf_ctrl_ch_8852b: it primes the RF18 (DAV+DDV) and RF 0xcf dwords once per epoch (invalidated by every full set_channel) and thereafter composes the channel bits and writes whole dwords — cutting ~12 per-hop reads (4× RF18 + 8× the 0xcf re-latch RMW).
  • The path-A synth relock (halrf_set_s0_arfc18: 0xd3 hold + RF18 write + 0xb7 LCK poll) and fast_lck_check_8852b (0xc5 verify + MMD-reset fallback) are kept verbatim — load-bearing (skipping the relock deafens the radio), and the LCK poll reads the physical lock state, so that plus the a-die serial-interface writes is the irreducible floor.
  • Two more cuts: the synth-lock diagnostic reads are gated off the hot path (vnd_rf_tune(..., diag=false)), and the gain-error re-applies only on a 5 GHz sub-band bucket move.

Net ~44 → ~25 ms; soak of 1500 hops, zero LCK timeouts, delivery unchanged (~97%). A Kestrel dwell-1 slot is now ~50 ms (vs ~70 ms before, ~20 ms on the 8822B). The 8852C keeps the vendored tune (fast_rf_channel_8852b returns false). rtw89 exposes no firmware channel-switch H2C (only SCAN_OFFLOAD + MCC), so a Kestrel FASTRETUNE_FW remains a no-go.

Also fixes the dwelltx teardown to release the device before libusb_exit (the Kestrel worker planes were still live, tripping a libusb mutex assertion at exit).

Docs: a Kestrel row + explanation in docs/frequency-hopping.md, and a FastRetune section in src/kestrel/CLAUDE.md. ctest 36/36.

🤖 Generated with Claude Code

The dwell-1 / N-channel data plane (examples/dwelltx) is chip-agnostic and
runs on Kestrel unchanged — validated on-air on an 8852B DUT: 3-channel
dwell-1, zero wrong-channel, ~97% delivery.

Kestrel's FastRetune started at ~44 ms/hop (vs ~2 ms on the 8822B). Profiling
put the cost in the vendored halrf channel setting, and the 11ac compose-cache
recipe applies here too: fast_rf_channel_8852b is a write-only port of
halrf_ctrl_ch_8852b — it primes the RF18 (DAV+DDV) and RF 0xcf dwords once per
epoch (invalidated by every full set_channel) and thereafter composes the
channel bits and writes whole dwords, cutting ~12 per-hop reads. The path-A
synth relock (halrf_set_s0_arfc18: 0xd3 hold + RF18 write + 0xb7 LCK poll) and
fast_lck_check_8852b (0xc5 verify + MMD-reset fallback) are kept verbatim —
load-bearing (skipping the relock deafens the radio) and the LCK poll reads the
physical lock, so that plus the a-die SI writes is the irreducible floor. Two
more cuts: the synth-lock diagnostic reads are gated off the hot path
(vnd_rf_tune diag=false) and the gain-error re-applies only on a 5 GHz sub-band
bucket move. Net ~44 -> ~25 ms; soak 1500 hops, zero LCK timeouts, delivery
unchanged. 8852C keeps the vendored tune (the lean path returns false). rtw89
exposes no firmware channel-switch H2C (only SCAN_OFFLOAD + MCC).

Also fixes the dwelltx teardown to release the device before libusb_exit (the
Kestrel worker planes were still live, tripping a libusb mutex assertion).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@josephnef
josephnef force-pushed the kestrel-fastretune-opt branch from 5453209 to f39a20b Compare July 20, 2026 18:23
@josephnef josephnef changed the title Kestrel: trim the FastRetune hop + bring up the dwell-1 data plane on AX Kestrel: compose-cache FastRetune (44→25 ms) + dwell-1 data plane on AX Jul 20, 2026
@josephnef
josephnef merged commit 2df59d3 into master Jul 20, 2026
18 checks passed
@josephnef
josephnef deleted the kestrel-fastretune-opt branch July 20, 2026 18:32
josephnef added a commit that referenced this pull request Jul 20, 2026
…9 ms) (#327)

Follow-up to #326's compose-cache — the two remaining levers, both
measured and soak-validated (and both contradicting my earlier "that
would deafen the radio" guess; I tested rather than assumed this time).

Per-stage profiling of the ~25 ms compose-cache hop showed the split:
**synth relock 10–18 ms** (~60%), path-B write ~3 ms, DDV ~3 ms.

## Lever 1 — relock only on a sub-band crossing (the big one)

The path-A channel write runs a full synth PLL relock
(`halrf_set_s0_arfc18`: `0xd3` hold + RF18 write + a **~13 ms `0xb7` LCK
poll**) + `fast_lck_check` (MMD-reset recovery). For a **same-sub-band**
hop the VCO moves only a little and settles on its own during the
caller's admission window, so the LCK poll is pure blocking — a plain
RF18 write holds channel accuracy. The full relock (the only path with
lock-failure recovery) is kept for a **sub-band crossing** (a bigger VCO
jump), gated on the same `gain_bucket` change that already drives the
gain re-apply.

## Lever 2 — drop the DDV writes

The d-die `0x10018` window is not populated on the single-die 8852B, so
its two SI writes + two `0xcf` toggles cost no channel accuracy.

## Results (8852B DUT, host oracles)

| hop | switch | wrong-channel |
|---|---|---|
| same-sub-band (36/40/44) | **~9 ms** | 0 (delivery 98.5%) |
| cross-sub-band (36/44/149) | ~13 ms | 0 |
| aggressive-config soak, 2000 hops | — | **0** (delivery ~97%) |

Net from the ~44 ms unoptimized hop: **~5×** (44 → 9 ms), putting
Kestrel FHSS within reach of the 11ac chips (~50 ms dwell-1 slot → ~30
ms). A `SetMonitorChannel` still always relocks, so the fast hop's
dropped lock-verify guarantee is bounded to the intra-sub-band case
where it's empirically safe.

Docs: updated Kestrel row + explanation in `docs/frequency-hopping.md`
and the FastRetune section in `src/kestrel/CLAUDE.md`. ctest 36/36.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
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