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

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
...@@ -1038,22 +1038,23 @@ static struct sk_buff *bnxt_rx_skb(struct bnxt *bp, ...@@ -1038,22 +1038,23 @@ static struct sk_buff *bnxt_rx_skb(struct bnxt *bp,
return skb; 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 bnxt_cp_ring_info *cpr,
struct sk_buff *skb, u16 idx, struct skb_shared_info *shinfo,
u32 agg_bufs, bool tpa) u16 idx, u32 agg_bufs, bool tpa)
{ {
struct bnxt_napi *bnapi = cpr->bnapi; struct bnxt_napi *bnapi = cpr->bnapi;
struct pci_dev *pdev = bp->pdev; struct pci_dev *pdev = bp->pdev;
struct bnxt_rx_ring_info *rxr = bnapi->rx_ring; struct bnxt_rx_ring_info *rxr = bnapi->rx_ring;
u16 prod = rxr->rx_agg_prod; u16 prod = rxr->rx_agg_prod;
u32 i, total_frag_len = 0;
bool p5_tpa = false; bool p5_tpa = false;
u32 i;
if ((bp->flags & BNXT_FLAG_CHIP_P5) && tpa) if ((bp->flags & BNXT_FLAG_CHIP_P5) && tpa)
p5_tpa = true; p5_tpa = true;
for (i = 0; i < agg_bufs; i++) { for (i = 0; i < agg_bufs; i++) {
skb_frag_t *frag = &shinfo->frags[i];
u16 cons, frag_len; u16 cons, frag_len;
struct rx_agg_cmp *agg; struct rx_agg_cmp *agg;
struct bnxt_sw_rx_agg_bd *cons_rx_buf; struct bnxt_sw_rx_agg_bd *cons_rx_buf;
...@@ -1069,8 +1070,10 @@ static struct sk_buff *bnxt_rx_pages(struct bnxt *bp, ...@@ -1069,8 +1070,10 @@ static struct sk_buff *bnxt_rx_pages(struct bnxt *bp,
RX_AGG_CMP_LEN) >> RX_AGG_CMP_LEN_SHIFT; RX_AGG_CMP_LEN) >> RX_AGG_CMP_LEN_SHIFT;
cons_rx_buf = &rxr->rx_agg_ring[cons]; cons_rx_buf = &rxr->rx_agg_ring[cons];
skb_fill_page_desc(skb, i, cons_rx_buf->page, skb_frag_off_set(frag, cons_rx_buf->offset);
cons_rx_buf->offset, frag_len); 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); __clear_bit(cons, rxr->rx_agg_bmap);
/* It is possible for bnxt_alloc_rx_page() to allocate /* It is possible for bnxt_alloc_rx_page() to allocate
...@@ -1082,15 +1085,10 @@ static struct sk_buff *bnxt_rx_pages(struct bnxt *bp, ...@@ -1082,15 +1085,10 @@ static struct sk_buff *bnxt_rx_pages(struct bnxt *bp,
cons_rx_buf->page = NULL; cons_rx_buf->page = NULL;
if (bnxt_alloc_rx_page(bp, rxr, prod, GFP_ATOMIC) != 0) { if (bnxt_alloc_rx_page(bp, rxr, prod, GFP_ATOMIC) != 0) {
struct skb_shared_info *shinfo;
unsigned int nr_frags; unsigned int nr_frags;
shinfo = skb_shinfo(skb);
nr_frags = --shinfo->nr_frags; nr_frags = --shinfo->nr_frags;
__skb_frag_set_page(&shinfo->frags[nr_frags], NULL); __skb_frag_set_page(&shinfo->frags[nr_frags], NULL);
dev_kfree_skb(skb);
cons_rx_buf->page = page; cons_rx_buf->page = page;
/* Update prod since possibly some pages have been /* Update prod since possibly some pages have been
...@@ -1098,20 +1096,38 @@ static struct sk_buff *bnxt_rx_pages(struct bnxt *bp, ...@@ -1098,20 +1096,38 @@ static struct sk_buff *bnxt_rx_pages(struct bnxt *bp,
*/ */
rxr->rx_agg_prod = prod; rxr->rx_agg_prod = prod;
bnxt_reuse_rx_agg_bufs(cpr, idx, i, agg_bufs - i, tpa); 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_unmap_page_attrs(&pdev->dev, mapping, BNXT_RX_PAGE_SIZE,
DMA_FROM_DEVICE, DMA_FROM_DEVICE,
DMA_ATTR_WEAK_ORDERING); DMA_ATTR_WEAK_ORDERING);
skb->data_len += frag_len; total_frag_len += frag_len;
skb->len += frag_len;
skb->truesize += PAGE_SIZE;
prod = NEXT_RX_AGG(prod); prod = NEXT_RX_AGG(prod);
} }
rxr->rx_agg_prod = 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; return skb;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment