From 2b0cbdd8096e175500ca9bb4e323f68780eaee87 Mon Sep 17 00:00:00 2001 From: Dennis Brentjes Date: Sat, 10 Oct 2026 10:14:19 +0200 Subject: [PATCH] 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 --- gc_bba_test/source/tests.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/gc_bba_test/source/tests.c b/gc_bba_test/source/tests.c index b87484b..440ac3e 100644 --- a/gc_bba_test/source/tests.c +++ b/gc_bba_test/source/tests.c @@ -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);