Reception using DMA
Initialization
When µCµC/TCP-IP is initialized, the Network Device Driver allocates a memory block for all Receive descriptors; this is performed via calls to µCµC/LIB.
Then, the network device driver must allocate a list of descriptors and configure each address field to point to the start address of a Receive buffer. At the same time, the network device driver initializes three pointers: one to track the current descriptor, which is expected to contain the next received frame; a second to remember the descriptor list boundaries; and a third for the descriptor list starting address.
...
Figure 7-10 Descriptor allocation
F7-10(1) µCµC/TCP-IP allocates a list of descriptors based on the network device driver configuration and sets each address field to point to the start address of a receive buffer.
...
RxBufDescPtrStart
This pointer doesn’t doesn’t move, it always points to the first descriptor.
...
RxBufDescPtrEnd
This pointer doesn’t doesn’t move, it always points to the last descriptor.
...
NetDev_ISR_Handler()
is the function called by the IF layer when a Ethernet related ISR is generated and handled by the BSP layer. When Rx ISR occur, only NetOS_IF_RxTaskSignal()
has to be called. Nothing has to be done on RxBufDescPtrCur
. The complete receive process is delayed in order to have the fastest ISR handler as possible. If an error occurred on RX, you can increment driver statistic into the ISR handler or into NetDev_Rx()
, it’s it’s up to you to determine which of the cases is best. You must always signal the core that a packet is received using NetOS_IF_RxTaskSignal()
. If you fail to notify the core for each packet, a buffer leak will occur and performance will degrade. NetDev_Rx()
will discard the packet and it will say to the µCµC/TCP-IP module that the packet is received with an error.
...
NetDev_Rx()
is called by core once a NetOS_IF_RxTaskSignal()
call has been made to recover the received packet. If data received is valid, this function must replace the buffer of the current descriptor with a free buffer. Also, the current descriptor must be restarted (owned by the DMA) to be able to receive again. RxBufDescPtrCur
must be moved to point on the next descriptor. The sub-function NetDev_RxDescPtrCurInc()
is called to restart the current descriptor and to move the pointer to the next descriptor. If an error has occurred, you have to set data and length pointers to 0 and return an error. If there is no free Rx buffer available, the packet must be discarded by leaving the current data buffer assigned to the DMA, increment the current descriptor and return an error to the µCµC/TCP-IP module. Here is a pseudo code of NetDev_Rx()
:
...
L7-8(8) Set the value of the descriptor’s descriptor’s data buffer to the newly allocated data area.
...
NetDev_Stop()
is called to shutdown a network interface hardware by disabling the receiver and transmitter, disabling receive and transmit interrupts, free all receive descriptors and deallocate all transmit buffers. When the interface is stopped, you must deallocate the DMA descriptor ring. To do that, a sub-function is called NetDev_RxDescFreeAll()
where each descriptor’s descriptor’s buffer is freed and the DMA controller control is disabled:
...