aboutsummaryrefslogtreecommitdiffstats
path: root/net/core/net-sysfs.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/core/net-sysfs.c')
-rw-r--r--net/core/net-sysfs.c63
1 files changed, 58 insertions, 5 deletions
diff --git a/net/core/net-sysfs.c b/net/core/net-sysfs.c
index 427ded841224..59cfc7d8fc45 100644
--- a/net/core/net-sysfs.c
+++ b/net/core/net-sysfs.c
@@ -13,6 +13,7 @@
13#include <linux/kernel.h> 13#include <linux/kernel.h>
14#include <linux/netdevice.h> 14#include <linux/netdevice.h>
15#include <linux/if_arp.h> 15#include <linux/if_arp.h>
16#include <linux/slab.h>
16#include <net/sock.h> 17#include <net/sock.h>
17#include <linux/rtnetlink.h> 18#include <linux/rtnetlink.h>
18#include <linux/wireless.h> 19#include <linux/wireless.h>
@@ -130,6 +131,48 @@ static ssize_t show_carrier(struct device *dev,
130 return -EINVAL; 131 return -EINVAL;
131} 132}
132 133
134static ssize_t show_speed(struct device *dev,
135 struct device_attribute *attr, char *buf)
136{
137 struct net_device *netdev = to_net_dev(dev);
138 int ret = -EINVAL;
139
140 if (!rtnl_trylock())
141 return restart_syscall();
142
143 if (netif_running(netdev) &&
144 netdev->ethtool_ops &&
145 netdev->ethtool_ops->get_settings) {
146 struct ethtool_cmd cmd = { ETHTOOL_GSET };
147
148 if (!netdev->ethtool_ops->get_settings(netdev, &cmd))
149 ret = sprintf(buf, fmt_dec, ethtool_cmd_speed(&cmd));
150 }
151 rtnl_unlock();
152 return ret;
153}
154
155static ssize_t show_duplex(struct device *dev,
156 struct device_attribute *attr, char *buf)
157{
158 struct net_device *netdev = to_net_dev(dev);
159 int ret = -EINVAL;
160
161 if (!rtnl_trylock())
162 return restart_syscall();
163
164 if (netif_running(netdev) &&
165 netdev->ethtool_ops &&
166 netdev->ethtool_ops->get_settings) {
167 struct ethtool_cmd cmd = { ETHTOOL_GSET };
168
169 if (!netdev->ethtool_ops->get_settings(netdev, &cmd))
170 ret = sprintf(buf, "%s\n", cmd.duplex ? "full" : "half");
171 }
172 rtnl_unlock();
173 return ret;
174}
175
133static ssize_t show_dormant(struct device *dev, 176static ssize_t show_dormant(struct device *dev,
134 struct device_attribute *attr, char *buf) 177 struct device_attribute *attr, char *buf)
135{ 178{
@@ -259,6 +302,8 @@ static struct device_attribute net_class_attributes[] = {
259 __ATTR(address, S_IRUGO, show_address, NULL), 302 __ATTR(address, S_IRUGO, show_address, NULL),
260 __ATTR(broadcast, S_IRUGO, show_broadcast, NULL), 303 __ATTR(broadcast, S_IRUGO, show_broadcast, NULL),
261 __ATTR(carrier, S_IRUGO, show_carrier, NULL), 304 __ATTR(carrier, S_IRUGO, show_carrier, NULL),
305 __ATTR(speed, S_IRUGO, show_speed, NULL),
306 __ATTR(duplex, S_IRUGO, show_duplex, NULL),
262 __ATTR(dormant, S_IRUGO, show_dormant, NULL), 307 __ATTR(dormant, S_IRUGO, show_dormant, NULL),
263 __ATTR(operstate, S_IRUGO, show_operstate, NULL), 308 __ATTR(operstate, S_IRUGO, show_operstate, NULL),
264 __ATTR(mtu, S_IRUGO | S_IWUSR, show_mtu, store_mtu), 309 __ATTR(mtu, S_IRUGO | S_IWUSR, show_mtu, store_mtu),
@@ -366,7 +411,8 @@ static ssize_t wireless_show(struct device *d, char *buf,
366 const struct iw_statistics *iw; 411 const struct iw_statistics *iw;
367 ssize_t ret = -EINVAL; 412 ssize_t ret = -EINVAL;
368 413
369 rtnl_lock(); 414 if (!rtnl_trylock())
415 return restart_syscall();
370 if (dev_isalive(dev)) { 416 if (dev_isalive(dev)) {
371 iw = get_wireless_stats(dev); 417 iw = get_wireless_stats(dev);
372 if (iw) 418 if (iw)
@@ -481,7 +527,7 @@ void netdev_unregister_kobject(struct net_device * net)
481 527
482 kobject_get(&dev->kobj); 528 kobject_get(&dev->kobj);
483 529
484 if (dev_net(net) != &init_net) 530 if (!net_eq(dev_net(net), &init_net))
485 return; 531 return;
486 532
487 device_del(dev); 533 device_del(dev);
@@ -500,15 +546,22 @@ int netdev_register_kobject(struct net_device *net)
500 dev_set_name(dev, "%s", net->name); 546 dev_set_name(dev, "%s", net->name);
501 547
502#ifdef CONFIG_SYSFS 548#ifdef CONFIG_SYSFS
503 *groups++ = &netstat_group; 549 /* Allow for a device specific group */
550 if (*groups)
551 groups++;
504 552
553 *groups++ = &netstat_group;
505#ifdef CONFIG_WIRELESS_EXT_SYSFS 554#ifdef CONFIG_WIRELESS_EXT_SYSFS
506 if (net->wireless_handlers || net->ieee80211_ptr) 555 if (net->ieee80211_ptr)
507 *groups++ = &wireless_group; 556 *groups++ = &wireless_group;
557#ifdef CONFIG_WIRELESS_EXT
558 else if (net->wireless_handlers)
559 *groups++ = &wireless_group;
560#endif
508#endif 561#endif
509#endif /* CONFIG_SYSFS */ 562#endif /* CONFIG_SYSFS */
510 563
511 if (dev_net(net) != &init_net) 564 if (!net_eq(dev_net(net), &init_net))
512 return 0; 565 return 0;
513 566
514 return device_add(dev); 567 return device_add(dev);