diff options
author | Michael Chan <mchan@broadcom.com> | 2007-12-20 22:59:30 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-01-28 17:57:37 -0500 |
commit | b4b360420dcbbffb15f5749fc78225f4113cc7e2 (patch) | |
tree | a7378249d52fd80ac2599c66f624abf5918318ed /drivers/net | |
parent | a1f6019090f2c075b41624c32a825775f6865577 (diff) |
[BNX2]: Support multiple MSIX IRQs.
Change bnx2_napi struct into an array and add code to manage multiple
IRQs. MSIX hardware structures and new registers are also added.
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 | 161 | ||||
-rw-r--r-- | drivers/net/bnx2.h | 40 |
2 files changed, 163 insertions, 38 deletions
diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c index ecfaad102f70..4f2ca8a53af5 100644 --- a/drivers/net/bnx2.c +++ b/drivers/net/bnx2.c | |||
@@ -399,44 +399,65 @@ bnx2_write_phy(struct bnx2 *bp, u32 reg, u32 val) | |||
399 | static void | 399 | static void |
400 | bnx2_disable_int(struct bnx2 *bp) | 400 | bnx2_disable_int(struct bnx2 *bp) |
401 | { | 401 | { |
402 | REG_WR(bp, BNX2_PCICFG_INT_ACK_CMD, | 402 | int i; |
403 | BNX2_PCICFG_INT_ACK_CMD_MASK_INT); | 403 | struct bnx2_napi *bnapi; |
404 | |||
405 | for (i = 0; i < bp->irq_nvecs; i++) { | ||
406 | bnapi = &bp->bnx2_napi[i]; | ||
407 | REG_WR(bp, BNX2_PCICFG_INT_ACK_CMD, bnapi->int_num | | ||
408 | BNX2_PCICFG_INT_ACK_CMD_MASK_INT); | ||
409 | } | ||
404 | REG_RD(bp, BNX2_PCICFG_INT_ACK_CMD); | 410 | REG_RD(bp, BNX2_PCICFG_INT_ACK_CMD); |
405 | } | 411 | } |
406 | 412 | ||
407 | static void | 413 | static void |
408 | bnx2_enable_int(struct bnx2 *bp) | 414 | bnx2_enable_int(struct bnx2 *bp) |
409 | { | 415 | { |
410 | struct bnx2_napi *bnapi = &bp->bnx2_napi; | 416 | int i; |
417 | struct bnx2_napi *bnapi; | ||
411 | 418 | ||
412 | REG_WR(bp, BNX2_PCICFG_INT_ACK_CMD, | 419 | for (i = 0; i < bp->irq_nvecs; i++) { |
413 | BNX2_PCICFG_INT_ACK_CMD_INDEX_VALID | | 420 | bnapi = &bp->bnx2_napi[i]; |
414 | BNX2_PCICFG_INT_ACK_CMD_MASK_INT | bnapi->last_status_idx); | ||
415 | 421 | ||
416 | REG_WR(bp, BNX2_PCICFG_INT_ACK_CMD, | 422 | REG_WR(bp, BNX2_PCICFG_INT_ACK_CMD, bnapi->int_num | |
417 | BNX2_PCICFG_INT_ACK_CMD_INDEX_VALID | bnapi->last_status_idx); | 423 | BNX2_PCICFG_INT_ACK_CMD_INDEX_VALID | |
424 | BNX2_PCICFG_INT_ACK_CMD_MASK_INT | | ||
425 | bnapi->last_status_idx); | ||
418 | 426 | ||
427 | REG_WR(bp, BNX2_PCICFG_INT_ACK_CMD, bnapi->int_num | | ||
428 | BNX2_PCICFG_INT_ACK_CMD_INDEX_VALID | | ||
429 | bnapi->last_status_idx); | ||
430 | } | ||
419 | REG_WR(bp, BNX2_HC_COMMAND, bp->hc_cmd | BNX2_HC_COMMAND_COAL_NOW); | 431 | REG_WR(bp, BNX2_HC_COMMAND, bp->hc_cmd | BNX2_HC_COMMAND_COAL_NOW); |
420 | } | 432 | } |
421 | 433 | ||
422 | static void | 434 | static void |
423 | bnx2_disable_int_sync(struct bnx2 *bp) | 435 | bnx2_disable_int_sync(struct bnx2 *bp) |
424 | { | 436 | { |
437 | int i; | ||
438 | |||
425 | atomic_inc(&bp->intr_sem); | 439 | atomic_inc(&bp->intr_sem); |
426 | bnx2_disable_int(bp); | 440 | bnx2_disable_int(bp); |
427 | synchronize_irq(bp->pdev->irq); | 441 | for (i = 0; i < bp->irq_nvecs; i++) |
442 | synchronize_irq(bp->irq_tbl[i].vector); | ||
428 | } | 443 | } |
429 | 444 | ||
430 | static void | 445 | static void |
431 | bnx2_napi_disable(struct bnx2 *bp) | 446 | bnx2_napi_disable(struct bnx2 *bp) |
432 | { | 447 | { |
433 | napi_disable(&bp->bnx2_napi.napi); | 448 | int i; |
449 | |||
450 | for (i = 0; i < bp->irq_nvecs; i++) | ||
451 | napi_disable(&bp->bnx2_napi[i].napi); | ||
434 | } | 452 | } |
435 | 453 | ||
436 | static void | 454 | static void |
437 | bnx2_napi_enable(struct bnx2 *bp) | 455 | bnx2_napi_enable(struct bnx2 *bp) |
438 | { | 456 | { |
439 | napi_enable(&bp->bnx2_napi.napi); | 457 | int i; |
458 | |||
459 | for (i = 0; i < bp->irq_nvecs; i++) | ||
460 | napi_enable(&bp->bnx2_napi[i].napi); | ||
440 | } | 461 | } |
441 | 462 | ||
442 | static void | 463 | static void |
@@ -559,6 +580,9 @@ bnx2_alloc_mem(struct bnx2 *bp) | |||
559 | 580 | ||
560 | /* Combine status and statistics blocks into one allocation. */ | 581 | /* Combine status and statistics blocks into one allocation. */ |
561 | status_blk_size = L1_CACHE_ALIGN(sizeof(struct status_block)); | 582 | status_blk_size = L1_CACHE_ALIGN(sizeof(struct status_block)); |
583 | if (bp->flags & MSIX_CAP_FLAG) | ||
584 | status_blk_size = L1_CACHE_ALIGN(BNX2_MAX_MSIX_HW_VEC * | ||
585 | BNX2_SBLK_MSIX_ALIGN_SIZE); | ||
562 | bp->status_stats_size = status_blk_size + | 586 | bp->status_stats_size = status_blk_size + |
563 | sizeof(struct statistics_block); | 587 | sizeof(struct statistics_block); |
564 | 588 | ||
@@ -569,7 +593,17 @@ bnx2_alloc_mem(struct bnx2 *bp) | |||
569 | 593 | ||
570 | memset(bp->status_blk, 0, bp->status_stats_size); | 594 | memset(bp->status_blk, 0, bp->status_stats_size); |
571 | 595 | ||
572 | bp->bnx2_napi.status_blk = bp->status_blk; | 596 | bp->bnx2_napi[0].status_blk = bp->status_blk; |
597 | if (bp->flags & MSIX_CAP_FLAG) { | ||
598 | for (i = 1; i < BNX2_MAX_MSIX_VEC; i++) { | ||
599 | struct bnx2_napi *bnapi = &bp->bnx2_napi[i]; | ||
600 | |||
601 | bnapi->status_blk = (void *) | ||
602 | ((unsigned long) bp->status_blk + | ||
603 | BNX2_SBLK_MSIX_ALIGN_SIZE * i); | ||
604 | bnapi->int_num = i << 24; | ||
605 | } | ||
606 | } | ||
573 | 607 | ||
574 | bp->stats_blk = (void *) ((unsigned long) bp->status_blk + | 608 | bp->stats_blk = (void *) ((unsigned long) bp->status_blk + |
575 | status_blk_size); | 609 | status_blk_size); |
@@ -2767,7 +2801,7 @@ bnx2_msi(int irq, void *dev_instance) | |||
2767 | { | 2801 | { |
2768 | struct net_device *dev = dev_instance; | 2802 | struct net_device *dev = dev_instance; |
2769 | struct bnx2 *bp = netdev_priv(dev); | 2803 | struct bnx2 *bp = netdev_priv(dev); |
2770 | struct bnx2_napi *bnapi = &bp->bnx2_napi; | 2804 | struct bnx2_napi *bnapi = &bp->bnx2_napi[0]; |
2771 | 2805 | ||
2772 | prefetch(bnapi->status_blk); | 2806 | prefetch(bnapi->status_blk); |
2773 | REG_WR(bp, BNX2_PCICFG_INT_ACK_CMD, | 2807 | REG_WR(bp, BNX2_PCICFG_INT_ACK_CMD, |
@@ -2788,7 +2822,7 @@ bnx2_msi_1shot(int irq, void *dev_instance) | |||
2788 | { | 2822 | { |
2789 | struct net_device *dev = dev_instance; | 2823 | struct net_device *dev = dev_instance; |
2790 | struct bnx2 *bp = netdev_priv(dev); | 2824 | struct bnx2 *bp = netdev_priv(dev); |
2791 | struct bnx2_napi *bnapi = &bp->bnx2_napi; | 2825 | struct bnx2_napi *bnapi = &bp->bnx2_napi[0]; |
2792 | 2826 | ||
2793 | prefetch(bnapi->status_blk); | 2827 | prefetch(bnapi->status_blk); |
2794 | 2828 | ||
@@ -2806,7 +2840,7 @@ bnx2_interrupt(int irq, void *dev_instance) | |||
2806 | { | 2840 | { |
2807 | struct net_device *dev = dev_instance; | 2841 | struct net_device *dev = dev_instance; |
2808 | struct bnx2 *bp = netdev_priv(dev); | 2842 | struct bnx2 *bp = netdev_priv(dev); |
2809 | struct bnx2_napi *bnapi = &bp->bnx2_napi; | 2843 | struct bnx2_napi *bnapi = &bp->bnx2_napi[0]; |
2810 | struct status_block *sblk = bnapi->status_blk; | 2844 | struct status_block *sblk = bnapi->status_blk; |
2811 | 2845 | ||
2812 | /* When using INTx, it is possible for the interrupt to arrive | 2846 | /* When using INTx, it is possible for the interrupt to arrive |
@@ -2911,7 +2945,7 @@ static int bnx2_poll(struct napi_struct *napi, int budget) | |||
2911 | rmb(); | 2945 | rmb(); |
2912 | if (likely(!bnx2_has_work(bnapi))) { | 2946 | if (likely(!bnx2_has_work(bnapi))) { |
2913 | netif_rx_complete(bp->dev, napi); | 2947 | netif_rx_complete(bp->dev, napi); |
2914 | if (likely(bp->flags & USING_MSI_FLAG)) { | 2948 | if (likely(bp->flags & USING_MSI_OR_MSIX_FLAG)) { |
2915 | REG_WR(bp, BNX2_PCICFG_INT_ACK_CMD, | 2949 | REG_WR(bp, BNX2_PCICFG_INT_ACK_CMD, |
2916 | BNX2_PCICFG_INT_ACK_CMD_INDEX_VALID | | 2950 | BNX2_PCICFG_INT_ACK_CMD_INDEX_VALID | |
2917 | bnapi->last_status_idx); | 2951 | bnapi->last_status_idx); |
@@ -4072,6 +4106,15 @@ bnx2_init_remote_phy(struct bnx2 *bp) | |||
4072 | } | 4106 | } |
4073 | } | 4107 | } |
4074 | 4108 | ||
4109 | static void | ||
4110 | bnx2_setup_msix_tbl(struct bnx2 *bp) | ||
4111 | { | ||
4112 | REG_WR(bp, BNX2_PCI_GRC_WINDOW_ADDR, BNX2_PCI_GRC_WINDOW_ADDR_SEP_WIN); | ||
4113 | |||
4114 | REG_WR(bp, BNX2_PCI_GRC_WINDOW2_ADDR, BNX2_MSIX_TABLE_ADDR); | ||
4115 | REG_WR(bp, BNX2_PCI_GRC_WINDOW3_ADDR, BNX2_MSIX_PBA_ADDR); | ||
4116 | } | ||
4117 | |||
4075 | static int | 4118 | static int |
4076 | bnx2_reset_chip(struct bnx2 *bp, u32 reset_code) | 4119 | bnx2_reset_chip(struct bnx2 *bp, u32 reset_code) |
4077 | { | 4120 | { |
@@ -4171,6 +4214,9 @@ bnx2_reset_chip(struct bnx2 *bp, u32 reset_code) | |||
4171 | rc = bnx2_alloc_bad_rbuf(bp); | 4214 | rc = bnx2_alloc_bad_rbuf(bp); |
4172 | } | 4215 | } |
4173 | 4216 | ||
4217 | if (bp->flags & USING_MSIX_FLAG) | ||
4218 | bnx2_setup_msix_tbl(bp); | ||
4219 | |||
4174 | return rc; | 4220 | return rc; |
4175 | } | 4221 | } |
4176 | 4222 | ||
@@ -4178,7 +4224,7 @@ static int | |||
4178 | bnx2_init_chip(struct bnx2 *bp) | 4224 | bnx2_init_chip(struct bnx2 *bp) |
4179 | { | 4225 | { |
4180 | u32 val; | 4226 | u32 val; |
4181 | int rc; | 4227 | int rc, i; |
4182 | 4228 | ||
4183 | /* Make sure the interrupt is not active. */ | 4229 | /* Make sure the interrupt is not active. */ |
4184 | REG_WR(bp, BNX2_PCICFG_INT_ACK_CMD, BNX2_PCICFG_INT_ACK_CMD_MASK_INT); | 4230 | REG_WR(bp, BNX2_PCICFG_INT_ACK_CMD, BNX2_PCICFG_INT_ACK_CMD_MASK_INT); |
@@ -4274,7 +4320,9 @@ bnx2_init_chip(struct bnx2 *bp) | |||
4274 | val |= BNX2_EMAC_RX_MTU_SIZE_JUMBO_ENA; | 4320 | val |= BNX2_EMAC_RX_MTU_SIZE_JUMBO_ENA; |
4275 | REG_WR(bp, BNX2_EMAC_RX_MTU_SIZE, val); | 4321 | REG_WR(bp, BNX2_EMAC_RX_MTU_SIZE, val); |
4276 | 4322 | ||
4277 | bp->bnx2_napi.last_status_idx = 0; | 4323 | for (i = 0; i < BNX2_MAX_MSIX_VEC; i++) |
4324 | bp->bnx2_napi[i].last_status_idx = 0; | ||
4325 | |||
4278 | bp->rx_mode = BNX2_EMAC_RX_MODE_SORT_MODE; | 4326 | bp->rx_mode = BNX2_EMAC_RX_MODE_SORT_MODE; |
4279 | 4327 | ||
4280 | /* Set up how to generate a link change interrupt. */ | 4328 | /* Set up how to generate a link change interrupt. */ |
@@ -4386,7 +4434,7 @@ bnx2_init_tx_ring(struct bnx2 *bp) | |||
4386 | { | 4434 | { |
4387 | struct tx_bd *txbd; | 4435 | struct tx_bd *txbd; |
4388 | u32 cid; | 4436 | u32 cid; |
4389 | struct bnx2_napi *bnapi = &bp->bnx2_napi; | 4437 | struct bnx2_napi *bnapi = &bp->bnx2_napi[0]; |
4390 | 4438 | ||
4391 | bp->tx_wake_thresh = bp->tx_ring_size / 2; | 4439 | bp->tx_wake_thresh = bp->tx_ring_size / 2; |
4392 | 4440 | ||
@@ -4437,7 +4485,7 @@ bnx2_init_rx_ring(struct bnx2 *bp) | |||
4437 | int i; | 4485 | int i; |
4438 | u16 prod, ring_prod; | 4486 | u16 prod, ring_prod; |
4439 | u32 val, rx_cid_addr = GET_CID_ADDR(RX_CID); | 4487 | u32 val, rx_cid_addr = GET_CID_ADDR(RX_CID); |
4440 | struct bnx2_napi *bnapi = &bp->bnx2_napi; | 4488 | struct bnx2_napi *bnapi = &bp->bnx2_napi[0]; |
4441 | 4489 | ||
4442 | bnapi->rx_prod = 0; | 4490 | bnapi->rx_prod = 0; |
4443 | bnapi->rx_cons = 0; | 4491 | bnapi->rx_cons = 0; |
@@ -4917,7 +4965,7 @@ bnx2_run_loopback(struct bnx2 *bp, int loopback_mode) | |||
4917 | struct sw_bd *rx_buf; | 4965 | struct sw_bd *rx_buf; |
4918 | struct l2_fhdr *rx_hdr; | 4966 | struct l2_fhdr *rx_hdr; |
4919 | int ret = -ENODEV; | 4967 | int ret = -ENODEV; |
4920 | struct bnx2_napi *bnapi = &bp->bnx2_napi; | 4968 | struct bnx2_napi *bnapi = &bp->bnx2_napi[0]; |
4921 | 4969 | ||
4922 | if (loopback_mode == BNX2_MAC_LOOPBACK) { | 4970 | if (loopback_mode == BNX2_MAC_LOOPBACK) { |
4923 | bp->loopback = MAC_LOOPBACK; | 4971 | bp->loopback = MAC_LOOPBACK; |
@@ -5266,14 +5314,22 @@ bnx2_request_irq(struct bnx2 *bp) | |||
5266 | { | 5314 | { |
5267 | struct net_device *dev = bp->dev; | 5315 | struct net_device *dev = bp->dev; |
5268 | unsigned long flags; | 5316 | unsigned long flags; |
5269 | struct bnx2_irq *irq = &bp->irq_tbl[0]; | 5317 | struct bnx2_irq *irq; |
5270 | int rc; | 5318 | int rc = 0, i; |
5271 | 5319 | ||
5272 | if (bp->flags & USING_MSI_FLAG) | 5320 | if (bp->flags & USING_MSI_OR_MSIX_FLAG) |
5273 | flags = 0; | 5321 | flags = 0; |
5274 | else | 5322 | else |
5275 | flags = IRQF_SHARED; | 5323 | flags = IRQF_SHARED; |
5276 | rc = request_irq(irq->vector, irq->handler, flags, dev->name, dev); | 5324 | |
5325 | for (i = 0; i < bp->irq_nvecs; i++) { | ||
5326 | irq = &bp->irq_tbl[i]; | ||
5327 | rc = request_irq(irq->vector, irq->handler, flags, dev->name, | ||
5328 | dev); | ||
5329 | if (rc) | ||
5330 | break; | ||
5331 | irq->requested = 1; | ||
5332 | } | ||
5277 | return rc; | 5333 | return rc; |
5278 | } | 5334 | } |
5279 | 5335 | ||
@@ -5281,12 +5337,30 @@ static void | |||
5281 | bnx2_free_irq(struct bnx2 *bp) | 5337 | bnx2_free_irq(struct bnx2 *bp) |
5282 | { | 5338 | { |
5283 | struct net_device *dev = bp->dev; | 5339 | struct net_device *dev = bp->dev; |
5340 | struct bnx2_irq *irq; | ||
5341 | int i; | ||
5284 | 5342 | ||
5285 | free_irq(bp->irq_tbl[0].vector, dev); | 5343 | for (i = 0; i < bp->irq_nvecs; i++) { |
5286 | if (bp->flags & USING_MSI_FLAG) { | 5344 | irq = &bp->irq_tbl[i]; |
5287 | pci_disable_msi(bp->pdev); | 5345 | if (irq->requested) |
5288 | bp->flags &= ~(USING_MSI_FLAG | ONE_SHOT_MSI_FLAG); | 5346 | free_irq(irq->vector, dev); |
5347 | irq->requested = 0; | ||
5289 | } | 5348 | } |
5349 | if (bp->flags & USING_MSI_FLAG) | ||
5350 | pci_disable_msi(bp->pdev); | ||
5351 | else if (bp->flags & USING_MSIX_FLAG) | ||
5352 | pci_disable_msix(bp->pdev); | ||
5353 | |||
5354 | bp->flags &= ~(USING_MSI_OR_MSIX_FLAG | ONE_SHOT_MSI_FLAG); | ||
5355 | } | ||
5356 | |||
5357 | static void | ||
5358 | bnx2_enable_msix(struct bnx2 *bp) | ||
5359 | { | ||
5360 | bnx2_setup_msix_tbl(bp); | ||
5361 | REG_WR(bp, BNX2_PCI_MSIX_CONTROL, BNX2_MAX_MSIX_HW_VEC - 1); | ||
5362 | REG_WR(bp, BNX2_PCI_MSIX_TBL_OFF_BIR, BNX2_PCI_GRC_WINDOW2_BASE); | ||
5363 | REG_WR(bp, BNX2_PCI_MSIX_PBA_OFF_BIT, BNX2_PCI_GRC_WINDOW3_BASE); | ||
5290 | } | 5364 | } |
5291 | 5365 | ||
5292 | static void | 5366 | static void |
@@ -5294,8 +5368,14 @@ bnx2_setup_int_mode(struct bnx2 *bp, int dis_msi) | |||
5294 | { | 5368 | { |
5295 | bp->irq_tbl[0].handler = bnx2_interrupt; | 5369 | bp->irq_tbl[0].handler = bnx2_interrupt; |
5296 | strcpy(bp->irq_tbl[0].name, bp->dev->name); | 5370 | strcpy(bp->irq_tbl[0].name, bp->dev->name); |
5371 | bp->irq_nvecs = 1; | ||
5372 | bp->irq_tbl[0].vector = bp->pdev->irq; | ||
5373 | |||
5374 | if ((bp->flags & MSIX_CAP_FLAG) && !dis_msi) | ||
5375 | bnx2_enable_msix(bp); | ||
5297 | 5376 | ||
5298 | if ((bp->flags & MSI_CAP_FLAG) && !dis_msi) { | 5377 | if ((bp->flags & MSI_CAP_FLAG) && !dis_msi && |
5378 | !(bp->flags & USING_MSIX_FLAG)) { | ||
5299 | if (pci_enable_msi(bp->pdev) == 0) { | 5379 | if (pci_enable_msi(bp->pdev) == 0) { |
5300 | bp->flags |= USING_MSI_FLAG; | 5380 | bp->flags |= USING_MSI_FLAG; |
5301 | if (CHIP_NUM(bp) == CHIP_NUM_5709) { | 5381 | if (CHIP_NUM(bp) == CHIP_NUM_5709) { |
@@ -5303,10 +5383,10 @@ bnx2_setup_int_mode(struct bnx2 *bp, int dis_msi) | |||
5303 | bp->irq_tbl[0].handler = bnx2_msi_1shot; | 5383 | bp->irq_tbl[0].handler = bnx2_msi_1shot; |
5304 | } else | 5384 | } else |
5305 | bp->irq_tbl[0].handler = bnx2_msi; | 5385 | bp->irq_tbl[0].handler = bnx2_msi; |
5386 | |||
5387 | bp->irq_tbl[0].vector = bp->pdev->irq; | ||
5306 | } | 5388 | } |
5307 | } | 5389 | } |
5308 | |||
5309 | bp->irq_tbl[0].vector = bp->pdev->irq; | ||
5310 | } | 5390 | } |
5311 | 5391 | ||
5312 | /* Called with rtnl_lock */ | 5392 | /* Called with rtnl_lock */ |
@@ -5448,7 +5528,7 @@ bnx2_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
5448 | u32 len, vlan_tag_flags, last_frag, mss; | 5528 | u32 len, vlan_tag_flags, last_frag, mss; |
5449 | u16 prod, ring_prod; | 5529 | u16 prod, ring_prod; |
5450 | int i; | 5530 | int i; |
5451 | struct bnx2_napi *bnapi = &bp->bnx2_napi; | 5531 | struct bnx2_napi *bnapi = &bp->bnx2_napi[0]; |
5452 | 5532 | ||
5453 | if (unlikely(bnx2_tx_avail(bp, bnapi) < | 5533 | if (unlikely(bnx2_tx_avail(bp, bnapi) < |
5454 | (skb_shinfo(skb)->nr_frags + 1))) { | 5534 | (skb_shinfo(skb)->nr_frags + 1))) { |
@@ -6848,6 +6928,11 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev) | |||
6848 | } | 6928 | } |
6849 | } | 6929 | } |
6850 | 6930 | ||
6931 | if (CHIP_NUM(bp) == CHIP_NUM_5709 && CHIP_REV(bp) != CHIP_REV_Ax) { | ||
6932 | if (pci_find_capability(pdev, PCI_CAP_ID_MSIX)) | ||
6933 | bp->flags |= MSIX_CAP_FLAG; | ||
6934 | } | ||
6935 | |||
6851 | if (CHIP_ID(bp) != CHIP_ID_5706_A0 && CHIP_ID(bp) != CHIP_ID_5706_A1) { | 6936 | if (CHIP_ID(bp) != CHIP_ID_5706_A0 && CHIP_ID(bp) != CHIP_ID_5706_A1) { |
6852 | if (pci_find_capability(pdev, PCI_CAP_ID_MSI)) | 6937 | if (pci_find_capability(pdev, PCI_CAP_ID_MSI)) |
6853 | bp->flags |= MSI_CAP_FLAG; | 6938 | bp->flags |= MSI_CAP_FLAG; |
@@ -7118,10 +7203,14 @@ bnx2_bus_string(struct bnx2 *bp, char *str) | |||
7118 | static int __devinit | 7203 | static int __devinit |
7119 | bnx2_init_napi(struct bnx2 *bp) | 7204 | bnx2_init_napi(struct bnx2 *bp) |
7120 | { | 7205 | { |
7121 | struct bnx2_napi *bnapi = &bp->bnx2_napi; | 7206 | int i; |
7207 | struct bnx2_napi *bnapi; | ||
7122 | 7208 | ||
7123 | bnapi->bp = bp; | 7209 | for (i = 0; i < BNX2_MAX_MSIX_VEC; i++) { |
7124 | netif_napi_add(bp->dev, &bnapi->napi, bnx2_poll, 64); | 7210 | bnapi = &bp->bnx2_napi[i]; |
7211 | bnapi->bp = bp; | ||
7212 | } | ||
7213 | netif_napi_add(bp->dev, &bp->bnx2_napi[0].napi, bnx2_poll, 64); | ||
7125 | } | 7214 | } |
7126 | 7215 | ||
7127 | static int __devinit | 7216 | static int __devinit |
diff --git a/drivers/net/bnx2.h b/drivers/net/bnx2.h index b75795b4f8cf..d71ceb6c176f 100644 --- a/drivers/net/bnx2.h +++ b/drivers/net/bnx2.h | |||
@@ -154,6 +154,33 @@ struct status_block { | |||
154 | #endif | 154 | #endif |
155 | }; | 155 | }; |
156 | 156 | ||
157 | /* | ||
158 | * status_block definition | ||
159 | */ | ||
160 | struct status_block_msix { | ||
161 | #if defined(__BIG_ENDIAN) | ||
162 | u16 status_tx_quick_consumer_index; | ||
163 | u16 status_rx_quick_consumer_index; | ||
164 | u16 status_completion_producer_index; | ||
165 | u16 status_cmd_consumer_index; | ||
166 | u32 status_unused; | ||
167 | u16 status_idx; | ||
168 | u8 status_unused2; | ||
169 | u8 status_blk_num; | ||
170 | #elif defined(__LITTLE_ENDIAN) | ||
171 | u16 status_rx_quick_consumer_index; | ||
172 | u16 status_tx_quick_consumer_index; | ||
173 | u16 status_cmd_consumer_index; | ||
174 | u16 status_completion_producer_index; | ||
175 | u32 status_unused; | ||
176 | u8 status_blk_num; | ||
177 | u8 status_unused2; | ||
178 | u16 status_idx; | ||
179 | #endif | ||
180 | }; | ||
181 | |||
182 | #define BNX2_SBLK_MSIX_ALIGN_SIZE 128 | ||
183 | |||
157 | 184 | ||
158 | /* | 185 | /* |
159 | * statistics_block definition | 186 | * statistics_block definition |
@@ -413,6 +440,7 @@ struct l2_fhdr { | |||
413 | #define BNX2_PCICFG_INT_ACK_CMD_USE_INT_HC_PARAM (1L<<17) | 440 | #define BNX2_PCICFG_INT_ACK_CMD_USE_INT_HC_PARAM (1L<<17) |
414 | #define BNX2_PCICFG_INT_ACK_CMD_MASK_INT (1L<<18) | 441 | #define BNX2_PCICFG_INT_ACK_CMD_MASK_INT (1L<<18) |
415 | #define BNX2_PCICFG_INT_ACK_CMD_INTERRUPT_NUM (0xfL<<24) | 442 | #define BNX2_PCICFG_INT_ACK_CMD_INTERRUPT_NUM (0xfL<<24) |
443 | #define BNX2_PCICFG_INT_ACK_CMD_INT_NUM_SHIFT 24 | ||
416 | 444 | ||
417 | #define BNX2_PCICFG_STATUS_BIT_SET_CMD 0x00000088 | 445 | #define BNX2_PCICFG_STATUS_BIT_SET_CMD 0x00000088 |
418 | #define BNX2_PCICFG_STATUS_BIT_CLEAR_CMD 0x0000008c | 446 | #define BNX2_PCICFG_STATUS_BIT_CLEAR_CMD 0x0000008c |
@@ -428,6 +456,9 @@ struct l2_fhdr { | |||
428 | #define BNX2_PCI_GRC_WINDOW_ADDR_VALUE (0x1ffL<<13) | 456 | #define BNX2_PCI_GRC_WINDOW_ADDR_VALUE (0x1ffL<<13) |
429 | #define BNX2_PCI_GRC_WINDOW_ADDR_SEP_WIN (1L<<31) | 457 | #define BNX2_PCI_GRC_WINDOW_ADDR_SEP_WIN (1L<<31) |
430 | 458 | ||
459 | #define BNX2_PCI_GRC_WINDOW2_BASE 0xc000 | ||
460 | #define BNX2_PCI_GRC_WINDOW3_BASE 0xe000 | ||
461 | |||
431 | #define BNX2_PCI_CONFIG_1 0x00000404 | 462 | #define BNX2_PCI_CONFIG_1 0x00000404 |
432 | #define BNX2_PCI_CONFIG_1_RESERVED0 (0xffL<<0) | 463 | #define BNX2_PCI_CONFIG_1_RESERVED0 (0xffL<<0) |
433 | #define BNX2_PCI_CONFIG_1_READ_BOUNDARY (0x7L<<8) | 464 | #define BNX2_PCI_CONFIG_1_READ_BOUNDARY (0x7L<<8) |
@@ -700,6 +731,8 @@ struct l2_fhdr { | |||
700 | #define BNX2_PCI_GRC_WINDOW3_ADDR 0x00000618 | 731 | #define BNX2_PCI_GRC_WINDOW3_ADDR 0x00000618 |
701 | #define BNX2_PCI_GRC_WINDOW3_ADDR_VALUE (0x1ffL<<13) | 732 | #define BNX2_PCI_GRC_WINDOW3_ADDR_VALUE (0x1ffL<<13) |
702 | 733 | ||
734 | #define BNX2_MSIX_TABLE_ADDR 0x318000 | ||
735 | #define BNX2_MSIX_PBA_ADDR 0x31c000 | ||
703 | 736 | ||
704 | /* | 737 | /* |
705 | * misc_reg definition | 738 | * misc_reg definition |
@@ -6500,6 +6533,7 @@ struct flash_spec { | |||
6500 | struct bnx2_irq { | 6533 | struct bnx2_irq { |
6501 | irq_handler_t handler; | 6534 | irq_handler_t handler; |
6502 | u16 vector; | 6535 | u16 vector; |
6536 | u8 requested; | ||
6503 | char name[16]; | 6537 | char name[16]; |
6504 | }; | 6538 | }; |
6505 | 6539 | ||
@@ -6535,13 +6569,15 @@ struct bnx2 { | |||
6535 | u32 flags; | 6569 | u32 flags; |
6536 | #define PCIX_FLAG 0x00000001 | 6570 | #define PCIX_FLAG 0x00000001 |
6537 | #define PCI_32BIT_FLAG 0x00000002 | 6571 | #define PCI_32BIT_FLAG 0x00000002 |
6538 | #define ONE_TDMA_FLAG 0x00000004 /* no longer used */ | 6572 | #define MSIX_CAP_FLAG 0x00000004 |
6539 | #define NO_WOL_FLAG 0x00000008 | 6573 | #define NO_WOL_FLAG 0x00000008 |
6540 | #define USING_MSI_FLAG 0x00000020 | 6574 | #define USING_MSI_FLAG 0x00000020 |
6541 | #define ASF_ENABLE_FLAG 0x00000040 | 6575 | #define ASF_ENABLE_FLAG 0x00000040 |
6542 | #define MSI_CAP_FLAG 0x00000080 | 6576 | #define MSI_CAP_FLAG 0x00000080 |
6543 | #define ONE_SHOT_MSI_FLAG 0x00000100 | 6577 | #define ONE_SHOT_MSI_FLAG 0x00000100 |
6544 | #define PCIE_FLAG 0x00000200 | 6578 | #define PCIE_FLAG 0x00000200 |
6579 | #define USING_MSIX_FLAG 0x00000400 | ||
6580 | #define USING_MSI_OR_MSIX_FLAG (USING_MSI_FLAG | USING_MSIX_FLAG) | ||
6545 | 6581 | ||
6546 | /* Put tx producer and consumer fields in separate cache lines. */ | 6582 | /* Put tx producer and consumer fields in separate cache lines. */ |
6547 | 6583 | ||
@@ -6550,7 +6586,7 @@ struct bnx2 { | |||
6550 | u32 tx_bidx_addr; | 6586 | u32 tx_bidx_addr; |
6551 | u32 tx_bseq_addr; | 6587 | u32 tx_bseq_addr; |
6552 | 6588 | ||
6553 | struct bnx2_napi bnx2_napi; | 6589 | struct bnx2_napi bnx2_napi[BNX2_MAX_MSIX_VEC]; |
6554 | 6590 | ||
6555 | #ifdef BCM_VLAN | 6591 | #ifdef BCM_VLAN |
6556 | struct vlan_group *vlgrp; | 6592 | struct vlan_group *vlgrp; |