Skip to content

Kestrel per-packet TX power: radiotap DBM_TX_POWER via fixed-dBm rewrite#302

Merged
josephnef merged 1 commit into
masterfrom
kestrel-per-pkt-txpwr
Jul 18, 2026
Merged

Kestrel per-packet TX power: radiotap DBM_TX_POWER via fixed-dBm rewrite#302
josephnef merged 1 commit into
masterfrom
kestrel-per-pkt-txpwr

Conversation

@josephnef

Copy link
Copy Markdown
Collaborator

What

Per-packet TX power for the Kestrel generation (RTL8852BU/8832BU + RTL8852CU/8832CU) — the last family without a per-packet or fast power lever.

The AX WD descriptor carries no per-frame power field (both wd_body layouts; the vendor mac_ax tree has none either), so the descriptor-LUT/bank approach of the 11ac families doesn't apply. Instead this uses the cheapest power write in the tree: the fixed-dBm BB target (0x09a4[16] arm + 0x4594[30:22] s(9,2)) is 2 register RMWs at 0.25 dB resolution. Since Kestrel submits one bulk transfer per frame, send_packet now honours a radiotap DBM_TX_POWER dB-delta by rewriting that target between frames when the requested level changes:

  • free while the value stays constant (change-detect against the hal offset member); 2 RMWs on a change
  • a field-less frame restores the SetTxPowerOffsetQdb session offset
  • clamped to the same 0..23 dBm PA window as the session lever, around the DEVOURER_TX_PWR base (whole dBm on this family)
  • sticky across SetMonitorChannel/FastRetune for free — the hal offset member is the single source of truth and both re-apply paths already fold it
  • global, like the Jaguar1 BB-swing lever: a HW beacon airing between frames follows the last-written level (documented)

Plumbing:

  • AdapterCaps: per_packet_txpower=true, per_pkt_txpwr_steps=0 (continuous), step_qdb=1 (0.25 dB), min/max from the PA window, measured=true
  • DEVOURER_TX_PKT_OFSET fans out to Kestrel too (nominal LUT dB onto the session fixed-dBm offset; radiotap still overrides per frame) — the shared on-air harness drives Kestrel DUTs unchanged
  • tests/txpkt_pwr_ofset_onair.sh gains a TX_PWR knob (Kestrel reads DEVOURER_TX_PWR as dBm — the Jaguar-index default 40 would clamp; TX_PWR=14 gives the ±sweep headroom)

Validation

On-air, ch36, MCS3, 14 dBm base, 8822BU chip-RSSI ground, windowed medians:

DUT LUT-mapped cells Radiotap per-packet cells Tracking
8852BU 5/5 2/2 +3→+3, +6→+6 exact; deep cuts over-deliver ~3 raw at the uncalibrated low-dBm end
8832CU 5/5 2/2 near-exact: +3→+3, +6→+6, −3→−3, −7→−6, −11→−10

Headless: full ctest 27/27; kestrel-only subset config builds and passes 26/26.

With this, every supported generation has a validated per-packet or fast TX-power lever.

🤖 Generated with Claude Code

The AX WD descriptor carries no per-frame power field (both wd_body
layouts; vendor mac_ax has none either), but Kestrel's power write is the
cheapest in the tree: the fixed-dBm BB target (halbb_set_txpwr_dbm form,
0x09a4[16] arm + 0x4594[30:22] s(9,2)) is 2 RMWs at 0.25 dB resolution.
Since Kestrel submits one bulk transfer per frame, send_packet now honours
a radiotap DBM_TX_POWER dB-delta by rewriting that target between frames
when the requested level changes — free while it stays constant, no
run-splitting machinery needed. A field-less frame restores the
SetTxPowerOffsetQdb session offset; the trim is clamped to the same
[0, 23] dBm PA window; the hal offset member stays the single source of
truth, so the existing set_channel/fast_retune re-apply keeps the
last-written level sticky across channel switches. Global, like the J1
BB-swing lever: a HW beacon airing between frames follows.

Caps: per_packet_txpower=true, steps=0 (continuous), step_qdb=1, min/max
derived from the PA window around the session base. DEVOURER_TX_PKT_OFSET
now fans out to Kestrel too (nominal LUT dB onto the session fixed-dBm
offset, radiotap still overriding per frame); the on-air harness gains a
TX_PWR knob (Kestrel reads DEVOURER_TX_PWR as whole dBm — 14 gives the
sweep headroom the Jaguar index 40 default would clamp away).

On-air (ch36, MCS3, 14 dBm base, 8822BU chip-RSSI ground): 8852BU 5/5
LUT-mapped cells + 2/2 radiotap cells correct (+3/+6 exact; deep cuts
over-deliver ~3 raw at the uncalibrated low-dBm end); 8832CU 5/5 + 2/2
near-exact (+3->+3, +6->+6, -3->-3, -7->-6, -11->-10).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@josephnef
josephnef merged commit 874b970 into master Jul 18, 2026
18 checks passed
@josephnef
josephnef deleted the kestrel-per-pkt-txpwr branch July 18, 2026 15:22
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