gc_bba_test: free the RX ring before waiting for a frame

t_rx reported "no frame in 2 s (RWP still 0x000F)" on a healthy adapter after
the Ethernet suite had been run a few times.  Page 15 is the giveaway: the app
never writes RRP, so ambient broadcast traffic fills the 15-page ring until
free = (1 + 15 - 15) mod 15 = 1, below _MAX_FRAME_PAGES (6).  RBFI then drops
every frame -- correctly, that is what it is for -- RWP stops advancing
permanently, and a test that waits for RWP to move can never pass again for the
rest of the session.

t_rx now catches RRP up to RWP before waiting, declaring what is already in the
ring consumed.  That is what a real driver does once it has read the frames out
and what netboot already does at start-up.  It also leaves exactly the newly
received frame unconsumed at RRP, which is where the SPRAM/DMA suite reads, so
t_dma still has something to parse.

No gateware change: the drop behaviour was correct and the bug was in the test
app's failure to consume.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-10-10 10:14:19 +02:00
parent e20b34b5e9
commit 2b0cbdd809
+16
View File
@@ -325,6 +325,22 @@ static int t_rx(char *m, size_t n)
u8 r0[2], r1[2];
int i, ir;
if (bba_read(REG_RWP_LO, r0, 2) < 0) { snprintf(m, n, "RWP read failed"); return 1; }
/* Catch RRP up to RWP before waiting, i.e. declare everything already in
* the ring consumed -- which is what a real driver does once it has read
* the frames out, and what netboot does at start-up.
*
* ⚠️ Without this the test fails on a HEALTHY adapter. This app never
* writes RRP, so ambient broadcast traffic fills the 15-page ring, `free`
* falls below _MAX_FRAME_PAGES (6) and RBFI then drops EVERY frame --
* correctly, to avoid lapping. RWP stops advancing permanently and this
* test reports "no frame in 2 s (RWP still 0x000F)" for the rest of the
* session. Page 15 is the giveaway: free = (1 + 15 - 15) mod 15 = 1.
*
* Freeing the ring here also leaves exactly the newly received frame
* unconsumed at RRP, which is where the SPRAM/DMA suite reads. */
if (bba_w8(REG_RRP_LO, r0[0]) < 0) {
snprintf(m, n, "RRP write failed"); return 1;
}
for (i = 0; i < 200; i++) { /* up to ~2 s */
if (bba_read(REG_RWP_LO, r1, 2) < 0) { snprintf(m, n, "RWP read failed"); return 1; }
ir = bba_r8(REG_IR);