diff --git a/arch/arm/src/stm32h7/stm32_ethernet.c b/arch/arm/src/stm32h7/stm32_ethernet.c index 3e9dd90cd81..1d3c821d7fb 100644 --- a/arch/arm/src/stm32h7/stm32_ethernet.c +++ b/arch/arm/src/stm32h7/stm32_ethernet.c @@ -212,6 +212,10 @@ # define CONFIG_STM32H7_ETH_NTXDESC 4 #endif +#ifndef min +# define min(a,b) ((a) < (b) ? (a) : (b)) +#endif + /* We need at least one more free buffer than transmit buffers */ #define STM32_ETH_NFREEBUFFERS (CONFIG_STM32H7_ETH_NTXDESC+1) @@ -1772,51 +1776,65 @@ static int stm32_recvframe(struct stm32_ethmac_s *priv) dev->d_len = ((rxdesc->des3 & ETH_RDES3_WB_PL_MASK) >> ETH_RDES3_WB_PL_SHIFT) - 4; - /* Get a buffer from the free list. We don't even check if - * this is successful because we already assure the free - * list is not empty above. - */ + if (priv->segments > 1 || + dev->d_len > ALIGNED_BUFSIZE) + { + /* The Frame is to big, it spans segments */ - buffer = stm32_allocbuffer(priv); + nerr("ERROR: Dropped, RX descriptor Too big: %d in %d " + "segments\n", dev->d_len, priv->segments); - /* Take the buffer from the RX descriptor of the first free - * segment, put it into the network device structure, then - * replace the buffer in the RX descriptor with the newly - * allocated buffer. - */ + stm32_freesegment(priv, rxcurr, priv->segments); + } + else + { + /* Get a buffer from the free list. We don't even + * check if this is successful because we already + * assure the free list is not empty above. + */ - DEBUGASSERT(dev->d_buf == NULL); - dev->d_buf = (uint8_t *)rxcurr->des0; - rxcurr->des0 = (uint32_t)buffer; + buffer = stm32_allocbuffer(priv); - /* Make sure that the modified RX descriptor is written to - * physical memory. - */ + /* Take the buffer from the RX descriptor of the first + * free segment, put it into the network device + * structure, then replace the buffer in the RX + * descriptor with the newly allocated buffer. + */ - up_clean_dcache((uintptr_t)rxcurr, - (uintptr_t)rxdesc + - sizeof(struct eth_desc_s)); + DEBUGASSERT(dev->d_buf == NULL); + dev->d_buf = (uint8_t *)rxcurr->des0; + rxcurr->des0 = (uint32_t)buffer; - /* Remember where we should re-start scanning and reset the - * segment scanning logic - */ + /* Make sure that the modified RX descriptor is written + * to physical memory. + */ - priv->rxhead = stm32_get_next_rxdesc(priv, rxdesc); - stm32_freesegment(priv, rxcurr, priv->segments); + up_clean_dcache((uintptr_t)rxcurr, + (uintptr_t)rxdesc + + sizeof(struct eth_desc_s)); - /* Force the completed RX DMA buffer to be re-read from - * physical memory. - */ + /* Remember where we should re-start scanning and reset + * the segment scanning logic + */ - up_invalidate_dcache((uintptr_t)dev->d_buf, - (uintptr_t)dev->d_buf + dev->d_len); + priv->rxhead = stm32_get_next_rxdesc(priv, rxdesc); + stm32_freesegment(priv, rxcurr, priv->segments); - ninfo("rxhead: %p d_buf: %p d_len: %d\n", - priv->rxhead, dev->d_buf, dev->d_len); + /* Force the completed RX DMA buffer to be re-read from + * physical memory. + */ - /* Return success */ + up_invalidate_dcache((uintptr_t)dev->d_buf, + (uintptr_t)dev->d_buf + + min(dev->d_len, ALIGNED_BUFSIZE)); - return OK; + ninfo("rxhead: %p d_buf: %p d_len: %d\n", + priv->rxhead, dev->d_buf, dev->d_len); + + /* Return success */ + + return OK; + } } else {