Commit ca1df2dd authored by Andy Gospodarek's avatar Andy Gospodarek Committed by David S. Miller
Browse files

bnxt: refactor bnxt_rx_pages operate on skb_shared_info



Rather than operating on an sk_buff, add frags from the aggregation
ring into the frags of an skb_shared_info.  This will allow the
caller to use either an sk_buff or xdp_buff.

Signed-off-by: default avatarAndy Gospodarek <gospo@broadcom.com>
Signed-off-by: default avatarMichael Chan <michael.chan@broadcom.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent ee536dcb
Loading
Loading
Loading
Loading
+33 −17
Original line number Diff line number Diff line
@@ -1038,22 +1038,23 @@ static struct sk_buff *bnxt_rx_skb(struct bnxt *bp,
	return skb;
}

static struct sk_buff *bnxt_rx_pages(struct bnxt *bp,
static u32 __bnxt_rx_pages(struct bnxt *bp,
			   struct bnxt_cp_ring_info *cpr,
				     struct sk_buff *skb, u16 idx,
				     u32 agg_bufs, bool tpa)
			   struct skb_shared_info *shinfo,
			   u16 idx, u32 agg_bufs, bool tpa)
{
	struct bnxt_napi *bnapi = cpr->bnapi;
	struct pci_dev *pdev = bp->pdev;
	struct bnxt_rx_ring_info *rxr = bnapi->rx_ring;
	u16 prod = rxr->rx_agg_prod;
	u32 i, total_frag_len = 0;
	bool p5_tpa = false;
	u32 i;

	if ((bp->flags & BNXT_FLAG_CHIP_P5) && tpa)
		p5_tpa = true;

	for (i = 0; i < agg_bufs; i++) {
		skb_frag_t *frag = &shinfo->frags[i];
		u16 cons, frag_len;
		struct rx_agg_cmp *agg;
		struct bnxt_sw_rx_agg_bd *cons_rx_buf;
@@ -1069,8 +1070,10 @@ static struct sk_buff *bnxt_rx_pages(struct bnxt *bp,
			    RX_AGG_CMP_LEN) >> RX_AGG_CMP_LEN_SHIFT;

		cons_rx_buf = &rxr->rx_agg_ring[cons];
		skb_fill_page_desc(skb, i, cons_rx_buf->page,
				   cons_rx_buf->offset, frag_len);
		skb_frag_off_set(frag, cons_rx_buf->offset);
		skb_frag_size_set(frag, frag_len);
		__skb_frag_set_page(frag, cons_rx_buf->page);
		shinfo->nr_frags = i + 1;
		__clear_bit(cons, rxr->rx_agg_bmap);

		/* It is possible for bnxt_alloc_rx_page() to allocate
@@ -1082,15 +1085,10 @@ static struct sk_buff *bnxt_rx_pages(struct bnxt *bp,
		cons_rx_buf->page = NULL;

		if (bnxt_alloc_rx_page(bp, rxr, prod, GFP_ATOMIC) != 0) {
			struct skb_shared_info *shinfo;
			unsigned int nr_frags;

			shinfo = skb_shinfo(skb);
			nr_frags = --shinfo->nr_frags;
			__skb_frag_set_page(&shinfo->frags[nr_frags], NULL);

			dev_kfree_skb(skb);

			cons_rx_buf->page = page;

			/* Update prod since possibly some pages have been
@@ -1098,20 +1096,38 @@ static struct sk_buff *bnxt_rx_pages(struct bnxt *bp,
			 */
			rxr->rx_agg_prod = prod;
			bnxt_reuse_rx_agg_bufs(cpr, idx, i, agg_bufs - i, tpa);
			return NULL;
			return 0;
		}

		dma_unmap_page_attrs(&pdev->dev, mapping, BNXT_RX_PAGE_SIZE,
				     DMA_FROM_DEVICE,
				     DMA_ATTR_WEAK_ORDERING);

		skb->data_len += frag_len;
		skb->len += frag_len;
		skb->truesize += PAGE_SIZE;

		total_frag_len += frag_len;
		prod = NEXT_RX_AGG(prod);
	}
	rxr->rx_agg_prod = prod;
	return total_frag_len;
}

static struct sk_buff *bnxt_rx_pages(struct bnxt *bp,
				     struct bnxt_cp_ring_info *cpr,
				     struct sk_buff *skb, u16 idx,
				     u32 agg_bufs, bool tpa)
{
	struct skb_shared_info *shinfo = skb_shinfo(skb);
	u32 total_frag_len = 0;

	total_frag_len = __bnxt_rx_pages(bp, cpr, shinfo, idx, agg_bufs, tpa);

	if (!total_frag_len) {
		dev_kfree_skb(skb);
		return NULL;
	}

	skb->data_len += total_frag_len;
	skb->len += total_frag_len;
	skb->truesize += PAGE_SIZE * agg_bufs;
	return skb;
}