diff --git a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c index f442b874bb59..ccc24a1301f2 100644 --- a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c +++ b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c @@ -3917,10 +3917,10 @@ static int mvpp2_rx(struct mvpp2_port *port, struct napi_struct *napi, struct mvpp2_bm_pool *bm_pool; struct page_pool *pp = NULL; struct sk_buff *skb; - unsigned int frag_size; + unsigned int frag_size, rx_sync_size; dma_addr_t dma_addr; phys_addr_t phys_addr; - int pool, rx_bytes, err, ret; + int pool, rx_bytes, rx_offset, err, ret; struct page *page; void *data; @@ -3933,6 +3933,8 @@ static int mvpp2_rx(struct mvpp2_port *port, struct napi_struct *napi, rx_status = mvpp2_rxdesc_status_get(port, rx_desc); rx_bytes = mvpp2_rxdesc_size_get(port, rx_desc); rx_bytes -= MVPP2_MH_SIZE; + rx_sync_size = rx_bytes + MVPP2_MH_SIZE; + rx_offset = MVPP2_MH_SIZE + MVPP2_SKB_HEADROOM; dma_addr = mvpp2_rxdesc_dma_addr_get(port, rx_desc); pool = (rx_status & MVPP2_RXD_BM_POOL_ID_MASK) >> @@ -3946,9 +3948,10 @@ static int mvpp2_rx(struct mvpp2_port *port, struct napi_struct *napi, dma_dir = DMA_FROM_DEVICE; } - dma_sync_single_for_cpu(dev->dev.parent, dma_addr, - rx_bytes + MVPP2_MH_SIZE, - dma_dir); + dma_sync_single_range_for_cpu(dev->dev.parent, dma_addr, + MVPP2_SKB_HEADROOM, + rx_sync_size, + dma_dir); /* Buffer header not supported */ if (rx_status & MVPP2_RXD_BUF_HDR) @@ -3970,6 +3973,12 @@ static int mvpp2_rx(struct mvpp2_port *port, struct napi_struct *napi, else frag_size = bm_pool->frag_size; + err = mvpp2_rx_refill(port, bm_pool, pp, pool); + if (err) { + netdev_err(port->dev, "failed to refill BM pools\n"); + goto err_drop_frame; + } + if (xdp_prog) { struct xdp_rxq_info *xdp_rxq; @@ -3978,7 +3987,7 @@ static int mvpp2_rx(struct mvpp2_port *port, struct napi_struct *napi, else xdp_rxq = &rxq->xdp_rxq_long; - xdp_init_buff(&xdp, PAGE_SIZE, xdp_rxq); + xdp_init_buff(&xdp, bm_pool->frag_size, xdp_rxq); xdp_prepare_buff(&xdp, data, MVPP2_MH_SIZE + MVPP2_SKB_HEADROOM, rx_bytes, true); @@ -3987,17 +3996,19 @@ static int mvpp2_rx(struct mvpp2_port *port, struct napi_struct *napi, if (ret) { xdp_ret |= ret; - err = mvpp2_rx_refill(port, bm_pool, pp, pool); - if (err) { - netdev_err(port->dev, "failed to refill BM pools\n"); - goto err_drop_frame; - } - ps.rx_packets++; ps.rx_bytes += rx_bytes; continue; } + rx_sync_size = max_t(unsigned int, rx_sync_size, + xdp.data_end - xdp.data_hard_start - + MVPP2_SKB_HEADROOM); + + /* Update offset and length to reflect any XDP adjustments. */ + rx_offset = xdp.data - data; + rx_bytes = xdp.data_end - xdp.data; + metasize = xdp.data - xdp.data_meta; } @@ -4007,8 +4018,20 @@ static int mvpp2_rx(struct mvpp2_port *port, struct napi_struct *napi, skb = slab_build_skb(data); if (!skb) { netdev_warn(port->dev, "skb build failed\n"); - goto err_drop_frame; + if (pp) { + page_pool_put_page(pp, virt_to_head_page(data), + rx_sync_size, true); + } else { + dma_unmap_single_attrs(dev->dev.parent, dma_addr, + bm_pool->buf_size, + DMA_FROM_DEVICE, + DMA_ATTR_SKIP_CPU_SYNC); + mvpp2_frag_free(bm_pool, pp, data); + } + goto err_drop_frame_retired; } + if (pp) + skb_mark_for_recycle(skb); /* If we have RX hardware timestamping enabled, grab the * timestamp from the queue and convert. @@ -4019,16 +4042,7 @@ static int mvpp2_rx(struct mvpp2_port *port, struct napi_struct *napi, skb_hwtstamps(skb)); } - err = mvpp2_rx_refill(port, bm_pool, pp, pool); - if (err) { - netdev_err(port->dev, "failed to refill BM pools\n"); - dev_kfree_skb_any(skb); - goto err_drop_frame; - } - - if (pp) - skb_mark_for_recycle(skb); - else + if (!pp) dma_unmap_single_attrs(dev->dev.parent, dma_addr, bm_pool->buf_size, DMA_FROM_DEVICE, DMA_ATTR_SKIP_CPU_SYNC); @@ -4036,7 +4050,7 @@ static int mvpp2_rx(struct mvpp2_port *port, struct napi_struct *napi, ps.rx_packets++; ps.rx_bytes += rx_bytes; - skb_reserve(skb, MVPP2_MH_SIZE + MVPP2_SKB_HEADROOM); + skb_reserve(skb, rx_offset); skb_put(skb, rx_bytes); if (metasize) skb_metadata_set(skb, metasize); @@ -4047,13 +4061,14 @@ static int mvpp2_rx(struct mvpp2_port *port, struct napi_struct *napi, continue; err_drop_frame: - dev->stats.rx_errors++; - mvpp2_rx_error(port, rx_desc); /* Return the buffer to the pool */ if (rx_status & MVPP2_RXD_BUF_HDR) mvpp2_buff_hdr_pool_put(port, rx_desc, pool, rx_status); else mvpp2_bm_pool_put(port, pool, dma_addr, phys_addr); +err_drop_frame_retired: + dev->stats.rx_errors++; + mvpp2_rx_error(port, rx_desc); } if (xdp_ret & MVPP2_XDP_REDIR)