fix(tx): queue the frame length at TWD_HI so the drain runs concurrently
TXFrameDrain sat in IDLE until it had a length, and the length only reached tx_ctrl when the NCRA ST bits were written -- after the GC had streamed the whole frame. So the entire frame had to fit in the 16-deep tx_bytes FIFO, and BBARegisterFile silently drops bytes when w_rdy is low (SPI cannot back-pressure). On hardware this truncated frames at exactly 16 bytes: a captured ARP had 16 correct bytes followed by the frame restarting over itself. The length is now handed to the drain one cycle after the TWD_HI (0x35) write, which the GC issues BEFORE streaming data. The drain starts early and blocks on tx_bytes_r_rdy, consuming bytes as they arrive, so tx_bytes becomes a rate-matching buffer instead of whole-frame storage. The ST write remains a fallback trigger for software that skips TWD, guarded by tx_queued so one frame is never queued twice. Adds BBATop T8: streams a 34-byte frame (> the 16-deep FIFO) over EXI and checks the W5100 model received it byte-for-byte. Verified to FAIL without the fix with exactly the hardware symptom -- 16/34 bytes, first bad byte at index 16. The gap that let this ship: TXFrameDrain's own tests drive the FIFO signals directly, and the BBATop test only covered the RX loop. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -6,7 +6,14 @@ to notify the GC that the transmit is complete.
|
||||
|
||||
Flow
|
||||
----
|
||||
1. Wait for tx_len FIFO to have a length word (signals a complete frame queued).
|
||||
1. Wait for tx_len FIFO to have a length word.
|
||||
|
||||
NOTE the length arrives when the GC writes TWD_HI (0x35), i.e. BEFORE it
|
||||
streams the frame bytes -- not at the NCRA ST trigger. So this FSM starts
|
||||
early and blocks in DRAIN on tx_bytes_r_rdy, consuming bytes as the GC
|
||||
writes them. That is deliberate: tx_bytes is only 16 deep, so waiting for
|
||||
ST (after the whole frame had been written) silently dropped everything past
|
||||
byte 16 -- observed on hardware as frames truncating at exactly 16 bytes.
|
||||
2. Pop the length from tx_len FIFO.
|
||||
3. Assert tx_sof on first byte, tx_eof on last byte, consuming tx_bytes FIFO.
|
||||
4. When W5500SPIMaster accepts the final byte: pulse tx_irq.
|
||||
|
||||
Reference in New Issue
Block a user