net: stmmac: size the RX buffers from the frame length, not the MTU

When picking the buffsize to use based on the MTU, we shouldn't check
only the MTU value, but also :
 - ETH_HLEN for the L2 header,
 - up to 2 VLAN tags,
 - the FCS,

The default bufsize is 1536 bytes, which is enough to contain all the
above so this hasn't surfaced before, but the addition of NET_IP_ALIGN
to the start of buffer address tripped the Jumbo selftest, leading to
this discovery.

With that, we don't need the '>=' checks on the buffer len, we can use
more consistent comparison operators in stmmac_set_bfsize.

Fixes: 286a837217 ("stmmac: add CHAINED descriptor mode support (V4)")
Reviewed-by: Nicolai Buchwitz <nb@tipi-net.de>
Signed-off-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
Link: https://patch.msgid.link/20260917215339.2022523-7-maxime.chevallier@bootlin.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
Maxime Chevallier 2026-09-17 23:53:37 +02:00 committed by Jakub Kicinski
parent b42e701277
commit b8a26d46c0

View File

@ -1536,17 +1536,17 @@ static unsigned int stmmac_rx_offset(struct stmmac_priv *priv)
return NET_SKB_PAD + NET_IP_ALIGN;
}
static int stmmac_set_bfsize(int mtu)
static int stmmac_set_bfsize(int len)
{
int ret;
if (mtu >= BUF_SIZE_8KiB)
if (len > BUF_SIZE_8KiB)
ret = BUF_SIZE_16KiB;
else if (mtu >= BUF_SIZE_4KiB)
else if (len > BUF_SIZE_4KiB)
ret = BUF_SIZE_8KiB;
else if (mtu >= BUF_SIZE_2KiB)
else if (len > BUF_SIZE_2KiB)
ret = BUF_SIZE_4KiB;
else if (mtu > DEFAULT_BUFSIZE)
else if (len > DEFAULT_BUFSIZE)
ret = BUF_SIZE_2KiB;
else
ret = DEFAULT_BUFSIZE;
@ -4063,7 +4063,7 @@ static struct stmmac_dma_conf *
stmmac_setup_dma_desc(struct stmmac_priv *priv, unsigned int mtu)
{
struct stmmac_dma_conf *dma_conf;
int bfsize, ret;
int bfsize, len, ret;
u8 chan;
dma_conf = kzalloc_obj(*dma_conf);
@ -4073,13 +4073,15 @@ stmmac_setup_dma_desc(struct stmmac_priv *priv, unsigned int mtu)
return ERR_PTR(-ENOMEM);
}
/* Returns 0 or BUF_SIZE_16KiB if mtu > 8KiB and dwmac4 or ring mode */
bfsize = stmmac_set_16kib_bfsize(priv, mtu);
len = mtu + ETH_HLEN + 2 * VLAN_HLEN + ETH_FCS_LEN;
/* Returns 0 or BUF_SIZE_16KiB if len > 8KiB and dwmac4 or ring mode */
bfsize = stmmac_set_16kib_bfsize(priv, len);
if (bfsize < 0)
bfsize = 0;
if (bfsize < BUF_SIZE_16KiB)
bfsize = stmmac_set_bfsize(mtu);
bfsize = stmmac_set_bfsize(len);
dma_conf->dma_buf_sz = bfsize;
/* Chose the tx/rx size from the already defined one in the