Skip to content

GetTxCaps + STBC-on-1T1R guard — stop airing malformed frames#197

Merged
josephnef merged 2 commits into
masterfrom
stbc-1t1r-guard
Jul 6, 2026
Merged

GetTxCaps + STBC-on-1T1R guard — stop airing malformed frames#197
josephnef merged 2 commits into
masterfrom
stbc-1t1r-guard

Conversation

@josephnef

Copy link
Copy Markdown
Collaborator

Why

From /tmp/adaptive-link-recipes.md (§10 pitfalls): "LDPC/STBC forced on a card that lacks them → link dies" — the 8811AU/8821AU/8821CU are 1T1R, and STBC needs ≥2 TX chains. devourer set the STBC descriptor bit unconditionally from the radiotap flag, even on 1T1R parts, producing a PPDU that never decodes.

Measured — it's a real delivery bug, not just spec-illegal

A/B on the 8821AU injecting MCS1/STBC, second-adapter delivery count:

build on-air delivery
unguarded (master) — STBC forced on 1T1R 0 hits
guarded — STBC dropped to clean MCS1 7000 hits

The recipe's "link dies" is literal.

What

  • src/TxCaps.hdevourer::TxCaps {n_ss, stbc_ok, ldpc_ok, sgi_ok, bw_max_mhz} + tx_caps_for_chains() (the load-bearing rule: stbc_ok = chains >= 2).
  • IRtlDevice::GetTxCaps() default + per-family override from the chip identity devourer already resolves: Jaguar1 EepromManager numTotalRfPath, Jaguar2 ChipVariant (C8821C 1T1R vs C8822B 2T2R), Jaguar3 8822C/E 2T2R.
  • send_packet drops STBC + warns once when !stbc_ok (each family). A no-op on 2T2R/4T4R; byte-identical when STBC isn't requested.

Validation

  • Unit (ctest + mingw list): TxCapsSelftest — the chains → {n_ss, stbc_ok} rule (1T1R→no STBC, 2T2R/4T4R→STBC ok).
  • On-air (tests/stbc_1t1r_check.sh): 4/4 — 8821AU + 8821CU (1T1R) drop STBC and deliver (6500/6000 hits) with the warning; 8812AU + 8822BU (2T2R) honour STBC, no warning, deliver.

Full all-chips build + J1-only subset green. GetTxCaps also gives an adaptive controller a clean way to query STBC/LDPC/n_ss/bw before requesting a feature.

🤖 Generated with Claude Code

josephnef and others added 2 commits July 6, 2026 11:50
The adaptive-link recipes flag a real footgun: "LDPC/STBC forced on a card that
lacks them => link dies" (8811AU/8821AU/8821CU are 1T1R; STBC needs >=2 TX
chains). devourer set the STBC descriptor bit unconditionally from the radiotap
flag, even on 1T1R parts, producing a PPDU that never decodes.

Measured A/B on the 8821AU (MCS1/STBC): forcing STBC delivered 0 frames; with
the guard (STBC dropped to clean MCS1) it delivered 7000. Real correctness fix,
not just defensive.

- src/TxCaps.h — devourer::TxCaps {n_ss, stbc_ok, ldpc_ok, sgi_ok, bw_max_mhz}
  + tx_caps_for_chains() (the load-bearing rule: stbc_ok = chains >= 2).
- IRtlDevice::GetTxCaps() default; per-family override from the chip identity
  devourer already resolves (Jaguar1 EepromManager numTotalRfPath; Jaguar2
  ChipVariant C8821C=1T1R vs C8822B=2T2R; Jaguar3 8822C/E 2T2R).
- send_packet drops STBC + warns once when !stbc_ok (each family; a no-op on
  2T2R/4T4R, byte-identical when STBC isn't requested).

Validated: TxCapsSelftest (ctest + mingw list) on the chains->caps rule;
tests/stbc_1t1r_check.sh 4/4 on-air — 8821AU + 8821CU (1T1R) drop STBC and
deliver (6500/6000 hits) with the warning; 8812AU + 8822BU (2T2R) honour STBC,
no warning, deliver. Full build + J1-only subset green.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@josephnef josephnef merged commit aabb011 into master Jul 6, 2026
15 checks passed
@josephnef josephnef deleted the stbc-1t1r-guard branch July 6, 2026 09:05
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