diff options
Diffstat (limited to 'drivers/net/tg3.c')
-rw-r--r-- | drivers/net/tg3.c | 40 |
1 files changed, 36 insertions, 4 deletions
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 59d6e74a4a5f..e5e901ecd808 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.75" | 67 | #define DRV_MODULE_VERSION "3.76" |
68 | #define DRV_MODULE_RELDATE "March 23, 2007" | 68 | #define DRV_MODULE_RELDATE "May 5, 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 |
@@ -3019,6 +3019,16 @@ static int tg3_setup_phy(struct tg3 *tp, int force_reset) | |||
3019 | } | 3019 | } |
3020 | } | 3020 | } |
3021 | 3021 | ||
3022 | if (tp->tg3_flags & TG3_FLAG_ASPM_WORKAROUND) { | ||
3023 | u32 val = tr32(PCIE_PWR_MGMT_THRESH); | ||
3024 | if (!netif_carrier_ok(tp->dev)) | ||
3025 | val = (val & ~PCIE_PWR_MGMT_L1_THRESH_MSK) | | ||
3026 | tp->pwrmgmt_thresh; | ||
3027 | else | ||
3028 | val |= PCIE_PWR_MGMT_L1_THRESH_MSK; | ||
3029 | tw32(PCIE_PWR_MGMT_THRESH, val); | ||
3030 | } | ||
3031 | |||
3022 | return err; | 3032 | return err; |
3023 | } | 3033 | } |
3024 | 3034 | ||
@@ -3580,8 +3590,12 @@ static irqreturn_t tg3_interrupt(int irq, void *dev_id) | |||
3580 | * Writing non-zero to intr-mbox-0 additional tells the | 3590 | * Writing non-zero to intr-mbox-0 additional tells the |
3581 | * NIC to stop sending us irqs, engaging "in-intr-handler" | 3591 | * NIC to stop sending us irqs, engaging "in-intr-handler" |
3582 | * event coalescing. | 3592 | * event coalescing. |
3593 | * | ||
3594 | * Flush the mailbox to de-assert the IRQ immediately to prevent | ||
3595 | * spurious interrupts. The flush impacts performance but | ||
3596 | * excessive spurious interrupts can be worse in some cases. | ||
3583 | */ | 3597 | */ |
3584 | tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, 0x00000001); | 3598 | tw32_mailbox_f(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, 0x00000001); |
3585 | if (tg3_irq_sync(tp)) | 3599 | if (tg3_irq_sync(tp)) |
3586 | goto out; | 3600 | goto out; |
3587 | sblk->status &= ~SD_STATUS_UPDATED; | 3601 | sblk->status &= ~SD_STATUS_UPDATED; |
@@ -3625,8 +3639,12 @@ static irqreturn_t tg3_interrupt_tagged(int irq, void *dev_id) | |||
3625 | * writing non-zero to intr-mbox-0 additional tells the | 3639 | * writing non-zero to intr-mbox-0 additional tells the |
3626 | * NIC to stop sending us irqs, engaging "in-intr-handler" | 3640 | * NIC to stop sending us irqs, engaging "in-intr-handler" |
3627 | * event coalescing. | 3641 | * event coalescing. |
3642 | * | ||
3643 | * Flush the mailbox to de-assert the IRQ immediately to prevent | ||
3644 | * spurious interrupts. The flush impacts performance but | ||
3645 | * excessive spurious interrupts can be worse in some cases. | ||
3628 | */ | 3646 | */ |
3629 | tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, 0x00000001); | 3647 | tw32_mailbox_f(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, 0x00000001); |
3630 | if (tg3_irq_sync(tp)) | 3648 | if (tg3_irq_sync(tp)) |
3631 | goto out; | 3649 | goto out; |
3632 | if (netif_rx_schedule_prep(dev)) { | 3650 | if (netif_rx_schedule_prep(dev)) { |
@@ -10004,6 +10022,8 @@ static void __devinit tg3_get_eeprom_hw_cfg(struct tg3 *tp) | |||
10004 | tp->tg3_flags &= ~TG3_FLAG_EEPROM_WRITE_PROT; | 10022 | tp->tg3_flags &= ~TG3_FLAG_EEPROM_WRITE_PROT; |
10005 | tp->tg3_flags2 |= TG3_FLG2_IS_NIC; | 10023 | tp->tg3_flags2 |= TG3_FLG2_IS_NIC; |
10006 | } | 10024 | } |
10025 | if (tr32(VCPU_CFGSHDW) & VCPU_CFGSHDW_ASPM_DBNC) | ||
10026 | tp->tg3_flags |= TG3_FLAG_ASPM_WORKAROUND; | ||
10007 | return; | 10027 | return; |
10008 | } | 10028 | } |
10009 | 10029 | ||
@@ -10131,6 +10151,14 @@ static void __devinit tg3_get_eeprom_hw_cfg(struct tg3 *tp) | |||
10131 | /* bootcode if bit 18 is set */ | 10151 | /* bootcode if bit 18 is set */ |
10132 | if (cfg2 & (1 << 18)) | 10152 | if (cfg2 & (1 << 18)) |
10133 | tp->tg3_flags2 |= TG3_FLG2_SERDES_PREEMPHASIS; | 10153 | tp->tg3_flags2 |= TG3_FLG2_SERDES_PREEMPHASIS; |
10154 | |||
10155 | if (tp->tg3_flags2 & TG3_FLG2_PCI_EXPRESS) { | ||
10156 | u32 cfg3; | ||
10157 | |||
10158 | tg3_read_mem(tp, NIC_SRAM_DATA_CFG_3, &cfg3); | ||
10159 | if (cfg3 & NIC_SRAM_ASPM_DEBOUNCE) | ||
10160 | tp->tg3_flags |= TG3_FLAG_ASPM_WORKAROUND; | ||
10161 | } | ||
10134 | } | 10162 | } |
10135 | } | 10163 | } |
10136 | 10164 | ||
@@ -10998,6 +11026,10 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) | |||
10998 | */ | 11026 | */ |
10999 | tp->tg3_flags &= ~TG3_FLAG_WOL_ENABLE; | 11027 | tp->tg3_flags &= ~TG3_FLAG_WOL_ENABLE; |
11000 | 11028 | ||
11029 | if (tp->tg3_flags & TG3_FLAG_ASPM_WORKAROUND) | ||
11030 | tp->pwrmgmt_thresh = tr32(PCIE_PWR_MGMT_THRESH) & | ||
11031 | PCIE_PWR_MGMT_L1_THRESH_MSK; | ||
11032 | |||
11001 | return err; | 11033 | return err; |
11002 | } | 11034 | } |
11003 | 11035 | ||