2 * WiMedia Logical Link Control Protocol (WLP)
4 * Copyright (C) 2005-2006 Intel Corporation
5 * Reinette Chatre <reinette.chatre@intel.com>
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License version
9 * 2 as published by the Free Software Foundation.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
25 #include <linux/wlp.h>
27 #include <linux/uwb/debug.h>
28 #include "wlp-internal.h"
32 void wlp_neighbor_init(struct wlp_neighbor_e
*neighbor
)
34 INIT_LIST_HEAD(&neighbor
->wssid
);
38 * Create area for device information storage
40 * wlp->mutex must be held
42 int __wlp_alloc_device_info(struct wlp
*wlp
)
44 struct device
*dev
= &wlp
->rc
->uwb_dev
.dev
;
45 BUG_ON(wlp
->dev_info
!= NULL
);
46 wlp
->dev_info
= kzalloc(sizeof(struct wlp_device_info
), GFP_KERNEL
);
47 if (wlp
->dev_info
== NULL
) {
48 dev_err(dev
, "WLP: Unable to allocate memory for "
49 "device information.\n");
57 * Fill in device information using function provided by driver
59 * wlp->mutex must be held
62 void __wlp_fill_device_info(struct wlp
*wlp
)
64 struct device
*dev
= &wlp
->rc
->uwb_dev
.dev
;
66 BUG_ON(wlp
->fill_device_info
== NULL
);
67 d_printf(6, dev
, "Retrieving device information "
68 "from device driver.\n");
69 wlp
->fill_device_info(wlp
, wlp
->dev_info
);
73 * Setup device information
75 * Allocate area for device information and populate it.
77 * wlp->mutex must be held
79 int __wlp_setup_device_info(struct wlp
*wlp
)
82 struct device
*dev
= &wlp
->rc
->uwb_dev
.dev
;
84 result
= __wlp_alloc_device_info(wlp
);
86 dev_err(dev
, "WLP: Unable to allocate area for "
87 "device information.\n");
90 __wlp_fill_device_info(wlp
);
95 * Remove information about neighbor stored temporarily
97 * Information learned during discovey should only be stored when the
98 * device enrolls in the neighbor's WSS. We do need to store this
99 * information temporarily in order to present it to the user.
101 * We are only interested in keeping neighbor WSS information if that
102 * neighbor is accepting enrollment.
104 * should be called with wlp->nbmutex held
106 void wlp_remove_neighbor_tmp_info(struct wlp_neighbor_e
*neighbor
)
108 struct wlp_wssid_e
*wssid_e
, *next
;
110 if (!list_empty(&neighbor
->wssid
)) {
111 list_for_each_entry_safe(wssid_e
, next
, &neighbor
->wssid
,
113 if (wssid_e
->info
!= NULL
) {
114 keep
= wssid_e
->info
->accept_enroll
;
115 kfree(wssid_e
->info
);
116 wssid_e
->info
= NULL
;
118 list_del(&wssid_e
->node
);
124 if (neighbor
->info
!= NULL
) {
125 kfree(neighbor
->info
);
126 neighbor
->info
= NULL
;
131 * Populate WLP neighborhood cache with neighbor information
133 * A new neighbor is found. If it is discoverable then we add it to the
134 * neighborhood cache.
138 int wlp_add_neighbor(struct wlp
*wlp
, struct uwb_dev
*dev
)
142 struct wlp_neighbor_e
*neighbor
;
144 d_fnstart(6, &dev
->dev
, "uwb %p \n", dev
);
145 d_printf(6, &dev
->dev
, "Found neighbor device %02x:%02x \n",
146 dev
->dev_addr
.data
[1], dev
->dev_addr
.data
[0]);
149 * Use contents of WLP IE found in beacon cache to determine if
150 * neighbor is discoverable.
151 * The device does not support WLP IE yet so this still needs to be
152 * done. Until then we assume all devices are discoverable.
154 discoverable
= 1; /* will be changed when FIXME disappears */
156 /* Add neighbor to cache for discovery */
157 neighbor
= kzalloc(sizeof(*neighbor
), GFP_KERNEL
);
158 if (neighbor
== NULL
) {
159 dev_err(&dev
->dev
, "Unable to create memory for "
164 wlp_neighbor_init(neighbor
);
166 neighbor
->uwb_dev
= dev
;
167 list_add(&neighbor
->node
, &wlp
->neighbors
);
170 d_fnend(6, &dev
->dev
, "uwb %p, result = %d \n", dev
, result
);
175 * Remove one neighbor from cache
178 void __wlp_neighbor_release(struct wlp_neighbor_e
*neighbor
)
180 struct wlp_wssid_e
*wssid_e
, *next_wssid_e
;
182 list_for_each_entry_safe(wssid_e
, next_wssid_e
,
183 &neighbor
->wssid
, node
) {
184 list_del(&wssid_e
->node
);
187 uwb_dev_put(neighbor
->uwb_dev
);
188 list_del(&neighbor
->node
);
193 * Clear entire neighborhood cache.
196 void __wlp_neighbors_release(struct wlp
*wlp
)
198 struct wlp_neighbor_e
*neighbor
, *next
;
199 if (list_empty(&wlp
->neighbors
))
201 list_for_each_entry_safe(neighbor
, next
, &wlp
->neighbors
, node
) {
202 __wlp_neighbor_release(neighbor
);
207 void wlp_neighbors_release(struct wlp
*wlp
)
209 mutex_lock(&wlp
->nbmutex
);
210 __wlp_neighbors_release(wlp
);
211 mutex_unlock(&wlp
->nbmutex
);
217 * Send D1 message to neighbor, receive D2 message
219 * @neighbor: neighbor to which D1 message will be sent
220 * @wss: if not NULL, it is an enrollment request for this WSS
221 * @wssid: if wss not NULL, this is the wssid of the WSS in which we
224 * A D1/D2 exchange is done for one of two reasons: discovery or
225 * enrollment. If done for discovery the D1 message is sent to the neighbor
226 * and the contents of the D2 response is stored in a temporary cache.
227 * If done for enrollment the @wss and @wssid are provided also. In this
228 * case the D1 message is sent to the neighbor, the D2 response is parsed
229 * for enrollment of the WSS with wssid.
231 * &wss->mutex is held
234 int wlp_d1d2_exchange(struct wlp
*wlp
, struct wlp_neighbor_e
*neighbor
,
235 struct wlp_wss
*wss
, struct wlp_uuid
*wssid
)
238 struct device
*dev
= &wlp
->rc
->uwb_dev
.dev
;
239 DECLARE_COMPLETION_ONSTACK(completion
);
240 struct wlp_session session
;
242 struct wlp_frame_assoc
*resp
;
243 struct uwb_dev_addr
*dev_addr
= &neighbor
->uwb_dev
->dev_addr
;
245 mutex_lock(&wlp
->mutex
);
246 if (!wlp_uuid_is_set(&wlp
->uuid
)) {
247 dev_err(dev
, "WLP: UUID is not set. Set via sysfs to "
252 /* Send D1 association frame */
253 result
= wlp_send_assoc_frame(wlp
, wss
, dev_addr
, WLP_ASSOC_D1
);
255 dev_err(dev
, "Unable to send D1 frame to neighbor "
256 "%02x:%02x (%d)\n", dev_addr
->data
[1],
257 dev_addr
->data
[0], result
);
258 d_printf(6, dev
, "Add placeholders into buffer next to "
259 "neighbor information we have (dev address).\n");
262 /* Create session, wait for response */
263 session
.exp_message
= WLP_ASSOC_D2
;
264 session
.cb
= wlp_session_cb
;
265 session
.cb_priv
= &completion
;
266 session
.neighbor_addr
= *dev_addr
;
267 BUG_ON(wlp
->session
!= NULL
);
268 wlp
->session
= &session
;
269 /* Wait for D2/F0 frame */
270 result
= wait_for_completion_interruptible_timeout(&completion
,
271 WLP_PER_MSG_TIMEOUT
* HZ
);
274 dev_err(dev
, "Timeout while sending D1 to neighbor "
275 "%02x:%02x.\n", dev_addr
->data
[1],
280 dev_err(dev
, "Unable to discover/enroll neighbor %02x:%02x.\n",
281 dev_addr
->data
[1], dev_addr
->data
[0]);
284 /* Parse message in session->data: it will be either D2 or F0 */
286 resp
= (void *) skb
->data
;
287 d_printf(6, dev
, "Received response to D1 frame. \n");
288 d_dump(6, dev
, skb
->data
, skb
->len
> 72 ? 72 : skb
->len
);
290 if (resp
->type
== WLP_ASSOC_F0
) {
291 result
= wlp_parse_f0(wlp
, skb
);
293 dev_err(dev
, "WLP: Unable to parse F0 from neighbor "
294 "%02x:%02x.\n", dev_addr
->data
[1],
297 goto error_resp_parse
;
301 result
= wlp_parse_d2_frame_to_cache(wlp
, skb
, neighbor
);
303 dev_err(dev
, "WLP: Unable to parse D2 message from "
304 "neighbor %02x:%02x for discovery.\n",
305 dev_addr
->data
[1], dev_addr
->data
[0]);
306 goto error_resp_parse
;
310 result
= wlp_parse_d2_frame_to_enroll(wss
, skb
, neighbor
,
313 dev_err(dev
, "WLP: Unable to parse D2 message from "
314 "neighbor %02x:%02x for enrollment.\n",
315 dev_addr
->data
[1], dev_addr
->data
[0]);
316 goto error_resp_parse
;
324 mutex_unlock(&wlp
->mutex
);
329 * Enroll into WSS of provided WSSID by using neighbor as registrar
331 * &wss->mutex is held
333 int wlp_enroll_neighbor(struct wlp
*wlp
, struct wlp_neighbor_e
*neighbor
,
334 struct wlp_wss
*wss
, struct wlp_uuid
*wssid
)
337 struct device
*dev
= &wlp
->rc
->uwb_dev
.dev
;
338 char buf
[WLP_WSS_UUID_STRSIZE
];
339 struct uwb_dev_addr
*dev_addr
= &neighbor
->uwb_dev
->dev_addr
;
340 wlp_wss_uuid_print(buf
, sizeof(buf
), wssid
);
341 d_fnstart(6, dev
, "wlp %p, neighbor %p, wss %p, wssid %p (%s)\n",
342 wlp
, neighbor
, wss
, wssid
, buf
);
343 d_printf(6, dev
, "Complete me.\n");
344 result
= wlp_d1d2_exchange(wlp
, neighbor
, wss
, wssid
);
346 dev_err(dev
, "WLP: D1/D2 message exchange for enrollment "
347 "failed. result = %d \n", result
);
350 if (wss
->state
!= WLP_WSS_STATE_PART_ENROLLED
) {
351 dev_err(dev
, "WLP: Unable to enroll into WSS %s using "
352 "neighbor %02x:%02x. \n", buf
,
353 dev_addr
->data
[1], dev_addr
->data
[0]);
357 if (wss
->secure_status
== WLP_WSS_SECURE
) {
358 dev_err(dev
, "FIXME: need to complete secure enrollment.\n");
362 wss
->state
= WLP_WSS_STATE_ENROLLED
;
363 d_printf(2, dev
, "WLP: Success Enrollment into unsecure WSS "
364 "%s using neighbor %02x:%02x. \n", buf
,
365 dev_addr
->data
[1], dev_addr
->data
[0]);
368 d_fnend(6, dev
, "wlp %p, neighbor %p, wss %p, wssid %p (%s)\n",
369 wlp
, neighbor
, wss
, wssid
, buf
);
378 * Discover WSS information of neighbor's active WSS
381 int wlp_discover_neighbor(struct wlp
*wlp
,
382 struct wlp_neighbor_e
*neighbor
)
384 return wlp_d1d2_exchange(wlp
, neighbor
, NULL
, NULL
);
389 * Each neighbor in the neighborhood cache is discoverable. Discover it.
391 * Discovery is done through sending of D1 association frame and parsing
392 * the D2 association frame response. Only wssid from D2 will be included
393 * in neighbor cache, rest is just displayed to user and forgotten.
395 * The discovery is not done in parallel. This is simple and enables us to
396 * maintain only one association context.
398 * The discovery of one neighbor does not affect the other, but if the
399 * discovery of a neighbor fails it is removed from the neighborhood cache.
402 int wlp_discover_all_neighbors(struct wlp
*wlp
)
405 struct device
*dev
= &wlp
->rc
->uwb_dev
.dev
;
406 struct wlp_neighbor_e
*neighbor
, *next
;
408 list_for_each_entry_safe(neighbor
, next
, &wlp
->neighbors
, node
) {
409 result
= wlp_discover_neighbor(wlp
, neighbor
);
411 dev_err(dev
, "WLP: Unable to discover neighbor "
412 "%02x:%02x, removing from neighborhood. \n",
413 neighbor
->uwb_dev
->dev_addr
.data
[1],
414 neighbor
->uwb_dev
->dev_addr
.data
[0]);
415 __wlp_neighbor_release(neighbor
);
421 static int wlp_add_neighbor_helper(struct device
*dev
, void *priv
)
423 struct wlp
*wlp
= priv
;
424 struct uwb_dev
*uwb_dev
= to_uwb_dev(dev
);
426 return wlp_add_neighbor(wlp
, uwb_dev
);
430 * Discover WLP neighborhood
432 * Will send D1 association frame to all devices in beacon group that have
433 * discoverable bit set in WLP IE. D2 frames will be received, information
434 * displayed to user in @buf. Partial information (from D2 association
435 * frame) will be cached to assist with future association
438 * The discovery of the WLP neighborhood is triggered by the user. This
439 * should occur infrequently and we thus free current cache and re-allocate
442 * If one neighbor fails during initial discovery (determining if it is a
443 * neighbor or not), we fail all - note that interaction with neighbor has
444 * not occured at this point so if a failure occurs we know something went wrong
445 * locally. We thus undo everything.
447 ssize_t
wlp_discover(struct wlp
*wlp
)
450 struct device
*dev
= &wlp
->rc
->uwb_dev
.dev
;
452 d_fnstart(6, dev
, "wlp %p \n", wlp
);
453 mutex_lock(&wlp
->nbmutex
);
454 /* Clear current neighborhood cache. */
455 __wlp_neighbors_release(wlp
);
456 /* Determine which devices in neighborhood. Repopulate cache. */
457 result
= uwb_dev_for_each(wlp
->rc
, wlp_add_neighbor_helper
, wlp
);
459 /* May have partial neighbor information, release all. */
460 __wlp_neighbors_release(wlp
);
461 goto error_dev_for_each
;
463 /* Discover the properties of devices in neighborhood. */
464 result
= wlp_discover_all_neighbors(wlp
);
465 /* In case of failure we still print our partial results. */
467 dev_err(dev
, "Unable to fully discover neighborhood. \n");
471 mutex_unlock(&wlp
->nbmutex
);
472 d_fnend(6, dev
, "wlp %p \n", wlp
);
477 * Handle events from UWB stack
479 * We handle events conservatively. If a neighbor goes off the air we
480 * remove it from the neighborhood. If an association process is in
481 * progress this function will block waiting for the nbmutex to become
482 * free. The association process will thus be allowed to complete before it
486 void wlp_uwb_notifs_cb(void *_wlp
, struct uwb_dev
*uwb_dev
,
487 enum uwb_notifs event
)
489 struct wlp
*wlp
= _wlp
;
490 struct device
*dev
= &wlp
->rc
->uwb_dev
.dev
;
491 struct wlp_neighbor_e
*neighbor
, *next
;
494 case UWB_NOTIF_ONAIR
:
495 d_printf(6, dev
, "UWB device %02x:%02x is onair\n",
496 uwb_dev
->dev_addr
.data
[1],
497 uwb_dev
->dev_addr
.data
[0]);
498 result
= wlp_eda_create_node(&wlp
->eda
,
499 uwb_dev
->mac_addr
.data
,
502 dev_err(dev
, "WLP: Unable to add new neighbor "
503 "%02x:%02x to EDA cache.\n",
504 uwb_dev
->dev_addr
.data
[1],
505 uwb_dev
->dev_addr
.data
[0]);
507 case UWB_NOTIF_OFFAIR
:
508 d_printf(6, dev
, "UWB device %02x:%02x is offair\n",
509 uwb_dev
->dev_addr
.data
[1],
510 uwb_dev
->dev_addr
.data
[0]);
511 wlp_eda_rm_node(&wlp
->eda
, &uwb_dev
->dev_addr
);
512 mutex_lock(&wlp
->nbmutex
);
513 list_for_each_entry_safe(neighbor
, next
, &wlp
->neighbors
,
515 if (neighbor
->uwb_dev
== uwb_dev
) {
516 d_printf(6, dev
, "Removing device from "
518 __wlp_neighbor_release(neighbor
);
521 mutex_unlock(&wlp
->nbmutex
);
524 dev_err(dev
, "don't know how to handle event %d from uwb\n",
529 int wlp_setup(struct wlp
*wlp
, struct uwb_rc
*rc
)
531 struct device
*dev
= &rc
->uwb_dev
.dev
;
534 d_fnstart(6, dev
, "wlp %p\n", wlp
);
535 BUG_ON(wlp
->fill_device_info
== NULL
);
536 BUG_ON(wlp
->xmit_frame
== NULL
);
537 BUG_ON(wlp
->stop_queue
== NULL
);
538 BUG_ON(wlp
->start_queue
== NULL
);
540 wlp_eda_init(&wlp
->eda
);/* Set up address cache */
541 wlp
->uwb_notifs_handler
.cb
= wlp_uwb_notifs_cb
;
542 wlp
->uwb_notifs_handler
.data
= wlp
;
543 uwb_notifs_register(rc
, &wlp
->uwb_notifs_handler
);
545 uwb_pal_init(&wlp
->pal
);
546 result
= uwb_pal_register(rc
, &wlp
->pal
);
548 uwb_notifs_deregister(wlp
->rc
, &wlp
->uwb_notifs_handler
);
550 d_fnend(6, dev
, "wlp %p, result = %d\n", wlp
, result
);
553 EXPORT_SYMBOL_GPL(wlp_setup
);
555 void wlp_remove(struct wlp
*wlp
)
557 struct device
*dev
= &wlp
->rc
->uwb_dev
.dev
;
558 d_fnstart(6, dev
, "wlp %p\n", wlp
);
559 wlp_neighbors_release(wlp
);
560 uwb_pal_unregister(wlp
->rc
, &wlp
->pal
);
561 uwb_notifs_deregister(wlp
->rc
, &wlp
->uwb_notifs_handler
);
562 wlp_eda_release(&wlp
->eda
);
563 mutex_lock(&wlp
->mutex
);
564 if (wlp
->dev_info
!= NULL
)
565 kfree(wlp
->dev_info
);
566 mutex_unlock(&wlp
->mutex
);
568 /* We have to use NULL here because this function can be called
569 * when the device disappeared. */
570 d_fnend(6, NULL
, "wlp %p\n", wlp
);
572 EXPORT_SYMBOL_GPL(wlp_remove
);
575 * wlp_reset_all - reset the WLP hardware
576 * @wlp: the WLP device to reset.
578 * This schedules a full hardware reset of the WLP device. The radio
579 * controller and any other PALs will also be reset.
581 void wlp_reset_all(struct wlp
*wlp
)
583 uwb_rc_reset_all(wlp
->rc
);
585 EXPORT_SYMBOL_GPL(wlp_reset_all
);