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 | |
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>
-rw-r--r-- | include/linux/ethtool.h | 4 | ||||
-rw-r--r-- | net/core/ethtool.c | 17 |
2 files changed, 18 insertions, 3 deletions
diff --git a/include/linux/ethtool.h b/include/linux/ethtool.h index 6628a507fd3b..1908929204a9 100644 --- a/include/linux/ethtool.h +++ b/include/linux/ethtool.h | |||
@@ -691,7 +691,9 @@ struct ethtool_ops { | |||
691 | #define ETHTOOL_GMSGLVL 0x00000007 /* Get driver message level */ | 691 | #define ETHTOOL_GMSGLVL 0x00000007 /* Get driver message level */ |
692 | #define ETHTOOL_SMSGLVL 0x00000008 /* Set driver msg level. */ | 692 | #define ETHTOOL_SMSGLVL 0x00000008 /* Set driver msg level. */ |
693 | #define ETHTOOL_NWAY_RST 0x00000009 /* Restart autonegotiation. */ | 693 | #define ETHTOOL_NWAY_RST 0x00000009 /* Restart autonegotiation. */ |
694 | #define ETHTOOL_GLINK 0x0000000a /* Get link status (ethtool_value) */ | 694 | /* Get link status for host, i.e. whether the interface *and* the |
695 | * physical port (if there is one) are up (ethtool_value). */ | ||
696 | #define ETHTOOL_GLINK 0x0000000a | ||
695 | #define ETHTOOL_GEEPROM 0x0000000b /* Get EEPROM data */ | 697 | #define ETHTOOL_GEEPROM 0x0000000b /* Get EEPROM data */ |
696 | #define ETHTOOL_SEEPROM 0x0000000c /* Set EEPROM data. */ | 698 | #define ETHTOOL_SEEPROM 0x0000000c /* Set EEPROM data. */ |
697 | #define ETHTOOL_GCOALESCE 0x0000000e /* Get coalesce config */ | 699 | #define ETHTOOL_GCOALESCE 0x0000000e /* Get coalesce config */ |
diff --git a/net/core/ethtool.c b/net/core/ethtool.c index d5bc28818883..17741782a345 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); |