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.c59
1 files changed, 55 insertions, 4 deletions
diff --git a/net/core/net-sysfs.c b/net/core/net-sysfs.c
index 427ded84122..fbc1c7472c5 100644
--- a/net/core/net-sysfs.c
+++ b/net/core/net-sysfs.c
@@ -130,6 +130,48 @@ 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) &&
143 netdev->ethtool_ops &&
144 netdev->ethtool_ops->get_settings) {
145 struct ethtool_cmd cmd = { ETHTOOL_GSET };
146
147 if (!netdev->ethtool_ops->get_settings(netdev, &cmd))
148 ret = sprintf(buf, fmt_dec, ethtool_cmd_speed(&cmd));
149 }
150 rtnl_unlock();
151 return ret;
152}
153
154static ssize_t show_duplex(struct device *dev,
155 struct device_attribute *attr, char *buf)
156{
157 struct net_device *netdev = to_net_dev(dev);
158 int ret = -EINVAL;
159
160 if (!rtnl_trylock())
161 return restart_syscall();
162
163 if (netif_running(netdev) &&
164 netdev->ethtool_ops &&
165 netdev->ethtool_ops->get_settings) {
166 struct ethtool_cmd cmd = { ETHTOOL_GSET };
167
168 if (!netdev->ethtool_ops->get_settings(netdev, &cmd))
169 ret = sprintf(buf, "%s\n", cmd.duplex ? "full" : "half");
170 }
171 rtnl_unlock();
172 return ret;
173}
174
133static ssize_t show_dormant(struct device *dev, 175static ssize_t show_dormant(struct device *dev,
134 struct device_attribute *attr, char *buf) 176 struct device_attribute *attr, char *buf)
135{ 177{
@@ -259,6 +301,8 @@ static struct device_attribute net_class_attributes[] = {
259 __ATTR(address, S_IRUGO, show_address, NULL), 301 __ATTR(address, S_IRUGO, show_address, NULL),
260 __ATTR(broadcast, S_IRUGO, show_broadcast, NULL), 302 __ATTR(broadcast, S_IRUGO, show_broadcast, NULL),
261 __ATTR(carrier, S_IRUGO, show_carrier, NULL), 303 __ATTR(carrier, S_IRUGO, show_carrier, NULL),
304 __ATTR(speed, S_IRUGO, show_speed, NULL),
305 __ATTR(duplex, S_IRUGO, show_duplex, NULL),
262 __ATTR(dormant, S_IRUGO, show_dormant, NULL), 306 __ATTR(dormant, S_IRUGO, show_dormant, NULL),
263 __ATTR(operstate, S_IRUGO, show_operstate, NULL), 307 __ATTR(operstate, S_IRUGO, show_operstate, NULL),
264 __ATTR(mtu, S_IRUGO | S_IWUSR, show_mtu, store_mtu), 308 __ATTR(mtu, S_IRUGO | S_IWUSR, show_mtu, store_mtu),
@@ -481,7 +525,7 @@ void netdev_unregister_kobject(struct net_device * net)
481 525
482 kobject_get(&dev->kobj); 526 kobject_get(&dev->kobj);
483 527
484 if (dev_net(net) != &init_net) 528 if (!net_eq(dev_net(net), &init_net))
485 return; 529 return;
486 530
487 device_del(dev); 531 device_del(dev);
@@ -500,15 +544,22 @@ int netdev_register_kobject(struct net_device *net)
500 dev_set_name(dev, "%s", net->name); 544 dev_set_name(dev, "%s", net->name);
501 545
502#ifdef CONFIG_SYSFS 546#ifdef CONFIG_SYSFS
503 *groups++ = &netstat_group; 547 /* Allow for a device specific group */
548 if (*groups)
549 groups++;
504 550
551 *groups++ = &netstat_group;
505#ifdef CONFIG_WIRELESS_EXT_SYSFS 552#ifdef CONFIG_WIRELESS_EXT_SYSFS
506 if (net->wireless_handlers || net->ieee80211_ptr) 553 if (net->ieee80211_ptr)
554 *groups++ = &wireless_group;
555#ifdef CONFIG_WIRELESS_EXT
556 else if (net->wireless_handlers)
507 *groups++ = &wireless_group; 557 *groups++ = &wireless_group;
508#endif 558#endif
559#endif
509#endif /* CONFIG_SYSFS */ 560#endif /* CONFIG_SYSFS */
510 561
511 if (dev_net(net) != &init_net) 562 if (!net_eq(dev_net(net), &init_net))
512 return 0; 563 return 0;
513 564
514 return device_add(dev); 565 return device_add(dev);