diff options
-rw-r--r-- | drivers/net/ethernet/broadcom/bnxt/bnxt.c | 53 | ||||
-rw-r--r-- | drivers/net/ethernet/broadcom/bnxt/bnxt.h | 13 |
2 files changed, 52 insertions, 14 deletions
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c index 12a009d720cd..72eb29ed0359 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c | |||
@@ -581,12 +581,30 @@ static inline int bnxt_alloc_rx_page(struct bnxt *bp, | |||
581 | struct page *page; | 581 | struct page *page; |
582 | dma_addr_t mapping; | 582 | dma_addr_t mapping; |
583 | u16 sw_prod = rxr->rx_sw_agg_prod; | 583 | u16 sw_prod = rxr->rx_sw_agg_prod; |
584 | unsigned int offset = 0; | ||
584 | 585 | ||
585 | page = alloc_page(gfp); | 586 | if (PAGE_SIZE > BNXT_RX_PAGE_SIZE) { |
586 | if (!page) | 587 | page = rxr->rx_page; |
587 | return -ENOMEM; | 588 | if (!page) { |
589 | page = alloc_page(gfp); | ||
590 | if (!page) | ||
591 | return -ENOMEM; | ||
592 | rxr->rx_page = page; | ||
593 | rxr->rx_page_offset = 0; | ||
594 | } | ||
595 | offset = rxr->rx_page_offset; | ||
596 | rxr->rx_page_offset += BNXT_RX_PAGE_SIZE; | ||
597 | if (rxr->rx_page_offset == PAGE_SIZE) | ||
598 | rxr->rx_page = NULL; | ||
599 | else | ||
600 | get_page(page); | ||
601 | } else { | ||
602 | page = alloc_page(gfp); | ||
603 | if (!page) | ||
604 | return -ENOMEM; | ||
605 | } | ||
588 | 606 | ||
589 | mapping = dma_map_page(&pdev->dev, page, 0, PAGE_SIZE, | 607 | mapping = dma_map_page(&pdev->dev, page, offset, BNXT_RX_PAGE_SIZE, |
590 | PCI_DMA_FROMDEVICE); | 608 | PCI_DMA_FROMDEVICE); |
591 | if (dma_mapping_error(&pdev->dev, mapping)) { | 609 | if (dma_mapping_error(&pdev->dev, mapping)) { |
592 | __free_page(page); | 610 | __free_page(page); |
@@ -601,6 +619,7 @@ static inline int bnxt_alloc_rx_page(struct bnxt *bp, | |||
601 | rxr->rx_sw_agg_prod = NEXT_RX_AGG(sw_prod); | 619 | rxr->rx_sw_agg_prod = NEXT_RX_AGG(sw_prod); |
602 | 620 | ||
603 | rx_agg_buf->page = page; | 621 | rx_agg_buf->page = page; |
622 | rx_agg_buf->offset = offset; | ||
604 | rx_agg_buf->mapping = mapping; | 623 | rx_agg_buf->mapping = mapping; |
605 | rxbd->rx_bd_haddr = cpu_to_le64(mapping); | 624 | rxbd->rx_bd_haddr = cpu_to_le64(mapping); |
606 | rxbd->rx_bd_opaque = sw_prod; | 625 | rxbd->rx_bd_opaque = sw_prod; |
@@ -642,6 +661,7 @@ static void bnxt_reuse_rx_agg_bufs(struct bnxt_napi *bnapi, u16 cp_cons, | |||
642 | page = cons_rx_buf->page; | 661 | page = cons_rx_buf->page; |
643 | cons_rx_buf->page = NULL; | 662 | cons_rx_buf->page = NULL; |
644 | prod_rx_buf->page = page; | 663 | prod_rx_buf->page = page; |
664 | prod_rx_buf->offset = cons_rx_buf->offset; | ||
645 | 665 | ||
646 | prod_rx_buf->mapping = cons_rx_buf->mapping; | 666 | prod_rx_buf->mapping = cons_rx_buf->mapping; |
647 | 667 | ||
@@ -709,7 +729,8 @@ static struct sk_buff *bnxt_rx_pages(struct bnxt *bp, struct bnxt_napi *bnapi, | |||
709 | RX_AGG_CMP_LEN) >> RX_AGG_CMP_LEN_SHIFT; | 729 | RX_AGG_CMP_LEN) >> RX_AGG_CMP_LEN_SHIFT; |
710 | 730 | ||
711 | cons_rx_buf = &rxr->rx_agg_ring[cons]; | 731 | cons_rx_buf = &rxr->rx_agg_ring[cons]; |
712 | skb_fill_page_desc(skb, i, cons_rx_buf->page, 0, frag_len); | 732 | skb_fill_page_desc(skb, i, cons_rx_buf->page, |
733 | cons_rx_buf->offset, frag_len); | ||
713 | __clear_bit(cons, rxr->rx_agg_bmap); | 734 | __clear_bit(cons, rxr->rx_agg_bmap); |
714 | 735 | ||
715 | /* It is possible for bnxt_alloc_rx_page() to allocate | 736 | /* It is possible for bnxt_alloc_rx_page() to allocate |
@@ -740,7 +761,7 @@ static struct sk_buff *bnxt_rx_pages(struct bnxt *bp, struct bnxt_napi *bnapi, | |||
740 | return NULL; | 761 | return NULL; |
741 | } | 762 | } |
742 | 763 | ||
743 | dma_unmap_page(&pdev->dev, mapping, PAGE_SIZE, | 764 | dma_unmap_page(&pdev->dev, mapping, BNXT_RX_PAGE_SIZE, |
744 | PCI_DMA_FROMDEVICE); | 765 | PCI_DMA_FROMDEVICE); |
745 | 766 | ||
746 | skb->data_len += frag_len; | 767 | skb->data_len += frag_len; |
@@ -1584,13 +1605,17 @@ static void bnxt_free_rx_skbs(struct bnxt *bp) | |||
1584 | 1605 | ||
1585 | dma_unmap_page(&pdev->dev, | 1606 | dma_unmap_page(&pdev->dev, |
1586 | dma_unmap_addr(rx_agg_buf, mapping), | 1607 | dma_unmap_addr(rx_agg_buf, mapping), |
1587 | PAGE_SIZE, PCI_DMA_FROMDEVICE); | 1608 | BNXT_RX_PAGE_SIZE, PCI_DMA_FROMDEVICE); |
1588 | 1609 | ||
1589 | rx_agg_buf->page = NULL; | 1610 | rx_agg_buf->page = NULL; |
1590 | __clear_bit(j, rxr->rx_agg_bmap); | 1611 | __clear_bit(j, rxr->rx_agg_bmap); |
1591 | 1612 | ||
1592 | __free_page(page); | 1613 | __free_page(page); |
1593 | } | 1614 | } |
1615 | if (rxr->rx_page) { | ||
1616 | __free_page(rxr->rx_page); | ||
1617 | rxr->rx_page = NULL; | ||
1618 | } | ||
1594 | } | 1619 | } |
1595 | } | 1620 | } |
1596 | 1621 | ||
@@ -1973,7 +1998,7 @@ static int bnxt_init_one_rx_ring(struct bnxt *bp, int ring_nr) | |||
1973 | if (!(bp->flags & BNXT_FLAG_AGG_RINGS)) | 1998 | if (!(bp->flags & BNXT_FLAG_AGG_RINGS)) |
1974 | return 0; | 1999 | return 0; |
1975 | 2000 | ||
1976 | type = ((u32)PAGE_SIZE << RX_BD_LEN_SHIFT) | | 2001 | type = ((u32)BNXT_RX_PAGE_SIZE << RX_BD_LEN_SHIFT) | |
1977 | RX_BD_TYPE_RX_AGG_BD | RX_BD_FLAGS_SOP; | 2002 | RX_BD_TYPE_RX_AGG_BD | RX_BD_FLAGS_SOP; |
1978 | 2003 | ||
1979 | bnxt_init_rxbd_pages(ring, type); | 2004 | bnxt_init_rxbd_pages(ring, type); |
@@ -2164,7 +2189,7 @@ void bnxt_set_ring_params(struct bnxt *bp) | |||
2164 | bp->rx_agg_nr_pages = 0; | 2189 | bp->rx_agg_nr_pages = 0; |
2165 | 2190 | ||
2166 | if (bp->flags & BNXT_FLAG_TPA) | 2191 | if (bp->flags & BNXT_FLAG_TPA) |
2167 | agg_factor = 4; | 2192 | agg_factor = min_t(u32, 4, 65536 / BNXT_RX_PAGE_SIZE); |
2168 | 2193 | ||
2169 | bp->flags &= ~BNXT_FLAG_JUMBO; | 2194 | bp->flags &= ~BNXT_FLAG_JUMBO; |
2170 | if (rx_space > PAGE_SIZE) { | 2195 | if (rx_space > PAGE_SIZE) { |
@@ -3020,12 +3045,12 @@ static int bnxt_hwrm_vnic_set_tpa(struct bnxt *bp, u16 vnic_id, u32 tpa_flags) | |||
3020 | /* Number of segs are log2 units, and first packet is not | 3045 | /* Number of segs are log2 units, and first packet is not |
3021 | * included as part of this units. | 3046 | * included as part of this units. |
3022 | */ | 3047 | */ |
3023 | if (mss <= PAGE_SIZE) { | 3048 | if (mss <= BNXT_RX_PAGE_SIZE) { |
3024 | n = PAGE_SIZE / mss; | 3049 | n = BNXT_RX_PAGE_SIZE / mss; |
3025 | nsegs = (MAX_SKB_FRAGS - 1) * n; | 3050 | nsegs = (MAX_SKB_FRAGS - 1) * n; |
3026 | } else { | 3051 | } else { |
3027 | n = mss / PAGE_SIZE; | 3052 | n = mss / BNXT_RX_PAGE_SIZE; |
3028 | if (mss & (PAGE_SIZE - 1)) | 3053 | if (mss & (BNXT_RX_PAGE_SIZE - 1)) |
3029 | n++; | 3054 | n++; |
3030 | nsegs = (MAX_SKB_FRAGS - n) / n; | 3055 | nsegs = (MAX_SKB_FRAGS - n) / n; |
3031 | } | 3056 | } |
@@ -4309,7 +4334,7 @@ static int bnxt_setup_int_mode(struct bnxt *bp) | |||
4309 | if (bp->flags & BNXT_FLAG_MSIX_CAP) | 4334 | if (bp->flags & BNXT_FLAG_MSIX_CAP) |
4310 | rc = bnxt_setup_msix(bp); | 4335 | rc = bnxt_setup_msix(bp); |
4311 | 4336 | ||
4312 | if (!(bp->flags & BNXT_FLAG_USING_MSIX)) { | 4337 | if (!(bp->flags & BNXT_FLAG_USING_MSIX) && BNXT_PF(bp)) { |
4313 | /* fallback to INTA */ | 4338 | /* fallback to INTA */ |
4314 | rc = bnxt_setup_inta(bp); | 4339 | rc = bnxt_setup_inta(bp); |
4315 | } | 4340 | } |
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.h b/drivers/net/ethernet/broadcom/bnxt/bnxt.h index 709b95b8fcba..8b823ff558ff 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt.h +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.h | |||
@@ -407,6 +407,15 @@ struct rx_tpa_end_cmp_ext { | |||
407 | 407 | ||
408 | #define BNXT_PAGE_SIZE (1 << BNXT_PAGE_SHIFT) | 408 | #define BNXT_PAGE_SIZE (1 << BNXT_PAGE_SHIFT) |
409 | 409 | ||
410 | /* The RXBD length is 16-bit so we can only support page sizes < 64K */ | ||
411 | #if (PAGE_SHIFT > 15) | ||
412 | #define BNXT_RX_PAGE_SHIFT 15 | ||
413 | #else | ||
414 | #define BNXT_RX_PAGE_SHIFT PAGE_SHIFT | ||
415 | #endif | ||
416 | |||
417 | #define BNXT_RX_PAGE_SIZE (1 << BNXT_RX_PAGE_SHIFT) | ||
418 | |||
410 | #define BNXT_MIN_PKT_SIZE 45 | 419 | #define BNXT_MIN_PKT_SIZE 45 |
411 | 420 | ||
412 | #define BNXT_NUM_TESTS(bp) 0 | 421 | #define BNXT_NUM_TESTS(bp) 0 |
@@ -506,6 +515,7 @@ struct bnxt_sw_rx_bd { | |||
506 | 515 | ||
507 | struct bnxt_sw_rx_agg_bd { | 516 | struct bnxt_sw_rx_agg_bd { |
508 | struct page *page; | 517 | struct page *page; |
518 | unsigned int offset; | ||
509 | dma_addr_t mapping; | 519 | dma_addr_t mapping; |
510 | }; | 520 | }; |
511 | 521 | ||
@@ -586,6 +596,9 @@ struct bnxt_rx_ring_info { | |||
586 | unsigned long *rx_agg_bmap; | 596 | unsigned long *rx_agg_bmap; |
587 | u16 rx_agg_bmap_size; | 597 | u16 rx_agg_bmap_size; |
588 | 598 | ||
599 | struct page *rx_page; | ||
600 | unsigned int rx_page_offset; | ||
601 | |||
589 | dma_addr_t rx_desc_mapping[MAX_RX_PAGES]; | 602 | dma_addr_t rx_desc_mapping[MAX_RX_PAGES]; |
590 | dma_addr_t rx_agg_desc_mapping[MAX_RX_AGG_PAGES]; | 603 | dma_addr_t rx_agg_desc_mapping[MAX_RX_AGG_PAGES]; |
591 | 604 | ||