diff options
Diffstat (limited to 'drivers/net/bnx2.c')
-rw-r--r-- | drivers/net/bnx2.c | 71 |
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 | |||
4787 | bnx2_init_all_rings(struct bnx2 *bp) | 4797 | bnx2_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 | ||
4805 | static u32 bnx2_find_max_ring(u32 ring_size, u32 max_size) | 4841 | static 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 | ||
5665 | static void | 5701 | static void |
5666 | bnx2_enable_msix(struct bnx2 *bp) | 5702 | bnx2_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) | |||
5694 | static void | 5730 | static void |
5695 | bnx2_setup_int_mode(struct bnx2 *bp, int dis_msi) | 5731 | bnx2_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 */ |