Merged in antmerlino/nuttx/samv7_emac_bna_fix (pull request #824)

arch/arm/src/samv7/sam_emac.c: Fixes rxdesc index logic to handle Buffer Not Available (BNA) condition.

If a SOF is found, but no EOF, don't move past the frame. Instead, keep the index at the SOF buffer until the rest of the data is written.

This fixes a receiver lockup condition where the peripheral and this driver get out of sync with there head pointers. In this case the driver has moved past buffers it owns, without clearing ownership, which results in the peripheral and driver in a deadlock with each other.

Approved-by: GregoryN <gnutt@nuttx.org>
This commit is contained in:
Anthony Merlino 2019-02-02 21:56:20 +00:00 committed by GregoryN
parent 7a0e62e24f
commit ee840c74da
1 changed files with 16 additions and 2 deletions

View File

@ -1873,9 +1873,23 @@ static int sam_recvframe(struct sam_emac_s *priv, int qid)
(uintptr_t)rxdesc + sizeof(struct emac_rxdesc_s));
}
/* No packet was found */
/* isframe indicates that we have found a SOF. If we've received a SOF, but not
* an EOF in the sequential buffers we own, it must mean that we have a partial
* packet. This should only happen if there was a Buffer Not Available (BNA) error.
* When bursts of data come in, quickly filling the available buffers, before our
* interrupts can even service them. Eventually, the ring buffer loops back on
* itself and the peripheral sees it cannot write the next fragment of the packet.
*
* In this case, we keep the rxndx at the start of the last frame, since the peripheral
* will finish writing the packet there next.
*
*/
if (!isframe)
{
xfrq->rxndx = rxndx;
}
xfrq->rxndx = rxndx;
ninfo("Exit rxndx[%d]: %d\n", qid, xfrq->rxndx);
return -EAGAIN;
}