blob: dea265873cbc6f7d843c5758ecb48be8ddb2e473 [file] [log] [blame]
Inaky Perez-Gonzalez183b9b52008-09-17 16:34:06 +01001/*
2 * Ultra Wide Band
3 * Life cycle of devices
4 *
5 * Copyright (C) 2005-2006 Intel Corporation
6 * Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com>
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License version
10 * 2 as published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
20 * 02110-1301, USA.
21 *
22 *
23 * FIXME: docs
24 */
Inaky Perez-Gonzalez183b9b52008-09-17 16:34:06 +010025#include <linux/kernel.h>
Tejun Heo5a0e3ad2010-03-24 17:04:11 +090026#include <linux/slab.h>
Inaky Perez-Gonzalez183b9b52008-09-17 16:34:06 +010027#include <linux/device.h>
28#include <linux/err.h>
29#include <linux/kdev_t.h>
30#include <linux/random.h>
Paul Gortmaker0b992082011-07-17 16:50:39 -040031#include <linux/stat.h>
Inaky Perez-Gonzalez183b9b52008-09-17 16:34:06 +010032#include "uwb-internal.h"
33
Inaky Perez-Gonzalez183b9b52008-09-17 16:34:06 +010034/* We initialize addresses to 0xff (invalid, as it is bcast) */
35static inline void uwb_dev_addr_init(struct uwb_dev_addr *addr)
36{
37 memset(&addr->data, 0xff, sizeof(addr->data));
38}
39
40static inline void uwb_mac_addr_init(struct uwb_mac_addr *addr)
41{
42 memset(&addr->data, 0xff, sizeof(addr->data));
43}
44
45/* @returns !0 if a device @addr is a broadcast address */
46static inline int uwb_dev_addr_bcast(const struct uwb_dev_addr *addr)
47{
48 static const struct uwb_dev_addr bcast = { .data = { 0xff, 0xff } };
49 return !uwb_dev_addr_cmp(addr, &bcast);
50}
51
52/*
53 * Add callback @new to be called when an event occurs in @rc.
54 */
55int uwb_notifs_register(struct uwb_rc *rc, struct uwb_notifs_handler *new)
56{
57 if (mutex_lock_interruptible(&rc->notifs_chain.mutex))
58 return -ERESTARTSYS;
59 list_add(&new->list_node, &rc->notifs_chain.list);
60 mutex_unlock(&rc->notifs_chain.mutex);
61 return 0;
62}
63EXPORT_SYMBOL_GPL(uwb_notifs_register);
64
65/*
66 * Remove event handler (callback)
67 */
68int uwb_notifs_deregister(struct uwb_rc *rc, struct uwb_notifs_handler *entry)
69{
70 if (mutex_lock_interruptible(&rc->notifs_chain.mutex))
71 return -ERESTARTSYS;
72 list_del(&entry->list_node);
73 mutex_unlock(&rc->notifs_chain.mutex);
74 return 0;
75}
76EXPORT_SYMBOL_GPL(uwb_notifs_deregister);
77
78/*
79 * Notify all event handlers of a given event on @rc
80 *
81 * We are called with a valid reference to the device, or NULL if the
82 * event is not for a particular event (e.g., a BG join event).
83 */
84void uwb_notify(struct uwb_rc *rc, struct uwb_dev *uwb_dev, enum uwb_notifs event)
85{
86 struct uwb_notifs_handler *handler;
87 if (mutex_lock_interruptible(&rc->notifs_chain.mutex))
88 return;
89 if (!list_empty(&rc->notifs_chain.list)) {
90 list_for_each_entry(handler, &rc->notifs_chain.list, list_node) {
91 handler->cb(handler->data, uwb_dev, event);
92 }
93 }
94 mutex_unlock(&rc->notifs_chain.mutex);
95}
96
97/*
98 * Release the backing device of a uwb_dev that has been dynamically allocated.
99 */
100static void uwb_dev_sys_release(struct device *dev)
101{
102 struct uwb_dev *uwb_dev = to_uwb_dev(dev);
103
Inaky Perez-Gonzalez183b9b52008-09-17 16:34:06 +0100104 uwb_bce_put(uwb_dev->bce);
Inaky Perez-Gonzalez183b9b52008-09-17 16:34:06 +0100105 memset(uwb_dev, 0x69, sizeof(*uwb_dev));
106 kfree(uwb_dev);
Inaky Perez-Gonzalez183b9b52008-09-17 16:34:06 +0100107}
108
109/*
110 * Initialize a UWB device instance
111 *
112 * Alloc, zero and call this function.
113 */
114void uwb_dev_init(struct uwb_dev *uwb_dev)
115{
116 mutex_init(&uwb_dev->mutex);
117 device_initialize(&uwb_dev->dev);
118 uwb_dev->dev.release = uwb_dev_sys_release;
119 uwb_dev_addr_init(&uwb_dev->dev_addr);
120 uwb_mac_addr_init(&uwb_dev->mac_addr);
121 bitmap_fill(uwb_dev->streams, UWB_NUM_GLOBAL_STREAMS);
122}
123
124static ssize_t uwb_dev_EUI_48_show(struct device *dev,
125 struct device_attribute *attr, char *buf)
126{
127 struct uwb_dev *uwb_dev = to_uwb_dev(dev);
128 char addr[UWB_ADDR_STRSIZE];
129
130 uwb_mac_addr_print(addr, sizeof(addr), &uwb_dev->mac_addr);
131 return sprintf(buf, "%s\n", addr);
132}
133static DEVICE_ATTR(EUI_48, S_IRUGO, uwb_dev_EUI_48_show, NULL);
134
135static ssize_t uwb_dev_DevAddr_show(struct device *dev,
136 struct device_attribute *attr, char *buf)
137{
138 struct uwb_dev *uwb_dev = to_uwb_dev(dev);
139 char addr[UWB_ADDR_STRSIZE];
140
141 uwb_dev_addr_print(addr, sizeof(addr), &uwb_dev->dev_addr);
142 return sprintf(buf, "%s\n", addr);
143}
144static DEVICE_ATTR(DevAddr, S_IRUGO, uwb_dev_DevAddr_show, NULL);
145
146/*
147 * Show the BPST of this device.
148 *
149 * Calculated from the receive time of the device's beacon and it's
150 * slot number.
151 */
152static ssize_t uwb_dev_BPST_show(struct device *dev,
153 struct device_attribute *attr, char *buf)
154{
155 struct uwb_dev *uwb_dev = to_uwb_dev(dev);
156 struct uwb_beca_e *bce;
157 struct uwb_beacon_frame *bf;
158 u16 bpst;
159
160 bce = uwb_dev->bce;
161 mutex_lock(&bce->mutex);
162 bf = (struct uwb_beacon_frame *)bce->be->BeaconInfo;
163 bpst = bce->be->wBPSTOffset
164 - (u16)(bf->Beacon_Slot_Number * UWB_BEACON_SLOT_LENGTH_US);
165 mutex_unlock(&bce->mutex);
166
167 return sprintf(buf, "%d\n", bpst);
168}
169static DEVICE_ATTR(BPST, S_IRUGO, uwb_dev_BPST_show, NULL);
170
171/*
172 * Show the IEs a device is beaconing
173 *
174 * We need to access the beacon cache, so we just lock it really
175 * quick, print the IEs and unlock.
176 *
177 * We have a reference on the cache entry, so that should be
178 * quite safe.
179 */
180static ssize_t uwb_dev_IEs_show(struct device *dev,
181 struct device_attribute *attr, char *buf)
182{
183 struct uwb_dev *uwb_dev = to_uwb_dev(dev);
184
185 return uwb_bce_print_IEs(uwb_dev, uwb_dev->bce, buf, PAGE_SIZE);
186}
187static DEVICE_ATTR(IEs, S_IRUGO | S_IWUSR, uwb_dev_IEs_show, NULL);
188
189static ssize_t uwb_dev_LQE_show(struct device *dev,
190 struct device_attribute *attr, char *buf)
191{
192 struct uwb_dev *uwb_dev = to_uwb_dev(dev);
193 struct uwb_beca_e *bce = uwb_dev->bce;
194 size_t result;
195
196 mutex_lock(&bce->mutex);
197 result = stats_show(&uwb_dev->bce->lqe_stats, buf);
198 mutex_unlock(&bce->mutex);
199 return result;
200}
201
202static ssize_t uwb_dev_LQE_store(struct device *dev,
203 struct device_attribute *attr,
204 const char *buf, size_t size)
205{
206 struct uwb_dev *uwb_dev = to_uwb_dev(dev);
207 struct uwb_beca_e *bce = uwb_dev->bce;
208 ssize_t result;
209
210 mutex_lock(&bce->mutex);
211 result = stats_store(&uwb_dev->bce->lqe_stats, buf, size);
212 mutex_unlock(&bce->mutex);
213 return result;
214}
215static DEVICE_ATTR(LQE, S_IRUGO | S_IWUSR, uwb_dev_LQE_show, uwb_dev_LQE_store);
216
217static ssize_t uwb_dev_RSSI_show(struct device *dev,
218 struct device_attribute *attr, char *buf)
219{
220 struct uwb_dev *uwb_dev = to_uwb_dev(dev);
221 struct uwb_beca_e *bce = uwb_dev->bce;
222 size_t result;
223
224 mutex_lock(&bce->mutex);
225 result = stats_show(&uwb_dev->bce->rssi_stats, buf);
226 mutex_unlock(&bce->mutex);
227 return result;
228}
229
230static ssize_t uwb_dev_RSSI_store(struct device *dev,
231 struct device_attribute *attr,
232 const char *buf, size_t size)
233{
234 struct uwb_dev *uwb_dev = to_uwb_dev(dev);
235 struct uwb_beca_e *bce = uwb_dev->bce;
236 ssize_t result;
237
238 mutex_lock(&bce->mutex);
239 result = stats_store(&uwb_dev->bce->rssi_stats, buf, size);
240 mutex_unlock(&bce->mutex);
241 return result;
242}
243static DEVICE_ATTR(RSSI, S_IRUGO | S_IWUSR, uwb_dev_RSSI_show, uwb_dev_RSSI_store);
244
245
246static struct attribute *dev_attrs[] = {
247 &dev_attr_EUI_48.attr,
248 &dev_attr_DevAddr.attr,
249 &dev_attr_BPST.attr,
250 &dev_attr_IEs.attr,
251 &dev_attr_LQE.attr,
252 &dev_attr_RSSI.attr,
253 NULL,
254};
255
256static struct attribute_group dev_attr_group = {
257 .attrs = dev_attrs,
258};
259
David Brownella4dbd672009-06-24 10:06:31 -0700260static const struct attribute_group *groups[] = {
Inaky Perez-Gonzalez183b9b52008-09-17 16:34:06 +0100261 &dev_attr_group,
262 NULL,
263};
264
265/**
266 * Device SYSFS registration
267 *
268 *
269 */
270static int __uwb_dev_sys_add(struct uwb_dev *uwb_dev, struct device *parent_dev)
271{
Inaky Perez-Gonzalez183b9b52008-09-17 16:34:06 +0100272 struct device *dev;
273
Inaky Perez-Gonzalez183b9b52008-09-17 16:34:06 +0100274 dev = &uwb_dev->dev;
275 /* Device sysfs files are only useful for neighbor devices not
276 local radio controllers. */
277 if (&uwb_dev->rc->uwb_dev != uwb_dev)
278 dev->groups = groups;
279 dev->parent = parent_dev;
280 dev_set_drvdata(dev, uwb_dev);
281
David Vrabelbce83692008-12-22 18:22:50 +0000282 return device_add(dev);
Inaky Perez-Gonzalez183b9b52008-09-17 16:34:06 +0100283}
284
285
286static void __uwb_dev_sys_rm(struct uwb_dev *uwb_dev)
287{
Inaky Perez-Gonzalez183b9b52008-09-17 16:34:06 +0100288 dev_set_drvdata(&uwb_dev->dev, NULL);
289 device_del(&uwb_dev->dev);
Inaky Perez-Gonzalez183b9b52008-09-17 16:34:06 +0100290}
291
292
293/**
294 * Register and initialize a new UWB device
295 *
296 * Did you call uwb_dev_init() on it?
297 *
298 * @parent_rc: is the parent radio controller who has the link to the
299 * device. When registering the UWB device that is a UWB
300 * Radio Controller, we point back to it.
301 *
302 * If registering the device that is part of a radio, caller has set
303 * rc->uwb_dev->dev. Otherwise it is to be left NULL--a new one will
304 * be allocated.
305 */
306int uwb_dev_add(struct uwb_dev *uwb_dev, struct device *parent_dev,
307 struct uwb_rc *parent_rc)
308{
309 int result;
310 struct device *dev;
311
312 BUG_ON(uwb_dev == NULL);
313 BUG_ON(parent_dev == NULL);
314 BUG_ON(parent_rc == NULL);
315
316 mutex_lock(&uwb_dev->mutex);
317 dev = &uwb_dev->dev;
318 uwb_dev->rc = parent_rc;
319 result = __uwb_dev_sys_add(uwb_dev, parent_dev);
320 if (result < 0)
321 printk(KERN_ERR "UWB: unable to register dev %s with sysfs: %d\n",
322 dev_name(dev), result);
323 mutex_unlock(&uwb_dev->mutex);
324 return result;
325}
326
327
328void uwb_dev_rm(struct uwb_dev *uwb_dev)
329{
330 mutex_lock(&uwb_dev->mutex);
331 __uwb_dev_sys_rm(uwb_dev);
332 mutex_unlock(&uwb_dev->mutex);
333}
334
335
336static
337int __uwb_dev_try_get(struct device *dev, void *__target_uwb_dev)
338{
339 struct uwb_dev *target_uwb_dev = __target_uwb_dev;
340 struct uwb_dev *uwb_dev = to_uwb_dev(dev);
341 if (uwb_dev == target_uwb_dev) {
342 uwb_dev_get(uwb_dev);
343 return 1;
344 } else
345 return 0;
346}
347
348
349/**
350 * Given a UWB device descriptor, validate and refcount it
351 *
352 * @returns NULL if the device does not exist or is quiescing; the ptr to
353 * it otherwise.
354 */
355struct uwb_dev *uwb_dev_try_get(struct uwb_rc *rc, struct uwb_dev *uwb_dev)
356{
357 if (uwb_dev_for_each(rc, __uwb_dev_try_get, uwb_dev))
358 return uwb_dev;
359 else
360 return NULL;
361}
362EXPORT_SYMBOL_GPL(uwb_dev_try_get);
363
364
365/**
366 * Remove a device from the system [grunt for other functions]
367 */
368int __uwb_dev_offair(struct uwb_dev *uwb_dev, struct uwb_rc *rc)
369{
370 struct device *dev = &uwb_dev->dev;
371 char macbuf[UWB_ADDR_STRSIZE], devbuf[UWB_ADDR_STRSIZE];
372
Inaky Perez-Gonzalez183b9b52008-09-17 16:34:06 +0100373 uwb_mac_addr_print(macbuf, sizeof(macbuf), &uwb_dev->mac_addr);
374 uwb_dev_addr_print(devbuf, sizeof(devbuf), &uwb_dev->dev_addr);
375 dev_info(dev, "uwb device (mac %s dev %s) disconnected from %s %s\n",
376 macbuf, devbuf,
377 rc ? rc->uwb_dev.dev.parent->bus->name : "n/a",
378 rc ? dev_name(rc->uwb_dev.dev.parent) : "");
379 uwb_dev_rm(uwb_dev);
Stefano Panella3af37302008-12-23 12:31:09 +0000380 list_del(&uwb_dev->bce->node);
381 uwb_bce_put(uwb_dev->bce);
Inaky Perez-Gonzalez183b9b52008-09-17 16:34:06 +0100382 uwb_dev_put(uwb_dev); /* for the creation in _onair() */
David Vrabelbce83692008-12-22 18:22:50 +0000383
Inaky Perez-Gonzalez183b9b52008-09-17 16:34:06 +0100384 return 0;
385}
386
387
388/**
389 * A device went off the air, clean up after it!
390 *
391 * This is called by the UWB Daemon (through the beacon purge function
392 * uwb_bcn_cache_purge) when it is detected that a device has been in
393 * radio silence for a while.
394 *
395 * If this device is actually a local radio controller we don't need
396 * to go through the offair process, as it is not registered as that.
397 *
398 * NOTE: uwb_bcn_cache.mutex is held!
399 */
400void uwbd_dev_offair(struct uwb_beca_e *bce)
401{
402 struct uwb_dev *uwb_dev;
403
404 uwb_dev = bce->uwb_dev;
405 if (uwb_dev) {
406 uwb_notify(uwb_dev->rc, uwb_dev, UWB_NOTIF_OFFAIR);
407 __uwb_dev_offair(uwb_dev, uwb_dev->rc);
408 }
409}
410
411
412/**
413 * A device went on the air, start it up!
414 *
415 * This is called by the UWB Daemon when it is detected that a device
416 * has popped up in the radio range of the radio controller.
417 *
418 * It will just create the freaking device, register the beacon and
419 * stuff and yatla, done.
420 *
421 *
422 * NOTE: uwb_beca.mutex is held, bce->mutex is held
423 */
424void uwbd_dev_onair(struct uwb_rc *rc, struct uwb_beca_e *bce)
425{
426 int result;
427 struct device *dev = &rc->uwb_dev.dev;
428 struct uwb_dev *uwb_dev;
429 char macbuf[UWB_ADDR_STRSIZE], devbuf[UWB_ADDR_STRSIZE];
430
431 uwb_mac_addr_print(macbuf, sizeof(macbuf), bce->mac_addr);
432 uwb_dev_addr_print(devbuf, sizeof(devbuf), &bce->dev_addr);
David Vrabel92c4d9b2008-10-15 14:50:10 +0100433 uwb_dev = kzalloc(sizeof(struct uwb_dev), GFP_KERNEL);
Inaky Perez-Gonzalez183b9b52008-09-17 16:34:06 +0100434 if (uwb_dev == NULL) {
435 dev_err(dev, "new device %s: Cannot allocate memory\n",
436 macbuf);
437 return;
438 }
439 uwb_dev_init(uwb_dev); /* This sets refcnt to one, we own it */
440 uwb_dev->mac_addr = *bce->mac_addr;
441 uwb_dev->dev_addr = bce->dev_addr;
442 dev_set_name(&uwb_dev->dev, macbuf);
443 result = uwb_dev_add(uwb_dev, &rc->uwb_dev.dev, rc);
444 if (result < 0) {
445 dev_err(dev, "new device %s: cannot instantiate device\n",
446 macbuf);
447 goto error_dev_add;
448 }
449 /* plug the beacon cache */
450 bce->uwb_dev = uwb_dev;
451 uwb_dev->bce = bce;
452 uwb_bce_get(bce); /* released in uwb_dev_sys_release() */
453 dev_info(dev, "uwb device (mac %s dev %s) connected to %s %s\n",
454 macbuf, devbuf, rc->uwb_dev.dev.parent->bus->name,
455 dev_name(rc->uwb_dev.dev.parent));
456 uwb_notify(rc, uwb_dev, UWB_NOTIF_ONAIR);
457 return;
458
459error_dev_add:
460 kfree(uwb_dev);
461 return;
462}
463
464/**
465 * Iterate over the list of UWB devices, calling a @function on each
466 *
467 * See docs for bus_for_each()....
468 *
469 * @rc: radio controller for the devices.
470 * @function: function to call.
471 * @priv: data to pass to @function.
472 * @returns: 0 if no invocation of function() returned a value
473 * different to zero. That value otherwise.
474 */
475int uwb_dev_for_each(struct uwb_rc *rc, uwb_dev_for_each_f function, void *priv)
476{
477 return device_for_each_child(&rc->uwb_dev.dev, priv, function);
478}
479EXPORT_SYMBOL_GPL(uwb_dev_for_each);