diff options
Diffstat (limited to 'drivers/net/tg3.c')
| -rw-r--r-- | drivers/net/tg3.c | 136 |
1 files changed, 71 insertions, 65 deletions
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 8c8f9f4d47a5..256969e1300c 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c | |||
| @@ -64,8 +64,8 @@ | |||
| 64 | 64 | ||
| 65 | #define DRV_MODULE_NAME "tg3" | 65 | #define DRV_MODULE_NAME "tg3" |
| 66 | #define PFX DRV_MODULE_NAME ": " | 66 | #define PFX DRV_MODULE_NAME ": " |
| 67 | #define DRV_MODULE_VERSION "3.74" | 67 | #define DRV_MODULE_VERSION "3.75" |
| 68 | #define DRV_MODULE_RELDATE "February 20, 2007" | 68 | #define DRV_MODULE_RELDATE "March 23, 2007" |
| 69 | 69 | ||
| 70 | #define TG3_DEF_MAC_MODE 0 | 70 | #define TG3_DEF_MAC_MODE 0 |
| 71 | #define TG3_DEF_RX_MODE 0 | 71 | #define TG3_DEF_RX_MODE 0 |
| @@ -3568,32 +3568,34 @@ static irqreturn_t tg3_interrupt(int irq, void *dev_id) | |||
| 3568 | * Reading the PCI State register will confirm whether the | 3568 | * Reading the PCI State register will confirm whether the |
| 3569 | * interrupt is ours and will flush the status block. | 3569 | * interrupt is ours and will flush the status block. |
| 3570 | */ | 3570 | */ |
| 3571 | if ((sblk->status & SD_STATUS_UPDATED) || | 3571 | if (unlikely(!(sblk->status & SD_STATUS_UPDATED))) { |
| 3572 | !(tr32(TG3PCI_PCISTATE) & PCISTATE_INT_NOT_ACTIVE)) { | 3572 | if ((tp->tg3_flags & TG3_FLAG_CHIP_RESETTING) || |
| 3573 | /* | 3573 | (tr32(TG3PCI_PCISTATE) & PCISTATE_INT_NOT_ACTIVE)) { |
| 3574 | * Writing any value to intr-mbox-0 clears PCI INTA# and | 3574 | handled = 0; |
| 3575 | * chip-internal interrupt pending events. | ||
| 3576 | * Writing non-zero to intr-mbox-0 additional tells the | ||
| 3577 | * NIC to stop sending us irqs, engaging "in-intr-handler" | ||
| 3578 | * event coalescing. | ||
| 3579 | */ | ||
| 3580 | tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, | ||
| 3581 | 0x00000001); | ||
| 3582 | if (tg3_irq_sync(tp)) | ||
| 3583 | goto out; | 3575 | goto out; |
| 3584 | sblk->status &= ~SD_STATUS_UPDATED; | ||
| 3585 | if (likely(tg3_has_work(tp))) { | ||
| 3586 | prefetch(&tp->rx_rcb[tp->rx_rcb_ptr]); | ||
| 3587 | netif_rx_schedule(dev); /* schedule NAPI poll */ | ||
| 3588 | } else { | ||
| 3589 | /* No work, shared interrupt perhaps? re-enable | ||
| 3590 | * interrupts, and flush that PCI write | ||
| 3591 | */ | ||
| 3592 | tw32_mailbox_f(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, | ||
| 3593 | 0x00000000); | ||
| 3594 | } | 3576 | } |
| 3595 | } else { /* shared interrupt */ | 3577 | } |
| 3596 | handled = 0; | 3578 | |
| 3579 | /* | ||
| 3580 | * Writing any value to intr-mbox-0 clears PCI INTA# and | ||
| 3581 | * chip-internal interrupt pending events. | ||
| 3582 | * Writing non-zero to intr-mbox-0 additional tells the | ||
| 3583 | * NIC to stop sending us irqs, engaging "in-intr-handler" | ||
| 3584 | * event coalescing. | ||
| 3585 | */ | ||
| 3586 | tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, 0x00000001); | ||
| 3587 | if (tg3_irq_sync(tp)) | ||
| 3588 | goto out; | ||
| 3589 | sblk->status &= ~SD_STATUS_UPDATED; | ||
| 3590 | if (likely(tg3_has_work(tp))) { | ||
| 3591 | prefetch(&tp->rx_rcb[tp->rx_rcb_ptr]); | ||
| 3592 | netif_rx_schedule(dev); /* schedule NAPI poll */ | ||
| 3593 | } else { | ||
| 3594 | /* No work, shared interrupt perhaps? re-enable | ||
| 3595 | * interrupts, and flush that PCI write | ||
| 3596 | */ | ||
| 3597 | tw32_mailbox_f(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, | ||
| 3598 | 0x00000000); | ||
| 3597 | } | 3599 | } |
| 3598 | out: | 3600 | out: |
| 3599 | return IRQ_RETVAL(handled); | 3601 | return IRQ_RETVAL(handled); |
| @@ -3611,31 +3613,33 @@ static irqreturn_t tg3_interrupt_tagged(int irq, void *dev_id) | |||
| 3611 | * Reading the PCI State register will confirm whether the | 3613 | * Reading the PCI State register will confirm whether the |
| 3612 | * interrupt is ours and will flush the status block. | 3614 | * interrupt is ours and will flush the status block. |
| 3613 | */ | 3615 | */ |
| 3614 | if ((sblk->status_tag != tp->last_tag) || | 3616 | if (unlikely(sblk->status_tag == tp->last_tag)) { |
| 3615 | !(tr32(TG3PCI_PCISTATE) & PCISTATE_INT_NOT_ACTIVE)) { | 3617 | if ((tp->tg3_flags & TG3_FLAG_CHIP_RESETTING) || |
| 3616 | /* | 3618 | (tr32(TG3PCI_PCISTATE) & PCISTATE_INT_NOT_ACTIVE)) { |
| 3617 | * writing any value to intr-mbox-0 clears PCI INTA# and | 3619 | handled = 0; |
| 3618 | * chip-internal interrupt pending events. | ||
| 3619 | * writing non-zero to intr-mbox-0 additional tells the | ||
| 3620 | * NIC to stop sending us irqs, engaging "in-intr-handler" | ||
| 3621 | * event coalescing. | ||
| 3622 | */ | ||
| 3623 | tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, | ||
| 3624 | 0x00000001); | ||
| 3625 | if (tg3_irq_sync(tp)) | ||
| 3626 | goto out; | 3620 | goto out; |
| 3627 | if (netif_rx_schedule_prep(dev)) { | ||
| 3628 | prefetch(&tp->rx_rcb[tp->rx_rcb_ptr]); | ||
| 3629 | /* Update last_tag to mark that this status has been | ||
| 3630 | * seen. Because interrupt may be shared, we may be | ||
| 3631 | * racing with tg3_poll(), so only update last_tag | ||
| 3632 | * if tg3_poll() is not scheduled. | ||
| 3633 | */ | ||
| 3634 | tp->last_tag = sblk->status_tag; | ||
| 3635 | __netif_rx_schedule(dev); | ||
| 3636 | } | 3621 | } |
| 3637 | } else { /* shared interrupt */ | 3622 | } |
| 3638 | handled = 0; | 3623 | |
| 3624 | /* | ||
| 3625 | * writing any value to intr-mbox-0 clears PCI INTA# and | ||
| 3626 | * chip-internal interrupt pending events. | ||
| 3627 | * writing non-zero to intr-mbox-0 additional tells the | ||
| 3628 | * NIC to stop sending us irqs, engaging "in-intr-handler" | ||
| 3629 | * event coalescing. | ||
| 3630 | */ | ||
| 3631 | tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, 0x00000001); | ||
| 3632 | if (tg3_irq_sync(tp)) | ||
| 3633 | goto out; | ||
| 3634 | if (netif_rx_schedule_prep(dev)) { | ||
| 3635 | prefetch(&tp->rx_rcb[tp->rx_rcb_ptr]); | ||
| 3636 | /* Update last_tag to mark that this status has been | ||
| 3637 | * seen. Because interrupt may be shared, we may be | ||
| 3638 | * racing with tg3_poll(), so only update last_tag | ||
| 3639 | * if tg3_poll() is not scheduled. | ||
| 3640 | */ | ||
| 3641 | tp->last_tag = sblk->status_tag; | ||
| 3642 | __netif_rx_schedule(dev); | ||
| 3639 | } | 3643 | } |
| 3640 | out: | 3644 | out: |
| 3641 | return IRQ_RETVAL(handled); | 3645 | return IRQ_RETVAL(handled); |
| @@ -4823,6 +4827,21 @@ static int tg3_chip_reset(struct tg3 *tp) | |||
| 4823 | if (write_op == tg3_write_flush_reg32) | 4827 | if (write_op == tg3_write_flush_reg32) |
| 4824 | tp->write32 = tg3_write32; | 4828 | tp->write32 = tg3_write32; |
| 4825 | 4829 | ||
| 4830 | /* Prevent the irq handler from reading or writing PCI registers | ||
| 4831 | * during chip reset when the memory enable bit in the PCI command | ||
| 4832 | * register may be cleared. The chip does not generate interrupt | ||
| 4833 | * at this time, but the irq handler may still be called due to irq | ||
| 4834 | * sharing or irqpoll. | ||
| 4835 | */ | ||
| 4836 | tp->tg3_flags |= TG3_FLAG_CHIP_RESETTING; | ||
| 4837 | if (tp->hw_status) { | ||
| 4838 | tp->hw_status->status = 0; | ||
| 4839 | tp->hw_status->status_tag = 0; | ||
| 4840 | } | ||
| 4841 | tp->last_tag = 0; | ||
| 4842 | smp_mb(); | ||
| 4843 | synchronize_irq(tp->pdev->irq); | ||
| 4844 | |||
| 4826 | /* do the reset */ | 4845 | /* do the reset */ |
| 4827 | val = GRC_MISC_CFG_CORECLK_RESET; | 4846 | val = GRC_MISC_CFG_CORECLK_RESET; |
| 4828 | 4847 | ||
| @@ -4904,6 +4923,8 @@ static int tg3_chip_reset(struct tg3 *tp) | |||
| 4904 | 4923 | ||
| 4905 | pci_restore_state(tp->pdev); | 4924 | pci_restore_state(tp->pdev); |
| 4906 | 4925 | ||
| 4926 | tp->tg3_flags &= ~TG3_FLAG_CHIP_RESETTING; | ||
| 4927 | |||
| 4907 | /* Make sure PCI-X relaxed ordering bit is clear. */ | 4928 | /* Make sure PCI-X relaxed ordering bit is clear. */ |
| 4908 | pci_read_config_dword(tp->pdev, TG3PCI_X_CAPS, &val); | 4929 | pci_read_config_dword(tp->pdev, TG3PCI_X_CAPS, &val); |
| 4909 | val &= ~PCIX_CAPS_RELAXED_ORDERING; | 4930 | val &= ~PCIX_CAPS_RELAXED_ORDERING; |
| @@ -6321,8 +6342,6 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy) | |||
| 6321 | RDMAC_MODE_ADDROFLOW_ENAB | RDMAC_MODE_FIFOOFLOW_ENAB | | 6342 | RDMAC_MODE_ADDROFLOW_ENAB | RDMAC_MODE_FIFOOFLOW_ENAB | |
| 6322 | RDMAC_MODE_FIFOURUN_ENAB | RDMAC_MODE_FIFOOREAD_ENAB | | 6343 | RDMAC_MODE_FIFOURUN_ENAB | RDMAC_MODE_FIFOOREAD_ENAB | |
| 6323 | RDMAC_MODE_LNGREAD_ENAB); | 6344 | RDMAC_MODE_LNGREAD_ENAB); |
| 6324 | if (tp->tg3_flags & TG3_FLAG_SPLIT_MODE) | ||
| 6325 | rdmac_mode |= RDMAC_MODE_SPLIT_ENABLE; | ||
| 6326 | 6345 | ||
| 6327 | /* If statement applies to 5705 and 5750 PCI devices only */ | 6346 | /* If statement applies to 5705 and 5750 PCI devices only */ |
| 6328 | if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705 && | 6347 | if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705 && |
| @@ -6495,9 +6514,6 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy) | |||
| 6495 | } else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704) { | 6514 | } else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704) { |
| 6496 | val &= ~(PCIX_CAPS_SPLIT_MASK | PCIX_CAPS_BURST_MASK); | 6515 | val &= ~(PCIX_CAPS_SPLIT_MASK | PCIX_CAPS_BURST_MASK); |
| 6497 | val |= (PCIX_CAPS_MAX_BURST_CPIOB << PCIX_CAPS_BURST_SHIFT); | 6516 | val |= (PCIX_CAPS_MAX_BURST_CPIOB << PCIX_CAPS_BURST_SHIFT); |
| 6498 | if (tp->tg3_flags & TG3_FLAG_SPLIT_MODE) | ||
| 6499 | val |= (tp->split_mode_max_reqs << | ||
| 6500 | PCIX_CAPS_SPLIT_SHIFT); | ||
| 6501 | } | 6517 | } |
| 6502 | tw32(TG3PCI_X_CAPS, val); | 6518 | tw32(TG3PCI_X_CAPS, val); |
| 6503 | } | 6519 | } |
| @@ -10863,14 +10879,6 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) | |||
| 10863 | grc_misc_cfg = tr32(GRC_MISC_CFG); | 10879 | grc_misc_cfg = tr32(GRC_MISC_CFG); |
| 10864 | grc_misc_cfg &= GRC_MISC_CFG_BOARD_ID_MASK; | 10880 | grc_misc_cfg &= GRC_MISC_CFG_BOARD_ID_MASK; |
| 10865 | 10881 | ||
| 10866 | /* Broadcom's driver says that CIOBE multisplit has a bug */ | ||
| 10867 | #if 0 | ||
| 10868 | if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704 && | ||
| 10869 | grc_misc_cfg == GRC_MISC_CFG_BOARD_ID_5704CIOBE) { | ||
| 10870 | tp->tg3_flags |= TG3_FLAG_SPLIT_MODE; | ||
| 10871 | tp->split_mode_max_reqs = SPLIT_MODE_5704_MAX_REQ; | ||
| 10872 | } | ||
| 10873 | #endif | ||
| 10874 | if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705 && | 10882 | if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705 && |
| 10875 | (grc_misc_cfg == GRC_MISC_CFG_BOARD_ID_5788 || | 10883 | (grc_misc_cfg == GRC_MISC_CFG_BOARD_ID_5788 || |
| 10876 | grc_misc_cfg == GRC_MISC_CFG_BOARD_ID_5788M)) | 10884 | grc_misc_cfg == GRC_MISC_CFG_BOARD_ID_5788M)) |
| @@ -11968,14 +11976,12 @@ static int __devinit tg3_init_one(struct pci_dev *pdev, | |||
| 11968 | i == 5 ? '\n' : ':'); | 11976 | i == 5 ? '\n' : ':'); |
| 11969 | 11977 | ||
| 11970 | printk(KERN_INFO "%s: RXcsums[%d] LinkChgREG[%d] " | 11978 | printk(KERN_INFO "%s: RXcsums[%d] LinkChgREG[%d] " |
| 11971 | "MIirq[%d] ASF[%d] Split[%d] WireSpeed[%d] " | 11979 | "MIirq[%d] ASF[%d] WireSpeed[%d] TSOcap[%d]\n", |
| 11972 | "TSOcap[%d] \n", | ||
| 11973 | dev->name, | 11980 | dev->name, |
| 11974 | (tp->tg3_flags & TG3_FLAG_RX_CHECKSUMS) != 0, | 11981 | (tp->tg3_flags & TG3_FLAG_RX_CHECKSUMS) != 0, |
| 11975 | (tp->tg3_flags & TG3_FLAG_USE_LINKCHG_REG) != 0, | 11982 | (tp->tg3_flags & TG3_FLAG_USE_LINKCHG_REG) != 0, |
| 11976 | (tp->tg3_flags & TG3_FLAG_USE_MI_INTERRUPT) != 0, | 11983 | (tp->tg3_flags & TG3_FLAG_USE_MI_INTERRUPT) != 0, |
| 11977 | (tp->tg3_flags & TG3_FLAG_ENABLE_ASF) != 0, | 11984 | (tp->tg3_flags & TG3_FLAG_ENABLE_ASF) != 0, |
| 11978 | (tp->tg3_flags & TG3_FLAG_SPLIT_MODE) != 0, | ||
| 11979 | (tp->tg3_flags2 & TG3_FLG2_NO_ETH_WIRE_SPEED) == 0, | 11985 | (tp->tg3_flags2 & TG3_FLG2_NO_ETH_WIRE_SPEED) == 0, |
| 11980 | (tp->tg3_flags2 & TG3_FLG2_TSO_CAPABLE) != 0); | 11986 | (tp->tg3_flags2 & TG3_FLG2_TSO_CAPABLE) != 0); |
| 11981 | printk(KERN_INFO "%s: dma_rwctrl[%08x] dma_mask[%d-bit]\n", | 11987 | printk(KERN_INFO "%s: dma_rwctrl[%08x] dma_mask[%d-bit]\n", |
