diff --git a/arch/arm/src/samv7/sam_emac.c b/arch/arm/src/samv7/sam_emac.c index f30b618a7a..3cad26a493 100644 --- a/arch/arm/src/samv7/sam_emac.c +++ b/arch/arm/src/samv7/sam_emac.c @@ -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; }