aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/broadcom
diff options
context:
space:
mode:
authorMichael Chan <mchan@broadcom.com>2012-09-28 03:12:38 -0400
committerDavid S. Miller <davem@davemloft.net>2012-09-30 02:10:35 -0400
commit9102426a87f9b7edb943e17f76d46ee412083e10 (patch)
tree887540f5f6549cdbbc99dc40fea2729687418f9c /drivers/net/ethernet/broadcom
parent49a359e31762f798f3abef00c7d6b807a644eadf (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.c74
-rw-r--r--drivers/net/ethernet/broadcom/tg3.h5
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
8657static void tg3_rss_init_dflt_indir_tbl(struct tg3 *tp) 8657static 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
8666static void tg3_rss_check_indir_tbl(struct tg3 *tp) 8665static 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
8688static void tg3_rss_write_indir_tbl(struct tg3 *tp) 8687static 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
10206static bool tg3_enable_msix(struct tg3 *tp) 10205static 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
10221static 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
2866struct tg3_napi { 2867struct 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