diff options
author | Michael Chan <mchan@broadcom.com> | 2012-09-28 03:12:38 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2012-09-30 02:10:35 -0400 |
commit | 9102426a87f9b7edb943e17f76d46ee412083e10 (patch) | |
tree | 887540f5f6549cdbbc99dc40fea2729687418f9c /drivers/net/ethernet/broadcom | |
parent | 49a359e31762f798f3abef00c7d6b807a644eadf (diff) |
tg3: Allow number of rx and tx rings to be set independently.
irq_cnt is no longer necessarily equal to the number rx or tx rings.
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')
-rw-r--r-- | drivers/net/ethernet/broadcom/tg3.c | 74 | ||||
-rw-r--r-- | drivers/net/ethernet/broadcom/tg3.h | 5 |
2 files changed, 53 insertions, 26 deletions
diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c index 93b8120bbf68..330356bdaf0c 100644 --- a/drivers/net/ethernet/broadcom/tg3.c +++ b/drivers/net/ethernet/broadcom/tg3.c | |||
@@ -6278,7 +6278,7 @@ static int tg3_poll_work(struct tg3_napi *tnapi, int work_done, int budget) | |||
6278 | u32 jmb_prod_idx = dpr->rx_jmb_prod_idx; | 6278 | u32 jmb_prod_idx = dpr->rx_jmb_prod_idx; |
6279 | 6279 | ||
6280 | tp->rx_refill = false; | 6280 | tp->rx_refill = false; |
6281 | for (i = 1; i < tp->irq_cnt; i++) | 6281 | for (i = 1; i <= tp->rxq_cnt; i++) |
6282 | err |= tg3_rx_prodring_xfer(tp, dpr, | 6282 | err |= tg3_rx_prodring_xfer(tp, dpr, |
6283 | &tp->napi[i].prodring); | 6283 | &tp->napi[i].prodring); |
6284 | 6284 | ||
@@ -8654,13 +8654,12 @@ static void __tg3_set_rx_mode(struct net_device *dev) | |||
8654 | } | 8654 | } |
8655 | } | 8655 | } |
8656 | 8656 | ||
8657 | static void tg3_rss_init_dflt_indir_tbl(struct tg3 *tp) | 8657 | static void tg3_rss_init_dflt_indir_tbl(struct tg3 *tp, u32 qcnt) |
8658 | { | 8658 | { |
8659 | int i; | 8659 | int i; |
8660 | 8660 | ||
8661 | for (i = 0; i < TG3_RSS_INDIR_TBL_SIZE; i++) | 8661 | for (i = 0; i < TG3_RSS_INDIR_TBL_SIZE; i++) |
8662 | tp->rss_ind_tbl[i] = | 8662 | tp->rss_ind_tbl[i] = ethtool_rxfh_indir_default(i, qcnt); |
8663 | ethtool_rxfh_indir_default(i, tp->irq_cnt - 1); | ||
8664 | } | 8663 | } |
8665 | 8664 | ||
8666 | static void tg3_rss_check_indir_tbl(struct tg3 *tp) | 8665 | static void tg3_rss_check_indir_tbl(struct tg3 *tp) |
@@ -8682,7 +8681,7 @@ static void tg3_rss_check_indir_tbl(struct tg3 *tp) | |||
8682 | } | 8681 | } |
8683 | 8682 | ||
8684 | if (i != TG3_RSS_INDIR_TBL_SIZE) | 8683 | if (i != TG3_RSS_INDIR_TBL_SIZE) |
8685 | tg3_rss_init_dflt_indir_tbl(tp); | 8684 | tg3_rss_init_dflt_indir_tbl(tp, tp->rxq_cnt); |
8686 | } | 8685 | } |
8687 | 8686 | ||
8688 | static void tg3_rss_write_indir_tbl(struct tg3 *tp) | 8687 | static void tg3_rss_write_indir_tbl(struct tg3 *tp) |
@@ -10203,22 +10202,36 @@ static int tg3_request_firmware(struct tg3 *tp) | |||
10203 | return 0; | 10202 | return 0; |
10204 | } | 10203 | } |
10205 | 10204 | ||
10206 | static bool tg3_enable_msix(struct tg3 *tp) | 10205 | static u32 tg3_irq_count(struct tg3 *tp) |
10207 | { | 10206 | { |
10208 | int i, rc; | 10207 | u32 irq_cnt = max(tp->rxq_cnt, tp->txq_cnt); |
10209 | struct msix_entry msix_ent[tp->irq_max]; | ||
10210 | 10208 | ||
10211 | tp->irq_cnt = netif_get_num_default_rss_queues(); | 10209 | if (irq_cnt > 1) { |
10212 | if (tp->irq_cnt > 1) { | ||
10213 | /* We want as many rx rings enabled as there are cpus. | 10210 | /* We want as many rx rings enabled as there are cpus. |
10214 | * In multiqueue MSI-X mode, the first MSI-X vector | 10211 | * In multiqueue MSI-X mode, the first MSI-X vector |
10215 | * only deals with link interrupts, etc, so we add | 10212 | * only deals with link interrupts, etc, so we add |
10216 | * one to the number of vectors we are requesting. | 10213 | * one to the number of vectors we are requesting. |
10217 | */ | 10214 | */ |
10218 | tp->irq_cnt = min_t(unsigned, tp->irq_cnt + 1, tp->irq_max); | 10215 | irq_cnt = min_t(unsigned, irq_cnt + 1, tp->irq_max); |
10219 | tp->rxq_cnt = tp->irq_cnt - 1; | ||
10220 | } | 10216 | } |
10221 | 10217 | ||
10218 | return irq_cnt; | ||
10219 | } | ||
10220 | |||
10221 | static bool tg3_enable_msix(struct tg3 *tp) | ||
10222 | { | ||
10223 | int i, rc; | ||
10224 | struct msix_entry msix_ent[tp->irq_max]; | ||
10225 | |||
10226 | tp->rxq_cnt = netif_get_num_default_rss_queues(); | ||
10227 | if (tp->rxq_cnt > tp->rxq_max) | ||
10228 | tp->rxq_cnt = tp->rxq_max; | ||
10229 | if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719 || | ||
10230 | GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5720) | ||
10231 | tp->txq_cnt = min(tp->rxq_cnt, tp->txq_max); | ||
10232 | |||
10233 | tp->irq_cnt = tg3_irq_count(tp); | ||
10234 | |||
10222 | for (i = 0; i < tp->irq_max; i++) { | 10235 | for (i = 0; i < tp->irq_max; i++) { |
10223 | msix_ent[i].entry = i; | 10236 | msix_ent[i].entry = i; |
10224 | msix_ent[i].vector = 0; | 10237 | msix_ent[i].vector = 0; |
@@ -10234,6 +10247,8 @@ static bool tg3_enable_msix(struct tg3 *tp) | |||
10234 | tp->irq_cnt, rc); | 10247 | tp->irq_cnt, rc); |
10235 | tp->irq_cnt = rc; | 10248 | tp->irq_cnt = rc; |
10236 | tp->rxq_cnt = max(rc - 1, 1); | 10249 | tp->rxq_cnt = max(rc - 1, 1); |
10250 | if (tp->txq_cnt) | ||
10251 | tp->txq_cnt = min(tp->rxq_cnt, tp->txq_max); | ||
10237 | } | 10252 | } |
10238 | 10253 | ||
10239 | for (i = 0; i < tp->irq_max; i++) | 10254 | for (i = 0; i < tp->irq_max; i++) |
@@ -10244,16 +10259,15 @@ static bool tg3_enable_msix(struct tg3 *tp) | |||
10244 | return false; | 10259 | return false; |
10245 | } | 10260 | } |
10246 | 10261 | ||
10247 | if (tp->irq_cnt > 1) { | 10262 | if (tp->irq_cnt == 1) |
10248 | tg3_flag_set(tp, ENABLE_RSS); | 10263 | return true; |
10249 | 10264 | ||
10250 | if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719 || | 10265 | tg3_flag_set(tp, ENABLE_RSS); |
10251 | GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5720) { | 10266 | |
10252 | tg3_flag_set(tp, ENABLE_TSS); | 10267 | if (tp->txq_cnt > 1) |
10253 | tp->txq_cnt = tp->rxq_cnt; | 10268 | tg3_flag_set(tp, ENABLE_TSS); |
10254 | netif_set_real_num_tx_queues(tp->dev, tp->txq_cnt); | 10269 | |
10255 | } | 10270 | netif_set_real_num_tx_queues(tp->dev, tp->txq_cnt); |
10256 | } | ||
10257 | 10271 | ||
10258 | return true; | 10272 | return true; |
10259 | } | 10273 | } |
@@ -11275,11 +11289,11 @@ static int tg3_get_rxnfc(struct net_device *dev, struct ethtool_rxnfc *info, | |||
11275 | switch (info->cmd) { | 11289 | switch (info->cmd) { |
11276 | case ETHTOOL_GRXRINGS: | 11290 | case ETHTOOL_GRXRINGS: |
11277 | if (netif_running(tp->dev)) | 11291 | if (netif_running(tp->dev)) |
11278 | info->data = tp->irq_cnt; | 11292 | info->data = tp->rxq_cnt; |
11279 | else { | 11293 | else { |
11280 | info->data = num_online_cpus(); | 11294 | info->data = num_online_cpus(); |
11281 | if (info->data > TG3_IRQ_MAX_VECS_RSS) | 11295 | if (info->data > TG3_RSS_MAX_NUM_QS) |
11282 | info->data = TG3_IRQ_MAX_VECS_RSS; | 11296 | info->data = TG3_RSS_MAX_NUM_QS; |
11283 | } | 11297 | } |
11284 | 11298 | ||
11285 | /* The first interrupt vector only | 11299 | /* The first interrupt vector only |
@@ -14600,10 +14614,20 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) | |||
14600 | if (tg3_flag(tp, 57765_PLUS)) { | 14614 | if (tg3_flag(tp, 57765_PLUS)) { |
14601 | tg3_flag_set(tp, SUPPORT_MSIX); | 14615 | tg3_flag_set(tp, SUPPORT_MSIX); |
14602 | tp->irq_max = TG3_IRQ_MAX_VECS; | 14616 | tp->irq_max = TG3_IRQ_MAX_VECS; |
14603 | tg3_rss_init_dflt_indir_tbl(tp); | ||
14604 | } | 14617 | } |
14605 | } | 14618 | } |
14606 | 14619 | ||
14620 | tp->txq_max = 1; | ||
14621 | tp->rxq_max = 1; | ||
14622 | if (tp->irq_max > 1) { | ||
14623 | tp->rxq_max = TG3_RSS_MAX_NUM_QS; | ||
14624 | tg3_rss_init_dflt_indir_tbl(tp, TG3_RSS_MAX_NUM_QS); | ||
14625 | |||
14626 | if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719 || | ||
14627 | GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5720) | ||
14628 | tp->txq_max = tp->irq_max - 1; | ||
14629 | } | ||
14630 | |||
14607 | if (tg3_flag(tp, 5755_PLUS) || | 14631 | if (tg3_flag(tp, 5755_PLUS) || |
14608 | GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) | 14632 | GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) |
14609 | tg3_flag_set(tp, SHORT_DMA_BUG); | 14633 | tg3_flag_set(tp, SHORT_DMA_BUG); |
diff --git a/drivers/net/ethernet/broadcom/tg3.h b/drivers/net/ethernet/broadcom/tg3.h index 5838dea79563..2abe94cfd47f 100644 --- a/drivers/net/ethernet/broadcom/tg3.h +++ b/drivers/net/ethernet/broadcom/tg3.h | |||
@@ -2860,7 +2860,8 @@ struct tg3_rx_prodring_set { | |||
2860 | dma_addr_t rx_jmb_mapping; | 2860 | dma_addr_t rx_jmb_mapping; |
2861 | }; | 2861 | }; |
2862 | 2862 | ||
2863 | #define TG3_IRQ_MAX_VECS_RSS 5 | 2863 | #define TG3_RSS_MAX_NUM_QS 4 |
2864 | #define TG3_IRQ_MAX_VECS_RSS (TG3_RSS_MAX_NUM_QS + 1) | ||
2864 | #define TG3_IRQ_MAX_VECS TG3_IRQ_MAX_VECS_RSS | 2865 | #define TG3_IRQ_MAX_VECS TG3_IRQ_MAX_VECS_RSS |
2865 | 2866 | ||
2866 | struct tg3_napi { | 2867 | struct tg3_napi { |
@@ -3038,6 +3039,7 @@ struct tg3 { | |||
3038 | u32); | 3039 | u32); |
3039 | u32 dma_limit; | 3040 | u32 dma_limit; |
3040 | u32 txq_cnt; | 3041 | u32 txq_cnt; |
3042 | u32 txq_max; | ||
3041 | 3043 | ||
3042 | /* begin "rx thread" cacheline section */ | 3044 | /* begin "rx thread" cacheline section */ |
3043 | struct tg3_napi napi[TG3_IRQ_MAX_VECS]; | 3045 | struct tg3_napi napi[TG3_IRQ_MAX_VECS]; |
@@ -3053,6 +3055,7 @@ struct tg3 { | |||
3053 | u32 rx_offset; | 3055 | u32 rx_offset; |
3054 | u32 rx_pkt_map_sz; | 3056 | u32 rx_pkt_map_sz; |
3055 | u32 rxq_cnt; | 3057 | u32 rxq_cnt; |
3058 | u32 rxq_max; | ||
3056 | bool rx_refill; | 3059 | bool rx_refill; |
3057 | 3060 | ||
3058 | 3061 | ||