diff options
author | Michael Chan <mchan@broadcom.com> | 2007-12-20 23:01:19 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-01-28 17:57:38 -0500 |
commit | c76c04758b8fd24a1c38b19742e3437e954e945b (patch) | |
tree | 248d6953e058d7513c5bb9442f24a0ae92ea4305 /drivers/net | |
parent | b4b360420dcbbffb15f5749fc78225f4113cc7e2 (diff) |
[BNX2]: Add support for a new tx ring.
To separate TX IRQs into a different MSIX vector, we need to
support a new tx ring. The original tx ring will still be used
when not using MSIX.
Signed-off-by: Michael Chan <mchan@broadcom.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/bnx2.c | 78 | ||||
-rw-r--r-- | drivers/net/bnx2.h | 5 |
2 files changed, 65 insertions, 18 deletions
diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c index 4f2ca8a53af5..4fc9d1653cda 100644 --- a/drivers/net/bnx2.c +++ b/drivers/net/bnx2.c | |||
@@ -2378,7 +2378,10 @@ bnx2_get_hw_tx_cons(struct bnx2_napi *bnapi) | |||
2378 | { | 2378 | { |
2379 | u16 cons; | 2379 | u16 cons; |
2380 | 2380 | ||
2381 | cons = bnapi->status_blk->status_tx_quick_consumer_index0; | 2381 | if (bnapi->int_num == 0) |
2382 | cons = bnapi->status_blk->status_tx_quick_consumer_index0; | ||
2383 | else | ||
2384 | cons = bnapi->status_blk_msix->status_tx_quick_consumer_index; | ||
2382 | 2385 | ||
2383 | if (unlikely((cons & MAX_TX_DESC_CNT) == MAX_TX_DESC_CNT)) | 2386 | if (unlikely((cons & MAX_TX_DESC_CNT) == MAX_TX_DESC_CNT)) |
2384 | cons++; | 2387 | cons++; |
@@ -2389,7 +2392,6 @@ static void | |||
2389 | bnx2_tx_int(struct bnx2 *bp, struct bnx2_napi *bnapi) | 2392 | bnx2_tx_int(struct bnx2 *bp, struct bnx2_napi *bnapi) |
2390 | { | 2393 | { |
2391 | u16 hw_cons, sw_cons, sw_ring_cons; | 2394 | u16 hw_cons, sw_cons, sw_ring_cons; |
2392 | int tx_free_bd = 0; | ||
2393 | 2395 | ||
2394 | hw_cons = bnx2_get_hw_tx_cons(bnapi); | 2396 | hw_cons = bnx2_get_hw_tx_cons(bnapi); |
2395 | sw_cons = bnapi->tx_cons; | 2397 | sw_cons = bnapi->tx_cons; |
@@ -2439,8 +2441,6 @@ bnx2_tx_int(struct bnx2 *bp, struct bnx2_napi *bnapi) | |||
2439 | 2441 | ||
2440 | sw_cons = NEXT_TX_BD(sw_cons); | 2442 | sw_cons = NEXT_TX_BD(sw_cons); |
2441 | 2443 | ||
2442 | tx_free_bd += last + 1; | ||
2443 | |||
2444 | dev_kfree_skb(skb); | 2444 | dev_kfree_skb(skb); |
2445 | 2445 | ||
2446 | hw_cons = bnx2_get_hw_tx_cons(bnapi); | 2446 | hw_cons = bnx2_get_hw_tx_cons(bnapi); |
@@ -4369,6 +4369,24 @@ bnx2_init_chip(struct bnx2 *bp) | |||
4369 | BNX2_HC_CONFIG_COLLECT_STATS; | 4369 | BNX2_HC_CONFIG_COLLECT_STATS; |
4370 | } | 4370 | } |
4371 | 4371 | ||
4372 | if (bp->flags & USING_MSIX_FLAG) { | ||
4373 | REG_WR(bp, BNX2_HC_MSIX_BIT_VECTOR, | ||
4374 | BNX2_HC_MSIX_BIT_VECTOR_VAL); | ||
4375 | |||
4376 | REG_WR(bp, BNX2_HC_SB_CONFIG_1, | ||
4377 | BNX2_HC_SB_CONFIG_1_TX_TMR_MODE | | ||
4378 | BNX2_HC_SB_CONFIG_1_ONE_SHOT); | ||
4379 | |||
4380 | REG_WR(bp, BNX2_HC_TX_QUICK_CONS_TRIP_1, | ||
4381 | (bp->tx_quick_cons_trip_int << 16) | | ||
4382 | bp->tx_quick_cons_trip); | ||
4383 | |||
4384 | REG_WR(bp, BNX2_HC_TX_TICKS_1, | ||
4385 | (bp->tx_ticks_int << 16) | bp->tx_ticks); | ||
4386 | |||
4387 | val |= BNX2_HC_CONFIG_SB_ADDR_INC_128B; | ||
4388 | } | ||
4389 | |||
4372 | if (bp->flags & ONE_SHOT_MSI_FLAG) | 4390 | if (bp->flags & ONE_SHOT_MSI_FLAG) |
4373 | val |= BNX2_HC_CONFIG_ONE_SHOT; | 4391 | val |= BNX2_HC_CONFIG_ONE_SHOT; |
4374 | 4392 | ||
@@ -4401,6 +4419,25 @@ bnx2_init_chip(struct bnx2 *bp) | |||
4401 | } | 4419 | } |
4402 | 4420 | ||
4403 | static void | 4421 | static void |
4422 | bnx2_clear_ring_states(struct bnx2 *bp) | ||
4423 | { | ||
4424 | struct bnx2_napi *bnapi; | ||
4425 | int i; | ||
4426 | |||
4427 | for (i = 0; i < BNX2_MAX_MSIX_VEC; i++) { | ||
4428 | bnapi = &bp->bnx2_napi[i]; | ||
4429 | |||
4430 | bnapi->tx_cons = 0; | ||
4431 | bnapi->hw_tx_cons = 0; | ||
4432 | bnapi->rx_prod_bseq = 0; | ||
4433 | bnapi->rx_prod = 0; | ||
4434 | bnapi->rx_cons = 0; | ||
4435 | bnapi->rx_pg_prod = 0; | ||
4436 | bnapi->rx_pg_cons = 0; | ||
4437 | } | ||
4438 | } | ||
4439 | |||
4440 | static void | ||
4404 | bnx2_init_tx_context(struct bnx2 *bp, u32 cid) | 4441 | bnx2_init_tx_context(struct bnx2 *bp, u32 cid) |
4405 | { | 4442 | { |
4406 | u32 val, offset0, offset1, offset2, offset3; | 4443 | u32 val, offset0, offset1, offset2, offset3; |
@@ -4433,8 +4470,17 @@ static void | |||
4433 | bnx2_init_tx_ring(struct bnx2 *bp) | 4470 | bnx2_init_tx_ring(struct bnx2 *bp) |
4434 | { | 4471 | { |
4435 | struct tx_bd *txbd; | 4472 | struct tx_bd *txbd; |
4436 | u32 cid; | 4473 | u32 cid = TX_CID; |
4437 | struct bnx2_napi *bnapi = &bp->bnx2_napi[0]; | 4474 | struct bnx2_napi *bnapi; |
4475 | |||
4476 | bp->tx_vec = 0; | ||
4477 | if (bp->flags & USING_MSIX_FLAG) { | ||
4478 | cid = TX_TSS_CID; | ||
4479 | bp->tx_vec = BNX2_TX_VEC; | ||
4480 | REG_WR(bp, BNX2_TSCH_TSS_CFG, BNX2_TX_INT_NUM | | ||
4481 | (TX_TSS_CID << 7)); | ||
4482 | } | ||
4483 | bnapi = &bp->bnx2_napi[bp->tx_vec]; | ||
4438 | 4484 | ||
4439 | bp->tx_wake_thresh = bp->tx_ring_size / 2; | 4485 | bp->tx_wake_thresh = bp->tx_ring_size / 2; |
4440 | 4486 | ||
@@ -4444,11 +4490,8 @@ bnx2_init_tx_ring(struct bnx2 *bp) | |||
4444 | txbd->tx_bd_haddr_lo = (u64) bp->tx_desc_mapping & 0xffffffff; | 4490 | txbd->tx_bd_haddr_lo = (u64) bp->tx_desc_mapping & 0xffffffff; |
4445 | 4491 | ||
4446 | bp->tx_prod = 0; | 4492 | bp->tx_prod = 0; |
4447 | bnapi->tx_cons = 0; | ||
4448 | bnapi->hw_tx_cons = 0; | ||
4449 | bp->tx_prod_bseq = 0; | 4493 | bp->tx_prod_bseq = 0; |
4450 | 4494 | ||
4451 | cid = TX_CID; | ||
4452 | bp->tx_bidx_addr = MB_GET_CID_ADDR(cid) + BNX2_L2CTX_TX_HOST_BIDX; | 4495 | bp->tx_bidx_addr = MB_GET_CID_ADDR(cid) + BNX2_L2CTX_TX_HOST_BIDX; |
4453 | bp->tx_bseq_addr = MB_GET_CID_ADDR(cid) + BNX2_L2CTX_TX_HOST_BSEQ; | 4496 | bp->tx_bseq_addr = MB_GET_CID_ADDR(cid) + BNX2_L2CTX_TX_HOST_BSEQ; |
4454 | 4497 | ||
@@ -4487,12 +4530,6 @@ bnx2_init_rx_ring(struct bnx2 *bp) | |||
4487 | u32 val, rx_cid_addr = GET_CID_ADDR(RX_CID); | 4530 | u32 val, rx_cid_addr = GET_CID_ADDR(RX_CID); |
4488 | struct bnx2_napi *bnapi = &bp->bnx2_napi[0]; | 4531 | struct bnx2_napi *bnapi = &bp->bnx2_napi[0]; |
4489 | 4532 | ||
4490 | bnapi->rx_prod = 0; | ||
4491 | bnapi->rx_cons = 0; | ||
4492 | bnapi->rx_prod_bseq = 0; | ||
4493 | bnapi->rx_pg_prod = 0; | ||
4494 | bnapi->rx_pg_cons = 0; | ||
4495 | |||
4496 | bnx2_init_rxbd_rings(bp->rx_desc_ring, bp->rx_desc_mapping, | 4533 | bnx2_init_rxbd_rings(bp->rx_desc_ring, bp->rx_desc_mapping, |
4497 | bp->rx_buf_use_size, bp->rx_max_ring); | 4534 | bp->rx_buf_use_size, bp->rx_max_ring); |
4498 | 4535 | ||
@@ -4694,6 +4731,7 @@ bnx2_reset_nic(struct bnx2 *bp, u32 reset_code) | |||
4694 | if ((rc = bnx2_init_chip(bp)) != 0) | 4731 | if ((rc = bnx2_init_chip(bp)) != 0) |
4695 | return rc; | 4732 | return rc; |
4696 | 4733 | ||
4734 | bnx2_clear_ring_states(bp); | ||
4697 | bnx2_init_tx_ring(bp); | 4735 | bnx2_init_tx_ring(bp); |
4698 | bnx2_init_rx_ring(bp); | 4736 | bnx2_init_rx_ring(bp); |
4699 | return 0; | 4737 | return 0; |
@@ -4965,7 +5003,11 @@ bnx2_run_loopback(struct bnx2 *bp, int loopback_mode) | |||
4965 | struct sw_bd *rx_buf; | 5003 | struct sw_bd *rx_buf; |
4966 | struct l2_fhdr *rx_hdr; | 5004 | struct l2_fhdr *rx_hdr; |
4967 | int ret = -ENODEV; | 5005 | int ret = -ENODEV; |
4968 | struct bnx2_napi *bnapi = &bp->bnx2_napi[0]; | 5006 | struct bnx2_napi *bnapi = &bp->bnx2_napi[0], *tx_napi; |
5007 | |||
5008 | tx_napi = bnapi; | ||
5009 | if (bp->flags & USING_MSIX_FLAG) | ||
5010 | tx_napi = &bp->bnx2_napi[BNX2_TX_VEC]; | ||
4969 | 5011 | ||
4970 | if (loopback_mode == BNX2_MAC_LOOPBACK) { | 5012 | if (loopback_mode == BNX2_MAC_LOOPBACK) { |
4971 | bp->loopback = MAC_LOOPBACK; | 5013 | bp->loopback = MAC_LOOPBACK; |
@@ -5030,7 +5072,7 @@ bnx2_run_loopback(struct bnx2 *bp, int loopback_mode) | |||
5030 | pci_unmap_single(bp->pdev, map, pkt_size, PCI_DMA_TODEVICE); | 5072 | pci_unmap_single(bp->pdev, map, pkt_size, PCI_DMA_TODEVICE); |
5031 | dev_kfree_skb(skb); | 5073 | dev_kfree_skb(skb); |
5032 | 5074 | ||
5033 | if (bnx2_get_hw_tx_cons(bnapi) != bp->tx_prod) | 5075 | if (bnx2_get_hw_tx_cons(tx_napi) != bp->tx_prod) |
5034 | goto loopback_test_done; | 5076 | goto loopback_test_done; |
5035 | 5077 | ||
5036 | rx_idx = bnx2_get_hw_rx_cons(bnapi); | 5078 | rx_idx = bnx2_get_hw_rx_cons(bnapi); |
@@ -5324,7 +5366,7 @@ bnx2_request_irq(struct bnx2 *bp) | |||
5324 | 5366 | ||
5325 | for (i = 0; i < bp->irq_nvecs; i++) { | 5367 | for (i = 0; i < bp->irq_nvecs; i++) { |
5326 | irq = &bp->irq_tbl[i]; | 5368 | irq = &bp->irq_tbl[i]; |
5327 | rc = request_irq(irq->vector, irq->handler, flags, dev->name, | 5369 | rc = request_irq(irq->vector, irq->handler, flags, irq->name, |
5328 | dev); | 5370 | dev); |
5329 | if (rc) | 5371 | if (rc) |
5330 | break; | 5372 | break; |
diff --git a/drivers/net/bnx2.h b/drivers/net/bnx2.h index d71ceb6c176f..68fb5904f75c 100644 --- a/drivers/net/bnx2.h +++ b/drivers/net/bnx2.h | |||
@@ -6529,6 +6529,9 @@ struct flash_spec { | |||
6529 | 6529 | ||
6530 | #define BNX2_MAX_MSIX_HW_VEC 9 | 6530 | #define BNX2_MAX_MSIX_HW_VEC 9 |
6531 | #define BNX2_MAX_MSIX_VEC 1 | 6531 | #define BNX2_MAX_MSIX_VEC 1 |
6532 | #define BNX2_BASE_VEC 0 | ||
6533 | #define BNX2_TX_VEC 1 | ||
6534 | #define BNX2_TX_INT_NUM (BNX2_TX_VEC << BNX2_PCICFG_INT_ACK_CMD_INT_NUM_SHIFT) | ||
6532 | 6535 | ||
6533 | struct bnx2_irq { | 6536 | struct bnx2_irq { |
6534 | irq_handler_t handler; | 6537 | irq_handler_t handler; |
@@ -6541,6 +6544,7 @@ struct bnx2_napi { | |||
6541 | struct napi_struct napi ____cacheline_aligned; | 6544 | struct napi_struct napi ____cacheline_aligned; |
6542 | struct bnx2 *bp; | 6545 | struct bnx2 *bp; |
6543 | struct status_block *status_blk; | 6546 | struct status_block *status_blk; |
6547 | struct status_block_msix *status_blk_msix; | ||
6544 | u32 last_status_idx; | 6548 | u32 last_status_idx; |
6545 | u32 int_num; | 6549 | u32 int_num; |
6546 | 6550 | ||
@@ -6583,6 +6587,7 @@ struct bnx2 { | |||
6583 | 6587 | ||
6584 | u32 tx_prod_bseq __attribute__((aligned(L1_CACHE_BYTES))); | 6588 | u32 tx_prod_bseq __attribute__((aligned(L1_CACHE_BYTES))); |
6585 | u16 tx_prod; | 6589 | u16 tx_prod; |
6590 | u8 tx_vec; | ||
6586 | u32 tx_bidx_addr; | 6591 | u32 tx_bidx_addr; |
6587 | u32 tx_bseq_addr; | 6592 | u32 tx_bseq_addr; |
6588 | 6593 | ||