root/net/wireless/sysfs.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. dev_to_rdev
  2. name_show
  3. addresses_show
  4. wiphy_dev_release
  5. wiphy_uevent
  6. cfg80211_leave_all
  7. wiphy_suspend
  8. wiphy_resume
  9. wiphy_namespace
  10. wiphy_sysfs_init
  11. wiphy_sysfs_exit

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * This file provides /sys/class/ieee80211/<wiphy name>/
   4  * and some default attributes.
   5  *
   6  * Copyright 2005-2006  Jiri Benc <jbenc@suse.cz>
   7  * Copyright 2006       Johannes Berg <johannes@sipsolutions.net>
   8  */
   9 
  10 #include <linux/device.h>
  11 #include <linux/module.h>
  12 #include <linux/netdevice.h>
  13 #include <linux/nl80211.h>
  14 #include <linux/rtnetlink.h>
  15 #include <net/cfg80211.h>
  16 #include "sysfs.h"
  17 #include "core.h"
  18 #include "rdev-ops.h"
  19 
  20 static inline struct cfg80211_registered_device *dev_to_rdev(
  21         struct device *dev)
  22 {
  23         return container_of(dev, struct cfg80211_registered_device, wiphy.dev);
  24 }
  25 
  26 #define SHOW_FMT(name, fmt, member)                                     \
  27 static ssize_t name ## _show(struct device *dev,                        \
  28                               struct device_attribute *attr,            \
  29                               char *buf)                                \
  30 {                                                                       \
  31         return sprintf(buf, fmt "\n", dev_to_rdev(dev)->member);        \
  32 }                                                                       \
  33 static DEVICE_ATTR_RO(name)
  34 
  35 SHOW_FMT(index, "%d", wiphy_idx);
  36 SHOW_FMT(macaddress, "%pM", wiphy.perm_addr);
  37 SHOW_FMT(address_mask, "%pM", wiphy.addr_mask);
  38 
  39 static ssize_t name_show(struct device *dev,
  40                          struct device_attribute *attr,
  41                          char *buf)
  42 {
  43         struct wiphy *wiphy = &dev_to_rdev(dev)->wiphy;
  44 
  45         return sprintf(buf, "%s\n", wiphy_name(wiphy));
  46 }
  47 static DEVICE_ATTR_RO(name);
  48 
  49 static ssize_t addresses_show(struct device *dev,
  50                               struct device_attribute *attr,
  51                               char *buf)
  52 {
  53         struct wiphy *wiphy = &dev_to_rdev(dev)->wiphy;
  54         char *start = buf;
  55         int i;
  56 
  57         if (!wiphy->addresses)
  58                 return sprintf(buf, "%pM\n", wiphy->perm_addr);
  59 
  60         for (i = 0; i < wiphy->n_addresses; i++)
  61                 buf += sprintf(buf, "%pM\n", wiphy->addresses[i].addr);
  62 
  63         return buf - start;
  64 }
  65 static DEVICE_ATTR_RO(addresses);
  66 
  67 static struct attribute *ieee80211_attrs[] = {
  68         &dev_attr_index.attr,
  69         &dev_attr_macaddress.attr,
  70         &dev_attr_address_mask.attr,
  71         &dev_attr_addresses.attr,
  72         &dev_attr_name.attr,
  73         NULL,
  74 };
  75 ATTRIBUTE_GROUPS(ieee80211);
  76 
  77 static void wiphy_dev_release(struct device *dev)
  78 {
  79         struct cfg80211_registered_device *rdev = dev_to_rdev(dev);
  80 
  81         cfg80211_dev_free(rdev);
  82 }
  83 
  84 static int wiphy_uevent(struct device *dev, struct kobj_uevent_env *env)
  85 {
  86         /* TODO, we probably need stuff here */
  87         return 0;
  88 }
  89 
  90 #ifdef CONFIG_PM_SLEEP
  91 static void cfg80211_leave_all(struct cfg80211_registered_device *rdev)
  92 {
  93         struct wireless_dev *wdev;
  94 
  95         list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list)
  96                 cfg80211_leave(rdev, wdev);
  97 }
  98 
  99 static int wiphy_suspend(struct device *dev)
 100 {
 101         struct cfg80211_registered_device *rdev = dev_to_rdev(dev);
 102         int ret = 0;
 103 
 104         rdev->suspend_at = ktime_get_boottime_seconds();
 105 
 106         rtnl_lock();
 107         if (rdev->wiphy.registered) {
 108                 if (!rdev->wiphy.wowlan_config) {
 109                         cfg80211_leave_all(rdev);
 110                         cfg80211_process_rdev_events(rdev);
 111                 }
 112                 if (rdev->ops->suspend)
 113                         ret = rdev_suspend(rdev, rdev->wiphy.wowlan_config);
 114                 if (ret == 1) {
 115                         /* Driver refuse to configure wowlan */
 116                         cfg80211_leave_all(rdev);
 117                         cfg80211_process_rdev_events(rdev);
 118                         ret = rdev_suspend(rdev, NULL);
 119                 }
 120         }
 121         rtnl_unlock();
 122 
 123         return ret;
 124 }
 125 
 126 static int wiphy_resume(struct device *dev)
 127 {
 128         struct cfg80211_registered_device *rdev = dev_to_rdev(dev);
 129         int ret = 0;
 130 
 131         /* Age scan results with time spent in suspend */
 132         cfg80211_bss_age(rdev, ktime_get_boottime_seconds() - rdev->suspend_at);
 133 
 134         rtnl_lock();
 135         if (rdev->wiphy.registered && rdev->ops->resume)
 136                 ret = rdev_resume(rdev);
 137         rtnl_unlock();
 138 
 139         return ret;
 140 }
 141 
 142 static SIMPLE_DEV_PM_OPS(wiphy_pm_ops, wiphy_suspend, wiphy_resume);
 143 #define WIPHY_PM_OPS (&wiphy_pm_ops)
 144 #else
 145 #define WIPHY_PM_OPS NULL
 146 #endif
 147 
 148 static const void *wiphy_namespace(struct device *d)
 149 {
 150         struct wiphy *wiphy = container_of(d, struct wiphy, dev);
 151 
 152         return wiphy_net(wiphy);
 153 }
 154 
 155 struct class ieee80211_class = {
 156         .name = "ieee80211",
 157         .owner = THIS_MODULE,
 158         .dev_release = wiphy_dev_release,
 159         .dev_groups = ieee80211_groups,
 160         .dev_uevent = wiphy_uevent,
 161         .pm = WIPHY_PM_OPS,
 162         .ns_type = &net_ns_type_operations,
 163         .namespace = wiphy_namespace,
 164 };
 165 
 166 int wiphy_sysfs_init(void)
 167 {
 168         return class_register(&ieee80211_class);
 169 }
 170 
 171 void wiphy_sysfs_exit(void)
 172 {
 173         class_unregister(&ieee80211_class);
 174 }

/* [<][>][^][v][top][bottom][index][help] */