Bug#496647: ethtool-lite incorrectly reports status of e1000e
tag 496647 +confirmed
tag 496647 +patch
[tl;dr: Here be dragons]
Yeah, there's definitely something screwy going on here... but I'm not
entirely sure it's ethtool-lite's fault. I get similar results to the
submitter on an e1000e-equipped laptop (Thinkpad X60s), but mii-diag also
screws up in a similar fashion: basically, if a network cable has *ever*
been plugged in and the interface brought up, mii-diag will show that the
link is established, regardless of whether the cable is connected or not,
and whether or not ip link set <up|down> has been run.
Based on this, I'm inclined to think that this isn't necessarily an
ethtool-lite problem -- it's actually more of a NIC driver problem. To
strengthen this conclusion, I've got another laptop (Thinkpad T42) with an
e1000 NIC, and it behaves (somewhat) as one would expect:
Cable in Cable out
ip link set eth0 up eth0 is connected. eth1 is disconnected (MII).
ip link set eth0 down eth0 is disconnected (MII) eth1 is disconnected (MII).
Although this could well be considered a driver bug, I think there is a
workaround that could be implemented in ethtool-lite. Basically, in the
e1000e driver, SIOCETHTOOL works. Why do we then second-guess it and
fallback to MII whenever it says that "yes, the link is disconnected"?
The logic in ethtool-lite for determining whether to use ethtool or MII
doesn't seem right to me -- to my mind, the only time we should fall back to
MII is if ioctl(SIOCETHTOOL) *failed*, not just if it didn't affirmitively
report "link is connected".
The attached patch implements this modification. It makes link detection
work correctly for the e1000e driver (as in, does the same thing as the
table above) on my laptop.
Another option, mooted in #591012, is to use /sys/class/net/<dev>/carrier,
which does seem awesome in the cases where it works, but does require the
interface to be up before link detection can take place, too. As an added
bonus, it works with wireless interfaces, too (at least the iwl3945). I'll
put more comments and a relevant patch in that bug report.
My recommendation on this bug would be for people with as many different
chipsets as possible to try my modified ethtool-lite on their machines
(especially chipsets with drivers that don't implement SIOCETHTOOL -- if any
such beasts still exist), and see whether it Does The Right Thing
everywhere. The more adventurous option would be to put the patch in
immediately after squeeze, and see if anyone reports catastrophic network
link detection failure as a result.
The other option is to punt this whole bug report at the kernel, since the
e1000e driver obviously has some confusion in the realm of MII support.
--- ethtool-lite.c (revision 66154)
+++ ethtool-lite.c (working copy)
@@ -75,16 +75,15 @@
ifr.ifr_data = (char *)&edata;
strncpy (ifr.ifr_name, iface, IFNAMSIZ);
- if (ioctl (fd, SIOCETHTOOL, &ifr) < 0)
- di_info("ethtool ioctl on %s failed\n", iface);
- if (edata.data)
+ if (ioctl (fd, SIOCETHTOOL, &ifr) >= 0)
- di_info("%s is connected.\n", iface);
- return CONNECTED;
+ di_info("%s is %sconnected.\n", iface,
+ (edata.data) ? "" : "dis");
+ return (edata.data) ? CONNECTED : DISCONNECTED;
+ di_info("ethtool ioctl on %s failed\n", iface);
u_int16_t *data = (u_int16_t *)&ifr.ifr_data;
data = 0;