diff --git a/net/core/net-sysfs.c b/net/core/net-sysfs.c index 352173df7578..7bb8bbc1f71e 100644 --- a/net/core/net-sysfs.c +++ b/net/core/net-sysfs.c @@ -118,6 +118,34 @@ unbreak: return ret; } +static int sysfs_get_link_ksettings(struct device *dev, + struct device_attribute *attr, + struct ethtool_link_ksettings *cmd) +{ + struct net_device *netdev = to_net_dev(dev); + int ret; + + /* + * The check is also done in __ethtool_get_link_ksettings; this helps + * returning early without hitting the locking section below. + */ + if (!netdev->ethtool_ops->get_link_ksettings) + return -EINVAL; + + ret = sysfs_rtnl_lock(&dev->kobj, &attr->attr, netdev); + if (ret) + return ret; + + ret = -EINVAL; + if (netif_running(netdev)) { + if (!__ethtool_get_link_ksettings(netdev, cmd)) + ret = 0; + } + + rtnl_unlock(); + return ret; +} + /* use same locking rules as GIF* ioctl's */ static ssize_t netdev_show(const struct device *dev, struct device_attribute *attr, char *buf, @@ -332,70 +360,41 @@ static DEVICE_ATTR_RW(carrier); static ssize_t speed_show(struct device *dev, struct device_attribute *attr, char *buf) { - struct net_device *netdev = to_net_dev(dev); - int ret = -EINVAL; + struct ethtool_link_ksettings cmd; + int ret; - /* The check is also done in __ethtool_get_link_ksettings; this helps - * returning early without hitting the locking section below. - */ - if (!netdev->ethtool_ops->get_link_ksettings) - return ret; - - ret = sysfs_rtnl_lock(&dev->kobj, &attr->attr, netdev); + ret = sysfs_get_link_ksettings(dev, attr, &cmd); if (ret) return ret; - ret = -EINVAL; - if (netif_running(netdev)) { - struct ethtool_link_ksettings cmd; - - if (!__ethtool_get_link_ksettings(netdev, &cmd)) - ret = sysfs_emit(buf, fmt_dec, cmd.base.speed); - } - rtnl_unlock(); - return ret; + return sysfs_emit(buf, fmt_dec, cmd.base.speed); } static DEVICE_ATTR_RO(speed); static ssize_t duplex_show(struct device *dev, struct device_attribute *attr, char *buf) { - struct net_device *netdev = to_net_dev(dev); - int ret = -EINVAL; + struct ethtool_link_ksettings cmd; + const char *duplex; + int ret; - /* The check is also done in __ethtool_get_link_ksettings; this helps - * returning early without hitting the locking section below. - */ - if (!netdev->ethtool_ops->get_link_ksettings) - return ret; - - ret = sysfs_rtnl_lock(&dev->kobj, &attr->attr, netdev); + ret = sysfs_get_link_ksettings(dev, attr, &cmd); if (ret) return ret; - ret = -EINVAL; - if (netif_running(netdev)) { - struct ethtool_link_ksettings cmd; - - if (!__ethtool_get_link_ksettings(netdev, &cmd)) { - const char *duplex; - - switch (cmd.base.duplex) { - case DUPLEX_HALF: - duplex = "half"; - break; - case DUPLEX_FULL: - duplex = "full"; - break; - default: - duplex = "unknown"; - break; - } - ret = sysfs_emit(buf, "%s\n", duplex); - } + switch (cmd.base.duplex) { + case DUPLEX_HALF: + duplex = "half"; + break; + case DUPLEX_FULL: + duplex = "full"; + break; + default: + duplex = "unknown"; + break; } - rtnl_unlock(); - return ret; + + return sysfs_emit(buf, "%s\n", duplex); } static DEVICE_ATTR_RO(duplex);