1/* 2 * Ultra Wide Band 3 * Life cycle of radio controllers 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 * 25 * A UWB radio controller is also a UWB device, so it embeds one... 26 * 27 * List of RCs comes from the 'struct class uwb_rc_class'. 28 */ 29 30#include <linux/kernel.h> 31#include <linux/string.h> 32#include <linux/device.h> 33#include <linux/err.h> 34#include <linux/random.h> 35#include <linux/kdev_t.h> 36#include <linux/etherdevice.h> 37#include <linux/usb.h> 38#include <linux/slab.h> 39#include <linux/export.h> 40 41#include "uwb-internal.h" 42 43static int uwb_rc_index_match(struct device *dev, void *data) 44{ 45 int *index = data; 46 struct uwb_rc *rc = dev_get_drvdata(dev); 47 48 if (rc->index == *index) 49 return 1; 50 return 0; 51} 52 53static struct uwb_rc *uwb_rc_find_by_index(int index) 54{ 55 struct device *dev; 56 struct uwb_rc *rc = NULL; 57 58 dev = class_find_device(&uwb_rc_class, NULL, &index, uwb_rc_index_match); 59 if (dev) 60 rc = dev_get_drvdata(dev); 61 return rc; 62} 63 64static int uwb_rc_new_index(void) 65{ 66 int index = 0; 67 68 for (;;) { 69 if (!uwb_rc_find_by_index(index)) 70 return index; 71 if (++index < 0) 72 index = 0; 73 } 74} 75 76/** 77 * Release the backing device of a uwb_rc that has been dynamically allocated. 78 */ 79static void uwb_rc_sys_release(struct device *dev) 80{ 81 struct uwb_dev *uwb_dev = container_of(dev, struct uwb_dev, dev); 82 struct uwb_rc *rc = container_of(uwb_dev, struct uwb_rc, uwb_dev); 83 84 uwb_rc_ie_release(rc); 85 kfree(rc); 86} 87 88 89void uwb_rc_init(struct uwb_rc *rc) 90{ 91 struct uwb_dev *uwb_dev = &rc->uwb_dev; 92 93 uwb_dev_init(uwb_dev); 94 rc->uwb_dev.dev.class = &uwb_rc_class; 95 rc->uwb_dev.dev.release = uwb_rc_sys_release; 96 uwb_rc_neh_create(rc); 97 rc->beaconing = -1; 98 rc->scan_type = UWB_SCAN_DISABLED; 99 INIT_LIST_HEAD(&rc->notifs_chain.list); 100 mutex_init(&rc->notifs_chain.mutex); 101 INIT_LIST_HEAD(&rc->uwb_beca.list); 102 mutex_init(&rc->uwb_beca.mutex); 103 uwb_drp_avail_init(rc); 104 uwb_rc_ie_init(rc); 105 uwb_rsv_init(rc); 106 uwb_rc_pal_init(rc); 107} 108EXPORT_SYMBOL_GPL(uwb_rc_init); 109 110 111struct uwb_rc *uwb_rc_alloc(void) 112{ 113 struct uwb_rc *rc; 114 rc = kzalloc(sizeof(*rc), GFP_KERNEL); 115 if (rc == NULL) 116 return NULL; 117 uwb_rc_init(rc); 118 return rc; 119} 120EXPORT_SYMBOL_GPL(uwb_rc_alloc); 121 122static struct attribute *rc_attrs[] = { 123 &dev_attr_mac_address.attr, 124 &dev_attr_scan.attr, 125 &dev_attr_beacon.attr, 126 NULL, 127}; 128 129static struct attribute_group rc_attr_group = { 130 .attrs = rc_attrs, 131}; 132 133/* 134 * Registration of sysfs specific stuff 135 */ 136static int uwb_rc_sys_add(struct uwb_rc *rc) 137{ 138 return sysfs_create_group(&rc->uwb_dev.dev.kobj, &rc_attr_group); 139} 140 141 142static void __uwb_rc_sys_rm(struct uwb_rc *rc) 143{ 144 sysfs_remove_group(&rc->uwb_dev.dev.kobj, &rc_attr_group); 145} 146 147/** 148 * uwb_rc_mac_addr_setup - get an RC's EUI-48 address or set it 149 * @rc: the radio controller. 150 * 151 * If the EUI-48 address is 00:00:00:00:00:00 or FF:FF:FF:FF:FF:FF 152 * then a random locally administered EUI-48 is generated and set on 153 * the device. The probability of address collisions is sufficiently 154 * unlikely (1/2^40 = 9.1e-13) that they're not checked for. 155 */ 156static 157int uwb_rc_mac_addr_setup(struct uwb_rc *rc) 158{ 159 int result; 160 struct device *dev = &rc->uwb_dev.dev; 161 struct uwb_dev *uwb_dev = &rc->uwb_dev; 162 char devname[UWB_ADDR_STRSIZE]; 163 struct uwb_mac_addr addr; 164 165 result = uwb_rc_mac_addr_get(rc, &addr); 166 if (result < 0) { 167 dev_err(dev, "cannot retrieve UWB EUI-48 address: %d\n", result); 168 return result; 169 } 170 171 if (uwb_mac_addr_unset(&addr) || uwb_mac_addr_bcast(&addr)) { 172 addr.data[0] = 0x02; /* locally administered and unicast */ 173 get_random_bytes(&addr.data[1], sizeof(addr.data)-1); 174 175 result = uwb_rc_mac_addr_set(rc, &addr); 176 if (result < 0) { 177 uwb_mac_addr_print(devname, sizeof(devname), &addr); 178 dev_err(dev, "cannot set EUI-48 address %s: %d\n", 179 devname, result); 180 return result; 181 } 182 } 183 uwb_dev->mac_addr = addr; 184 return 0; 185} 186 187 188 189static int uwb_rc_setup(struct uwb_rc *rc) 190{ 191 int result; 192 struct device *dev = &rc->uwb_dev.dev; 193 194 result = uwb_radio_setup(rc); 195 if (result < 0) { 196 dev_err(dev, "cannot setup UWB radio: %d\n", result); 197 goto error; 198 } 199 result = uwb_rc_mac_addr_setup(rc); 200 if (result < 0) { 201 dev_err(dev, "cannot setup UWB MAC address: %d\n", result); 202 goto error; 203 } 204 result = uwb_rc_dev_addr_assign(rc); 205 if (result < 0) { 206 dev_err(dev, "cannot assign UWB DevAddr: %d\n", result); 207 goto error; 208 } 209 result = uwb_rc_ie_setup(rc); 210 if (result < 0) { 211 dev_err(dev, "cannot setup IE subsystem: %d\n", result); 212 goto error_ie_setup; 213 } 214 result = uwb_rsv_setup(rc); 215 if (result < 0) { 216 dev_err(dev, "cannot setup reservation subsystem: %d\n", result); 217 goto error_rsv_setup; 218 } 219 uwb_dbg_add_rc(rc); 220 return 0; 221 222error_rsv_setup: 223 uwb_rc_ie_release(rc); 224error_ie_setup: 225error: 226 return result; 227} 228 229 230/** 231 * Register a new UWB radio controller 232 * 233 * Did you call uwb_rc_init() on your rc? 234 * 235 * We assume that this is being called with a > 0 refcount on 236 * it [through ops->{get|put}_device(). We'll take our own, though. 237 * 238 * @parent_dev is our real device, the one that provides the actual UWB device 239 */ 240int uwb_rc_add(struct uwb_rc *rc, struct device *parent_dev, void *priv) 241{ 242 int result; 243 struct device *dev; 244 char macbuf[UWB_ADDR_STRSIZE], devbuf[UWB_ADDR_STRSIZE]; 245 246 rc->index = uwb_rc_new_index(); 247 248 dev = &rc->uwb_dev.dev; 249 dev_set_name(dev, "uwb%d", rc->index); 250 251 rc->priv = priv; 252 253 init_waitqueue_head(&rc->uwbd.wq); 254 INIT_LIST_HEAD(&rc->uwbd.event_list); 255 spin_lock_init(&rc->uwbd.event_list_lock); 256 257 uwbd_start(rc); 258 259 result = rc->start(rc); 260 if (result < 0) 261 goto error_rc_start; 262 263 result = uwb_rc_setup(rc); 264 if (result < 0) { 265 dev_err(dev, "cannot setup UWB radio controller: %d\n", result); 266 goto error_rc_setup; 267 } 268 269 result = uwb_dev_add(&rc->uwb_dev, parent_dev, rc); 270 if (result < 0 && result != -EADDRNOTAVAIL) 271 goto error_dev_add; 272 273 result = uwb_rc_sys_add(rc); 274 if (result < 0) { 275 dev_err(parent_dev, "cannot register UWB radio controller " 276 "dev attributes: %d\n", result); 277 goto error_sys_add; 278 } 279 280 uwb_mac_addr_print(macbuf, sizeof(macbuf), &rc->uwb_dev.mac_addr); 281 uwb_dev_addr_print(devbuf, sizeof(devbuf), &rc->uwb_dev.dev_addr); 282 dev_info(dev, 283 "new uwb radio controller (mac %s dev %s) on %s %s\n", 284 macbuf, devbuf, parent_dev->bus->name, dev_name(parent_dev)); 285 rc->ready = 1; 286 return 0; 287 288error_sys_add: 289 uwb_dev_rm(&rc->uwb_dev); 290error_dev_add: 291error_rc_setup: 292 rc->stop(rc); 293error_rc_start: 294 uwbd_stop(rc); 295 return result; 296} 297EXPORT_SYMBOL_GPL(uwb_rc_add); 298 299 300static int uwb_dev_offair_helper(struct device *dev, void *priv) 301{ 302 struct uwb_dev *uwb_dev = to_uwb_dev(dev); 303 304 return __uwb_dev_offair(uwb_dev, uwb_dev->rc); 305} 306 307/* 308 * Remove a Radio Controller; stop beaconing/scanning, disconnect all children 309 */ 310void uwb_rc_rm(struct uwb_rc *rc) 311{ 312 rc->ready = 0; 313 314 uwb_dbg_del_rc(rc); 315 uwb_rsv_remove_all(rc); 316 uwb_radio_shutdown(rc); 317 318 rc->stop(rc); 319 320 uwbd_stop(rc); 321 uwb_rc_neh_destroy(rc); 322 323 uwb_dev_lock(&rc->uwb_dev); 324 rc->priv = NULL; 325 rc->cmd = NULL; 326 uwb_dev_unlock(&rc->uwb_dev); 327 mutex_lock(&rc->uwb_beca.mutex); 328 uwb_dev_for_each(rc, uwb_dev_offair_helper, NULL); 329 __uwb_rc_sys_rm(rc); 330 mutex_unlock(&rc->uwb_beca.mutex); 331 uwb_rsv_cleanup(rc); 332 uwb_beca_release(rc); 333 uwb_dev_rm(&rc->uwb_dev); 334} 335EXPORT_SYMBOL_GPL(uwb_rc_rm); 336 337static int find_rc_try_get(struct device *dev, void *data) 338{ 339 struct uwb_rc *target_rc = data; 340 struct uwb_rc *rc = dev_get_drvdata(dev); 341 342 if (rc == NULL) { 343 WARN_ON(1); 344 return 0; 345 } 346 if (rc == target_rc) { 347 if (rc->ready == 0) 348 return 0; 349 else 350 return 1; 351 } 352 return 0; 353} 354 355/** 356 * Given a radio controller descriptor, validate and refcount it 357 * 358 * @returns NULL if the rc does not exist or is quiescing; the ptr to 359 * it otherwise. 360 */ 361struct uwb_rc *__uwb_rc_try_get(struct uwb_rc *target_rc) 362{ 363 struct device *dev; 364 struct uwb_rc *rc = NULL; 365 366 dev = class_find_device(&uwb_rc_class, NULL, target_rc, 367 find_rc_try_get); 368 if (dev) { 369 rc = dev_get_drvdata(dev); 370 __uwb_rc_get(rc); 371 } 372 return rc; 373} 374EXPORT_SYMBOL_GPL(__uwb_rc_try_get); 375 376/* 377 * RC get for external refcount acquirers... 378 * 379 * Increments the refcount of the device and it's backend modules 380 */ 381static inline struct uwb_rc *uwb_rc_get(struct uwb_rc *rc) 382{ 383 if (rc->ready == 0) 384 return NULL; 385 uwb_dev_get(&rc->uwb_dev); 386 return rc; 387} 388 389static int find_rc_grandpa(struct device *dev, void *data) 390{ 391 struct device *grandpa_dev = data; 392 struct uwb_rc *rc = dev_get_drvdata(dev); 393 394 if (rc->uwb_dev.dev.parent->parent == grandpa_dev) { 395 rc = uwb_rc_get(rc); 396 return 1; 397 } 398 return 0; 399} 400 401/** 402 * Locate and refcount a radio controller given a common grand-parent 403 * 404 * @grandpa_dev Pointer to the 'grandparent' device structure. 405 * @returns NULL If the rc does not exist or is quiescing; the ptr to 406 * it otherwise, properly referenced. 407 * 408 * The Radio Control interface (or the UWB Radio Controller) is always 409 * an interface of a device. The parent is the interface, the 410 * grandparent is the device that encapsulates the interface. 411 * 412 * There is no need to lock around as the "grandpa" would be 413 * refcounted by the target, and to remove the referemes, the 414 * uwb_rc_class->sem would have to be taken--we hold it, ergo we 415 * should be safe. 416 */ 417struct uwb_rc *uwb_rc_get_by_grandpa(const struct device *grandpa_dev) 418{ 419 struct device *dev; 420 struct uwb_rc *rc = NULL; 421 422 dev = class_find_device(&uwb_rc_class, NULL, (void *)grandpa_dev, 423 find_rc_grandpa); 424 if (dev) 425 rc = dev_get_drvdata(dev); 426 return rc; 427} 428EXPORT_SYMBOL_GPL(uwb_rc_get_by_grandpa); 429 430/** 431 * Find a radio controller by device address 432 * 433 * @returns the pointer to the radio controller, properly referenced 434 */ 435static int find_rc_dev(struct device *dev, void *data) 436{ 437 struct uwb_dev_addr *addr = data; 438 struct uwb_rc *rc = dev_get_drvdata(dev); 439 440 if (rc == NULL) { 441 WARN_ON(1); 442 return 0; 443 } 444 if (!uwb_dev_addr_cmp(&rc->uwb_dev.dev_addr, addr)) { 445 rc = uwb_rc_get(rc); 446 return 1; 447 } 448 return 0; 449} 450 451struct uwb_rc *uwb_rc_get_by_dev(const struct uwb_dev_addr *addr) 452{ 453 struct device *dev; 454 struct uwb_rc *rc = NULL; 455 456 dev = class_find_device(&uwb_rc_class, NULL, (void *)addr, 457 find_rc_dev); 458 if (dev) 459 rc = dev_get_drvdata(dev); 460 461 return rc; 462} 463EXPORT_SYMBOL_GPL(uwb_rc_get_by_dev); 464 465/** 466 * Drop a reference on a radio controller 467 * 468 * This is the version that should be done by entities external to the 469 * UWB Radio Control stack (ie: clients of the API). 470 */ 471void uwb_rc_put(struct uwb_rc *rc) 472{ 473 __uwb_rc_put(rc); 474} 475EXPORT_SYMBOL_GPL(uwb_rc_put); 476