diff options
| -rw-r--r-- | drivers/net/bnx2.c | 108 | ||||
| -rw-r--r-- | drivers/net/bnx2.h | 14 |
2 files changed, 81 insertions, 41 deletions
diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c index f072028e3e3b..97ed4006a345 100644 --- a/drivers/net/bnx2.c +++ b/drivers/net/bnx2.c | |||
| @@ -2262,6 +2262,23 @@ bnx2_msi(int irq, void *dev_instance) | |||
| 2262 | } | 2262 | } |
| 2263 | 2263 | ||
| 2264 | static irqreturn_t | 2264 | static irqreturn_t |
| 2265 | bnx2_msi_1shot(int irq, void *dev_instance) | ||
| 2266 | { | ||
| 2267 | struct net_device *dev = dev_instance; | ||
| 2268 | struct bnx2 *bp = netdev_priv(dev); | ||
| 2269 | |||
| 2270 | prefetch(bp->status_blk); | ||
| 2271 | |||
| 2272 | /* Return here if interrupt is disabled. */ | ||
| 2273 | if (unlikely(atomic_read(&bp->intr_sem) != 0)) | ||
| 2274 | return IRQ_HANDLED; | ||
| 2275 | |||
| 2276 | netif_rx_schedule(dev); | ||
| 2277 | |||
| 2278 | return IRQ_HANDLED; | ||
| 2279 | } | ||
| 2280 | |||
| 2281 | static irqreturn_t | ||
| 2265 | bnx2_interrupt(int irq, void *dev_instance) | 2282 | bnx2_interrupt(int irq, void *dev_instance) |
| 2266 | { | 2283 | { |
| 2267 | struct net_device *dev = dev_instance; | 2284 | struct net_device *dev = dev_instance; |
| @@ -3759,13 +3776,17 @@ bnx2_init_chip(struct bnx2 *bp) | |||
| 3759 | REG_WR(bp, BNX2_HC_STAT_COLLECT_TICKS, 0xbb8); /* 3ms */ | 3776 | REG_WR(bp, BNX2_HC_STAT_COLLECT_TICKS, 0xbb8); /* 3ms */ |
| 3760 | 3777 | ||
| 3761 | if (CHIP_ID(bp) == CHIP_ID_5706_A1) | 3778 | if (CHIP_ID(bp) == CHIP_ID_5706_A1) |
| 3762 | REG_WR(bp, BNX2_HC_CONFIG, BNX2_HC_CONFIG_COLLECT_STATS); | 3779 | val = BNX2_HC_CONFIG_COLLECT_STATS; |
| 3763 | else { | 3780 | else { |
| 3764 | REG_WR(bp, BNX2_HC_CONFIG, BNX2_HC_CONFIG_RX_TMR_MODE | | 3781 | val = BNX2_HC_CONFIG_RX_TMR_MODE | BNX2_HC_CONFIG_TX_TMR_MODE | |
| 3765 | BNX2_HC_CONFIG_TX_TMR_MODE | | 3782 | BNX2_HC_CONFIG_COLLECT_STATS; |
| 3766 | BNX2_HC_CONFIG_COLLECT_STATS); | ||
| 3767 | } | 3783 | } |
| 3768 | 3784 | ||
| 3785 | if (bp->flags & ONE_SHOT_MSI_FLAG) | ||
| 3786 | val |= BNX2_HC_CONFIG_ONE_SHOT; | ||
| 3787 | |||
| 3788 | REG_WR(bp, BNX2_HC_CONFIG, val); | ||
| 3789 | |||
| 3769 | /* Clear internal stats counters. */ | 3790 | /* Clear internal stats counters. */ |
| 3770 | REG_WR(bp, BNX2_HC_COMMAND, BNX2_HC_COMMAND_CLR_STAT_NOW); | 3791 | REG_WR(bp, BNX2_HC_COMMAND, BNX2_HC_COMMAND_CLR_STAT_NOW); |
| 3771 | 3792 | ||
| @@ -4610,6 +4631,38 @@ bnx2_restart_timer: | |||
| 4610 | mod_timer(&bp->timer, jiffies + bp->current_interval); | 4631 | mod_timer(&bp->timer, jiffies + bp->current_interval); |
| 4611 | } | 4632 | } |
| 4612 | 4633 | ||
| 4634 | static int | ||
| 4635 | bnx2_request_irq(struct bnx2 *bp) | ||
| 4636 | { | ||
| 4637 | struct net_device *dev = bp->dev; | ||
| 4638 | int rc = 0; | ||
| 4639 | |||
| 4640 | if (bp->flags & USING_MSI_FLAG) { | ||
| 4641 | irq_handler_t fn = bnx2_msi; | ||
| 4642 | |||
| 4643 | if (bp->flags & ONE_SHOT_MSI_FLAG) | ||
| 4644 | fn = bnx2_msi_1shot; | ||
| 4645 | |||
| 4646 | rc = request_irq(bp->pdev->irq, fn, 0, dev->name, dev); | ||
| 4647 | } else | ||
| 4648 | rc = request_irq(bp->pdev->irq, bnx2_interrupt, | ||
| 4649 | IRQF_SHARED, dev->name, dev); | ||
| 4650 | return rc; | ||
| 4651 | } | ||
| 4652 | |||
| 4653 | static void | ||
| 4654 | bnx2_free_irq(struct bnx2 *bp) | ||
| 4655 | { | ||
| 4656 | struct net_device *dev = bp->dev; | ||
| 4657 | |||
| 4658 | if (bp->flags & USING_MSI_FLAG) { | ||
| 4659 | free_irq(bp->pdev->irq, dev); | ||
| 4660 | pci_disable_msi(bp->pdev); | ||
| 4661 | bp->flags &= ~(USING_MSI_FLAG | ONE_SHOT_MSI_FLAG); | ||
| 4662 | } else | ||
| 4663 | free_irq(bp->pdev->irq, dev); | ||
| 4664 | } | ||
| 4665 | |||
| 4613 | /* Called with rtnl_lock */ | 4666 | /* Called with rtnl_lock */ |
| 4614 | static int | 4667 | static int |
| 4615 | bnx2_open(struct net_device *dev) | 4668 | bnx2_open(struct net_device *dev) |
| @@ -4626,24 +4679,15 @@ bnx2_open(struct net_device *dev) | |||
| 4626 | if (rc) | 4679 | if (rc) |
| 4627 | return rc; | 4680 | return rc; |
| 4628 | 4681 | ||
| 4629 | if ((CHIP_ID(bp) != CHIP_ID_5706_A0) && | 4682 | if ((bp->flags & MSI_CAP_FLAG) && !disable_msi) { |
| 4630 | (CHIP_ID(bp) != CHIP_ID_5706_A1) && | ||
| 4631 | !disable_msi) { | ||
| 4632 | |||
| 4633 | if (pci_enable_msi(bp->pdev) == 0) { | 4683 | if (pci_enable_msi(bp->pdev) == 0) { |
| 4634 | bp->flags |= USING_MSI_FLAG; | 4684 | bp->flags |= USING_MSI_FLAG; |
| 4635 | rc = request_irq(bp->pdev->irq, bnx2_msi, 0, dev->name, | 4685 | if (CHIP_NUM(bp) == CHIP_NUM_5709) |
| 4636 | dev); | 4686 | bp->flags |= ONE_SHOT_MSI_FLAG; |
| 4637 | } | 4687 | } |
| 4638 | else { | ||
| 4639 | rc = request_irq(bp->pdev->irq, bnx2_interrupt, | ||
| 4640 | IRQF_SHARED, dev->name, dev); | ||
| 4641 | } | ||
| 4642 | } | ||
| 4643 | else { | ||
| 4644 | rc = request_irq(bp->pdev->irq, bnx2_interrupt, IRQF_SHARED, | ||
| 4645 | dev->name, dev); | ||
| 4646 | } | 4688 | } |
| 4689 | rc = bnx2_request_irq(bp); | ||
| 4690 | |||
| 4647 | if (rc) { | 4691 | if (rc) { |
| 4648 | bnx2_free_mem(bp); | 4692 | bnx2_free_mem(bp); |
| 4649 | return rc; | 4693 | return rc; |
| @@ -4652,11 +4696,7 @@ bnx2_open(struct net_device *dev) | |||
| 4652 | rc = bnx2_init_nic(bp); | 4696 | rc = bnx2_init_nic(bp); |
| 4653 | 4697 | ||
| 4654 | if (rc) { | 4698 | if (rc) { |
| 4655 | free_irq(bp->pdev->irq, dev); | 4699 | bnx2_free_irq(bp); |
| 4656 | if (bp->flags & USING_MSI_FLAG) { | ||
| 4657 | pci_disable_msi(bp->pdev); | ||
| 4658 | bp->flags &= ~USING_MSI_FLAG; | ||
| 4659 | } | ||
| 4660 | bnx2_free_skbs(bp); | 4700 | bnx2_free_skbs(bp); |
| 4661 | bnx2_free_mem(bp); | 4701 | bnx2_free_mem(bp); |
| 4662 | return rc; | 4702 | return rc; |
| @@ -4680,16 +4720,13 @@ bnx2_open(struct net_device *dev) | |||
| 4680 | bp->dev->name); | 4720 | bp->dev->name); |
| 4681 | 4721 | ||
| 4682 | bnx2_disable_int(bp); | 4722 | bnx2_disable_int(bp); |
| 4683 | free_irq(bp->pdev->irq, dev); | 4723 | bnx2_free_irq(bp); |
| 4684 | pci_disable_msi(bp->pdev); | ||
| 4685 | bp->flags &= ~USING_MSI_FLAG; | ||
| 4686 | 4724 | ||
| 4687 | rc = bnx2_init_nic(bp); | 4725 | rc = bnx2_init_nic(bp); |
| 4688 | 4726 | ||
| 4689 | if (!rc) { | 4727 | if (!rc) |
| 4690 | rc = request_irq(bp->pdev->irq, bnx2_interrupt, | 4728 | rc = bnx2_request_irq(bp); |
| 4691 | IRQF_SHARED, dev->name, dev); | 4729 | |
| 4692 | } | ||
| 4693 | if (rc) { | 4730 | if (rc) { |
| 4694 | bnx2_free_skbs(bp); | 4731 | bnx2_free_skbs(bp); |
| 4695 | bnx2_free_mem(bp); | 4732 | bnx2_free_mem(bp); |
| @@ -4927,11 +4964,7 @@ bnx2_close(struct net_device *dev) | |||
| 4927 | else | 4964 | else |
| 4928 | reset_code = BNX2_DRV_MSG_CODE_SUSPEND_NO_WOL; | 4965 | reset_code = BNX2_DRV_MSG_CODE_SUSPEND_NO_WOL; |
| 4929 | bnx2_reset_chip(bp, reset_code); | 4966 | bnx2_reset_chip(bp, reset_code); |
| 4930 | free_irq(bp->pdev->irq, dev); | 4967 | bnx2_free_irq(bp); |
| 4931 | if (bp->flags & USING_MSI_FLAG) { | ||
| 4932 | pci_disable_msi(bp->pdev); | ||
| 4933 | bp->flags &= ~USING_MSI_FLAG; | ||
| 4934 | } | ||
| 4935 | bnx2_free_skbs(bp); | 4968 | bnx2_free_skbs(bp); |
| 4936 | bnx2_free_mem(bp); | 4969 | bnx2_free_mem(bp); |
| 4937 | bp->link_up = 0; | 4970 | bp->link_up = 0; |
| @@ -6095,6 +6128,11 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev) | |||
| 6095 | } | 6128 | } |
| 6096 | } | 6129 | } |
| 6097 | 6130 | ||
| 6131 | if (CHIP_ID(bp) != CHIP_ID_5706_A0 && CHIP_ID(bp) != CHIP_ID_5706_A1) { | ||
| 6132 | if (pci_find_capability(pdev, PCI_CAP_ID_MSI)) | ||
| 6133 | bp->flags |= MSI_CAP_FLAG; | ||
| 6134 | } | ||
| 6135 | |||
| 6098 | /* 5708 cannot support DMA addresses > 40-bit. */ | 6136 | /* 5708 cannot support DMA addresses > 40-bit. */ |
| 6099 | if (CHIP_NUM(bp) == CHIP_NUM_5708) | 6137 | if (CHIP_NUM(bp) == CHIP_NUM_5708) |
| 6100 | persist_dma_mask = dma_mask = DMA_40BIT_MASK; | 6138 | persist_dma_mask = dma_mask = DMA_40BIT_MASK; |
diff --git a/drivers/net/bnx2.h b/drivers/net/bnx2.h index ba175a800c8e..121576d144d0 100644 --- a/drivers/net/bnx2.h +++ b/drivers/net/bnx2.h | |||
| @@ -6468,12 +6468,14 @@ struct bnx2 { | |||
| 6468 | u32 last_status_idx; | 6468 | u32 last_status_idx; |
| 6469 | 6469 | ||
| 6470 | u32 flags; | 6470 | u32 flags; |
| 6471 | #define PCIX_FLAG 1 | 6471 | #define PCIX_FLAG 0x00000001 |
| 6472 | #define PCI_32BIT_FLAG 2 | 6472 | #define PCI_32BIT_FLAG 0x00000002 |
| 6473 | #define ONE_TDMA_FLAG 4 /* no longer used */ | 6473 | #define ONE_TDMA_FLAG 0x00000004 /* no longer used */ |
| 6474 | #define NO_WOL_FLAG 8 | 6474 | #define NO_WOL_FLAG 0x00000008 |
| 6475 | #define USING_MSI_FLAG 0x20 | 6475 | #define USING_MSI_FLAG 0x00000020 |
| 6476 | #define ASF_ENABLE_FLAG 0x40 | 6476 | #define ASF_ENABLE_FLAG 0x00000040 |
| 6477 | #define MSI_CAP_FLAG 0x00000080 | ||
| 6478 | #define ONE_SHOT_MSI_FLAG 0x00000100 | ||
| 6477 | 6479 | ||
| 6478 | /* Put tx producer and consumer fields in separate cache lines. */ | 6480 | /* Put tx producer and consumer fields in separate cache lines. */ |
| 6479 | 6481 | ||
