RX path failures are more subtle than
TX failures because packets can potentially arrive at the PHY but never reach the
application due to ALE filtering or DMA buffer exhaustion. Understanding the
complete packet flow from wire to application helps isolate where the failure
occurs. The expected RX packet flow is:
When a packet arrives from the
network, the packet follows this sequence:
- The packet arrives at an external
MAC port → macStats.rxGoodFrames increments.
- The ALE examines the destination
MAC and forwards the destination to the host port → hostStats.rxGoodFrames
increments.
- DMA transfers the packet to
memory → An RX interrupt fires.
- The application retrieves the
packet → The EnetDma_retrieveRxPktQ() function returns packet.
If any step fails, packets are dropped silently. Start debugging by setting a
breakpoint in your RX interrupt handler or callback function, typically named
something like EnetApp_rxIsrFxn(). Send a test packet to the device from a link
partner. If the breakpoint never hits:
- Check that the EnetDma_enableRxEvent() function was called on your RX channel
handle during initialization.
- Verify the interrupt routing configuration in SYSCFG matches the CPSW interrupt
controller setup.
- Read the host port statistics
directly and check if rxGoodFrames is incrementing.
Note: If rxGoodFrames increases, but the interrupt
handler never called, the problem is in the interrupt configuration not the
packet reception.
If the interrupt handler breakpoint
does hit, the RX hardware path is working correctly.
- Move to the next checkpoint by setting a breakpoint at the
EnetDma_retrieveRxPktQ() function inside your RX task.
Note: This function
retrieves packets from the DMA and places those packets in a queue for
application processing.
- Step through the retrieve call and inspect the returned queue count.
A critical, but often overlooked aspect of RX debugging, is buffer resubmission.
After the application processes each received packet, the application must return
the buffer to the DMA by calling the EnetDma_submitRxPktQ() function.
- Set a breakpoint at this function call and verify the breakpoint executes for
every packet retrieved. If buffers are not resubmitted:
- The DMA descriptor pool gradually exhausts.
- Subsequent packets are dropped even though the packets arrive at the
host port.
- Manifests as the initial packets being received successfully, followed
by complete RX silence.
- The rxBottomOfFifoDrop counter in host port statistics increments
rapidly.
Note: Your code flow must be: Retrieve packet → Process data → Resubmit
buffer. Missing the resubmit step is the most common RX
implementation bug.
Statistics counters provide definitive
evidence of where packets are being dropped. Read both the MAC port and the host
port statistics before and after sending a test packet in the following
scenarios:
Scenario 1: MAC rxGoodFrames
increments but the host rxGoodFrames does NOT →
- The ALE is filtering packets
before the packets reach the host (the most common RX failure).
- Check the hostStats.portMaskDrop
counter.
- If the portMaskDrop increments:
The ALE entry exists but the port mask excludes the host port.
- Dump the ALE table with
CPSW_ALE_IOCTL_DUMP_TABLE and verify the destination MAC has entry with the host
port included.
Scenario 2: Both MAC and the host
rxGoodFrames increment, but the application identifies nothing.
- The packets reach DMA but the
application does not retrieve the packets.
- Check the RX task is running and
being scheduled by RTOS.
- Verify the
EnetDma_retrieveRxPktQ() function is called in response to the RX
interrupt.
- Common bug: Forgetting to post
semaphore in the interrupt handler to wake the RX task.
Scenario 3: Counters increment
initially, then stop.
- The RX descriptor pool is
exhausted (missing buffer resubmission).
- Check the rxBottomOfFifoDrop
counter.
- Verify the EnetDma_submitRxPktQ()
function is called after processing each packet.
This methodical approach isolates the exact failure point in the RX path.