diff options
author | Matt Carlson <mcarlson@broadcom.com> | 2009-11-13 08:03:48 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-11-16 01:14:51 -0500 |
commit | 2b2cdb65bec42d38268b2ac115876b066afa7f95 (patch) | |
tree | 239a38242e57bc4d56b79d1bbc4e118a0cbc73d9 /drivers/net | |
parent | 4361935afe3abc3e5a93006b99197fac1fabbd50 (diff) |
tg3: Lay proucer ring handling groundwork
The patch increases the number of producer rings available and
implements the constructor and destructor code that deals with them.
Signed-off-by: Matt Carlson <mcarlson@broadcom.com>
Reviewed-by: Michael Chan <mchan@broadcom.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/tg3.c | 85 | ||||
-rw-r--r-- | drivers/net/tg3.h | 2 |
2 files changed, 50 insertions, 37 deletions
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index beda9bf0767b..168a7ca58b85 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c | |||
@@ -137,6 +137,12 @@ | |||
137 | #define TG3_RX_STD_MAP_SZ TG3_RX_DMA_TO_MAP_SZ(TG3_RX_STD_DMA_SZ) | 137 | #define TG3_RX_STD_MAP_SZ TG3_RX_DMA_TO_MAP_SZ(TG3_RX_STD_DMA_SZ) |
138 | #define TG3_RX_JMB_MAP_SZ TG3_RX_DMA_TO_MAP_SZ(TG3_RX_JMB_DMA_SZ) | 138 | #define TG3_RX_JMB_MAP_SZ TG3_RX_DMA_TO_MAP_SZ(TG3_RX_JMB_DMA_SZ) |
139 | 139 | ||
140 | #define TG3_RX_STD_BUFF_RING_SIZE \ | ||
141 | (sizeof(struct ring_info) * TG3_RX_RING_SIZE) | ||
142 | |||
143 | #define TG3_RX_JMB_BUFF_RING_SIZE \ | ||
144 | (sizeof(struct ring_info) * TG3_RX_JUMBO_RING_SIZE) | ||
145 | |||
140 | /* minimum number of free TX descriptors required to wake up TX process */ | 146 | /* minimum number of free TX descriptors required to wake up TX process */ |
141 | #define TG3_TX_WAKEUP_THRESH(tnapi) ((tnapi)->tx_pending / 4) | 147 | #define TG3_TX_WAKEUP_THRESH(tnapi) ((tnapi)->tx_pending / 4) |
142 | 148 | ||
@@ -4397,6 +4403,17 @@ static void tg3_tx(struct tg3_napi *tnapi) | |||
4397 | } | 4403 | } |
4398 | } | 4404 | } |
4399 | 4405 | ||
4406 | static void tg3_rx_skb_free(struct tg3 *tp, struct ring_info *ri, u32 map_sz) | ||
4407 | { | ||
4408 | if (!ri->skb) | ||
4409 | return; | ||
4410 | |||
4411 | pci_unmap_single(tp->pdev, pci_unmap_addr(ri, mapping), | ||
4412 | map_sz, PCI_DMA_FROMDEVICE); | ||
4413 | dev_kfree_skb_any(ri->skb); | ||
4414 | ri->skb = NULL; | ||
4415 | } | ||
4416 | |||
4400 | /* Returns size of skb allocated or < 0 on error. | 4417 | /* Returns size of skb allocated or < 0 on error. |
4401 | * | 4418 | * |
4402 | * We only need to fill in the address because the other members | 4419 | * We only need to fill in the address because the other members |
@@ -5701,36 +5718,18 @@ static void tg3_rx_prodring_free(struct tg3 *tp, | |||
5701 | struct tg3_rx_prodring_set *tpr) | 5718 | struct tg3_rx_prodring_set *tpr) |
5702 | { | 5719 | { |
5703 | int i; | 5720 | int i; |
5704 | struct ring_info *rxp; | ||
5705 | 5721 | ||
5706 | for (i = 0; i < TG3_RX_RING_SIZE; i++) { | 5722 | if (tpr != &tp->prodring[0]) |
5707 | rxp = &tpr->rx_std_buffers[i]; | 5723 | return; |
5708 | 5724 | ||
5709 | if (rxp->skb == NULL) | 5725 | for (i = 0; i < TG3_RX_RING_SIZE; i++) |
5710 | continue; | 5726 | tg3_rx_skb_free(tp, &tpr->rx_std_buffers[i], |
5711 | 5727 | tp->rx_pkt_map_sz); | |
5712 | pci_unmap_single(tp->pdev, | ||
5713 | pci_unmap_addr(rxp, mapping), | ||
5714 | tp->rx_pkt_map_sz, | ||
5715 | PCI_DMA_FROMDEVICE); | ||
5716 | dev_kfree_skb_any(rxp->skb); | ||
5717 | rxp->skb = NULL; | ||
5718 | } | ||
5719 | 5728 | ||
5720 | if (tp->tg3_flags & TG3_FLAG_JUMBO_CAPABLE) { | 5729 | if (tp->tg3_flags & TG3_FLAG_JUMBO_CAPABLE) { |
5721 | for (i = 0; i < TG3_RX_JUMBO_RING_SIZE; i++) { | 5730 | for (i = 0; i < TG3_RX_JUMBO_RING_SIZE; i++) |
5722 | rxp = &tpr->rx_jmb_buffers[i]; | 5731 | tg3_rx_skb_free(tp, &tpr->rx_jmb_buffers[i], |
5723 | 5732 | TG3_RX_JMB_MAP_SZ); | |
5724 | if (rxp->skb == NULL) | ||
5725 | continue; | ||
5726 | |||
5727 | pci_unmap_single(tp->pdev, | ||
5728 | pci_unmap_addr(rxp, mapping), | ||
5729 | TG3_RX_JMB_MAP_SZ, | ||
5730 | PCI_DMA_FROMDEVICE); | ||
5731 | dev_kfree_skb_any(rxp->skb); | ||
5732 | rxp->skb = NULL; | ||
5733 | } | ||
5734 | } | 5733 | } |
5735 | } | 5734 | } |
5736 | 5735 | ||
@@ -5746,6 +5745,14 @@ static int tg3_rx_prodring_alloc(struct tg3 *tp, | |||
5746 | { | 5745 | { |
5747 | u32 i, rx_pkt_dma_sz; | 5746 | u32 i, rx_pkt_dma_sz; |
5748 | 5747 | ||
5748 | if (tpr != &tp->prodring[0]) { | ||
5749 | memset(&tpr->rx_std_buffers[0], 0, TG3_RX_STD_BUFF_RING_SIZE); | ||
5750 | if (tp->tg3_flags & TG3_FLAG_JUMBO_CAPABLE) | ||
5751 | memset(&tpr->rx_jmb_buffers[0], 0, | ||
5752 | TG3_RX_JMB_BUFF_RING_SIZE); | ||
5753 | goto done; | ||
5754 | } | ||
5755 | |||
5749 | /* Zero out all descriptors. */ | 5756 | /* Zero out all descriptors. */ |
5750 | memset(tpr->rx_std, 0, TG3_RX_RING_BYTES); | 5757 | memset(tpr->rx_std, 0, TG3_RX_RING_BYTES); |
5751 | 5758 | ||
@@ -5847,8 +5854,7 @@ static void tg3_rx_prodring_fini(struct tg3 *tp, | |||
5847 | static int tg3_rx_prodring_init(struct tg3 *tp, | 5854 | static int tg3_rx_prodring_init(struct tg3 *tp, |
5848 | struct tg3_rx_prodring_set *tpr) | 5855 | struct tg3_rx_prodring_set *tpr) |
5849 | { | 5856 | { |
5850 | tpr->rx_std_buffers = kzalloc(sizeof(struct ring_info) * | 5857 | tpr->rx_std_buffers = kzalloc(TG3_RX_STD_BUFF_RING_SIZE, GFP_KERNEL); |
5851 | TG3_RX_RING_SIZE, GFP_KERNEL); | ||
5852 | if (!tpr->rx_std_buffers) | 5858 | if (!tpr->rx_std_buffers) |
5853 | return -ENOMEM; | 5859 | return -ENOMEM; |
5854 | 5860 | ||
@@ -5858,8 +5864,7 @@ static int tg3_rx_prodring_init(struct tg3 *tp, | |||
5858 | goto err_out; | 5864 | goto err_out; |
5859 | 5865 | ||
5860 | if (tp->tg3_flags & TG3_FLAG_JUMBO_CAPABLE) { | 5866 | if (tp->tg3_flags & TG3_FLAG_JUMBO_CAPABLE) { |
5861 | tpr->rx_jmb_buffers = kzalloc(sizeof(struct ring_info) * | 5867 | tpr->rx_jmb_buffers = kzalloc(TG3_RX_JMB_BUFF_RING_SIZE, |
5862 | TG3_RX_JUMBO_RING_SIZE, | ||
5863 | GFP_KERNEL); | 5868 | GFP_KERNEL); |
5864 | if (!tpr->rx_jmb_buffers) | 5869 | if (!tpr->rx_jmb_buffers) |
5865 | goto err_out; | 5870 | goto err_out; |
@@ -5915,9 +5920,10 @@ static void tg3_free_rings(struct tg3 *tp) | |||
5915 | 5920 | ||
5916 | dev_kfree_skb_any(skb); | 5921 | dev_kfree_skb_any(skb); |
5917 | } | 5922 | } |
5918 | } | ||
5919 | 5923 | ||
5920 | tg3_rx_prodring_free(tp, &tp->prodring[0]); | 5924 | if (tp->irq_cnt == 1 || j != tp->irq_cnt - 1) |
5925 | tg3_rx_prodring_free(tp, &tp->prodring[j]); | ||
5926 | } | ||
5921 | } | 5927 | } |
5922 | 5928 | ||
5923 | /* Initialize tx/rx rings for packet processing. | 5929 | /* Initialize tx/rx rings for packet processing. |
@@ -5951,9 +5957,13 @@ static int tg3_init_rings(struct tg3 *tp) | |||
5951 | tnapi->rx_rcb_ptr = 0; | 5957 | tnapi->rx_rcb_ptr = 0; |
5952 | if (tnapi->rx_rcb) | 5958 | if (tnapi->rx_rcb) |
5953 | memset(tnapi->rx_rcb, 0, TG3_RX_RCB_RING_BYTES(tp)); | 5959 | memset(tnapi->rx_rcb, 0, TG3_RX_RCB_RING_BYTES(tp)); |
5960 | |||
5961 | if ((tp->irq_cnt == 1 || i != tp->irq_cnt - 1) && | ||
5962 | tg3_rx_prodring_alloc(tp, &tp->prodring[i])) | ||
5963 | return -ENOMEM; | ||
5954 | } | 5964 | } |
5955 | 5965 | ||
5956 | return tg3_rx_prodring_alloc(tp, &tp->prodring[0]); | 5966 | return 0; |
5957 | } | 5967 | } |
5958 | 5968 | ||
5959 | /* | 5969 | /* |
@@ -5997,7 +6007,8 @@ static void tg3_free_consistent(struct tg3 *tp) | |||
5997 | tp->hw_stats = NULL; | 6007 | tp->hw_stats = NULL; |
5998 | } | 6008 | } |
5999 | 6009 | ||
6000 | tg3_rx_prodring_fini(tp, &tp->prodring[0]); | 6010 | for (i = 0; i < (tp->irq_cnt == 1 ? 1 : tp->irq_cnt - 1); i++) |
6011 | tg3_rx_prodring_fini(tp, &tp->prodring[i]); | ||
6001 | } | 6012 | } |
6002 | 6013 | ||
6003 | /* | 6014 | /* |
@@ -6008,8 +6019,10 @@ static int tg3_alloc_consistent(struct tg3 *tp) | |||
6008 | { | 6019 | { |
6009 | int i; | 6020 | int i; |
6010 | 6021 | ||
6011 | if (tg3_rx_prodring_init(tp, &tp->prodring[0])) | 6022 | for (i = 0; i < (tp->irq_cnt == 1 ? 1 : tp->irq_cnt - 1); i++) { |
6012 | return -ENOMEM; | 6023 | if (tg3_rx_prodring_init(tp, &tp->prodring[i])) |
6024 | goto err_out; | ||
6025 | } | ||
6013 | 6026 | ||
6014 | tp->hw_stats = pci_alloc_consistent(tp->pdev, | 6027 | tp->hw_stats = pci_alloc_consistent(tp->pdev, |
6015 | sizeof(struct tg3_hw_stats), | 6028 | sizeof(struct tg3_hw_stats), |
diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h index e0b86ba3b5b9..715df2b595dc 100644 --- a/drivers/net/tg3.h +++ b/drivers/net/tg3.h | |||
@@ -2682,7 +2682,7 @@ struct tg3 { | |||
2682 | struct vlan_group *vlgrp; | 2682 | struct vlan_group *vlgrp; |
2683 | #endif | 2683 | #endif |
2684 | 2684 | ||
2685 | struct tg3_rx_prodring_set prodring[1]; | 2685 | struct tg3_rx_prodring_set prodring[TG3_IRQ_MAX_VECS - 1]; |
2686 | 2686 | ||
2687 | 2687 | ||
2688 | /* begin "everything else" cacheline(s) section */ | 2688 | /* begin "everything else" cacheline(s) section */ |