diff options
Diffstat (limited to 'net/wireless/sysfs.c')
| -rw-r--r-- | net/wireless/sysfs.c | 119 |
1 files changed, 104 insertions, 15 deletions
diff --git a/net/wireless/sysfs.c b/net/wireless/sysfs.c index 29f820e1825..9ee6bc1a761 100644 --- a/net/wireless/sysfs.c +++ b/net/wireless/sysfs.c @@ -16,6 +16,7 @@ #include <net/cfg80211.h> #include "sysfs.h" #include "core.h" +#include "rdev-ops.h" static inline struct cfg80211_registered_device *dev_to_rdev( struct device *dev) @@ -23,27 +24,54 @@ static inline struct cfg80211_registered_device *dev_to_rdev( return container_of(dev, struct cfg80211_registered_device, wiphy.dev); } -static ssize_t _show_index(struct device *dev, struct device_attribute *attr, - char *buf) -{ - return sprintf(buf, "%d\n", dev_to_rdev(dev)->idx); +#define SHOW_FMT(name, fmt, member) \ +static ssize_t name ## _show(struct device *dev, \ + struct device_attribute *attr, \ + char *buf) \ +{ \ + return sprintf(buf, fmt "\n", dev_to_rdev(dev)->member); \ +} \ +static DEVICE_ATTR_RO(name) + +SHOW_FMT(index, "%d", wiphy_idx); +SHOW_FMT(macaddress, "%pM", wiphy.perm_addr); +SHOW_FMT(address_mask, "%pM", wiphy.addr_mask); + +static ssize_t name_show(struct device *dev, + struct device_attribute *attr, + char *buf) { + struct wiphy *wiphy = &dev_to_rdev(dev)->wiphy; + return sprintf(buf, "%s\n", dev_name(&wiphy->dev)); } +static DEVICE_ATTR_RO(name); -static ssize_t _show_permaddr(struct device *dev, +static ssize_t addresses_show(struct device *dev, struct device_attribute *attr, char *buf) { - unsigned char *addr = dev_to_rdev(dev)->wiphy.perm_addr; + struct wiphy *wiphy = &dev_to_rdev(dev)->wiphy; + char *start = buf; + int i; + + if (!wiphy->addresses) + return sprintf(buf, "%pM\n", wiphy->perm_addr); - return sprintf(buf, "%.2x:%.2x:%.2x:%.2x:%.2x:%.2x\n", - addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]); + for (i = 0; i < wiphy->n_addresses; i++) + buf += sprintf(buf, "%pM\n", &wiphy->addresses[i].addr); + + return buf - start; } +static DEVICE_ATTR_RO(addresses); -static struct device_attribute ieee80211_dev_attrs[] = { - __ATTR(index, S_IRUGO, _show_index, NULL), - __ATTR(macaddress, S_IRUGO, _show_permaddr, NULL), - {} +static struct attribute *ieee80211_attrs[] = { + &dev_attr_index.attr, + &dev_attr_macaddress.attr, + &dev_attr_address_mask.attr, + &dev_attr_addresses.attr, + &dev_attr_name.attr, + NULL, }; +ATTRIBUTE_GROUPS(ieee80211); static void wiphy_dev_release(struct device *dev) { @@ -52,22 +80,83 @@ static void wiphy_dev_release(struct device *dev) cfg80211_dev_free(rdev); } -#ifdef CONFIG_HOTPLUG static int wiphy_uevent(struct device *dev, struct kobj_uevent_env *env) { /* TODO, we probably need stuff here */ return 0; } + +#ifdef CONFIG_PM +static void cfg80211_leave_all(struct cfg80211_registered_device *rdev) +{ + struct wireless_dev *wdev; + + list_for_each_entry(wdev, &rdev->wdev_list, list) + cfg80211_leave(rdev, wdev); +} + +static int wiphy_suspend(struct device *dev, pm_message_t state) +{ + struct cfg80211_registered_device *rdev = dev_to_rdev(dev); + int ret = 0; + + rdev->suspend_at = get_seconds(); + + rtnl_lock(); + if (rdev->wiphy.registered) { + if (!rdev->wiphy.wowlan_config) + cfg80211_leave_all(rdev); + if (rdev->ops->suspend) + ret = rdev_suspend(rdev, rdev->wiphy.wowlan_config); + if (ret == 1) { + /* Driver refuse to configure wowlan */ + cfg80211_leave_all(rdev); + ret = rdev_suspend(rdev, NULL); + } + } + rtnl_unlock(); + + return ret; +} + +static int wiphy_resume(struct device *dev) +{ + struct cfg80211_registered_device *rdev = dev_to_rdev(dev); + int ret = 0; + + /* Age scan results with time spent in suspend */ + cfg80211_bss_age(rdev, get_seconds() - rdev->suspend_at); + + if (rdev->ops->resume) { + rtnl_lock(); + if (rdev->wiphy.registered) + ret = rdev_resume(rdev); + rtnl_unlock(); + } + + return ret; +} #endif +static const void *wiphy_namespace(struct device *d) +{ + struct wiphy *wiphy = container_of(d, struct wiphy, dev); + + return wiphy_net(wiphy); +} + struct class ieee80211_class = { .name = "ieee80211", .owner = THIS_MODULE, .dev_release = wiphy_dev_release, - .dev_attrs = ieee80211_dev_attrs, -#ifdef CONFIG_HOTPLUG + .dev_groups = ieee80211_groups, .dev_uevent = wiphy_uevent, +#ifdef CONFIG_PM + .suspend = wiphy_suspend, + .resume = wiphy_resume, #endif + .ns_type = &net_ns_type_operations, + .namespace = wiphy_namespace, }; int wiphy_sysfs_init(void) |
