1 2#include <linux/wlp.h> 3#include <linux/slab.h> 4 5#include "wlp-internal.h" 6 7static 8void wlp_neighbor_init(struct wlp_neighbor_e *neighbor) 9{ 10 INIT_LIST_HEAD(&neighbor->wssid); 11} 12 13/** 14 * Create area for device information storage 15 * 16 * wlp->mutex must be held 17 */ 18int __wlp_alloc_device_info(struct wlp *wlp) 19{ 20 struct device *dev = &wlp->rc->uwb_dev.dev; 21 BUG_ON(wlp->dev_info != NULL); 22 wlp->dev_info = kzalloc(sizeof(struct wlp_device_info), GFP_KERNEL); 23 if (wlp->dev_info == NULL) { 24 dev_err(dev, "WLP: Unable to allocate memory for " 25 "device information.\n"); 26 return -ENOMEM; 27 } 28 return 0; 29} 30 31 32/** 33 * Fill in device information using function provided by driver 34 * 35 * wlp->mutex must be held 36 */ 37static 38void __wlp_fill_device_info(struct wlp *wlp) 39{ 40 wlp->fill_device_info(wlp, wlp->dev_info); 41} 42 43/** 44 * Setup device information 45 * 46 * Allocate area for device information and populate it. 47 * 48 * wlp->mutex must be held 49 */ 50int __wlp_setup_device_info(struct wlp *wlp) 51{ 52 int result; 53 struct device *dev = &wlp->rc->uwb_dev.dev; 54 55 result = __wlp_alloc_device_info(wlp); 56 if (result < 0) { 57 dev_err(dev, "WLP: Unable to allocate area for " 58 "device information.\n"); 59 return result; 60 } 61 __wlp_fill_device_info(wlp); 62 return 0; 63} 64 65/** 66 * Remove information about neighbor stored temporarily 67 * 68 * Information learned during discovey should only be stored when the 69 * device enrolls in the neighbor's WSS. We do need to store this 70 * information temporarily in order to present it to the user. 71 * 72 * We are only interested in keeping neighbor WSS information if that 73 * neighbor is accepting enrollment. 74 * 75 * should be called with wlp->nbmutex held 76 */ 77void wlp_remove_neighbor_tmp_info(struct wlp_neighbor_e *neighbor) 78{ 79 struct wlp_wssid_e *wssid_e, *next; 80 u8 keep; 81 if (!list_empty(&neighbor->wssid)) { 82 list_for_each_entry_safe(wssid_e, next, &neighbor->wssid, 83 node) { 84 if (wssid_e->info != NULL) { 85 keep = wssid_e->info->accept_enroll; 86 kfree(wssid_e->info); 87 wssid_e->info = NULL; 88 if (!keep) { 89 list_del(&wssid_e->node); 90 kfree(wssid_e); 91 } 92 } 93 } 94 } 95 if (neighbor->info != NULL) { 96 kfree(neighbor->info); 97 neighbor->info = NULL; 98 } 99} 100 101/* 102 * Populate WLP neighborhood cache with neighbor information 103 * 104 * A new neighbor is found. If it is discoverable then we add it to the 105 * neighborhood cache. 106 * 107 */ 108static 109int wlp_add_neighbor(struct wlp *wlp, struct uwb_dev *dev) 110{ 111 int result = 0; 112 int discoverable; 113 struct wlp_neighbor_e *neighbor; 114 115 discoverable = 1; 116 if (discoverable) { 117 /* Add neighbor to cache for discovery */ 118 neighbor = kzalloc(sizeof(*neighbor), GFP_KERNEL); 119 if (neighbor == NULL) { 120 dev_err(&dev->dev, "Unable to create memory for " 121 "new neighbor. \n"); 122 result = -ENOMEM; 123 goto error_no_mem; 124 } 125 wlp_neighbor_init(neighbor); 126 uwb_dev_get(dev); 127 neighbor->uwb_dev = dev; 128 list_add(&neighbor->node, &wlp->neighbors); 129 } 130error_no_mem: 131 return result; 132} 133 134/** 135 * Remove one neighbor from cache 136 */ 137static 138void __wlp_neighbor_release(struct wlp_neighbor_e *neighbor) 139{ 140 struct wlp_wssid_e *wssid_e, *next_wssid_e; 141 142 list_for_each_entry_safe(wssid_e, next_wssid_e, 143 &neighbor->wssid, node) { 144 list_del(&wssid_e->node); 145 kfree(wssid_e); 146 } 147 uwb_dev_put(neighbor->uwb_dev); 148 list_del(&neighbor->node); 149 kfree(neighbor); 150} 151 152/** 153 * Clear entire neighborhood cache. 154 */ 155static 156void __wlp_neighbors_release(struct wlp *wlp) 157{ 158 struct wlp_neighbor_e *neighbor, *next; 159 if (list_empty(&wlp->neighbors)) 160 return; 161 list_for_each_entry_safe(neighbor, next, &wlp->neighbors, node) { 162 __wlp_neighbor_release(neighbor); 163 } 164} 165 166static 167void wlp_neighbors_release(struct wlp *wlp) 168{ 169 mutex_lock(&wlp->nbmutex); 170 __wlp_neighbors_release(wlp); 171 mutex_unlock(&wlp->nbmutex); 172} 173 174 175 176/** 177 * Send D1 message to neighbor, receive D2 message 178 * 179 * @neighbor: neighbor to which D1 message will be sent 180 * @wss: if not NULL, it is an enrollment request for this WSS 181 * @wssid: if wss not NULL, this is the wssid of the WSS in which we 182 * want to enroll 183 * 184 * A D1/D2 exchange is done for one of two reasons: discovery or 185 * enrollment. If done for discovery the D1 message is sent to the neighbor 186 * and the contents of the D2 response is stored in a temporary cache. 187 * If done for enrollment the @wss and @wssid are provided also. In this 188 * case the D1 message is sent to the neighbor, the D2 response is parsed 189 * for enrollment of the WSS with wssid. 190 * 191 * &wss->mutex is held 192 */ 193static 194int wlp_d1d2_exchange(struct wlp *wlp, struct wlp_neighbor_e *neighbor, 195 struct wlp_wss *wss, struct wlp_uuid *wssid) 196{ 197 int result; 198 struct device *dev = &wlp->rc->uwb_dev.dev; 199 DECLARE_COMPLETION_ONSTACK(completion); 200 struct wlp_session session; 201 struct sk_buff *skb; 202 struct wlp_frame_assoc *resp; 203 struct uwb_dev_addr *dev_addr = &neighbor->uwb_dev->dev_addr; 204 205 mutex_lock(&wlp->mutex); 206 if (!wlp_uuid_is_set(&wlp->uuid)) { 207 dev_err(dev, "WLP: UUID is not set. Set via sysfs to " 208 "proceed.\n"); 209 result = -ENXIO; 210 goto out; 211 } 212 /* Send D1 association frame */ 213 result = wlp_send_assoc_frame(wlp, wss, dev_addr, WLP_ASSOC_D1); 214 if (result < 0) { 215 dev_err(dev, "Unable to send D1 frame to neighbor " 216 "%02x:%02x (%d)\n", dev_addr->data[1], 217 dev_addr->data[0], result); 218 goto out; 219 } 220 /* Create session, wait for response */ 221 session.exp_message = WLP_ASSOC_D2; 222 session.cb = wlp_session_cb; 223 session.cb_priv = &completion; 224 session.neighbor_addr = *dev_addr; 225 BUG_ON(wlp->session != NULL); 226 wlp->session = &session; 227 /* Wait for D2/F0 frame */ 228 result = wait_for_completion_interruptible_timeout(&completion, 229 WLP_PER_MSG_TIMEOUT * HZ); 230 if (result == 0) { 231 result = -ETIMEDOUT; 232 dev_err(dev, "Timeout while sending D1 to neighbor " 233 "%02x:%02x.\n", dev_addr->data[1], 234 dev_addr->data[0]); 235 goto error_session; 236 } 237 if (result < 0) { 238 dev_err(dev, "Unable to discover/enroll neighbor %02x:%02x.\n", 239 dev_addr->data[1], dev_addr->data[0]); 240 goto error_session; 241 } 242 /* Parse message in session->data: it will be either D2 or F0 */ 243 skb = session.data; 244 resp = (void *) skb->data; 245 246 if (resp->type == WLP_ASSOC_F0) { 247 result = wlp_parse_f0(wlp, skb); 248 if (result < 0) 249 dev_err(dev, "WLP: Unable to parse F0 from neighbor " 250 "%02x:%02x.\n", dev_addr->data[1], 251 dev_addr->data[0]); 252 result = -EINVAL; 253 goto error_resp_parse; 254 } 255 if (wss == NULL) { 256 /* Discovery */ 257 result = wlp_parse_d2_frame_to_cache(wlp, skb, neighbor); 258 if (result < 0) { 259 dev_err(dev, "WLP: Unable to parse D2 message from " 260 "neighbor %02x:%02x for discovery.\n", 261 dev_addr->data[1], dev_addr->data[0]); 262 goto error_resp_parse; 263 } 264 } else { 265 /* Enrollment */ 266 result = wlp_parse_d2_frame_to_enroll(wss, skb, neighbor, 267 wssid); 268 if (result < 0) { 269 dev_err(dev, "WLP: Unable to parse D2 message from " 270 "neighbor %02x:%02x for enrollment.\n", 271 dev_addr->data[1], dev_addr->data[0]); 272 goto error_resp_parse; 273 } 274 } 275error_resp_parse: 276 kfree_skb(skb); 277error_session: 278 wlp->session = NULL; 279out: 280 mutex_unlock(&wlp->mutex); 281 return result; 282} 283 284/** 285 * Enroll into WSS of provided WSSID by using neighbor as registrar 286 * 287 * &wss->mutex is held 288 */ 289int wlp_enroll_neighbor(struct wlp *wlp, struct wlp_neighbor_e *neighbor, 290 struct wlp_wss *wss, struct wlp_uuid *wssid) 291{ 292 int result = 0; 293 struct device *dev = &wlp->rc->uwb_dev.dev; 294 char buf[WLP_WSS_UUID_STRSIZE]; 295 struct uwb_dev_addr *dev_addr = &neighbor->uwb_dev->dev_addr; 296 297 wlp_wss_uuid_print(buf, sizeof(buf), wssid); 298 299 result = wlp_d1d2_exchange(wlp, neighbor, wss, wssid); 300 if (result < 0) { 301 dev_err(dev, "WLP: D1/D2 message exchange for enrollment " 302 "failed. result = %d \n", result); 303 goto out; 304 } 305 if (wss->state != WLP_WSS_STATE_PART_ENROLLED) { 306 dev_err(dev, "WLP: Unable to enroll into WSS %s using " 307 "neighbor %02x:%02x. \n", buf, 308 dev_addr->data[1], dev_addr->data[0]); 309 result = -EINVAL; 310 goto out; 311 } 312 if (wss->secure_status == WLP_WSS_SECURE) { 313 dev_err(dev, "FIXME: need to complete secure enrollment.\n"); 314 result = -EINVAL; 315 goto error; 316 } else { 317 wss->state = WLP_WSS_STATE_ENROLLED; 318 dev_dbg(dev, "WLP: Success Enrollment into unsecure WSS " 319 "%s using neighbor %02x:%02x. \n", 320 buf, dev_addr->data[1], dev_addr->data[0]); 321 } 322out: 323 return result; 324error: 325 wlp_wss_reset(wss); 326 return result; 327} 328 329/** 330 * Discover WSS information of neighbor's active WSS 331 */ 332static 333int wlp_discover_neighbor(struct wlp *wlp, 334 struct wlp_neighbor_e *neighbor) 335{ 336 return wlp_d1d2_exchange(wlp, neighbor, NULL, NULL); 337} 338 339 340/** 341 * Each neighbor in the neighborhood cache is discoverable. Discover it. 342 * 343 * Discovery is done through sending of D1 association frame and parsing 344 * the D2 association frame response. Only wssid from D2 will be included 345 * in neighbor cache, rest is just displayed to user and forgotten. 346 * 347 * The discovery is not done in parallel. This is simple and enables us to 348 * maintain only one association context. 349 * 350 * The discovery of one neighbor does not affect the other, but if the 351 * discovery of a neighbor fails it is removed from the neighborhood cache. 352 */ 353static 354int wlp_discover_all_neighbors(struct wlp *wlp) 355{ 356 int result = 0; 357 struct device *dev = &wlp->rc->uwb_dev.dev; 358 struct wlp_neighbor_e *neighbor, *next; 359 360 list_for_each_entry_safe(neighbor, next, &wlp->neighbors, node) { 361 result = wlp_discover_neighbor(wlp, neighbor); 362 if (result < 0) { 363 dev_err(dev, "WLP: Unable to discover neighbor " 364 "%02x:%02x, removing from neighborhood. \n", 365 neighbor->uwb_dev->dev_addr.data[1], 366 neighbor->uwb_dev->dev_addr.data[0]); 367 __wlp_neighbor_release(neighbor); 368 } 369 } 370 return result; 371} 372 373static int wlp_add_neighbor_helper(struct device *dev, void *priv) 374{ 375 struct wlp *wlp = priv; 376 struct uwb_dev *uwb_dev = to_uwb_dev(dev); 377 378 return wlp_add_neighbor(wlp, uwb_dev); 379} 380 381/** 382 * Discover WLP neighborhood 383 * 384 * Will send D1 association frame to all devices in beacon group that have 385 * discoverable bit set in WLP IE. D2 frames will be received, information 386 * displayed to user in @buf. Partial information (from D2 association 387 * frame) will be cached to assist with future association 388 * requests. 389 * 390 * The discovery of the WLP neighborhood is triggered by the user. This 391 * should occur infrequently and we thus free current cache and re-allocate 392 * memory if needed. 393 * 394 * If one neighbor fails during initial discovery (determining if it is a 395 * neighbor or not), we fail all - note that interaction with neighbor has 396 * not occured at this point so if a failure occurs we know something went wrong 397 * locally. We thus undo everything. 398 */ 399ssize_t wlp_discover(struct wlp *wlp) 400{ 401 int result = 0; 402 struct device *dev = &wlp->rc->uwb_dev.dev; 403 404 mutex_lock(&wlp->nbmutex); 405 /* Clear current neighborhood cache. */ 406 __wlp_neighbors_release(wlp); 407 /* Determine which devices in neighborhood. Repopulate cache. */ 408 result = uwb_dev_for_each(wlp->rc, wlp_add_neighbor_helper, wlp); 409 if (result < 0) { 410 /* May have partial neighbor information, release all. */ 411 __wlp_neighbors_release(wlp); 412 goto error_dev_for_each; 413 } 414 /* Discover the properties of devices in neighborhood. */ 415 result = wlp_discover_all_neighbors(wlp); 416 /* In case of failure we still print our partial results. */ 417 if (result < 0) { 418 dev_err(dev, "Unable to fully discover neighborhood. \n"); 419 result = 0; 420 } 421error_dev_for_each: 422 mutex_unlock(&wlp->nbmutex); 423 return result; 424} 425 426/** 427 * Handle events from UWB stack 428 * 429 * We handle events conservatively. If a neighbor goes off the air we 430 * remove it from the neighborhood. If an association process is in 431 * progress this function will block waiting for the nbmutex to become 432 * free. The association process will thus be allowed to complete before it 433 * is removed. 434 */ 435static 436void wlp_uwb_notifs_cb(void *_wlp, struct uwb_dev *uwb_dev, 437 enum uwb_notifs event) 438{ 439 struct wlp *wlp = _wlp; 440 struct device *dev = &wlp->rc->uwb_dev.dev; 441 struct wlp_neighbor_e *neighbor, *next; 442 int result; 443 switch (event) { 444 case UWB_NOTIF_ONAIR: 445 result = wlp_eda_create_node(&wlp->eda, 446 uwb_dev->mac_addr.data, 447 &uwb_dev->dev_addr); 448 if (result < 0) 449 dev_err(dev, "WLP: Unable to add new neighbor " 450 "%02x:%02x to EDA cache.\n", 451 uwb_dev->dev_addr.data[1], 452 uwb_dev->dev_addr.data[0]); 453 break; 454 case UWB_NOTIF_OFFAIR: 455 wlp_eda_rm_node(&wlp->eda, &uwb_dev->dev_addr); 456 mutex_lock(&wlp->nbmutex); 457 list_for_each_entry_safe(neighbor, next, &wlp->neighbors, node) { 458 if (neighbor->uwb_dev == uwb_dev) 459 __wlp_neighbor_release(neighbor); 460 } 461 mutex_unlock(&wlp->nbmutex); 462 break; 463 default: 464 dev_err(dev, "don't know how to handle event %d from uwb\n", 465 event); 466 } 467} 468 469static void wlp_channel_changed(struct uwb_pal *pal, int channel) 470{ 471 struct wlp *wlp = container_of(pal, struct wlp, pal); 472 473 if (channel < 0) 474 netif_carrier_off(wlp->ndev); 475 else 476 netif_carrier_on(wlp->ndev); 477} 478 479int wlp_setup(struct wlp *wlp, struct uwb_rc *rc, struct net_device *ndev) 480{ 481 int result; 482 483 BUG_ON(wlp->fill_device_info == NULL); 484 BUG_ON(wlp->xmit_frame == NULL); 485 BUG_ON(wlp->stop_queue == NULL); 486 BUG_ON(wlp->start_queue == NULL); 487 488 wlp->rc = rc; 489 wlp->ndev = ndev; 490 wlp_eda_init(&wlp->eda);/* Set up address cache */ 491 wlp->uwb_notifs_handler.cb = wlp_uwb_notifs_cb; 492 wlp->uwb_notifs_handler.data = wlp; 493 uwb_notifs_register(rc, &wlp->uwb_notifs_handler); 494 495 uwb_pal_init(&wlp->pal); 496 wlp->pal.rc = rc; 497 wlp->pal.channel_changed = wlp_channel_changed; 498 result = uwb_pal_register(&wlp->pal); 499 if (result < 0) 500 uwb_notifs_deregister(wlp->rc, &wlp->uwb_notifs_handler); 501 502 return result; 503} 504EXPORT_SYMBOL_GPL(wlp_setup); 505 506void wlp_remove(struct wlp *wlp) 507{ 508 wlp_neighbors_release(wlp); 509 uwb_pal_unregister(&wlp->pal); 510 uwb_notifs_deregister(wlp->rc, &wlp->uwb_notifs_handler); 511 wlp_eda_release(&wlp->eda); 512 mutex_lock(&wlp->mutex); 513 if (wlp->dev_info != NULL) 514 kfree(wlp->dev_info); 515 mutex_unlock(&wlp->mutex); 516 wlp->rc = NULL; 517} 518EXPORT_SYMBOL_GPL(wlp_remove); 519 520/** 521 * wlp_reset_all - reset the WLP hardware 522 * @wlp: the WLP device to reset. 523 * 524 * This schedules a full hardware reset of the WLP device. The radio 525 * controller and any other PALs will also be reset. 526 */ 527void wlp_reset_all(struct wlp *wlp) 528{ 529 uwb_rc_reset_all(wlp->rc); 530} 531EXPORT_SYMBOL_GPL(wlp_reset_all); 532