diff options
Diffstat (limited to 'drivers/net/tg3.c')
-rw-r--r-- | drivers/net/tg3.c | 46 |
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 |