Commit fb4ce829 authored by David S. Miller's avatar David S. Miller

[TIGON3]: Fiber WOL support, chip clock bug fix.

- Support wake-on-lan with Fiber connections properly,
when possible.
- On device probe and device open, get out of 44MHZ core
clock rate if necessary.
parent 697f3abe
...@@ -237,6 +237,23 @@ static void tg3_enable_ints(struct tg3 *tp) ...@@ -237,6 +237,23 @@ static void tg3_enable_ints(struct tg3 *tp)
tr32(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW); 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 #define PHY_BUSY_LOOPS 5000
static int tg3_readphy(struct tg3 *tp, int reg, u32 *val) static int tg3_readphy(struct tg3 *tp, int reg, u32 *val)
...@@ -443,10 +460,12 @@ static int tg3_set_power_state(struct tg3 *tp, int state) ...@@ -443,10 +460,12 @@ static int tg3_set_power_state(struct tg3 *tp, int state)
tp->link_config.orig_autoneg = tp->link_config.autoneg; tp->link_config.orig_autoneg = tp->link_config.autoneg;
} }
tp->link_config.speed = SPEED_10; if (tp->phy_id != PHY_ID_SERDES) {
tp->link_config.duplex = DUPLEX_HALF; tp->link_config.speed = SPEED_10;
tp->link_config.autoneg = AUTONEG_ENABLE; tp->link_config.duplex = DUPLEX_HALF;
tg3_setup_phy(tp); tp->link_config.autoneg = AUTONEG_ENABLE;
tg3_setup_phy(tp);
}
tg3_halt(tp); tg3_halt(tp);
...@@ -455,14 +474,19 @@ static int tg3_set_power_state(struct tg3 *tp, int state) ...@@ -455,14 +474,19 @@ static int tg3_set_power_state(struct tg3 *tp, int state)
if (tp->tg3_flags & TG3_FLAG_WOL_ENABLE) { if (tp->tg3_flags & TG3_FLAG_WOL_ENABLE) {
u32 mac_mode; u32 mac_mode;
tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x5a); if (tp->phy_id != PHY_ID_SERDES) {
udelay(40); 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) && if (((power_caps & PCI_PM_CAP_PME_D3cold) &&
(tp->tg3_flags & TG3_FLAG_WOL_ENABLE))) (tp->tg3_flags & TG3_FLAG_WOL_ENABLE)))
...@@ -470,7 +494,7 @@ static int tg3_set_power_state(struct tg3 *tp, int state) ...@@ -470,7 +494,7 @@ static int tg3_set_power_state(struct tg3 *tp, int state)
tw32(MAC_MODE, mac_mode); tw32(MAC_MODE, mac_mode);
tr32(MAC_MODE); tr32(MAC_MODE);
udelay(40); udelay(100);
tw32(MAC_RX_MODE, RX_MODE_ENABLE); tw32(MAC_RX_MODE, RX_MODE_ENABLE);
tr32(MAC_RX_MODE); tr32(MAC_RX_MODE);
...@@ -4385,6 +4409,8 @@ static int tg3_init_hw(struct tg3 *tp) ...@@ -4385,6 +4409,8 @@ static int tg3_init_hw(struct tg3 *tp)
if (err) if (err)
goto out; goto out;
tg3_switch_clocks(tp);
tw32(TG3PCI_MEM_WIN_BASE_ADDR, 0); tw32(TG3PCI_MEM_WIN_BASE_ADDR, 0);
err = tg3_reset_hw(tp); err = tg3_reset_hw(tp);
...@@ -5259,6 +5285,11 @@ static int tg3_ethtool_ioctl (struct net_device *dev, void *useraddr) ...@@ -5259,6 +5285,11 @@ static int tg3_ethtool_ioctl (struct net_device *dev, void *useraddr)
return -EFAULT; return -EFAULT;
if (wol.wolopts & ~WAKE_MAGIC) if (wol.wolopts & ~WAKE_MAGIC)
return -EINVAL; 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); spin_lock_irq(&tp->lock);
if (wol.wolopts & WAKE_MAGIC) if (wol.wolopts & WAKE_MAGIC)
tp->tg3_flags |= TG3_FLAG_WOL_ENABLE; tp->tg3_flags |= TG3_FLAG_WOL_ENABLE;
...@@ -5793,6 +5824,8 @@ static int __devinit tg3_phy_probe(struct tg3 *tp) ...@@ -5793,6 +5824,8 @@ static int __devinit tg3_phy_probe(struct tg3 *tp)
if (nic_cfg & NIC_SRAM_DATA_CFG_ASF_ENABLE) if (nic_cfg & NIC_SRAM_DATA_CFG_ASF_ENABLE)
tp->tg3_flags |= TG3_FLAG_ENABLE_ASF; 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 /* Now read the physical PHY_ID from the chip and verify
...@@ -6131,8 +6164,9 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) ...@@ -6131,8 +6164,9 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
/* Initialize data/descriptor byte/word swapping. */ /* Initialize data/descriptor byte/word swapping. */
tw32(GRC_MODE, tp->grc_mode); tw32(GRC_MODE, tp->grc_mode);
/* Clear these out for sanity. */ tg3_switch_clocks(tp);
tw32(TG3PCI_CLOCK_CTRL, 0);
/* Clear this out for sanity. */
tw32(TG3PCI_MEM_WIN_BASE_ADDR, 0); tw32(TG3PCI_MEM_WIN_BASE_ADDR, 0);
pci_read_config_dword(tp->pdev, TG3PCI_PCISTATE, pci_read_config_dword(tp->pdev, TG3PCI_PCISTATE,
......
...@@ -1274,6 +1274,7 @@ ...@@ -1274,6 +1274,7 @@
#define NIC_SRAM_DATA_CFG_WOL_ENABLE 0x00000040 #define NIC_SRAM_DATA_CFG_WOL_ENABLE 0x00000040
#define NIC_SRAM_DATA_CFG_ASF_ENABLE 0x00000080 #define NIC_SRAM_DATA_CFG_ASF_ENABLE 0x00000080
#define NIC_SRAM_DATA_CFG_EEPROM_WP 0x00000100 #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_ID 0x00000b74
#define NIC_SRAM_DATA_PHY_ID1_MASK 0xffff0000 #define NIC_SRAM_DATA_PHY_ID1_MASK 0xffff0000
...@@ -1779,7 +1780,7 @@ struct tg3 { ...@@ -1779,7 +1780,7 @@ struct tg3 {
#define TG3_FLAG_PCI_32BIT 0x00080000 #define TG3_FLAG_PCI_32BIT 0x00080000
#define TG3_FLAG_NO_TX_PSEUDO_CSUM 0x00100000 #define TG3_FLAG_NO_TX_PSEUDO_CSUM 0x00100000
#define TG3_FLAG_NO_RX_PSEUDO_CSUM 0x00200000 #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_JUMBO_ENABLE 0x00800000
#define TG3_FLAG_10_100_ONLY 0x01000000 #define TG3_FLAG_10_100_ONLY 0x01000000
#define TG3_FLAG_PAUSE_AUTONEG 0x02000000 #define TG3_FLAG_PAUSE_AUTONEG 0x02000000
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment