tr32(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW);
}
+static void tg3_switch_clocks(struct tg3 *tp)
+{
+ if (tr32(TG3PCI_CLOCK_CTRL) & CLOCK_CTRL_44MHZ_CORE) {
+ tw32(TG3PCI_CLOCK_CTRL,
+ (CLOCK_CTRL_44MHZ_CORE | CLOCK_CTRL_ALTCLK));
+ tr32(TG3PCI_CLOCK_CTRL);
+ udelay(40);
+ tw32(TG3PCI_CLOCK_CTRL,
+ (CLOCK_CTRL_ALTCLK));
+ tr32(TG3PCI_CLOCK_CTRL);
+ udelay(40);
+ }
+ tw32(TG3PCI_CLOCK_CTRL, 0);
+ tr32(TG3PCI_CLOCK_CTRL);
+ udelay(40);
+}
+
#define PHY_BUSY_LOOPS 5000
static int tg3_readphy(struct tg3 *tp, int reg, u32 *val)
tp->link_config.orig_autoneg = tp->link_config.autoneg;
}
- tp->link_config.speed = SPEED_10;
- tp->link_config.duplex = DUPLEX_HALF;
- tp->link_config.autoneg = AUTONEG_ENABLE;
- tg3_setup_phy(tp);
+ if (tp->phy_id != PHY_ID_SERDES) {
+ tp->link_config.speed = SPEED_10;
+ tp->link_config.duplex = DUPLEX_HALF;
+ tp->link_config.autoneg = AUTONEG_ENABLE;
+ tg3_setup_phy(tp);
+ }
tg3_halt(tp);
if (tp->tg3_flags & TG3_FLAG_WOL_ENABLE) {
u32 mac_mode;
- tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x5a);
- udelay(40);
+ if (tp->phy_id != PHY_ID_SERDES) {
+ tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x5a);
+ udelay(40);
- mac_mode = MAC_MODE_PORT_MODE_MII;
+ mac_mode = MAC_MODE_PORT_MODE_MII;
+
+ if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5700 ||
+ !(tp->tg3_flags & TG3_FLAG_WOL_SPEED_100MB))
+ mac_mode |= MAC_MODE_LINK_POLARITY;
+ } else {
+ mac_mode = MAC_MODE_PORT_MODE_TBI;
+ }
- if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5700 ||
- !(tp->tg3_flags & TG3_FLAG_WOL_SPEED_100MB))
- mac_mode |= MAC_MODE_LINK_POLARITY;
if (((power_caps & PCI_PM_CAP_PME_D3cold) &&
(tp->tg3_flags & TG3_FLAG_WOL_ENABLE)))
tw32(MAC_MODE, mac_mode);
tr32(MAC_MODE);
- udelay(40);
+ udelay(100);
tw32(MAC_RX_MODE, RX_MODE_ENABLE);
tr32(MAC_RX_MODE);
if (err)
goto out;
+ tg3_switch_clocks(tp);
+
tw32(TG3PCI_MEM_WIN_BASE_ADDR, 0);
err = tg3_reset_hw(tp);
return -EFAULT;
if (wol.wolopts & ~WAKE_MAGIC)
return -EINVAL;
+ if ((wol.wolopts & WAKE_MAGIC) &&
+ tp->phy_id == PHY_ID_SERDES &&
+ !(tp->tg3_flags & TG3_FLAG_SERDES_WOL_CAP))
+ return -EINVAL;
+
spin_lock_irq(&tp->lock);
if (wol.wolopts & WAKE_MAGIC)
tp->tg3_flags |= TG3_FLAG_WOL_ENABLE;
if (nic_cfg & NIC_SRAM_DATA_CFG_ASF_ENABLE)
tp->tg3_flags |= TG3_FLAG_ENABLE_ASF;
+ if (nic_cfg & NIC_SRAM_DATA_CFG_FIBER_WOL)
+ tp->tg3_flags |= TG3_FLAG_SERDES_WOL_CAP;
}
/* Now read the physical PHY_ID from the chip and verify
/* Initialize data/descriptor byte/word swapping. */
tw32(GRC_MODE, tp->grc_mode);
- /* Clear these out for sanity. */
- tw32(TG3PCI_CLOCK_CTRL, 0);
+ tg3_switch_clocks(tp);
+
+ /* Clear this out for sanity. */
tw32(TG3PCI_MEM_WIN_BASE_ADDR, 0);
pci_read_config_dword(tp->pdev, TG3PCI_PCISTATE,
#define NIC_SRAM_DATA_CFG_WOL_ENABLE 0x00000040
#define NIC_SRAM_DATA_CFG_ASF_ENABLE 0x00000080
#define NIC_SRAM_DATA_CFG_EEPROM_WP 0x00000100
+#define NIC_SRAM_DATA_CFG_FIBER_WOL 0x00004000
#define NIC_SRAM_DATA_PHY_ID 0x00000b74
#define NIC_SRAM_DATA_PHY_ID1_MASK 0xffff0000
#define TG3_FLAG_PCI_32BIT 0x00080000
#define TG3_FLAG_NO_TX_PSEUDO_CSUM 0x00100000
#define TG3_FLAG_NO_RX_PSEUDO_CSUM 0x00200000
-#define TG3_FLAG_AUTONEG_DISABLE 0x00400000
+#define TG3_FLAG_SERDES_WOL_CAP 0x00400000
#define TG3_FLAG_JUMBO_ENABLE 0x00800000
#define TG3_FLAG_10_100_ONLY 0x01000000
#define TG3_FLAG_PAUSE_AUTONEG 0x02000000