diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c index 33814672c842..71858af6fd66 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c @@ -5912,18 +5912,23 @@ static int stmmac_rx(struct stmmac_priv *priv, int limit, u32 queue) status); } - if (unlikely(status & discard_frame)) { - page_pool_put_page(rx_q->page_pool, buf->page, 0, true); - buf->page = NULL; + if (unlikely(!error && (status & discard_frame))) { error = 1; if (!priv->hwts_rx_en) rx_errors++; } - if (unlikely(error && (status & rx_not_ls))) - goto read_again; + /* We do not support SG in XDP mode */ + if (unlikely(!error && (status & rx_not_ls) && + stmmac_xdp_is_enabled(priv))) { + rx_dropped++; + error = 1; + } if (unlikely(error)) { + if (status & rx_not_ls) + goto read_again; + dev_kfree_skb(skb); goto next; } @@ -5935,6 +5940,14 @@ static int stmmac_rx(struct stmmac_priv *priv, int limit, u32 queue) buf2_len = stmmac_rx_buf2_len(priv, p, status, len); len += buf2_len; + /* Drop the packet if it is split over buf1 and buf2 on a + * single descriptor if the interface is running in XDP mode. + */ + if (unlikely(stmmac_xdp_is_enabled(priv) && buf2_len)) { + rx_dropped++; + goto next; + } + /* ACS is disabled; strip manually. */ if (likely(!(status & rx_not_ls))) len -= ETH_FCS_LEN; @@ -5984,17 +5997,7 @@ static int stmmac_rx(struct stmmac_priv *priv, int limit, u32 queue) sync_len, true); buf->page = NULL; rx_dropped++; - - /* Clear skb as it was set as - * status by XDP program. - */ - skb = NULL; - - if (unlikely((status & rx_not_ls))) - goto read_again; - - count++; - continue; + goto next; } else if (xdp_res & (STMMAC_XDP_TX | STMMAC_XDP_REDIRECT)) { xdp_status |= xdp_res;