This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

AM3358-EP: Ethernet subsystem: Buffer Descriptor DMA stall & detection

Part Number: AM3358-EP

Hi there,

I have a mature bare-metal application using the AM3358-EP and its Ethernet subsystem (SPRUH73Q TRM chapter 14).

I can create the conditions for an RX DMA stall - whereby the DMA determines there are no buffer descriptors available "cycles before / at the same point" the host adds a new buffer descriptor to the chain.

Most of the time the suggested misqueue detection works well (Chapter 14.4.2 Receive Operation).

In some instances, the suggested "misqueue" detection mechanism fails. I can see that when the host checks the Buffer Descriptor in question, the DMA has not yet set the EOQ flag.

Compiled from the C language, using CPPI memory for BDs, I expected the DMA to be more efficient than the host.

1) When the DMA has determined an EOQ, can it please be confirmed that the DMA will action the Buffer Descriptor at the head descriptor pointer in the following order:

a) check the next pointer is null

b) set EOQ flag

c) clear ownership flag

d) write head descriptor pointer address to completion pointer

e) set head descriptor pointer to zero

2) can it be guaranteed that the DMA will complete the above "stall" in units of time / CPU cycles?

Edit - additional question added below:

3) Are there other mechanisms that would case the RX DMA to stall? The CPSW_STATS registers shows RX DMA Overruns and RX Start Of Frame Overruns both when the misqueue is detected and not detected.

With thanks, Mark

  • Hi,

    These are pretty detailed questions, we are checking into the questions you are asking and hope to have an answer early next week.

    Best Regards,


  •  Normally the cause of EOQ misses are due to Queuing late

    In Our receive ISR we always invalidate the cache for the HW portion of the RCB before we access it for the first time.

    after we have services multiple packets we perform the following...

        /* Write the completion pointer, Tell HW what we serviced, if HW disagrees, HW will generate a new interrupt! */



        RX_DMA_STATE_CP(HalDev->dev_base,Ch) = VirtToPhys(LastRcb)


        if (LastRcb->mode&CB_EOQ_BIT)        /* EOQ processing */
          if (CurrentRcb) {RX_DMA_STATE_HDP(HalDev->dev_base,Ch) = LastRcb->HNext;}   /*Restart the HW */
           else { pRxCtl->RxActive=FALSE;}<BR>

    It is important that the above is critical sectioned so that queuing another Rx buffer either occurs before or after but not during.

    That is the state of the CurrentRcb should not be changing...

  • Thanks for your response,

    In my current context, I would need more buffer descriptors than is feasible to process to ensure "CurrentRcb" is not modified (while allowing for true worst-case traffic).

    For others, I've found that testing the RX channel's CPDMA_STATERAM RX0_HDP for 0x00000000 can, in the right place, reliably detect a stall where the EOQ logic did not.

    I'd still be interested to know the answer to:

    2) can it be guaranteed that the DMA will complete the above "stall" in units of time / CPU cycles?

    Many thanks, Mark

  • "DMA will complete the above "stall" in units of time / CPU cycles"

    The DMA cannot do things in numbers of cycles when dependent on external accesses, and since external accesses can be delayed due to bus interference in both directions, coherency, refresh cycles, etc. operations in the EMIF the exact number of cycles is more nebulous.

    This is why the ISR indicates which was the last descriptor you processed to the hardware, and if the hardware disagrees, the hardware will generate another interrupt to inform the driver that ISR may have missed an event due to transit times of busses. It doesn’t happen very often but allows dealing with those long interference conditions.