aboutsummaryrefslogtreecommitdiff
path: root/drivers/net/tg3.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/tg3.c')
-rw-r--r--drivers/net/tg3.c30
1 files changed, 30 insertions, 0 deletions
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index ab2fa213b30..30349c5fd73 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -7281,6 +7281,32 @@ out:
return err;
}
+#define TG3_SERDES_TIMEOUT_SEC 2
+#define TG3_COPPER_TIMEOUT_SEC 6
+
+static int tg3_test_link(struct tg3 *tp)
+{
+ int i, max;
+
+ if (!netif_running(tp->dev))
+ return -ENODEV;
+
+ if (tp->tg3_flags2 & TG3_FLG2_PHY_SERDES)
+ max = TG3_SERDES_TIMEOUT_SEC;
+ else
+ max = TG3_COPPER_TIMEOUT_SEC;
+
+ for (i = 0; i < max; i++) {
+ if (netif_carrier_ok(tp->dev))
+ return 0;
+
+ if (msleep_interruptible(1000))
+ break;
+ }
+
+ return -EIO;
+}
+
static void tg3_self_test(struct net_device *dev, struct ethtool_test *etest,
u64 *data)
{
@@ -7292,6 +7318,10 @@ static void tg3_self_test(struct net_device *dev, struct ethtool_test *etest,
etest->flags |= ETH_TEST_FL_FAILED;
data[0] = 1;
}
+ if (tg3_test_link(tp) != 0) {
+ etest->flags |= ETH_TEST_FL_FAILED;
+ data[1] = 1;
+ }
}
static int tg3_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)