~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/net/ieee802154/wpan-class.c

Version: ~ [ linux-5.11-rc3 ] ~ [ linux-5.10.7 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.89 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.167 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.215 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.251 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.251 ] ~ [ linux-4.3.6 ] ~ [ linux-4.2.8 ] ~ [ linux-4.1.52 ] ~ [ linux-4.0.9 ] ~ [ linux-3.19.8 ] ~ [ linux-3.18.140 ] ~ [ linux-3.17.8 ] ~ [ linux-3.16.85 ] ~ [ linux-3.15.10 ] ~ [ linux-3.14.79 ] ~ [ linux-3.13.11 ] ~ [ linux-3.12.74 ] ~ [ linux-3.11.10 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.5 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /*
  2  * Copyright (C) 2007, 2008, 2009 Siemens AG
  3  *
  4  * This program is free software; you can redistribute it and/or modify
  5  * it under the terms of the GNU General Public License version 2
  6  * as published by the Free Software Foundation.
  7  *
  8  * This program is distributed in the hope that it will be useful,
  9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
 10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 11  * GNU General Public License for more details.
 12  *
 13  * You should have received a copy of the GNU General Public License along
 14  * with this program; if not, write to the Free Software Foundation, Inc.,
 15  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 16  *
 17  */
 18 
 19 #include <linux/slab.h>
 20 #include <linux/kernel.h>
 21 #include <linux/module.h>
 22 #include <linux/device.h>
 23 
 24 #include <net/wpan-phy.h>
 25 
 26 #include "ieee802154.h"
 27 
 28 #define MASTER_SHOW_COMPLEX(name, format_string, args...)               \
 29 static ssize_t name ## _show(struct device *dev,                        \
 30                             struct device_attribute *attr, char *buf)   \
 31 {                                                                       \
 32         struct wpan_phy *phy = container_of(dev, struct wpan_phy, dev); \
 33         int ret;                                                        \
 34                                                                         \
 35         mutex_lock(&phy->pib_lock);                                     \
 36         ret = snprintf(buf, PAGE_SIZE, format_string "\n", args);       \
 37         mutex_unlock(&phy->pib_lock);                                   \
 38         return ret;                                                     \
 39 }
 40 
 41 #define MASTER_SHOW(field, format_string)                               \
 42         MASTER_SHOW_COMPLEX(field, format_string, phy->field)
 43 
 44 MASTER_SHOW(current_channel, "%d");
 45 MASTER_SHOW(current_page, "%d");
 46 MASTER_SHOW_COMPLEX(transmit_power, "%d +- %d dB",
 47         ((signed char) (phy->transmit_power << 2)) >> 2,
 48         (phy->transmit_power >> 6) ? (phy->transmit_power >> 6) * 3 : 1 );
 49 MASTER_SHOW(cca_mode, "%d");
 50 
 51 static ssize_t channels_supported_show(struct device *dev,
 52                             struct device_attribute *attr, char *buf)
 53 {
 54         struct wpan_phy *phy = container_of(dev, struct wpan_phy, dev);
 55         int ret;
 56         int i, len = 0;
 57 
 58         mutex_lock(&phy->pib_lock);
 59         for (i = 0; i < 32; i++) {
 60                 ret = snprintf(buf + len, PAGE_SIZE - len,
 61                                 "%#09x\n", phy->channels_supported[i]);
 62                 if (ret < 0)
 63                         break;
 64                 len += ret;
 65         }
 66         mutex_unlock(&phy->pib_lock);
 67         return len;
 68 }
 69 
 70 static struct device_attribute pmib_attrs[] = {
 71         __ATTR_RO(current_channel),
 72         __ATTR_RO(current_page),
 73         __ATTR_RO(channels_supported),
 74         __ATTR_RO(transmit_power),
 75         __ATTR_RO(cca_mode),
 76         {},
 77 };
 78 
 79 static void wpan_phy_release(struct device *d)
 80 {
 81         struct wpan_phy *phy = container_of(d, struct wpan_phy, dev);
 82         kfree(phy);
 83 }
 84 
 85 static struct class wpan_phy_class = {
 86         .name = "ieee802154",
 87         .dev_release = wpan_phy_release,
 88         .dev_attrs = pmib_attrs,
 89 };
 90 
 91 static DEFINE_MUTEX(wpan_phy_mutex);
 92 static int wpan_phy_idx;
 93 
 94 static int wpan_phy_match(struct device *dev, const void *data)
 95 {
 96         return !strcmp(dev_name(dev), (const char *)data);
 97 }
 98 
 99 struct wpan_phy *wpan_phy_find(const char *str)
100 {
101         struct device *dev;
102 
103         if (WARN_ON(!str))
104                 return NULL;
105 
106         dev = class_find_device(&wpan_phy_class, NULL, str, wpan_phy_match);
107         if (!dev)
108                 return NULL;
109 
110         return container_of(dev, struct wpan_phy, dev);
111 }
112 EXPORT_SYMBOL(wpan_phy_find);
113 
114 struct wpan_phy_iter_data {
115         int (*fn)(struct wpan_phy *phy, void *data);
116         void *data;
117 };
118 
119 static int wpan_phy_iter(struct device *dev, void *_data)
120 {
121         struct wpan_phy_iter_data *wpid = _data;
122         struct wpan_phy *phy = container_of(dev, struct wpan_phy, dev);
123         return wpid->fn(phy, wpid->data);
124 }
125 
126 int wpan_phy_for_each(int (*fn)(struct wpan_phy *phy, void *data),
127                 void *data)
128 {
129         struct wpan_phy_iter_data wpid = {
130                 .fn = fn,
131                 .data = data,
132         };
133 
134         return class_for_each_device(&wpan_phy_class, NULL,
135                         &wpid, wpan_phy_iter);
136 }
137 EXPORT_SYMBOL(wpan_phy_for_each);
138 
139 static int wpan_phy_idx_valid(int idx)
140 {
141         return idx >= 0;
142 }
143 
144 struct wpan_phy *wpan_phy_alloc(size_t priv_size)
145 {
146         struct wpan_phy *phy = kzalloc(sizeof(*phy) + priv_size,
147                         GFP_KERNEL);
148 
149         if (!phy)
150                 goto out;
151         mutex_lock(&wpan_phy_mutex);
152         phy->idx = wpan_phy_idx++;
153         if (unlikely(!wpan_phy_idx_valid(phy->idx))) {
154                 wpan_phy_idx--;
155                 mutex_unlock(&wpan_phy_mutex);
156                 kfree(phy);
157                 goto out;
158         }
159         mutex_unlock(&wpan_phy_mutex);
160 
161         mutex_init(&phy->pib_lock);
162 
163         device_initialize(&phy->dev);
164         dev_set_name(&phy->dev, "wpan-phy%d", phy->idx);
165 
166         phy->dev.class = &wpan_phy_class;
167 
168         phy->current_channel = -1; /* not initialised */
169         phy->current_page = 0; /* for compatibility */
170 
171         return phy;
172 
173 out:
174         return NULL;
175 }
176 EXPORT_SYMBOL(wpan_phy_alloc);
177 
178 int wpan_phy_register(struct wpan_phy *phy)
179 {
180         return device_add(&phy->dev);
181 }
182 EXPORT_SYMBOL(wpan_phy_register);
183 
184 void wpan_phy_unregister(struct wpan_phy *phy)
185 {
186         device_del(&phy->dev);
187 }
188 EXPORT_SYMBOL(wpan_phy_unregister);
189 
190 void wpan_phy_free(struct wpan_phy *phy)
191 {
192         put_device(&phy->dev);
193 }
194 EXPORT_SYMBOL(wpan_phy_free);
195 
196 static int __init wpan_phy_class_init(void)
197 {
198         int rc;
199         rc = class_register(&wpan_phy_class);
200         if (rc)
201                 goto err;
202 
203         rc = ieee802154_nl_init();
204         if (rc)
205                 goto err_nl;
206 
207         return 0;
208 err_nl:
209         class_unregister(&wpan_phy_class);
210 err:
211         return rc;
212 }
213 subsys_initcall(wpan_phy_class_init);
214 
215 static void __exit wpan_phy_class_exit(void)
216 {
217         ieee802154_nl_exit();
218         class_unregister(&wpan_phy_class);
219 }
220 module_exit(wpan_phy_class_exit);
221 
222 MODULE_LICENSE("GPL v2");
223 MODULE_DESCRIPTION("IEEE 802.15.4 configuration interface");
224 MODULE_AUTHOR("Dmitry Eremin-Solenikov");
225 
226 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | Wiki (Japanese) | Wiki (English) | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

osdn.jp