source: src/linux/universal/linux-4.9/net/wireless/sysfs.c @ 31859

Last change on this file since 31859 was 31859, checked in by brainslayer, 11 days ago

kernel update

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