Skip to content

GetTxStats — driver-drop / congestion signal (xtx) for adaptive link#200

Merged
josephnef merged 3 commits into
masterfrom
tx-stats
Jul 6, 2026
Merged

GetTxStats — driver-drop / congestion signal (xtx) for adaptive link#200
josephnef merged 3 commits into
masterfrom
tx-stats

Conversation

@josephnef

Copy link
Copy Markdown
Collaborator

Why

Adaptive-link controllers key their bitrate cut on a driver-side TX-drop signal (/tmp/adaptive-link-recipes.md §1: driver-dropped TX → cut bitrate ~80% for 1 s — the "xtx" feed). devourer discarded it: send_packet returned bool, the libusb rc was dropped, and there was no way to tell FIFO back-pressure (recoverable congestion) from a dead path.

What

  • src/TxStats.hdevourer::TxStats {submitted, failed, last_error_rc, last_was_timeout}. Load-bearing field: last_was_timeout — a bulk-OUT TIMEOUT is the chip NAKing a full TX FIFO (congestion) vs a hard error (broken link).
  • RtlUsbAdapter counts at the shared USB bulk-OUT layer → family-neutral, covering both TX paths: the async send_packet (submit error + the transfer_callback completion, where LIBUSB_TRANSFER_TIMED_OUT surfaces) and the sync bulk_send_sync_ep (LIBUSB_ERROR_TIMEOUT). Counters are heap-shared (shared_ptr, like _tx_wedged) because the adapter is a copyable value type and the async callback runs on whichever copy submitted.
  • IRtlDevice::GetTxStats() default {} + a one-line forward on each of the three devices. txdemo emits <devourer-txstats>submitted/failed/was_timeout/last_rc on its periodic tick.

Validation — on-air, both counting paths (tests/tx_stats_congestion.sh, 3/3)

Back-to-back TX (gap=0, fills the FIFO) vs paced (gap=2000):

DUT path back-to-back paced
8812AU async failed=2891, was_timeout=1, rc=-2 (TRANSFER_TIMED_OUT) 0
8822EU sync failed=448, was_timeout=1, rc=-7 (ERROR_TIMEOUT) ~0
8822BU sync (USB3) 33k submitted, failed=0 — no congestion 0

The counter separates FIFO back-pressure from a healthy link on every family, and the timeout classification is correct on both the async (TRANSFER_TIMED_OUT) and sync (ERROR_TIMEOUT) paths.

No ctest selftest: the logic is USB-layer plumbing (not a pure mapping like M2's chains→caps), so the on-air A/B is the validation. Full all-chips build + ctest (8/8) green.

🤖 Generated with Claude Code

josephnef and others added 3 commits July 6, 2026 12:17
The adaptive-link controllers key their bitrate cut on a driver-side TX-drop
signal (the "xtx" feed). devourer discarded it: send_packet returned bool, the
libusb rc was dropped, and there was no way to tell FIFO back-pressure from a
dead path.

- src/TxStats.h — devourer::TxStats {submitted, failed, last_error_rc,
  last_was_timeout}. The load-bearing field is last_was_timeout: a bulk-OUT
  TIMEOUT is the chip NAKing a full TX FIFO (recoverable congestion) vs a hard
  error (broken link).
- RtlUsbAdapter counts at the shared USB bulk-OUT layer, so it is family-neutral
  and covers BOTH TX paths: the async send_packet (submit + the transfer_callback
  completion, where LIBUSB_TRANSFER_TIMED_OUT surfaces) and the sync
  bulk_send_sync_ep (LIBUSB_ERROR_TIMEOUT). Counters are heap-shared (shared_ptr,
  like _tx_wedged) because RtlUsbAdapter is a copyable value type and the async
  callback runs on whichever copy submitted.
- IRtlDevice::GetTxStats() default {} + a one-line forward on each of the three
  devices. txdemo emits <devourer-txstats>submitted/failed/was_timeout/last_rc
  on its periodic tick.

Validated on-air (tests/tx_stats_congestion.sh, 3/3, both counting paths):
back-to-back TX (gap=0) vs paced (gap=2000).
- 8812AU (async): b2b failed=2891 was_timeout=1 last_rc=-2 (TRANSFER_TIMED_OUT);
  paced 0.
- 8822EU (sync):  b2b failed=448  was_timeout=1 last_rc=-7 (ERROR_TIMEOUT);
  paced ~0.
- 8822BU (USB3):  drains at 33k submitted, failed=0 both — no congestion,
  reported honestly.
So the counter separates FIFO back-pressure from a healthy link on every family.

No ctest selftest: the logic is USB-layer plumbing (not a pure mapping like
M2's chains->caps), so the on-air A/B is the validation.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@josephnef josephnef merged commit 61a9912 into master Jul 6, 2026
15 checks passed
@josephnef josephnef deleted the tx-stats branch July 6, 2026 09:32
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