diff options
author | Matt Carlson <mcarlson@broadcom.com> | 2009-09-01 09:19:05 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-09-02 03:43:58 -0400 |
commit | 8d9d7cfc0ec2fe37ff9afd74326d03f38f96ad1b (patch) | |
tree | 3fc4ef598534d0e309a4a980b29e3a601f4581e1 | |
parent | 0c1d0e2b05e92ad847b3ebe1c75b7974086bc8fa (diff) |
tg3: Assign rx ret producer indexes by vector
When RSS is enabled, the status block format changes slightly. The
"rx_jumbo_consumer", "reserved", and "rx_mini_consumer" members get
mapped to the other three rx return ring producer indexes. This patch
introduces a new per-interrupt member which identifies which location
in the status block a particular vector should look for return ring
updates.
Signed-off-by: Matt Carlson <mcarlson@broadcom.com>
Reviewed-by: Benjamin Li <benli@broadcom.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/net/tg3.c | 31 | ||||
-rw-r--r-- | drivers/net/tg3.h | 1 |
2 files changed, 28 insertions, 4 deletions
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 5782511c9459..f71ea462ca41 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c | |||
@@ -667,7 +667,7 @@ static inline unsigned int tg3_has_work(struct tg3_napi *tnapi) | |||
667 | } | 667 | } |
668 | /* check for RX/TX work to do */ | 668 | /* check for RX/TX work to do */ |
669 | if (sblk->idx[0].tx_consumer != tnapi->tx_cons || | 669 | if (sblk->idx[0].tx_consumer != tnapi->tx_cons || |
670 | sblk->idx[0].rx_producer != tnapi->rx_rcb_ptr) | 670 | *(tnapi->rx_rcb_prod_idx) != tnapi->rx_rcb_ptr) |
671 | work_exists = 1; | 671 | work_exists = 1; |
672 | 672 | ||
673 | return work_exists; | 673 | return work_exists; |
@@ -4518,7 +4518,7 @@ static int tg3_rx(struct tg3_napi *tnapi, int budget) | |||
4518 | int received; | 4518 | int received; |
4519 | struct tg3_rx_prodring_set *tpr = &tp->prodring[0]; | 4519 | struct tg3_rx_prodring_set *tpr = &tp->prodring[0]; |
4520 | 4520 | ||
4521 | hw_idx = tnapi->hw_status->idx[0].rx_producer; | 4521 | hw_idx = *(tnapi->rx_rcb_prod_idx); |
4522 | /* | 4522 | /* |
4523 | * We need to order the read of hw_idx and the read of | 4523 | * We need to order the read of hw_idx and the read of |
4524 | * the opaque cookie. | 4524 | * the opaque cookie. |
@@ -4649,7 +4649,7 @@ next_pkt_nopost: | |||
4649 | 4649 | ||
4650 | /* Refresh hw_idx to see if there is new work */ | 4650 | /* Refresh hw_idx to see if there is new work */ |
4651 | if (sw_idx == hw_idx) { | 4651 | if (sw_idx == hw_idx) { |
4652 | hw_idx = tnapi->hw_status->idx[0].rx_producer; | 4652 | hw_idx = *(tnapi->rx_rcb_prod_idx); |
4653 | rmb(); | 4653 | rmb(); |
4654 | } | 4654 | } |
4655 | } | 4655 | } |
@@ -4711,7 +4711,7 @@ static int tg3_poll_work(struct tg3_napi *tnapi, int work_done, int budget) | |||
4711 | * All RX "locking" is done by ensuring outside | 4711 | * All RX "locking" is done by ensuring outside |
4712 | * code synchronizes with tg3->napi.poll() | 4712 | * code synchronizes with tg3->napi.poll() |
4713 | */ | 4713 | */ |
4714 | if (sblk->idx[0].rx_producer != tnapi->rx_rcb_ptr) | 4714 | if (*(tnapi->rx_rcb_prod_idx) != tnapi->rx_rcb_ptr) |
4715 | work_done += tg3_rx(tnapi, budget - work_done); | 4715 | work_done += tg3_rx(tnapi, budget - work_done); |
4716 | 4716 | ||
4717 | return work_done; | 4717 | return work_done; |
@@ -5896,6 +5896,7 @@ static int tg3_alloc_consistent(struct tg3 *tp) | |||
5896 | 5896 | ||
5897 | for (i = 0; i < tp->irq_cnt; i++) { | 5897 | for (i = 0; i < tp->irq_cnt; i++) { |
5898 | struct tg3_napi *tnapi = &tp->napi[i]; | 5898 | struct tg3_napi *tnapi = &tp->napi[i]; |
5899 | struct tg3_hw_status *sblk; | ||
5899 | 5900 | ||
5900 | tnapi->hw_status = pci_alloc_consistent(tp->pdev, | 5901 | tnapi->hw_status = pci_alloc_consistent(tp->pdev, |
5901 | TG3_HW_STATUS_SIZE, | 5902 | TG3_HW_STATUS_SIZE, |
@@ -5904,6 +5905,28 @@ static int tg3_alloc_consistent(struct tg3 *tp) | |||
5904 | goto err_out; | 5905 | goto err_out; |
5905 | 5906 | ||
5906 | memset(tnapi->hw_status, 0, TG3_HW_STATUS_SIZE); | 5907 | memset(tnapi->hw_status, 0, TG3_HW_STATUS_SIZE); |
5908 | sblk = tnapi->hw_status; | ||
5909 | |||
5910 | /* | ||
5911 | * When RSS is enabled, the status block format changes | ||
5912 | * slightly. The "rx_jumbo_consumer", "reserved", | ||
5913 | * and "rx_mini_consumer" members get mapped to the | ||
5914 | * other three rx return ring producer indexes. | ||
5915 | */ | ||
5916 | switch (i) { | ||
5917 | default: | ||
5918 | tnapi->rx_rcb_prod_idx = &sblk->idx[0].rx_producer; | ||
5919 | break; | ||
5920 | case 2: | ||
5921 | tnapi->rx_rcb_prod_idx = &sblk->rx_jumbo_consumer; | ||
5922 | break; | ||
5923 | case 3: | ||
5924 | tnapi->rx_rcb_prod_idx = &sblk->reserved; | ||
5925 | break; | ||
5926 | case 4: | ||
5927 | tnapi->rx_rcb_prod_idx = &sblk->rx_mini_consumer; | ||
5928 | break; | ||
5929 | } | ||
5907 | 5930 | ||
5908 | /* | 5931 | /* |
5909 | * If multivector RSS is enabled, vector 0 does not handle | 5932 | * If multivector RSS is enabled, vector 0 does not handle |
diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h index 348add254d11..685d9712a802 100644 --- a/drivers/net/tg3.h +++ b/drivers/net/tg3.h | |||
@@ -2538,6 +2538,7 @@ struct tg3_napi { | |||
2538 | 2538 | ||
2539 | u32 consmbox; | 2539 | u32 consmbox; |
2540 | u32 rx_rcb_ptr; | 2540 | u32 rx_rcb_ptr; |
2541 | u16 *rx_rcb_prod_idx; | ||
2541 | 2542 | ||
2542 | struct tg3_rx_buffer_desc *rx_rcb; | 2543 | struct tg3_rx_buffer_desc *rx_rcb; |
2543 | struct tg3_tx_buffer_desc *tx_ring; | 2544 | struct tg3_tx_buffer_desc *tx_ring; |