[PATCH] (4/4) add wireless statistics to sysfs
From: Stephen Hemminger <hidden>
Date: 2003-08-15 22:38:04
Add wireless statistics to /net/class/ethXX/wireless. diff -Nru a/net/core/net-sysfs.c b/net/core/net-sysfs.c
--- a/net/core/net-sysfs.c Fri Aug 15 15:25:00 2003
+++ b/net/core/net-sysfs.c Fri Aug 15 15:25:00 2003@@ -15,6 +15,7 @@ #include <linux/if_arp.h> #include <net/sock.h> #include <linux/rtnetlink.h> +#include <linux/wireless.h> #define to_class_dev(obj) container_of(obj,struct class_device,kobj) #define to_net_dev(class) container_of(class, struct net_device, class_dev)
@@ -276,6 +277,67 @@ .attrs = netstat_attrs, }; +#ifdef WIRELESS_EXT +/* helper function that does all the locking etc for wireless stats */ +static ssize_t wireless_show(struct class_device *cd, char *buf, + ssize_t (*format)(const struct iw_statistics *, + char *)) +{ + struct net_device *dev = to_net_dev(cd); + const struct iw_statistics *iw; + ssize_t ret = -EINVAL; + + read_lock(&dev_base_lock); + if (dev_isalive(dev) && dev->get_wireless_stats + && (iw = dev->get_wireless_stats(dev)) != NULL) + ret = (*format)(iw, buf); + read_unlock(&dev_base_lock); + + return ret; +} + +/* show function template for wireless fields */ +#define WIRELESS_SHOW(name, field, format_string) \ +static ssize_t format_iw_##name(const struct iw_statistics *iw, char *buf) \ +{ \ + return sprintf(buf, format_string, iw->field); \ +} \ +static ssize_t show_iw_##name(struct class_device *cd, char *buf) \ +{ \ + return wireless_show(cd, buf, format_iw_##name); \ +} \ +static CLASS_DEVICE_ATTR(name, S_IRUGO, show_iw_##name, NULL) + +WIRELESS_SHOW(status, status, fmt_hex); +WIRELESS_SHOW(link, qual.qual, fmt_dec); +WIRELESS_SHOW(level, qual.level, fmt_dec); +WIRELESS_SHOW(noise, qual.noise, fmt_dec); +WIRELESS_SHOW(nwid, discard.nwid, fmt_dec); +WIRELESS_SHOW(crypt, discard.code, fmt_dec); +WIRELESS_SHOW(fragment, discard.fragment, fmt_dec); +WIRELESS_SHOW(misc, discard.misc, fmt_dec); +WIRELESS_SHOW(retries, discard.retries, fmt_dec); +WIRELESS_SHOW(beacon, miss.beacon, fmt_dec); + +static struct attribute *wireless_attrs[] = { + &class_device_attr_status.attr, + &class_device_attr_link.attr, + &class_device_attr_level.attr, + &class_device_attr_noise.attr, + &class_device_attr_nwid.attr, + &class_device_attr_crypt.attr, + &class_device_attr_fragment.attr, + &class_device_attr_retries.attr, + &class_device_attr_misc.attr, + &class_device_attr_beacon.attr, + NULL +}; + +static struct attribute_group wireless_group = { + .name = "wireless", + .attrs = wireless_attrs, +}; +#endif #ifdef CONFIG_HOTPLUG static int netdev_hotplug(struct class_device *cd, char **envp,
@@ -331,6 +393,11 @@ (ret = sysfs_create_group(&class_dev->kobj, &netstat_group))) goto out_unreg; +#ifdef WIRELESS_EXT + if (net->get_wireless_stats && + (ret = sysfs_create_group(&class_dev->kobj, &wireless_group))) + goto out_unreg; +#endif return 0; out_unreg: