aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/bnx2.c
diff options
context:
space:
mode:
authorMichael Chan <mchan@broadcom.com>2008-06-19 19:43:17 -0400
committerDavid S. Miller <davem@davemloft.net>2008-06-19 19:43:17 -0400
commit5e9ad9e108883503fedfac3279ac101dce00bb56 (patch)
tree240d424599a9c384d382b56633b3bba4100aa97e /drivers/net/bnx2.c
parent2dffcc3dcd659b10ff97c6eda427d9d83a94a399 (diff)
bnx2: Turn on multi rx rings.
Enable multiple rx rings if MSI-X vectors are available. We enable up to 7 rx rings. Signed-off-by: Michael Chan <mchan@broadcom.com> Signed-off-by: Benjamin Li <benli@broadcom.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/bnx2.c')
-rw-r--r--drivers/net/bnx2.c71
1 files changed, 55 insertions, 16 deletions
diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c
index 0a297f77a276..3b907196ca48 100644
--- a/drivers/net/bnx2.c
+++ b/drivers/net/bnx2.c
@@ -4542,15 +4542,25 @@ bnx2_init_chip(struct bnx2 *bp)
4542 BNX2_HC_CONFIG_COLLECT_STATS; 4542 BNX2_HC_CONFIG_COLLECT_STATS;
4543 } 4543 }
4544 4544
4545 if (bp->flags & BNX2_FLAG_USING_MSIX) { 4545 if (bp->irq_nvecs > 1) {
4546 u32 base = ((BNX2_TX_VEC - 1) * BNX2_HC_SB_CONFIG_SIZE) +
4547 BNX2_HC_SB_CONFIG_1;
4548
4549 REG_WR(bp, BNX2_HC_MSIX_BIT_VECTOR, 4546 REG_WR(bp, BNX2_HC_MSIX_BIT_VECTOR,
4550 BNX2_HC_MSIX_BIT_VECTOR_VAL); 4547 BNX2_HC_MSIX_BIT_VECTOR_VAL);
4551 4548
4549 val |= BNX2_HC_CONFIG_SB_ADDR_INC_128B;
4550 }
4551
4552 if (bp->flags & BNX2_FLAG_ONE_SHOT_MSI)
4553 val |= BNX2_HC_CONFIG_ONE_SHOT;
4554
4555 REG_WR(bp, BNX2_HC_CONFIG, val);
4556
4557 for (i = 1; i < bp->irq_nvecs; i++) {
4558 u32 base = ((i - 1) * BNX2_HC_SB_CONFIG_SIZE) +
4559 BNX2_HC_SB_CONFIG_1;
4560
4552 REG_WR(bp, base, 4561 REG_WR(bp, base,
4553 BNX2_HC_SB_CONFIG_1_TX_TMR_MODE | 4562 BNX2_HC_SB_CONFIG_1_TX_TMR_MODE |
4563 BNX2_HC_SB_CONFIG_1_RX_TMR_MODE |
4554 BNX2_HC_SB_CONFIG_1_ONE_SHOT); 4564 BNX2_HC_SB_CONFIG_1_ONE_SHOT);
4555 4565
4556 REG_WR(bp, base + BNX2_HC_TX_QUICK_CONS_TRIP_OFF, 4566 REG_WR(bp, base + BNX2_HC_TX_QUICK_CONS_TRIP_OFF,
@@ -4560,13 +4570,13 @@ bnx2_init_chip(struct bnx2 *bp)
4560 REG_WR(bp, base + BNX2_HC_TX_TICKS_OFF, 4570 REG_WR(bp, base + BNX2_HC_TX_TICKS_OFF,
4561 (bp->tx_ticks_int << 16) | bp->tx_ticks); 4571 (bp->tx_ticks_int << 16) | bp->tx_ticks);
4562 4572
4563 val |= BNX2_HC_CONFIG_SB_ADDR_INC_128B; 4573 REG_WR(bp, base + BNX2_HC_RX_QUICK_CONS_TRIP_OFF,
4564 } 4574 (bp->rx_quick_cons_trip_int << 16) |
4565 4575 bp->rx_quick_cons_trip);
4566 if (bp->flags & BNX2_FLAG_ONE_SHOT_MSI)
4567 val |= BNX2_HC_CONFIG_ONE_SHOT;
4568 4576
4569 REG_WR(bp, BNX2_HC_CONFIG, val); 4577 REG_WR(bp, base + BNX2_HC_RX_TICKS_OFF,
4578 (bp->rx_ticks_int << 16) | bp->rx_ticks);
4579 }
4570 4580
4571 /* Clear internal stats counters. */ 4581 /* Clear internal stats counters. */
4572 REG_WR(bp, BNX2_HC_COMMAND, BNX2_HC_COMMAND_CLR_STAT_NOW); 4582 REG_WR(bp, BNX2_HC_COMMAND, BNX2_HC_COMMAND_CLR_STAT_NOW);
@@ -4737,7 +4747,7 @@ bnx2_init_rx_ring(struct bnx2 *bp, int ring_num)
4737 val = (bp->rx_buf_use_size << 16) | PAGE_SIZE; 4747 val = (bp->rx_buf_use_size << 16) | PAGE_SIZE;
4738 bnx2_ctx_wr(bp, rx_cid_addr, BNX2_L2CTX_PG_BUF_SIZE, val); 4748 bnx2_ctx_wr(bp, rx_cid_addr, BNX2_L2CTX_PG_BUF_SIZE, val);
4739 bnx2_ctx_wr(bp, rx_cid_addr, BNX2_L2CTX_RBDC_KEY, 4749 bnx2_ctx_wr(bp, rx_cid_addr, BNX2_L2CTX_RBDC_KEY,
4740 BNX2_L2CTX_RBDC_JUMBO_KEY); 4750 BNX2_L2CTX_RBDC_JUMBO_KEY - ring_num);
4741 4751
4742 val = (u64) rxr->rx_pg_desc_mapping[0] >> 32; 4752 val = (u64) rxr->rx_pg_desc_mapping[0] >> 32;
4743 bnx2_ctx_wr(bp, rx_cid_addr, BNX2_L2CTX_NX_PG_BDHADDR_HI, val); 4753 bnx2_ctx_wr(bp, rx_cid_addr, BNX2_L2CTX_NX_PG_BDHADDR_HI, val);
@@ -4787,6 +4797,7 @@ static void
4787bnx2_init_all_rings(struct bnx2 *bp) 4797bnx2_init_all_rings(struct bnx2 *bp)
4788{ 4798{
4789 int i; 4799 int i;
4800 u32 val;
4790 4801
4791 bnx2_clear_ring_states(bp); 4802 bnx2_clear_ring_states(bp);
4792 4803
@@ -4798,8 +4809,33 @@ bnx2_init_all_rings(struct bnx2 *bp)
4798 REG_WR(bp, BNX2_TSCH_TSS_CFG, ((bp->num_tx_rings - 1) << 24) | 4809 REG_WR(bp, BNX2_TSCH_TSS_CFG, ((bp->num_tx_rings - 1) << 24) |
4799 (TX_TSS_CID << 7)); 4810 (TX_TSS_CID << 7));
4800 4811
4812 REG_WR(bp, BNX2_RLUP_RSS_CONFIG, 0);
4813 bnx2_reg_wr_ind(bp, BNX2_RXP_SCRATCH_RSS_TBL_SZ, 0);
4814
4801 for (i = 0; i < bp->num_rx_rings; i++) 4815 for (i = 0; i < bp->num_rx_rings; i++)
4802 bnx2_init_rx_ring(bp, i); 4816 bnx2_init_rx_ring(bp, i);
4817
4818 if (bp->num_rx_rings > 1) {
4819 u32 tbl_32;
4820 u8 *tbl = (u8 *) &tbl_32;
4821
4822 bnx2_reg_wr_ind(bp, BNX2_RXP_SCRATCH_RSS_TBL_SZ,
4823 BNX2_RXP_SCRATCH_RSS_TBL_MAX_ENTRIES);
4824
4825 for (i = 0; i < BNX2_RXP_SCRATCH_RSS_TBL_MAX_ENTRIES; i++) {
4826 tbl[i % 4] = i % (bp->num_rx_rings - 1);
4827 if ((i % 4) == 3)
4828 bnx2_reg_wr_ind(bp,
4829 BNX2_RXP_SCRATCH_RSS_TBL + i,
4830 cpu_to_be32(tbl_32));
4831 }
4832
4833 val = BNX2_RLUP_RSS_CONFIG_IPV4_RSS_TYPE_ALL_XI |
4834 BNX2_RLUP_RSS_CONFIG_IPV6_RSS_TYPE_ALL_XI;
4835
4836 REG_WR(bp, BNX2_RLUP_RSS_CONFIG, val);
4837
4838 }
4803} 4839}
4804 4840
4805static u32 bnx2_find_max_ring(u32 ring_size, u32 max_size) 4841static u32 bnx2_find_max_ring(u32 ring_size, u32 max_size)
@@ -5663,7 +5699,7 @@ bnx2_free_irq(struct bnx2 *bp)
5663} 5699}
5664 5700
5665static void 5701static void
5666bnx2_enable_msix(struct bnx2 *bp) 5702bnx2_enable_msix(struct bnx2 *bp, int msix_vecs)
5667{ 5703{
5668 int i, rc; 5704 int i, rc;
5669 struct msix_entry msix_ent[BNX2_MAX_MSIX_VEC]; 5705 struct msix_entry msix_ent[BNX2_MAX_MSIX_VEC];
@@ -5685,7 +5721,7 @@ bnx2_enable_msix(struct bnx2 *bp)
5685 if (rc != 0) 5721 if (rc != 0)
5686 return; 5722 return;
5687 5723
5688 bp->irq_nvecs = BNX2_MAX_MSIX_VEC; 5724 bp->irq_nvecs = msix_vecs;
5689 bp->flags |= BNX2_FLAG_USING_MSIX | BNX2_FLAG_ONE_SHOT_MSI; 5725 bp->flags |= BNX2_FLAG_USING_MSIX | BNX2_FLAG_ONE_SHOT_MSI;
5690 for (i = 0; i < BNX2_MAX_MSIX_VEC; i++) 5726 for (i = 0; i < BNX2_MAX_MSIX_VEC; i++)
5691 bp->irq_tbl[i].vector = msix_ent[i].vector; 5727 bp->irq_tbl[i].vector = msix_ent[i].vector;
@@ -5694,13 +5730,16 @@ bnx2_enable_msix(struct bnx2 *bp)
5694static void 5730static void
5695bnx2_setup_int_mode(struct bnx2 *bp, int dis_msi) 5731bnx2_setup_int_mode(struct bnx2 *bp, int dis_msi)
5696{ 5732{
5733 int cpus = num_online_cpus();
5734 int msix_vecs = min(cpus + 1, RX_MAX_RSS_RINGS);
5735
5697 bp->irq_tbl[0].handler = bnx2_interrupt; 5736 bp->irq_tbl[0].handler = bnx2_interrupt;
5698 strcpy(bp->irq_tbl[0].name, bp->dev->name); 5737 strcpy(bp->irq_tbl[0].name, bp->dev->name);
5699 bp->irq_nvecs = 1; 5738 bp->irq_nvecs = 1;
5700 bp->irq_tbl[0].vector = bp->pdev->irq; 5739 bp->irq_tbl[0].vector = bp->pdev->irq;
5701 5740
5702 if ((bp->flags & BNX2_FLAG_MSIX_CAP) && !dis_msi) 5741 if ((bp->flags & BNX2_FLAG_MSIX_CAP) && !dis_msi && cpus > 1)
5703 bnx2_enable_msix(bp); 5742 bnx2_enable_msix(bp, msix_vecs);
5704 5743
5705 if ((bp->flags & BNX2_FLAG_MSI_CAP) && !dis_msi && 5744 if ((bp->flags & BNX2_FLAG_MSI_CAP) && !dis_msi &&
5706 !(bp->flags & BNX2_FLAG_USING_MSIX)) { 5745 !(bp->flags & BNX2_FLAG_USING_MSIX)) {
@@ -5716,7 +5755,7 @@ bnx2_setup_int_mode(struct bnx2 *bp, int dis_msi)
5716 } 5755 }
5717 } 5756 }
5718 bp->num_tx_rings = 1; 5757 bp->num_tx_rings = 1;
5719 bp->num_rx_rings = 1; 5758 bp->num_rx_rings = bp->irq_nvecs;
5720} 5759}
5721 5760
5722/* Called with rtnl_lock */ 5761/* Called with rtnl_lock */