diff options
author | Michael Chan <mchan@broadcom.com> | 2006-09-27 19:02:29 -0400 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2006-09-28 21:01:36 -0400 |
commit | 3f7045c1f28bedd44389b9392b54c6fdb83ee5c6 (patch) | |
tree | c504ff6ea5aa82500a43929fe10333060bc691d1 /drivers/net/tg3.c | |
parent | 130b8e4d0e4edadcecee9fdff2c32f33d77c4fe9 (diff) |
[TG3]: PHY fixes.
Some PHY related fixes:
1. Fix Serdes WoL.
2. Fix loopback test on 10/100 only devices.
Signed-off-by: Michael Chan <mchan@broadcom.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/tg3.c')
-rw-r--r-- | drivers/net/tg3.c | 51 |
1 files changed, 34 insertions, 17 deletions
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 6af8ebcf35f0..14e964524969 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c | |||
@@ -1117,6 +1117,12 @@ static void tg3_nvram_unlock(struct tg3 *); | |||
1117 | 1117 | ||
1118 | static void tg3_power_down_phy(struct tg3 *tp) | 1118 | static void tg3_power_down_phy(struct tg3 *tp) |
1119 | { | 1119 | { |
1120 | if (tp->tg3_flags2 & TG3_FLG2_PHY_SERDES) | ||
1121 | return; | ||
1122 | |||
1123 | tg3_writephy(tp, MII_TG3_EXT_CTRL, MII_TG3_EXT_CTRL_FORCE_LED_OFF); | ||
1124 | tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x01b2); | ||
1125 | |||
1120 | /* The PHY should not be powered down on some chips because | 1126 | /* The PHY should not be powered down on some chips because |
1121 | * of bugs. | 1127 | * of bugs. |
1122 | */ | 1128 | */ |
@@ -1223,7 +1229,10 @@ static int tg3_set_power_state(struct tg3 *tp, pci_power_t state) | |||
1223 | tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x5a); | 1229 | tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x5a); |
1224 | udelay(40); | 1230 | udelay(40); |
1225 | 1231 | ||
1226 | mac_mode = MAC_MODE_PORT_MODE_MII; | 1232 | if (tp->tg3_flags2 & TG3_FLG2_MII_SERDES) |
1233 | mac_mode = MAC_MODE_PORT_MODE_GMII; | ||
1234 | else | ||
1235 | mac_mode = MAC_MODE_PORT_MODE_MII; | ||
1227 | 1236 | ||
1228 | if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5700 || | 1237 | if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5700 || |
1229 | !(tp->tg3_flags & TG3_FLAG_WOL_SPEED_100MB)) | 1238 | !(tp->tg3_flags & TG3_FLAG_WOL_SPEED_100MB)) |
@@ -1301,15 +1310,8 @@ static int tg3_set_power_state(struct tg3 *tp, pci_power_t state) | |||
1301 | } | 1310 | } |
1302 | 1311 | ||
1303 | if (!(tp->tg3_flags & TG3_FLAG_WOL_ENABLE) && | 1312 | if (!(tp->tg3_flags & TG3_FLAG_WOL_ENABLE) && |
1304 | !(tp->tg3_flags & TG3_FLAG_ENABLE_ASF)) { | 1313 | !(tp->tg3_flags & TG3_FLAG_ENABLE_ASF)) |
1305 | /* Turn off the PHY */ | 1314 | tg3_power_down_phy(tp); |
1306 | if (!(tp->tg3_flags2 & TG3_FLG2_PHY_SERDES)) { | ||
1307 | tg3_writephy(tp, MII_TG3_EXT_CTRL, | ||
1308 | MII_TG3_EXT_CTRL_FORCE_LED_OFF); | ||
1309 | tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x01b2); | ||
1310 | tg3_power_down_phy(tp); | ||
1311 | } | ||
1312 | } | ||
1313 | 1315 | ||
1314 | tg3_frob_aux_power(tp); | 1316 | tg3_frob_aux_power(tp); |
1315 | 1317 | ||
@@ -7889,7 +7891,7 @@ static int tg3_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol) | |||
7889 | if (wol->wolopts & ~WAKE_MAGIC) | 7891 | if (wol->wolopts & ~WAKE_MAGIC) |
7890 | return -EINVAL; | 7892 | return -EINVAL; |
7891 | if ((wol->wolopts & WAKE_MAGIC) && | 7893 | if ((wol->wolopts & WAKE_MAGIC) && |
7892 | tp->tg3_flags2 & TG3_FLG2_PHY_SERDES && | 7894 | tp->tg3_flags2 & TG3_FLG2_ANY_SERDES && |
7893 | !(tp->tg3_flags & TG3_FLAG_SERDES_WOL_CAP)) | 7895 | !(tp->tg3_flags & TG3_FLAG_SERDES_WOL_CAP)) |
7894 | return -EINVAL; | 7896 | return -EINVAL; |
7895 | 7897 | ||
@@ -8573,12 +8575,22 @@ static int tg3_run_loopback(struct tg3 *tp, int loopback_mode) | |||
8573 | return 0; | 8575 | return 0; |
8574 | 8576 | ||
8575 | mac_mode = (tp->mac_mode & ~MAC_MODE_PORT_MODE_MASK) | | 8577 | mac_mode = (tp->mac_mode & ~MAC_MODE_PORT_MODE_MASK) | |
8576 | MAC_MODE_PORT_INT_LPBACK | MAC_MODE_LINK_POLARITY | | 8578 | MAC_MODE_PORT_INT_LPBACK | MAC_MODE_LINK_POLARITY; |
8577 | MAC_MODE_PORT_MODE_GMII; | 8579 | if (tp->tg3_flags & TG3_FLAG_10_100_ONLY) |
8580 | mac_mode |= MAC_MODE_PORT_MODE_MII; | ||
8581 | else | ||
8582 | mac_mode |= MAC_MODE_PORT_MODE_GMII; | ||
8578 | tw32(MAC_MODE, mac_mode); | 8583 | tw32(MAC_MODE, mac_mode); |
8579 | } else if (loopback_mode == TG3_PHY_LOOPBACK) { | 8584 | } else if (loopback_mode == TG3_PHY_LOOPBACK) { |
8580 | tg3_writephy(tp, MII_BMCR, BMCR_LOOPBACK | BMCR_FULLDPLX | | 8585 | u32 val; |
8581 | BMCR_SPEED1000); | 8586 | |
8587 | val = BMCR_LOOPBACK | BMCR_FULLDPLX; | ||
8588 | if (tp->tg3_flags & TG3_FLAG_10_100_ONLY) | ||
8589 | val |= BMCR_SPEED100; | ||
8590 | else | ||
8591 | val |= BMCR_SPEED1000; | ||
8592 | |||
8593 | tg3_writephy(tp, MII_BMCR, val); | ||
8582 | udelay(40); | 8594 | udelay(40); |
8583 | /* reset to prevent losing 1st rx packet intermittently */ | 8595 | /* reset to prevent losing 1st rx packet intermittently */ |
8584 | if (tp->tg3_flags2 & TG3_FLG2_MII_SERDES) { | 8596 | if (tp->tg3_flags2 & TG3_FLG2_MII_SERDES) { |
@@ -8587,7 +8599,11 @@ static int tg3_run_loopback(struct tg3 *tp, int loopback_mode) | |||
8587 | tw32_f(MAC_RX_MODE, tp->rx_mode); | 8599 | tw32_f(MAC_RX_MODE, tp->rx_mode); |
8588 | } | 8600 | } |
8589 | mac_mode = (tp->mac_mode & ~MAC_MODE_PORT_MODE_MASK) | | 8601 | mac_mode = (tp->mac_mode & ~MAC_MODE_PORT_MODE_MASK) | |
8590 | MAC_MODE_LINK_POLARITY | MAC_MODE_PORT_MODE_GMII; | 8602 | MAC_MODE_LINK_POLARITY; |
8603 | if (tp->tg3_flags & TG3_FLAG_10_100_ONLY) | ||
8604 | mac_mode |= MAC_MODE_PORT_MODE_MII; | ||
8605 | else | ||
8606 | mac_mode |= MAC_MODE_PORT_MODE_GMII; | ||
8591 | if ((tp->phy_id & PHY_ID_MASK) == PHY_ID_BCM5401) { | 8607 | if ((tp->phy_id & PHY_ID_MASK) == PHY_ID_BCM5401) { |
8592 | mac_mode &= ~MAC_MODE_LINK_POLARITY; | 8608 | mac_mode &= ~MAC_MODE_LINK_POLARITY; |
8593 | tg3_writephy(tp, MII_TG3_EXT_CTRL, | 8609 | tg3_writephy(tp, MII_TG3_EXT_CTRL, |
@@ -8636,7 +8652,8 @@ static int tg3_run_loopback(struct tg3 *tp, int loopback_mode) | |||
8636 | 8652 | ||
8637 | udelay(10); | 8653 | udelay(10); |
8638 | 8654 | ||
8639 | for (i = 0; i < 10; i++) { | 8655 | /* 250 usec to allow enough time on some 10/100 Mbps devices. */ |
8656 | for (i = 0; i < 25; i++) { | ||
8640 | tw32_f(HOSTCC_MODE, tp->coalesce_mode | HOSTCC_MODE_ENABLE | | 8657 | tw32_f(HOSTCC_MODE, tp->coalesce_mode | HOSTCC_MODE_ENABLE | |
8641 | HOSTCC_MODE_NOW); | 8658 | HOSTCC_MODE_NOW); |
8642 | 8659 | ||