Linux Audio

Check our new training course

Loading...
v3.1
 
  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
 20static 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)					\
 27static 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
 34SHOW_FMT(index, "%d", wiphy_idx);
 35SHOW_FMT(macaddress, "%pM", wiphy.perm_addr);
 36SHOW_FMT(address_mask, "%pM", wiphy.addr_mask);
 37
 38static ssize_t name_show(struct device *dev,
 39			 struct device_attribute *attr,
 40			 char *buf) {
 
 41	struct wiphy *wiphy = &dev_to_rdev(dev)->wiphy;
 42	return sprintf(buf, "%s\n", dev_name(&wiphy->dev));
 43}
 44
 
 
 
 45
 46static ssize_t addresses_show(struct device *dev,
 47			      struct device_attribute *attr,
 48			      char *buf)
 49{
 50	struct wiphy *wiphy = &dev_to_rdev(dev)->wiphy;
 51	char *start = buf;
 52	int i;
 53
 54	if (!wiphy->addresses)
 55		return sprintf(buf, "%pM\n", wiphy->perm_addr);
 56
 57	for (i = 0; i < wiphy->n_addresses; i++)
 58		buf += sprintf(buf, "%pM\n", &wiphy->addresses[i].addr);
 59
 60	return buf - start;
 61}
 
 62
 63static struct device_attribute ieee80211_dev_attrs[] = {
 64	__ATTR_RO(index),
 65	__ATTR_RO(macaddress),
 66	__ATTR_RO(address_mask),
 67	__ATTR_RO(addresses),
 68	__ATTR_RO(name),
 69	{}
 70};
 
 71
 72static void wiphy_dev_release(struct device *dev)
 73{
 74	struct cfg80211_registered_device *rdev = dev_to_rdev(dev);
 75
 76	cfg80211_dev_free(rdev);
 77}
 78
 79#ifdef CONFIG_HOTPLUG
 80static int wiphy_uevent(struct device *dev, struct kobj_uevent_env *env)
 81{
 82	/* TODO, we probably need stuff here */
 83	return 0;
 84}
 85#endif
 86
 87static int wiphy_suspend(struct device *dev, pm_message_t state)
 
 
 
 
 
 
 
 
 
 88{
 89	struct cfg80211_registered_device *rdev = dev_to_rdev(dev);
 90	int ret = 0;
 91
 92	rdev->suspend_at = get_seconds();
 93
 94	if (rdev->ops->suspend) {
 95		rtnl_lock();
 96		if (rdev->wiphy.registered)
 97			ret = rdev->ops->suspend(&rdev->wiphy, rdev->wowlan);
 98		rtnl_unlock();
 
 
 
 
 
 
 
 
 
 99	}
 
100
101	return ret;
102}
103
104static int wiphy_resume(struct device *dev)
105{
106	struct cfg80211_registered_device *rdev = dev_to_rdev(dev);
107	int ret = 0;
108
109	/* Age scan results with time spent in suspend */
110	spin_lock_bh(&rdev->bss_lock);
111	cfg80211_bss_age(rdev, get_seconds() - rdev->suspend_at);
112	spin_unlock_bh(&rdev->bss_lock);
113
114	if (rdev->ops->resume) {
115		rtnl_lock();
116		if (rdev->wiphy.registered)
117			ret = rdev->ops->resume(&rdev->wiphy);
118		rtnl_unlock();
119	}
120
121	return ret;
122}
123
 
 
 
 
 
 
124static const void *wiphy_namespace(struct device *d)
125{
126	struct wiphy *wiphy = container_of(d, struct wiphy, dev);
127
128	return wiphy_net(wiphy);
129}
130
131struct class ieee80211_class = {
132	.name = "ieee80211",
133	.owner = THIS_MODULE,
134	.dev_release = wiphy_dev_release,
135	.dev_attrs = ieee80211_dev_attrs,
136#ifdef CONFIG_HOTPLUG
137	.dev_uevent = wiphy_uevent,
138#endif
139	.suspend = wiphy_suspend,
140	.resume = wiphy_resume,
141	.ns_type = &net_ns_type_operations,
142	.namespace = wiphy_namespace,
143};
144
145int wiphy_sysfs_init(void)
146{
147	return class_register(&ieee80211_class);
148}
149
150void wiphy_sysfs_exit(void)
151{
152	class_unregister(&ieee80211_class);
153}
v5.4
  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
 20static 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)					\
 27static 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}									\
 33static DEVICE_ATTR_RO(name)
 34
 35SHOW_FMT(index, "%d", wiphy_idx);
 36SHOW_FMT(macaddress, "%pM", wiphy.perm_addr);
 37SHOW_FMT(address_mask, "%pM", wiphy.addr_mask);
 38
 39static 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}
 47static DEVICE_ATTR_RO(name);
 48
 49static 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}
 65static DEVICE_ATTR_RO(addresses);
 66
 67static 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};
 75ATTRIBUTE_GROUPS(ieee80211);
 76
 77static 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
 
 84static 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
 91static 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
 99static 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
126static 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
142static 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
148static 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
155struct 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
166int wiphy_sysfs_init(void)
167{
168	return class_register(&ieee80211_class);
169}
170
171void wiphy_sysfs_exit(void)
172{
173	class_unregister(&ieee80211_class);
174}