Repository navigation
M0 contracts on Kestrel/PCIe: beacon update/stop, PPDU-status pairing fix, PCIe-capable probes - #515
Conversation
… fix, PCIe-capable probes Re-measuring the four M0 contracts (#261) on RTL8852CE over PCIe (epic #254 rig) found three Kestrel gaps and one RX bug: - UpdateBeaconPayload was not implemented: now the BCN_UPD_V1 H2C with new content, port and TBTT untouched. 30/30 updates aired, 0 skips, 0 torn, update->air 13/16 ms p50/p99. - StopBeacon was not implemented, so a beacon kept airing after its process exited: now BCNTX_EN off (vendor MAC_AX_PCFG_TX_SW, rtw_hal_beacon_stop). - StartBeacon did not strip a leading radiotap header (IRadio contract), so a radiotap-prefixed beacon aired as a garbage frame. - RX: each PPDU-status report was attached to the WIFI frames that FOLLOWED it, but the MAC delivers a PPDU's frames first and its status after (traced: same ppdu_cnt, next RX buffer, ~140 us later), so every frame carried the previous PPDU's RSSI/SNR/EVM. Frames are now held until their status arrives (vendor phl_rx.c pairing: ppdu_cnt + rate/bw/gi/type), delivered without one on the next PPDU, after 2 ms idle, or at loop exit. This fixes per-UE attribution, GetRxQuality and GetActiveRxPaths on Kestrel. Attenuating one UE by 10 dB nominal now moves only that UE. The M0 probes (dl_departure_tx, txegress_witness, beacon_update_probe, ue_rx_probe) open USB or PCIe through examples/common/radio_open.h (DEVOURER_PCIE_BDF) and are CMake targets; dl_departure_tx takes DL_CSMA=1. docs/scheduled-mac.md gets the Kestrel rows: DL guard floor 1.3-2.0 us, p99.9 0.46 ms on a clean channel / 2.7 ms next to a foreign AP; the 8852CE ACK responder closes 1036/1036 first-try (9 copies unarmed). Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
PR Summary by QodoFix Kestrel beacon controls and RX pairing; enable PCIe M0 probes
AI Description
Diagram
High-Level Assessment
Files changed (11)
|
Code Review by Qodo
1.
|
- HeldRx value-initializes its Packet (Packet p{}): HeldRx h; left
rx_pkt_attrib's plain fields (pkt_rpt_type, seq_num, ...) indeterminate.
- A WIFI frame joins the held batch only if same_ppdu() (ppdu_cnt + rate,
bw, gi_ltf, ppdu_type), the same test the status pairing uses: the 3-bit
count wraps.
- held_mu: on USB's spsc RX mode on_data runs on a consumer thread while the
stop predicate's idle flush runs on the event thread.
- ITransport::set_rx_max_wait_us (USB: caps the 100 ms event wait / 200 ms
sync read): the Kestrel RX loop sets 1 ms, so the 2 ms hold bound holds on
USB too; reset on loop exit.
- StopBeacon also returns NET_TYPE to NO_LINK (IRadio StopBeacon contract).
- beacon_radiotap_len and same_ppdu move to FrameParserKestrel.h with
kestrel_rxparse selftest cases.
- The M0 probes are POSIX bench tools: not built on Windows (unistd.h).
Re-verified on RTL8852CE: ctest 79/79 on all three rig boxes; attenuated UE
reads -71.2 dBm vs -55.0 (no bleed); beacon update 30/30, 0 skips; 0 beacons
after StopBeacon; beacon egress 275/276 at 22 us.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
|
Addressed all five Qodo findings, plus the Windows build failure, in 2fe7abd:
Re-verified on RTL8852CE:
|
…t on macOS) Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
|
Applying |
…nner) (#517) `build-sanitizers` ran `cmake --build build-asan -j`. A bare `-j` is **unlimited**, so every target's RelWithDebInfo ASan+UBSan compile and link runs at once. At ~50 executables the hosted runner runs out of memory and is killed mid-link: "The runner has received a shutdown signal", exit 143. - Happened on master `c39b99b`, which went green only on a re-run. - Happened again on PR #516. - Both runs were killed at the same step (linking `Rtl8733bRxParseSelftest`, ~5.5 min in), after #515 added four probe executables. The fix is `-j "$(nproc)"`. This is the only unbounded `-j` in the workflows. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…Map IE (#516) Part of #255 (M1) / #254. This is the first headless piece of the single-cell scheduled MAC. It builds on the M0 contracts, re-measured on Kestrel in #515. - **`src/cell/SlotGrid.h`:** - Legacy-OFDM airtime and the epic's full **slot budget**: attempts × (PSDU + SIFS + ACK) + retry gaps + turnaround + the M0 departure guard. Payload size alone is not the budget. - The M1 **fixed grid** on one beacon interval: beacon, DL per UE, a turnaround guard, then UL per UE, anchored at the cell's TBTT phase. - TSF → superframe/slot lookup. - **`src/cell/GrantMap.h`:** - The DCI-style grant map as one vendor IE: version, cell id, epoch, *effective superframe*, period, and per-UE {dl/ul slot, rate, power, TA}, plus a CRC16. - Encode, decode, and find-in-beacon. - `GrantMapReceiver`: accepts only newer epochs, and applies a map at its superframe. That is the M0 beacon-update contract: content lands one to two TBTTs later, and the swap is not atomic, so maps are published for superframe N+2. - **`tests/cell_selftest.cpp`** (ctest `cell_core`) covers: - airtime against the 802.11a formula, and the budget arithmetic; - grid layout and overflow, and phase math across superframe boundaries and negative TSF; - IE round trip, plus every reject (CRC, version, OUI, length, truncation) and the 24-grant limit; - the receiver's replay, reorder and effective-superframe rules. Not in this PR: HT/HE airtime (M1 schedules legacy rates only) and authentication; the CRC detects corruption only. The scheduler, UE registry, DU/UE node and the on-air 2-UE test come next. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Part of #254. This re-measures the four M0 contracts (#261) on the RTL8852CE over PCIe/vfio, on the epic-254 rig: three J6412 boxes with two 8852CEs each, PTP-locked. M0 was originally measured on Jaguar USB and the 8821CE only, and every radio on the rig is Kestrel. The run found three Kestrel API gaps and one RX bug, all fixed here.
Fixes
UpdateBeaconPayloadwas not implemented on Kestrel. It is now theBCN_UPD_V1H2C with the new content; port and TBTT timing are not touched.StopBeaconwas not implemented, so a beacon kept airing after its process exited. It now clearsBCNTX_EN, matching vendorMAC_AX_PCFG_TX_SW/rtw_hal_beacon_stop.StartBeacondidn't strip a leading radiotap header, which the IRadio contract requires. A beacon with one (e.g.beacon_update_probe's) aired as a garbage frame and the witness heard nothing.ppdu_cntin the next RX buffer, ~140 µs later. So every frame carried the previous PPDU's RSSI/SNR/EVM.phl_rx.cpairing (ppdu_cntplus rate/bw/gi_ltf/ppdu_type).GetRxQualityandGetActiveRxPathson Kestrel.Tooling
examples/common/radio_open.h:dl_departure_tx,txegress_witness,beacon_update_probeandue_rx_probenow open USB or PCIe (DEVOURER_PCIE_BDF). They are also CMake targets now.dl_departure_txtakesDL_CSMA=1to keep carrier sense on.Measured (results in
docs/scheduled-mac.md)send_packet→air guardRe-checked after the RX change:
beacon_phase_observeregress timing is unchanged (276/276 at 22 µs, 0.43 µs RMS), and ctest passes 79/79 on j6412-1.Not covered: Kestrel USB (8852BU/CU, 8832xU) shares the RX loop but is not on this rig, so the pairing change is unverified there. The vendor pairing is bus-independent.
🤖 Generated with Claude Code