diff options
| author | Ben Hutchings <bhutchings@solarflare.com> | 2010-12-09 07:08:35 -0500 |
|---|---|---|
| committer | David S. Miller <davem@davemloft.net> | 2010-12-10 18:55:23 -0500 |
| commit | e596e6e4d578f2639416e620d367a3af34814a40 (patch) | |
| tree | 9ffe67f2abe3aebda15ce65ef4ff223f2db7d0f9 /net/core | |
| parent | 29639059a0122d95b34b5475bd9fee3910b401a3 (diff) | |
ethtool: Report link-down while interface is down
While an interface is down, many implementations of
ethtool_ops::get_link, including the default, ethtool_op_get_link(),
will report the last link state seen while the interface was up. In
general the current physical link state is not available if the
interface is down.
Define ETHTOOL_GLINK to reflect whether the interface *and* any
physical port have a working link, and consistently return 0 when the
interface is down.
Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/core')
| -rw-r--r-- | net/core/ethtool.c | 17 |
1 files changed, 15 insertions, 2 deletions
diff --git a/net/core/ethtool.c b/net/core/ethtool.c index d5bc2881888..17741782a34 100644 --- a/net/core/ethtool.c +++ b/net/core/ethtool.c | |||
| @@ -891,6 +891,20 @@ static int ethtool_nway_reset(struct net_device *dev) | |||
| 891 | return dev->ethtool_ops->nway_reset(dev); | 891 | return dev->ethtool_ops->nway_reset(dev); |
| 892 | } | 892 | } |
| 893 | 893 | ||
| 894 | static int ethtool_get_link(struct net_device *dev, char __user *useraddr) | ||
| 895 | { | ||
| 896 | struct ethtool_value edata = { .cmd = ETHTOOL_GLINK }; | ||
| 897 | |||
| 898 | if (!dev->ethtool_ops->get_link) | ||
| 899 | return -EOPNOTSUPP; | ||
| 900 | |||
| 901 | edata.data = netif_running(dev) && dev->ethtool_ops->get_link(dev); | ||
| 902 | |||
| 903 | if (copy_to_user(useraddr, &edata, sizeof(edata))) | ||
| 904 | return -EFAULT; | ||
| 905 | return 0; | ||
| 906 | } | ||
| 907 | |||
| 894 | static int ethtool_get_eeprom(struct net_device *dev, void __user *useraddr) | 908 | static int ethtool_get_eeprom(struct net_device *dev, void __user *useraddr) |
| 895 | { | 909 | { |
| 896 | struct ethtool_eeprom eeprom; | 910 | struct ethtool_eeprom eeprom; |
| @@ -1530,8 +1544,7 @@ int dev_ethtool(struct net *net, struct ifreq *ifr) | |||
| 1530 | rc = ethtool_nway_reset(dev); | 1544 | rc = ethtool_nway_reset(dev); |
| 1531 | break; | 1545 | break; |
| 1532 | case ETHTOOL_GLINK: | 1546 | case ETHTOOL_GLINK: |
| 1533 | rc = ethtool_get_value(dev, useraddr, ethcmd, | 1547 | rc = ethtool_get_link(dev, useraddr); |
| 1534 | dev->ethtool_ops->get_link); | ||
| 1535 | break; | 1548 | break; |
| 1536 | case ETHTOOL_GEEPROM: | 1549 | case ETHTOOL_GEEPROM: |
| 1537 | rc = ethtool_get_eeprom(dev, useraddr); | 1550 | rc = ethtool_get_eeprom(dev, useraddr); |
