aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/tg3.c
diff options
context:
space:
mode:
authorMatt Carlson <mcarlson@broadcom.com>2010-02-12 09:47:05 -0500
committerDavid S. Miller <davem@davemloft.net>2010-02-12 20:05:51 -0500
commite4af1af900328e4aa71cd5df75bb22669ab11522 (patch)
tree53e299387fd52fbb372eb9886a118747c4ee397c /drivers/net/tg3.c
parent8151d2948e088c20b7d29c793cf1fd744b6a2699 (diff)
tg3: Give MSI-X vec 1 rx backlog space
RSS ring 1 is responsible for submitting new rx buffers to the hardware on behalf of all the other RSS rx return rings. Up until now this ring submitted its new rx buffers to the producer ring directly. The following patch will require that this ring have a place to put backlogged rx packets. As a consequence, it can no longer submit new buffers to the producer ring. This patch adds code to allocate an extra shadow producer ring for this RSS ring and adds RSS ring 1 to the list of rings needing buffer transfers. Signed-off-by: Matt Carlson <mcarlson@broadcom.com> Signed-off-by: Michael Chan <mchan@broadcom.com> Reviewed-by: Benjamin Li <benli@broadcom.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/tg3.c')
-rw-r--r--drivers/net/tg3.c46
1 files changed, 21 insertions, 25 deletions
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index d29282f01c23..661e9ddd1401 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -4733,7 +4733,7 @@ next_pkt_nopost:
4733 tw32_rx_mbox(tnapi->consmbox, sw_idx); 4733 tw32_rx_mbox(tnapi->consmbox, sw_idx);
4734 4734
4735 /* Refill RX ring(s). */ 4735 /* Refill RX ring(s). */
4736 if (!(tp->tg3_flags3 & TG3_FLG3_ENABLE_RSS) || tnapi == &tp->napi[1]) { 4736 if (!(tp->tg3_flags3 & TG3_FLG3_ENABLE_RSS)) {
4737 if (work_mask & RXD_OPAQUE_RING_STD) { 4737 if (work_mask & RXD_OPAQUE_RING_STD) {
4738 tpr->rx_std_prod_idx = std_prod_idx % TG3_RX_RING_SIZE; 4738 tpr->rx_std_prod_idx = std_prod_idx % TG3_RX_RING_SIZE;
4739 tw32_rx_mbox(TG3_RX_STD_PROD_IDX_REG, 4739 tw32_rx_mbox(TG3_RX_STD_PROD_IDX_REG,
@@ -4755,7 +4755,8 @@ next_pkt_nopost:
4755 tpr->rx_std_prod_idx = std_prod_idx % TG3_RX_RING_SIZE; 4755 tpr->rx_std_prod_idx = std_prod_idx % TG3_RX_RING_SIZE;
4756 tpr->rx_jmb_prod_idx = jmb_prod_idx % TG3_RX_JUMBO_RING_SIZE; 4756 tpr->rx_jmb_prod_idx = jmb_prod_idx % TG3_RX_JUMBO_RING_SIZE;
4757 4757
4758 napi_schedule(&tp->napi[1].napi); 4758 if (tnapi != &tp->napi[1])
4759 napi_schedule(&tp->napi[1].napi);
4759 } 4760 }
4760 4761
4761 return received; 4762 return received;
@@ -4893,25 +4894,23 @@ static int tg3_poll_work(struct tg3_napi *tnapi, int work_done, int budget)
4893 work_done += tg3_rx(tnapi, budget - work_done); 4894 work_done += tg3_rx(tnapi, budget - work_done);
4894 4895
4895 if ((tp->tg3_flags3 & TG3_FLG3_ENABLE_RSS) && tnapi == &tp->napi[1]) { 4896 if ((tp->tg3_flags3 & TG3_FLG3_ENABLE_RSS) && tnapi == &tp->napi[1]) {
4897 struct tg3_rx_prodring_set *dpr = &tp->prodring[0];
4896 int i; 4898 int i;
4897 u32 std_prod_idx = tp->prodring[0].rx_std_prod_idx; 4899 u32 std_prod_idx = dpr->rx_std_prod_idx;
4898 u32 jmb_prod_idx = tp->prodring[0].rx_jmb_prod_idx; 4900 u32 jmb_prod_idx = dpr->rx_jmb_prod_idx;
4899 4901
4900 for (i = 2; i < tp->irq_cnt; i++) 4902 for (i = 1; i < tp->irq_cnt; i++)
4901 tg3_rx_prodring_xfer(tp, tnapi->prodring, 4903 tg3_rx_prodring_xfer(tp, dpr, tp->napi[i].prodring);
4902 tp->napi[i].prodring);
4903 4904
4904 wmb(); 4905 wmb();
4905 4906
4906 if (std_prod_idx != tp->prodring[0].rx_std_prod_idx) { 4907 if (std_prod_idx != dpr->rx_std_prod_idx)
4907 u32 mbox = TG3_RX_STD_PROD_IDX_REG; 4908 tw32_rx_mbox(TG3_RX_STD_PROD_IDX_REG,
4908 tw32_rx_mbox(mbox, tp->prodring[0].rx_std_prod_idx); 4909 dpr->rx_std_prod_idx);
4909 }
4910 4910
4911 if (jmb_prod_idx != tp->prodring[0].rx_jmb_prod_idx) { 4911 if (jmb_prod_idx != dpr->rx_jmb_prod_idx)
4912 u32 mbox = TG3_RX_JMB_PROD_IDX_REG; 4912 tw32_rx_mbox(TG3_RX_JMB_PROD_IDX_REG,
4913 tw32_rx_mbox(mbox, tp->prodring[0].rx_jmb_prod_idx); 4913 dpr->rx_jmb_prod_idx);
4914 }
4915 4914
4916 mmiowb(); 4915 mmiowb();
4917 } 4916 }
@@ -6173,8 +6172,7 @@ static void tg3_free_rings(struct tg3 *tp)
6173 dev_kfree_skb_any(skb); 6172 dev_kfree_skb_any(skb);
6174 } 6173 }
6175 6174
6176 if (tp->irq_cnt == 1 || j != tp->irq_cnt - 1) 6175 tg3_rx_prodring_free(tp, &tp->prodring[j]);
6177 tg3_rx_prodring_free(tp, &tp->prodring[j]);
6178 } 6176 }
6179} 6177}
6180 6178
@@ -6210,9 +6208,10 @@ static int tg3_init_rings(struct tg3 *tp)
6210 if (tnapi->rx_rcb) 6208 if (tnapi->rx_rcb)
6211 memset(tnapi->rx_rcb, 0, TG3_RX_RCB_RING_BYTES(tp)); 6209 memset(tnapi->rx_rcb, 0, TG3_RX_RCB_RING_BYTES(tp));
6212 6210
6213 if ((tp->irq_cnt == 1 || i != tp->irq_cnt - 1) && 6211 if (tg3_rx_prodring_alloc(tp, &tp->prodring[i])) {
6214 tg3_rx_prodring_alloc(tp, &tp->prodring[i])) 6212 tg3_free_rings(tp);
6215 return -ENOMEM; 6213 return -ENOMEM;
6214 }
6216 } 6215 }
6217 6216
6218 return 0; 6217 return 0;
@@ -6259,7 +6258,7 @@ static void tg3_free_consistent(struct tg3 *tp)
6259 tp->hw_stats = NULL; 6258 tp->hw_stats = NULL;
6260 } 6259 }
6261 6260
6262 for (i = 0; i < (tp->irq_cnt == 1 ? 1 : tp->irq_cnt - 1); i++) 6261 for (i = 0; i < tp->irq_cnt; i++)
6263 tg3_rx_prodring_fini(tp, &tp->prodring[i]); 6262 tg3_rx_prodring_fini(tp, &tp->prodring[i]);
6264} 6263}
6265 6264
@@ -6271,7 +6270,7 @@ static int tg3_alloc_consistent(struct tg3 *tp)
6271{ 6270{
6272 int i; 6271 int i;
6273 6272
6274 for (i = 0; i < (tp->irq_cnt == 1 ? 1 : tp->irq_cnt - 1); i++) { 6273 for (i = 0; i < tp->irq_cnt; i++) {
6275 if (tg3_rx_prodring_init(tp, &tp->prodring[i])) 6274 if (tg3_rx_prodring_init(tp, &tp->prodring[i]))
6276 goto err_out; 6275 goto err_out;
6277 } 6276 }
@@ -6336,10 +6335,7 @@ static int tg3_alloc_consistent(struct tg3 *tp)
6336 break; 6335 break;
6337 } 6336 }
6338 6337
6339 if (tp->irq_cnt == 1) 6338 tnapi->prodring = &tp->prodring[i];
6340 tnapi->prodring = &tp->prodring[0];
6341 else if (i)
6342 tnapi->prodring = &tp->prodring[i - 1];
6343 6339
6344 /* 6340 /*
6345 * If multivector RSS is enabled, vector 0 does not handle 6341 * If multivector RSS is enabled, vector 0 does not handle