diff options
author | Matt Carlson <mcarlson@broadcom.com> | 2011-01-25 10:58:52 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2011-01-25 22:38:18 -0500 |
commit | 49692ca1e686970bac5726c3fd925427bb3ae89d (patch) | |
tree | 369ecfec808cd59aae198ada75837f5c0baea1af /drivers | |
parent | f746a3136a61ae535c5d0b49a9418fa21edc61b5 (diff) |
tg3: Fix loopback tests
The half-duplex bit in the MAC MODE register will be set during the
loopback test if the external link is in half-duplex mode. This will
cause the loopback test to fail on newer devices. This patch turns the
half-duplex bit off for the test.
Also, newer devices fail the internal phy loopback test because the phy
link takes a little while to come up. This patch adds code to wait for
the link before proceeding with the test.
Signed-off-by: Matt Carlson <mcarlson@broadcom.com>
Reviewed-by: Michael Chan <mchan@broadcom.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/net/tg3.c | 15 |
1 files changed, 12 insertions, 3 deletions
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 370c67a9d08a..9c5690366f37 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c | |||
@@ -10845,8 +10845,9 @@ static int tg3_run_loopback(struct tg3 *tp, int loopback_mode) | |||
10845 | if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5780) | 10845 | if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5780) |
10846 | return 0; | 10846 | return 0; |
10847 | 10847 | ||
10848 | mac_mode = (tp->mac_mode & ~MAC_MODE_PORT_MODE_MASK) | | 10848 | mac_mode = tp->mac_mode & |
10849 | MAC_MODE_PORT_INT_LPBACK; | 10849 | ~(MAC_MODE_PORT_MODE_MASK | MAC_MODE_HALF_DUPLEX); |
10850 | mac_mode |= MAC_MODE_PORT_INT_LPBACK; | ||
10850 | if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS)) | 10851 | if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS)) |
10851 | mac_mode |= MAC_MODE_LINK_POLARITY; | 10852 | mac_mode |= MAC_MODE_LINK_POLARITY; |
10852 | if (tp->phy_flags & TG3_PHYFLG_10_100_ONLY) | 10853 | if (tp->phy_flags & TG3_PHYFLG_10_100_ONLY) |
@@ -10868,7 +10869,8 @@ static int tg3_run_loopback(struct tg3 *tp, int loopback_mode) | |||
10868 | tg3_writephy(tp, MII_BMCR, val); | 10869 | tg3_writephy(tp, MII_BMCR, val); |
10869 | udelay(40); | 10870 | udelay(40); |
10870 | 10871 | ||
10871 | mac_mode = tp->mac_mode & ~MAC_MODE_PORT_MODE_MASK; | 10872 | mac_mode = tp->mac_mode & |
10873 | ~(MAC_MODE_PORT_MODE_MASK | MAC_MODE_HALF_DUPLEX); | ||
10872 | if (tp->phy_flags & TG3_PHYFLG_IS_FET) { | 10874 | if (tp->phy_flags & TG3_PHYFLG_IS_FET) { |
10873 | tg3_writephy(tp, MII_TG3_FET_PTEST, | 10875 | tg3_writephy(tp, MII_TG3_FET_PTEST, |
10874 | MII_TG3_FET_PTEST_FRC_TX_LINK | | 10876 | MII_TG3_FET_PTEST_FRC_TX_LINK | |
@@ -10896,6 +10898,13 @@ static int tg3_run_loopback(struct tg3 *tp, int loopback_mode) | |||
10896 | MII_TG3_EXT_CTRL_LNK3_LED_MODE); | 10898 | MII_TG3_EXT_CTRL_LNK3_LED_MODE); |
10897 | } | 10899 | } |
10898 | tw32(MAC_MODE, mac_mode); | 10900 | tw32(MAC_MODE, mac_mode); |
10901 | |||
10902 | /* Wait for link */ | ||
10903 | for (i = 0; i < 100; i++) { | ||
10904 | if (tr32(MAC_TX_STATUS) & TX_STATUS_LINK_UP) | ||
10905 | break; | ||
10906 | mdelay(1); | ||
10907 | } | ||
10899 | } else { | 10908 | } else { |
10900 | return -EINVAL; | 10909 | return -EINVAL; |
10901 | } | 10910 | } |