netboot: detect being lapped by the ring writer; quiet-link guidance
The alignment bug is FIXED -- hardware now reports "frame 1 (342 B) etype=0800 at 12: FF FF FF FF FF FF 00 2B", i.e. broadcast dst at 0, host MAC at 6, ethertype at 12. Perfectly aligned, correctly received, correctly skipped as not ours. So 00 00 00 01 was never a dropped write. It is frame data being read as a descriptor, because the ring HAS NO OVERFLOW PROTECTION: nothing in the gateware consumes RRP, so RXFrameAssembler keeps writing and laps the reader (the real BBA has RBFI for exactly this). The poll loop costs ~5 EXI transactions per frame (~200 us) while a 100 Mbit link delivers a 342-byte frame every ~30 us, and the ring is 15 pages -- roughly 3 to 11 frames. Under continuous traffic pages are reused before they are read. That is also why it "worked once out of three tries": it is a race against the host's background traffic. ring_next() now returns -4 when the writer is more than two thirds of the ring ahead, and the caller resyncs and continues instead of parsing bytes that belong to a different frame. The timeout reports seen / bad-descriptor / lapped counts so the three cases stay distinguishable. Detection is not prevention, so the app and the README both now say to quiet the link first with gc-testlink.sh, which sets a static address and takes the interface out of NetworkManager -- stopping the DHCP client whose 342-byte broadcasts are the main offender. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -122,6 +122,33 @@ suite already proves on hardware — `bba_tx_bytes()` for TX and the SPRAM ring
|
||||
at RRP for RX — so each update doubles as a few hundred round trips of soak
|
||||
testing through that path.
|
||||
|
||||
### ⚠️ Quiet the link first — the ring has no overflow protection
|
||||
|
||||
```bash
|
||||
sudo ./scripts/gc-testlink.sh up <iface> # static IP, no DHCP, NM off
|
||||
```
|
||||
|
||||
Nothing in the gateware consumes RRP, so `RXFrameAssembler` keeps writing and
|
||||
**laps the reader** — the real BBA has RBFI for this and this design does not.
|
||||
The poll loop costs ~5 EXI transactions per frame (~200 µs) while a 100 Mbit
|
||||
link delivers a 342-byte frame every ~30 µs, and the ring is only 15 pages
|
||||
(~3–11 frames). Under continuous traffic pages are overwritten before they are
|
||||
read, and the "descriptor" you then parse is really frame data from the frame
|
||||
that replaced it.
|
||||
|
||||
That is where a descriptor of `00 00 00 01` comes from. It is **not** a dropped
|
||||
write — it is someone else's bytes.
|
||||
|
||||
The biggest offender is usually the host's own DHCP client broadcasting on that
|
||||
interface (a 342-byte broadcast). `gc-testlink.sh up` sets a static address and
|
||||
takes the device out of NetworkManager, which stops it. Disabling IPv6 and mDNS
|
||||
on that interface helps further.
|
||||
|
||||
`netboot_receive()` detects being lapped (writer more than two thirds of the
|
||||
ring ahead), resyncs and continues rather than parsing untrustworthy bytes, and
|
||||
reports the count on timeout — but detection is not prevention. A busy link
|
||||
will still cost retransmissions.
|
||||
|
||||
### Stop-and-wait is load-bearing
|
||||
|
||||
The gateware does not consume RRP, so `RXFrameAssembler` can overwrite ring
|
||||
|
||||
Reference in New Issue
Block a user