aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/broadcom/tg3.c
diff options
context:
space:
mode:
authorMichael Chan <mchan@broadcom.com>2012-09-28 03:12:37 -0400
committerDavid S. Miller <davem@davemloft.net>2012-09-30 02:10:35 -0400
commit49a359e31762f798f3abef00c7d6b807a644eadf (patch)
tree1efafb46b643467cec48d3086528e5c47b2b6e9b /drivers/net/ethernet/broadcom/tg3.c
parent188c517a050ec5b123e72cab76ea213721e5bd9d (diff)
tg3: Introduce separate functions to allocate/free RX/TX rings.
This is preparation work to allow the number of RX and TX rings to be configured separately. Reviewed-by: Nithin Nayak Sujir <nsujir@broadcom.com> Reviewed-by: Benjamin Li <benli@broadcom.com> Signed-off-by: Michael Chan <mchan@broadcom.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/broadcom/tg3.c')
-rw-r--r--drivers/net/ethernet/broadcom/tg3.c220
1 files changed, 144 insertions, 76 deletions
diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c
index bf906c51d82a..93b8120bbf68 100644
--- a/drivers/net/ethernet/broadcom/tg3.c
+++ b/drivers/net/ethernet/broadcom/tg3.c
@@ -7607,15 +7607,11 @@ static int tg3_init_rings(struct tg3 *tp)
7607 return 0; 7607 return 0;
7608} 7608}
7609 7609
7610/* 7610static void tg3_mem_tx_release(struct tg3 *tp)
7611 * Must not be invoked with interrupt sources disabled and
7612 * the hardware shutdown down.
7613 */
7614static void tg3_free_consistent(struct tg3 *tp)
7615{ 7611{
7616 int i; 7612 int i;
7617 7613
7618 for (i = 0; i < tp->irq_cnt; i++) { 7614 for (i = 0; i < tp->irq_max; i++) {
7619 struct tg3_napi *tnapi = &tp->napi[i]; 7615 struct tg3_napi *tnapi = &tp->napi[i];
7620 7616
7621 if (tnapi->tx_ring) { 7617 if (tnapi->tx_ring) {
@@ -7626,17 +7622,114 @@ static void tg3_free_consistent(struct tg3 *tp)
7626 7622
7627 kfree(tnapi->tx_buffers); 7623 kfree(tnapi->tx_buffers);
7628 tnapi->tx_buffers = NULL; 7624 tnapi->tx_buffers = NULL;
7625 }
7626}
7629 7627
7630 if (tnapi->rx_rcb) { 7628static int tg3_mem_tx_acquire(struct tg3 *tp)
7631 dma_free_coherent(&tp->pdev->dev, 7629{
7632 TG3_RX_RCB_RING_BYTES(tp), 7630 int i;
7633 tnapi->rx_rcb, 7631 struct tg3_napi *tnapi = &tp->napi[0];
7634 tnapi->rx_rcb_mapping); 7632
7635 tnapi->rx_rcb = NULL; 7633 /* If multivector TSS is enabled, vector 0 does not handle
7636 } 7634 * tx interrupts. Don't allocate any resources for it.
7635 */
7636 if (tg3_flag(tp, ENABLE_TSS))
7637 tnapi++;
7638
7639 for (i = 0; i < tp->txq_cnt; i++, tnapi++) {
7640 tnapi->tx_buffers = kzalloc(sizeof(struct tg3_tx_ring_info) *
7641 TG3_TX_RING_SIZE, GFP_KERNEL);
7642 if (!tnapi->tx_buffers)
7643 goto err_out;
7644
7645 tnapi->tx_ring = dma_alloc_coherent(&tp->pdev->dev,
7646 TG3_TX_RING_BYTES,
7647 &tnapi->tx_desc_mapping,
7648 GFP_KERNEL);
7649 if (!tnapi->tx_ring)
7650 goto err_out;
7651 }
7652
7653 return 0;
7654
7655err_out:
7656 tg3_mem_tx_release(tp);
7657 return -ENOMEM;
7658}
7659
7660static void tg3_mem_rx_release(struct tg3 *tp)
7661{
7662 int i;
7663
7664 for (i = 0; i < tp->irq_max; i++) {
7665 struct tg3_napi *tnapi = &tp->napi[i];
7637 7666
7638 tg3_rx_prodring_fini(tp, &tnapi->prodring); 7667 tg3_rx_prodring_fini(tp, &tnapi->prodring);
7639 7668
7669 if (!tnapi->rx_rcb)
7670 continue;
7671
7672 dma_free_coherent(&tp->pdev->dev,
7673 TG3_RX_RCB_RING_BYTES(tp),
7674 tnapi->rx_rcb,
7675 tnapi->rx_rcb_mapping);
7676 tnapi->rx_rcb = NULL;
7677 }
7678}
7679
7680static int tg3_mem_rx_acquire(struct tg3 *tp)
7681{
7682 unsigned int i, limit;
7683
7684 limit = tp->rxq_cnt;
7685
7686 /* If RSS is enabled, we need a (dummy) producer ring
7687 * set on vector zero. This is the true hw prodring.
7688 */
7689 if (tg3_flag(tp, ENABLE_RSS))
7690 limit++;
7691
7692 for (i = 0; i < limit; i++) {
7693 struct tg3_napi *tnapi = &tp->napi[i];
7694
7695 if (tg3_rx_prodring_init(tp, &tnapi->prodring))
7696 goto err_out;
7697
7698 /* If multivector RSS is enabled, vector 0
7699 * does not handle rx or tx interrupts.
7700 * Don't allocate any resources for it.
7701 */
7702 if (!i && tg3_flag(tp, ENABLE_RSS))
7703 continue;
7704
7705 tnapi->rx_rcb = dma_alloc_coherent(&tp->pdev->dev,
7706 TG3_RX_RCB_RING_BYTES(tp),
7707 &tnapi->rx_rcb_mapping,
7708 GFP_KERNEL);
7709 if (!tnapi->rx_rcb)
7710 goto err_out;
7711
7712 memset(tnapi->rx_rcb, 0, TG3_RX_RCB_RING_BYTES(tp));
7713 }
7714
7715 return 0;
7716
7717err_out:
7718 tg3_mem_rx_release(tp);
7719 return -ENOMEM;
7720}
7721
7722/*
7723 * Must not be invoked with interrupt sources disabled and
7724 * the hardware shutdown down.
7725 */
7726static void tg3_free_consistent(struct tg3 *tp)
7727{
7728 int i;
7729
7730 for (i = 0; i < tp->irq_cnt; i++) {
7731 struct tg3_napi *tnapi = &tp->napi[i];
7732
7640 if (tnapi->hw_status) { 7733 if (tnapi->hw_status) {
7641 dma_free_coherent(&tp->pdev->dev, TG3_HW_STATUS_SIZE, 7734 dma_free_coherent(&tp->pdev->dev, TG3_HW_STATUS_SIZE,
7642 tnapi->hw_status, 7735 tnapi->hw_status,
@@ -7645,6 +7738,9 @@ static void tg3_free_consistent(struct tg3 *tp)
7645 } 7738 }
7646 } 7739 }
7647 7740
7741 tg3_mem_rx_release(tp);
7742 tg3_mem_tx_release(tp);
7743
7648 if (tp->hw_stats) { 7744 if (tp->hw_stats) {
7649 dma_free_coherent(&tp->pdev->dev, sizeof(struct tg3_hw_stats), 7745 dma_free_coherent(&tp->pdev->dev, sizeof(struct tg3_hw_stats),
7650 tp->hw_stats, tp->stats_mapping); 7746 tp->hw_stats, tp->stats_mapping);
@@ -7683,72 +7779,38 @@ static int tg3_alloc_consistent(struct tg3 *tp)
7683 memset(tnapi->hw_status, 0, TG3_HW_STATUS_SIZE); 7779 memset(tnapi->hw_status, 0, TG3_HW_STATUS_SIZE);
7684 sblk = tnapi->hw_status; 7780 sblk = tnapi->hw_status;
7685 7781
7686 if (tg3_rx_prodring_init(tp, &tnapi->prodring)) 7782 if (tg3_flag(tp, ENABLE_RSS)) {
7687 goto err_out; 7783 u16 *prodptr = 0;
7688 7784
7689 /* If multivector TSS is enabled, vector 0 does not handle 7785 /*
7690 * tx interrupts. Don't allocate any resources for it. 7786 * When RSS is enabled, the status block format changes
7691 */ 7787 * slightly. The "rx_jumbo_consumer", "reserved",
7692 if ((!i && !tg3_flag(tp, ENABLE_TSS)) || 7788 * and "rx_mini_consumer" members get mapped to the
7693 (i && tg3_flag(tp, ENABLE_TSS))) { 7789 * other three rx return ring producer indexes.
7694 tnapi->tx_buffers = kzalloc( 7790 */
7695 sizeof(struct tg3_tx_ring_info) * 7791 switch (i) {
7696 TG3_TX_RING_SIZE, GFP_KERNEL); 7792 case 1:
7697 if (!tnapi->tx_buffers) 7793 prodptr = &sblk->idx[0].rx_producer;
7698 goto err_out; 7794 break;
7699 7795 case 2:
7700 tnapi->tx_ring = dma_alloc_coherent(&tp->pdev->dev, 7796 prodptr = &sblk->rx_jumbo_consumer;
7701 TG3_TX_RING_BYTES, 7797 break;
7702 &tnapi->tx_desc_mapping, 7798 case 3:
7703 GFP_KERNEL); 7799 prodptr = &sblk->reserved;
7704 if (!tnapi->tx_ring) 7800 break;
7705 goto err_out; 7801 case 4:
7706 } 7802 prodptr = &sblk->rx_mini_consumer;
7707
7708 /*
7709 * When RSS is enabled, the status block format changes
7710 * slightly. The "rx_jumbo_consumer", "reserved",
7711 * and "rx_mini_consumer" members get mapped to the
7712 * other three rx return ring producer indexes.
7713 */
7714 switch (i) {
7715 default:
7716 if (tg3_flag(tp, ENABLE_RSS)) {
7717 tnapi->rx_rcb_prod_idx = NULL;
7718 break; 7803 break;
7719 } 7804 }
7720 /* Fall through */ 7805 tnapi->rx_rcb_prod_idx = prodptr;
7721 case 1: 7806 } else {
7722 tnapi->rx_rcb_prod_idx = &sblk->idx[0].rx_producer; 7807 tnapi->rx_rcb_prod_idx = &sblk->idx[0].rx_producer;
7723 break;
7724 case 2:
7725 tnapi->rx_rcb_prod_idx = &sblk->rx_jumbo_consumer;
7726 break;
7727 case 3:
7728 tnapi->rx_rcb_prod_idx = &sblk->reserved;
7729 break;
7730 case 4:
7731 tnapi->rx_rcb_prod_idx = &sblk->rx_mini_consumer;
7732 break;
7733 } 7808 }
7734
7735 /*
7736 * If multivector RSS is enabled, vector 0 does not handle
7737 * rx or tx interrupts. Don't allocate any resources for it.
7738 */
7739 if (!i && tg3_flag(tp, ENABLE_RSS))
7740 continue;
7741
7742 tnapi->rx_rcb = dma_alloc_coherent(&tp->pdev->dev,
7743 TG3_RX_RCB_RING_BYTES(tp),
7744 &tnapi->rx_rcb_mapping,
7745 GFP_KERNEL);
7746 if (!tnapi->rx_rcb)
7747 goto err_out;
7748
7749 memset(tnapi->rx_rcb, 0, TG3_RX_RCB_RING_BYTES(tp));
7750 } 7809 }
7751 7810
7811 if (tg3_mem_tx_acquire(tp) || tg3_mem_rx_acquire(tp))
7812 goto err_out;
7813
7752 return 0; 7814 return 0;
7753 7815
7754err_out: 7816err_out:
@@ -10154,6 +10216,7 @@ static bool tg3_enable_msix(struct tg3 *tp)
10154 * one to the number of vectors we are requesting. 10216 * one to the number of vectors we are requesting.
10155 */ 10217 */
10156 tp->irq_cnt = min_t(unsigned, tp->irq_cnt + 1, tp->irq_max); 10218 tp->irq_cnt = min_t(unsigned, tp->irq_cnt + 1, tp->irq_max);
10219 tp->rxq_cnt = tp->irq_cnt - 1;
10157 } 10220 }
10158 10221
10159 for (i = 0; i < tp->irq_max; i++) { 10222 for (i = 0; i < tp->irq_max; i++) {
@@ -10170,14 +10233,13 @@ static bool tg3_enable_msix(struct tg3 *tp)
10170 netdev_notice(tp->dev, "Requested %d MSI-X vectors, received %d\n", 10233 netdev_notice(tp->dev, "Requested %d MSI-X vectors, received %d\n",
10171 tp->irq_cnt, rc); 10234 tp->irq_cnt, rc);
10172 tp->irq_cnt = rc; 10235 tp->irq_cnt = rc;
10236 tp->rxq_cnt = max(rc - 1, 1);
10173 } 10237 }
10174 10238
10175 for (i = 0; i < tp->irq_max; i++) 10239 for (i = 0; i < tp->irq_max; i++)
10176 tp->napi[i].irq_vec = msix_ent[i].vector; 10240 tp->napi[i].irq_vec = msix_ent[i].vector;
10177 10241
10178 netif_set_real_num_tx_queues(tp->dev, 1); 10242 if (netif_set_real_num_rx_queues(tp->dev, tp->rxq_cnt)) {
10179 rc = tp->irq_cnt > 1 ? tp->irq_cnt - 1 : 1;
10180 if (netif_set_real_num_rx_queues(tp->dev, rc)) {
10181 pci_disable_msix(tp->pdev); 10243 pci_disable_msix(tp->pdev);
10182 return false; 10244 return false;
10183 } 10245 }
@@ -10188,7 +10250,8 @@ static bool tg3_enable_msix(struct tg3 *tp)
10188 if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719 || 10250 if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719 ||
10189 GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5720) { 10251 GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5720) {
10190 tg3_flag_set(tp, ENABLE_TSS); 10252 tg3_flag_set(tp, ENABLE_TSS);
10191 netif_set_real_num_tx_queues(tp->dev, tp->irq_cnt - 1); 10253 tp->txq_cnt = tp->rxq_cnt;
10254 netif_set_real_num_tx_queues(tp->dev, tp->txq_cnt);
10192 } 10255 }
10193 } 10256 }
10194 10257
@@ -10224,6 +10287,11 @@ defcfg:
10224 if (!tg3_flag(tp, USING_MSIX)) { 10287 if (!tg3_flag(tp, USING_MSIX)) {
10225 tp->irq_cnt = 1; 10288 tp->irq_cnt = 1;
10226 tp->napi[0].irq_vec = tp->pdev->irq; 10289 tp->napi[0].irq_vec = tp->pdev->irq;
10290 }
10291
10292 if (tp->irq_cnt == 1) {
10293 tp->txq_cnt = 1;
10294 tp->rxq_cnt = 1;
10227 netif_set_real_num_tx_queues(tp->dev, 1); 10295 netif_set_real_num_tx_queues(tp->dev, 1);
10228 netif_set_real_num_rx_queues(tp->dev, 1); 10296 netif_set_real_num_rx_queues(tp->dev, 1);
10229 } 10297 }