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:
@@ -325,6 +325,22 @@ static int t_rx(char *m, size_t n)
|
|||||||
u8 r0[2], r1[2];
|
u8 r0[2], r1[2];
|
||||||
int i, ir;
|
int i, ir;
|
||||||
if (bba_read(REG_RWP_LO, r0, 2) < 0) { snprintf(m, n, "RWP read failed"); return 1; }
|
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 */
|
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; }
|
if (bba_read(REG_RWP_LO, r1, 2) < 0) { snprintf(m, n, "RWP read failed"); return 1; }
|
||||||
ir = bba_r8(REG_IR);
|
ir = bba_r8(REG_IR);
|
||||||
|
|||||||
Reference in New Issue
Block a user