AnsweredAssumed Answered

MACNET: BDs expected to be set to "Ready" in reverse order?

Question asked by hmijail on Apr 17, 2014
Latest reply on Apr 18, 2014 by Naoum Gitnik

Vybrid's MACNET is appallingly scarcely documented, seemingly like the rest of the uC, but I have finally managed to find good information in the i.MX52 Reference Manual about the FEC module, which is theoretically similar to MACNET - apart from the register changes and who knows what else.


The thing is, in there there is discussion about the TX BDs having to be marked as "Ready" in reverse order. For example, if we have buffers 1, 2 and 3 defining together a single frame, they should be marked as "Ready" starting by the 3rd, then 2nd, then 1st. The explanation is that in that way we avoid the situation of the DMA starting transmission of a buffer (say, the 1st) when the 2nd is still not marked as "Ready", which would cause an underrun.


My question is: what about the situation of the 3rd buffer being marked as "Ready", and before we manage to mark the 2nd one, the DMA engine starts transferring the 3rd one?


To me it looks like a worse problem, because at that point the FIFO is *guaranteed* to underrun. In contrast, if we had marked them in their natural order, there is the chance that while the DMA transfers the 1st buffer, the 2nd might still be marked "Ready" on time.

Furthermore, the description of how the DMA engine looks for ready buffers says that once DMA finds a non-Ready BD, it will recheck it once more. So we have an extra chance - if we set the buffers as Ready in the natural order, not reverse!


Of course this talk about "chances" sounds rather unreliable anyway, and yet it is better than the guaranteed underrun/broken frame.


One possible answer is that, since the DMA would have stopped when it found the non-Ready BD, then marking them in reverse order makes the DMA engine stop before it finds the already-marked BD. But that in fact only minimizes the window of opportunity: say the 3rd buffer is Ready, DMA checks 2nd buffer and finds it non-Ready, and before it re-checks, the 2nd buffer is set. Again we have underrun/broken frame.


So, am I missing something?


Another related question is: the TDAR discussion always says that setting TDAR tells the DMA to read the *next* BD in the ring. Now, let's suppose that in the last transmission the last buffer read was the 2nd. So, next time TDAR transitions 0->1, the DMA will directly go to the 3rd buffer? What happens then if it was part of a BD "chain"? Again underrun/broken frame?

On the other hand, let's suppose that transitioning TDAR 0->1 makes the DMA start from the 1st BD. Now, what happens if we had set our BD in position 2? (for example because we had just transmitted a frame from buffer 1). Theoretically the DMA engine would find the 1st BD non-Ready, will retry, will find it again non-Ready and will stop trying.


Looking at how u-boot's, Linux's, and MQX's FEC drivers work, it has to be that the DMA continues working from where it was. But then what happens to a possible BD chain?

At this point it looks highly suspicious that all those drivers work exclusively with non-chained BDs...