DEVOURER_ACK_TIMEOUT_US: the hardware-ARQ range lever, every generation - #380
Conversation
The MAC writes a frame off (and retries) when no ACK is counted within its
response window, and round-trip propagation eats ~6.7 µs/km — so the window
is what caps hardware-ARQ distance. It is one 8-bit µs register everywhere:
REG_ACKTO 0x640 on the 11ac generations (J1/J2 default 0x80 — the vendor
doubled its own 0x40 "for BCM IOT"; J3 halmac default 0x21, scaled to
0x3D/0x75 at 10/5 MHz narrowband), R_AX_RSP_CHK_SIG 0xCC00 byte0 on Kestrel
(the field its vendor narrowband path scales). The knob (1..255 µs, 0 =
per-chip default) applies at bring-up; on J3 it overrides the per-bandwidth
default init_wmac_cfg writes, so an override must budget the slowest ACK
duration in use.
Bench (8812CU TX -> live 8812EU responder, MCS3, retry 8):
default: ok=100% retries {0:891, 1:3}
ACKTO=8: ok=0% retries pinned {8:907} — the window closes before the
ACK's flight time, every frame written off despite the
responder ACKing: the register provably gates the ARQ verdict
ACKTO=255: ok=100% retries {0:897, 1:5} — opening the window costs
nothing at bench range
Register-proof on the other families: 0x640 reads back 0xfa on the 8821AU
and 0xCC00 byte0 0xfa on the 8832CU with ACKTO=250.
Also: the DeviceConfig retry_limit doc no longer claims the knob is inert
on Kestrel (its WD attempts field carries it).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
PR Summary by QodoAdd DEVOURER_ACK_TIMEOUT_US to tune hardware ACK window across generations
AI Description
Diagram
High-Level Assessment
Files changed (7)
|
…e-offs 1.8x under loss The "255 behaves as the default" claim held only when ACKs arrive. The other half, measured (dead RA, retry 8, max duty on the 8812CU): every retry of a lost frame waits the full window, so write-off cadence drops 2719 -> 2015 -> 1507 frames/8 s at 33/128/255 µs (~1.8x slower at max). Size the window to the link (~6.7 µs/km + margin); the 0/vendor-faithful default exists precisely so nobody pays this tax without opting in. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Code Review by Qodo
1.
|
…ly doc - DEVOURER_ACK_TIMEOUT_US=0 no longer collapses to 1 µs (which would write off every frame) — 0 passes through as use-per-chip-default; verified live: =0 leaves REG_ACKTO at the halmac 0x21. - Programmatic ack_timeout_us > 255 clamps at every apply site instead of silently wrapping through the uint8_t cast. - The doc claims the ACK window only — the CTS window (REG_CTS2TO 0x641) is a separate register this knob does not touch. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…er-chip sentinel
The 0-means-vendor-default design exported four chips' defaults through one
knob: the same configuration gave 128 µs of range budget on an 8812AU and
33 µs on an 8812CU — hardware-ARQ range silently depended on which die was
plugged, the same per-chip-divergence disease the EDCCA silent no-op was
(and the opposite of the retry-limit knob, whose +1 fold exists precisely
so N means N everywhere).
Now: ack_timeout_us defaults to 128 and is programmed identically on every
generation at bring-up. 128 is the vendor's interop-blessed J1/J2 value
and covers the slowest narrowband ACK in the tree (5 MHz vendor value
117 µs), so the per-bandwidth special cases collapse too; J3 gains ~12 km
of round-trip range budget out of the box. Knob 1..255 clamped at parse
AND at every apply site (a sub-1 value would write off every frame — the
first cut of this rework proved it on air: a silently-failed default edit
left the field 0, the <1 clamp wrote a 1 µs window, and the validation
matrix caught 0% ok / retries pinned before it could ship).
Validated live, no env: 0x640 reads 0x80 on the 8812CU and 8821AU, 0xCC00
byte0 0x80 on the 8832CU; the responder cell at the uniform default runs
100% ok, retries {0:895, 1:4}. ctest 49/49.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Prompted by the PixelPilot dev's question: yes, the hardware ACK window is adjustable — and it's the knob that caps hardware-ARQ distance (round trip eats ~6.7 µs/km).
Design: one default, every chip
DEVOURER_ACK_TIMEOUT_US(1..255 µs, clamped) with a library default of 128 µs programmed identically on every generation — the same knob value means the same range budget (~15 km round trip) no matter which die is plugged. The vendor defaults ranged 33..128 µs per chip (and per bandwidth), which made hardware-ARQ range silently die-dependent — the same per-chip-divergence trap the EDCCA silent no-op was. 128 is the vendor's own interop-blessed J1/J2 value and covers the slowest narrowband ACK in the tree (5 MHz vendor value = 117 µs), so the per-bandwidth special cases collapse into the one number; J3 gains ~12 km of range budget out of the box.Register:
REG_ACKTO 0x640(11ac),R_AX_RSP_CHK_SIG 0xCC00byte0 (Kestrel). The CTS window (0x641) is separate and untouched.Measured, both directions
The 8 µs arm proves the register gates the ARQ verdict; the write-off column is the honest price of long windows (every retry of a lost frame waits the full window) — sizing guidance at the field doc: ~6.7 µs × round-trip km + ~50 µs margin.
Validated live with no env:
0x640reads0x80on the 8812CU and 8821AU,0xCC00byte00x80on the 8832CU. The first cut of this rework also demonstrated why the clamps matter: a silently-failed default edit left the field 0, the<1clamp wrote a 1 µs window, and the validation matrix caught 0% ok / retries pinned before it could ship.Also fixes the stale
retry_limitdoc claim that the knob is inert on Kestrel (#375 wired it).🤖 Generated with Claude Code