aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorAndy Gospodarek <andy@greyhouse.net>2009-10-02 05:26:12 -0400
committerDavid S. Miller <davem@davemloft.net>2009-10-05 03:43:35 -0400
commitd519e17e2d01a0ee9abe083019532061b4438065 (patch)
tree3f90e369fe65ff84dc46ec513f758b51a2834559 /net
parent053a93dd126f68ba37973f95f00af6045fa7c957 (diff)
net: export device speed and duplex via sysfs
This patch exports the link-speed (in Mbps) and duplex of an interface via sysfs. This eliminates the need to use ethtool just to check the link-speed. Not requiring 'ethtool' and not relying on the SIOCETHTOOL ioctl should be helpful in an embedded environment where space is at a premium as well. NOTE: This patch also intentionally allows non-root users to check the link speed and duplex -- something not possible with ethtool. Here's some sample output: # cat /sys/class/net/eth0/speed 100 # cat /sys/class/net/eth0/duplex half # ethtool eth0 Settings for eth0: Supported ports: [ TP ] Supported link modes: 10baseT/Half 10baseT/Full 100baseT/Half 100baseT/Full 1000baseT/Half 1000baseT/Full Supports auto-negotiation: Yes Advertised link modes: Not reported Advertised auto-negotiation: No Speed: 100Mb/s Duplex: Half Port: Twisted Pair PHYAD: 1 Transceiver: internal Auto-negotiation: off Supports Wake-on: g Wake-on: g Current message level: 0x000000ff (255) Link detected: yes Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r--net/core/net-sysfs.c40
1 files changed, 40 insertions, 0 deletions
diff --git a/net/core/net-sysfs.c b/net/core/net-sysfs.c
index 821d30918cfc..effb78410eb2 100644
--- a/net/core/net-sysfs.c
+++ b/net/core/net-sysfs.c
@@ -130,6 +130,44 @@ static ssize_t show_carrier(struct device *dev,
130 return -EINVAL; 130 return -EINVAL;
131} 131}
132 132
133static ssize_t show_speed(struct device *dev,
134 struct device_attribute *attr, char *buf)
135{
136 struct net_device *netdev = to_net_dev(dev);
137 int ret = -EINVAL;
138
139 if (!rtnl_trylock())
140 return restart_syscall();
141
142 if (netif_running(netdev) && netdev->ethtool_ops->get_settings) {
143 struct ethtool_cmd cmd = { ETHTOOL_GSET };
144
145 if (!netdev->ethtool_ops->get_settings(netdev, &cmd))
146 ret = sprintf(buf, fmt_dec, ethtool_cmd_speed(&cmd));
147 }
148 rtnl_unlock();
149 return ret;
150}
151
152static ssize_t show_duplex(struct device *dev,
153 struct device_attribute *attr, char *buf)
154{
155 struct net_device *netdev = to_net_dev(dev);
156 int ret = -EINVAL;
157
158 if (!rtnl_trylock())
159 return restart_syscall();
160
161 if (netif_running(netdev) && netdev->ethtool_ops->get_settings) {
162 struct ethtool_cmd cmd = { ETHTOOL_GSET };
163
164 if (!netdev->ethtool_ops->get_settings(netdev, &cmd))
165 ret = sprintf(buf, "%s\n", cmd.duplex ? "full" : "half");
166 }
167 rtnl_unlock();
168 return ret;
169}
170
133static ssize_t show_dormant(struct device *dev, 171static ssize_t show_dormant(struct device *dev,
134 struct device_attribute *attr, char *buf) 172 struct device_attribute *attr, char *buf)
135{ 173{
@@ -259,6 +297,8 @@ static struct device_attribute net_class_attributes[] = {
259 __ATTR(address, S_IRUGO, show_address, NULL), 297 __ATTR(address, S_IRUGO, show_address, NULL),
260 __ATTR(broadcast, S_IRUGO, show_broadcast, NULL), 298 __ATTR(broadcast, S_IRUGO, show_broadcast, NULL),
261 __ATTR(carrier, S_IRUGO, show_carrier, NULL), 299 __ATTR(carrier, S_IRUGO, show_carrier, NULL),
300 __ATTR(speed, S_IRUGO, show_speed, NULL),
301 __ATTR(duplex, S_IRUGO, show_duplex, NULL),
262 __ATTR(dormant, S_IRUGO, show_dormant, NULL), 302 __ATTR(dormant, S_IRUGO, show_dormant, NULL),
263 __ATTR(operstate, S_IRUGO, show_operstate, NULL), 303 __ATTR(operstate, S_IRUGO, show_operstate, NULL),
264 __ATTR(mtu, S_IRUGO | S_IWUSR, show_mtu, store_mtu), 304 __ATTR(mtu, S_IRUGO | S_IWUSR, show_mtu, store_mtu),