A frame longer than the packet ready threshold arrives in several descriptors, each with its own status block. Only the first one also carries the two alignment bytes. The length check assumes the pad is always there, so a continuation holding a single byte looks a byte too short and the whole frame is dropped. Account for the pad on the first descriptor only. The MTU cannot produce a frame past the threshold yet, so nothing hits this today. It is preparation for the larger MTU. Tested-by: Pierre-Marin Leclercq Reviewed-by: Florian Fainelli Signed-off-by: Nicolai Buchwitz --- drivers/net/ethernet/broadcom/genet/bcmgenet.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.c b/drivers/net/ethernet/broadcom/genet/bcmgenet.c index 86c8f8f8fe15..9f9c3fde8725 100644 --- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c +++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c @@ -53,7 +53,8 @@ /* Page pool RX buffer layout: * RSB(64) + pad(2) | frame data | skb_shared_info - * The HW writes the 64B RSB + 2B alignment padding before the frame. + * The HW writes the 64B RSB before every descriptor of a frame. Only the + * first one also gets the 2B alignment padding. */ #define GENET_RSB_PAD (sizeof(struct status_64) + 2) @@ -2336,6 +2337,7 @@ static unsigned int bcmgenet_desc_rx(struct bcmgenet_rx_ring *ring, unsigned int rx_offset, rx_size; struct status_64 *status; struct page *rx_page; + unsigned int min_len; void *hard_start; __be16 rx_csum; @@ -2372,8 +2374,12 @@ static unsigned int bcmgenet_desc_rx(struct bcmgenet_rx_ring *ring, __func__, p_index, ring->c_index, ring->read_ptr, dma_length_status); + /* Only the first descriptor carries the alignment pad */ + min_len = dma_flag & DMA_SOP ? GENET_RSB_PAD + : sizeof(struct status_64); + /* Reject lengths that would underflow the SKB build path. */ - if (unlikely(len > RX_BUF_LENGTH || len < GENET_RSB_PAD)) { + if (unlikely(len > RX_BUF_LENGTH || len < min_len)) { netif_err(priv, rx_status, dev, "invalid packet length %d\n", len); BCMGENET_STATS64_INC(stats, length_errors); -- 2.53.0