[ARM] pxa: update defconfig for Verdex Pro
[linux-2.6/verdex.git] / drivers / uwb / wlp / wlp-lc.c
blob13db739c4e397621487b88abbcd7b2c07c93f332
1 /*
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
19 * 02110-1301, USA.
22 * FIXME: docs
24 #include <linux/wlp.h>
26 #include "wlp-internal.h"
28 static
29 void wlp_neighbor_init(struct wlp_neighbor_e *neighbor)
31 INIT_LIST_HEAD(&neighbor->wssid);
34 /**
35 * Create area for device information storage
37 * wlp->mutex must be held
39 int __wlp_alloc_device_info(struct wlp *wlp)
41 struct device *dev = &wlp->rc->uwb_dev.dev;
42 BUG_ON(wlp->dev_info != NULL);
43 wlp->dev_info = kzalloc(sizeof(struct wlp_device_info), GFP_KERNEL);
44 if (wlp->dev_info == NULL) {
45 dev_err(dev, "WLP: Unable to allocate memory for "
46 "device information.\n");
47 return -ENOMEM;
49 return 0;
53 /**
54 * Fill in device information using function provided by driver
56 * wlp->mutex must be held
58 static
59 void __wlp_fill_device_info(struct wlp *wlp)
61 wlp->fill_device_info(wlp, wlp->dev_info);
64 /**
65 * Setup device information
67 * Allocate area for device information and populate it.
69 * wlp->mutex must be held
71 int __wlp_setup_device_info(struct wlp *wlp)
73 int result;
74 struct device *dev = &wlp->rc->uwb_dev.dev;
76 result = __wlp_alloc_device_info(wlp);
77 if (result < 0) {
78 dev_err(dev, "WLP: Unable to allocate area for "
79 "device information.\n");
80 return result;
82 __wlp_fill_device_info(wlp);
83 return 0;
86 /**
87 * Remove information about neighbor stored temporarily
89 * Information learned during discovey should only be stored when the
90 * device enrolls in the neighbor's WSS. We do need to store this
91 * information temporarily in order to present it to the user.
93 * We are only interested in keeping neighbor WSS information if that
94 * neighbor is accepting enrollment.
96 * should be called with wlp->nbmutex held
98 void wlp_remove_neighbor_tmp_info(struct wlp_neighbor_e *neighbor)
100 struct wlp_wssid_e *wssid_e, *next;
101 u8 keep;
102 if (!list_empty(&neighbor->wssid)) {
103 list_for_each_entry_safe(wssid_e, next, &neighbor->wssid,
104 node) {
105 if (wssid_e->info != NULL) {
106 keep = wssid_e->info->accept_enroll;
107 kfree(wssid_e->info);
108 wssid_e->info = NULL;
109 if (!keep) {
110 list_del(&wssid_e->node);
111 kfree(wssid_e);
116 if (neighbor->info != NULL) {
117 kfree(neighbor->info);
118 neighbor->info = NULL;
123 * Populate WLP neighborhood cache with neighbor information
125 * A new neighbor is found. If it is discoverable then we add it to the
126 * neighborhood cache.
129 static
130 int wlp_add_neighbor(struct wlp *wlp, struct uwb_dev *dev)
132 int result = 0;
133 int discoverable;
134 struct wlp_neighbor_e *neighbor;
137 * FIXME:
138 * Use contents of WLP IE found in beacon cache to determine if
139 * neighbor is discoverable.
140 * The device does not support WLP IE yet so this still needs to be
141 * done. Until then we assume all devices are discoverable.
143 discoverable = 1; /* will be changed when FIXME disappears */
144 if (discoverable) {
145 /* Add neighbor to cache for discovery */
146 neighbor = kzalloc(sizeof(*neighbor), GFP_KERNEL);
147 if (neighbor == NULL) {
148 dev_err(&dev->dev, "Unable to create memory for "
149 "new neighbor. \n");
150 result = -ENOMEM;
151 goto error_no_mem;
153 wlp_neighbor_init(neighbor);
154 uwb_dev_get(dev);
155 neighbor->uwb_dev = dev;
156 list_add(&neighbor->node, &wlp->neighbors);
158 error_no_mem:
159 return result;
163 * Remove one neighbor from cache
165 static
166 void __wlp_neighbor_release(struct wlp_neighbor_e *neighbor)
168 struct wlp_wssid_e *wssid_e, *next_wssid_e;
170 list_for_each_entry_safe(wssid_e, next_wssid_e,
171 &neighbor->wssid, node) {
172 list_del(&wssid_e->node);
173 kfree(wssid_e);
175 uwb_dev_put(neighbor->uwb_dev);
176 list_del(&neighbor->node);
177 kfree(neighbor);
181 * Clear entire neighborhood cache.
183 static
184 void __wlp_neighbors_release(struct wlp *wlp)
186 struct wlp_neighbor_e *neighbor, *next;
187 if (list_empty(&wlp->neighbors))
188 return;
189 list_for_each_entry_safe(neighbor, next, &wlp->neighbors, node) {
190 __wlp_neighbor_release(neighbor);
194 static
195 void wlp_neighbors_release(struct wlp *wlp)
197 mutex_lock(&wlp->nbmutex);
198 __wlp_neighbors_release(wlp);
199 mutex_unlock(&wlp->nbmutex);
205 * Send D1 message to neighbor, receive D2 message
207 * @neighbor: neighbor to which D1 message will be sent
208 * @wss: if not NULL, it is an enrollment request for this WSS
209 * @wssid: if wss not NULL, this is the wssid of the WSS in which we
210 * want to enroll
212 * A D1/D2 exchange is done for one of two reasons: discovery or
213 * enrollment. If done for discovery the D1 message is sent to the neighbor
214 * and the contents of the D2 response is stored in a temporary cache.
215 * If done for enrollment the @wss and @wssid are provided also. In this
216 * case the D1 message is sent to the neighbor, the D2 response is parsed
217 * for enrollment of the WSS with wssid.
219 * &wss->mutex is held
221 static
222 int wlp_d1d2_exchange(struct wlp *wlp, struct wlp_neighbor_e *neighbor,
223 struct wlp_wss *wss, struct wlp_uuid *wssid)
225 int result;
226 struct device *dev = &wlp->rc->uwb_dev.dev;
227 DECLARE_COMPLETION_ONSTACK(completion);
228 struct wlp_session session;
229 struct sk_buff *skb;
230 struct wlp_frame_assoc *resp;
231 struct uwb_dev_addr *dev_addr = &neighbor->uwb_dev->dev_addr;
233 mutex_lock(&wlp->mutex);
234 if (!wlp_uuid_is_set(&wlp->uuid)) {
235 dev_err(dev, "WLP: UUID is not set. Set via sysfs to "
236 "proceed.\n");
237 result = -ENXIO;
238 goto out;
240 /* Send D1 association frame */
241 result = wlp_send_assoc_frame(wlp, wss, dev_addr, WLP_ASSOC_D1);
242 if (result < 0) {
243 dev_err(dev, "Unable to send D1 frame to neighbor "
244 "%02x:%02x (%d)\n", dev_addr->data[1],
245 dev_addr->data[0], result);
246 goto out;
248 /* Create session, wait for response */
249 session.exp_message = WLP_ASSOC_D2;
250 session.cb = wlp_session_cb;
251 session.cb_priv = &completion;
252 session.neighbor_addr = *dev_addr;
253 BUG_ON(wlp->session != NULL);
254 wlp->session = &session;
255 /* Wait for D2/F0 frame */
256 result = wait_for_completion_interruptible_timeout(&completion,
257 WLP_PER_MSG_TIMEOUT * HZ);
258 if (result == 0) {
259 result = -ETIMEDOUT;
260 dev_err(dev, "Timeout while sending D1 to neighbor "
261 "%02x:%02x.\n", dev_addr->data[1],
262 dev_addr->data[0]);
263 goto error_session;
265 if (result < 0) {
266 dev_err(dev, "Unable to discover/enroll neighbor %02x:%02x.\n",
267 dev_addr->data[1], dev_addr->data[0]);
268 goto error_session;
270 /* Parse message in session->data: it will be either D2 or F0 */
271 skb = session.data;
272 resp = (void *) skb->data;
274 if (resp->type == WLP_ASSOC_F0) {
275 result = wlp_parse_f0(wlp, skb);
276 if (result < 0)
277 dev_err(dev, "WLP: Unable to parse F0 from neighbor "
278 "%02x:%02x.\n", dev_addr->data[1],
279 dev_addr->data[0]);
280 result = -EINVAL;
281 goto error_resp_parse;
283 if (wss == NULL) {
284 /* Discovery */
285 result = wlp_parse_d2_frame_to_cache(wlp, skb, neighbor);
286 if (result < 0) {
287 dev_err(dev, "WLP: Unable to parse D2 message from "
288 "neighbor %02x:%02x for discovery.\n",
289 dev_addr->data[1], dev_addr->data[0]);
290 goto error_resp_parse;
292 } else {
293 /* Enrollment */
294 result = wlp_parse_d2_frame_to_enroll(wss, skb, neighbor,
295 wssid);
296 if (result < 0) {
297 dev_err(dev, "WLP: Unable to parse D2 message from "
298 "neighbor %02x:%02x for enrollment.\n",
299 dev_addr->data[1], dev_addr->data[0]);
300 goto error_resp_parse;
303 error_resp_parse:
304 kfree_skb(skb);
305 error_session:
306 wlp->session = NULL;
307 out:
308 mutex_unlock(&wlp->mutex);
309 return result;
313 * Enroll into WSS of provided WSSID by using neighbor as registrar
315 * &wss->mutex is held
317 int wlp_enroll_neighbor(struct wlp *wlp, struct wlp_neighbor_e *neighbor,
318 struct wlp_wss *wss, struct wlp_uuid *wssid)
320 int result = 0;
321 struct device *dev = &wlp->rc->uwb_dev.dev;
322 char buf[WLP_WSS_UUID_STRSIZE];
323 struct uwb_dev_addr *dev_addr = &neighbor->uwb_dev->dev_addr;
325 wlp_wss_uuid_print(buf, sizeof(buf), wssid);
327 result = wlp_d1d2_exchange(wlp, neighbor, wss, wssid);
328 if (result < 0) {
329 dev_err(dev, "WLP: D1/D2 message exchange for enrollment "
330 "failed. result = %d \n", result);
331 goto out;
333 if (wss->state != WLP_WSS_STATE_PART_ENROLLED) {
334 dev_err(dev, "WLP: Unable to enroll into WSS %s using "
335 "neighbor %02x:%02x. \n", buf,
336 dev_addr->data[1], dev_addr->data[0]);
337 result = -EINVAL;
338 goto out;
340 if (wss->secure_status == WLP_WSS_SECURE) {
341 dev_err(dev, "FIXME: need to complete secure enrollment.\n");
342 result = -EINVAL;
343 goto error;
344 } else {
345 wss->state = WLP_WSS_STATE_ENROLLED;
346 dev_dbg(dev, "WLP: Success Enrollment into unsecure WSS "
347 "%s using neighbor %02x:%02x. \n",
348 buf, dev_addr->data[1], dev_addr->data[0]);
350 out:
351 return result;
352 error:
353 wlp_wss_reset(wss);
354 return result;
358 * Discover WSS information of neighbor's active WSS
360 static
361 int wlp_discover_neighbor(struct wlp *wlp,
362 struct wlp_neighbor_e *neighbor)
364 return wlp_d1d2_exchange(wlp, neighbor, NULL, NULL);
369 * Each neighbor in the neighborhood cache is discoverable. Discover it.
371 * Discovery is done through sending of D1 association frame and parsing
372 * the D2 association frame response. Only wssid from D2 will be included
373 * in neighbor cache, rest is just displayed to user and forgotten.
375 * The discovery is not done in parallel. This is simple and enables us to
376 * maintain only one association context.
378 * The discovery of one neighbor does not affect the other, but if the
379 * discovery of a neighbor fails it is removed from the neighborhood cache.
381 static
382 int wlp_discover_all_neighbors(struct wlp *wlp)
384 int result = 0;
385 struct device *dev = &wlp->rc->uwb_dev.dev;
386 struct wlp_neighbor_e *neighbor, *next;
388 list_for_each_entry_safe(neighbor, next, &wlp->neighbors, node) {
389 result = wlp_discover_neighbor(wlp, neighbor);
390 if (result < 0) {
391 dev_err(dev, "WLP: Unable to discover neighbor "
392 "%02x:%02x, removing from neighborhood. \n",
393 neighbor->uwb_dev->dev_addr.data[1],
394 neighbor->uwb_dev->dev_addr.data[0]);
395 __wlp_neighbor_release(neighbor);
398 return result;
401 static int wlp_add_neighbor_helper(struct device *dev, void *priv)
403 struct wlp *wlp = priv;
404 struct uwb_dev *uwb_dev = to_uwb_dev(dev);
406 return wlp_add_neighbor(wlp, uwb_dev);
410 * Discover WLP neighborhood
412 * Will send D1 association frame to all devices in beacon group that have
413 * discoverable bit set in WLP IE. D2 frames will be received, information
414 * displayed to user in @buf. Partial information (from D2 association
415 * frame) will be cached to assist with future association
416 * requests.
418 * The discovery of the WLP neighborhood is triggered by the user. This
419 * should occur infrequently and we thus free current cache and re-allocate
420 * memory if needed.
422 * If one neighbor fails during initial discovery (determining if it is a
423 * neighbor or not), we fail all - note that interaction with neighbor has
424 * not occured at this point so if a failure occurs we know something went wrong
425 * locally. We thus undo everything.
427 ssize_t wlp_discover(struct wlp *wlp)
429 int result = 0;
430 struct device *dev = &wlp->rc->uwb_dev.dev;
432 mutex_lock(&wlp->nbmutex);
433 /* Clear current neighborhood cache. */
434 __wlp_neighbors_release(wlp);
435 /* Determine which devices in neighborhood. Repopulate cache. */
436 result = uwb_dev_for_each(wlp->rc, wlp_add_neighbor_helper, wlp);
437 if (result < 0) {
438 /* May have partial neighbor information, release all. */
439 __wlp_neighbors_release(wlp);
440 goto error_dev_for_each;
442 /* Discover the properties of devices in neighborhood. */
443 result = wlp_discover_all_neighbors(wlp);
444 /* In case of failure we still print our partial results. */
445 if (result < 0) {
446 dev_err(dev, "Unable to fully discover neighborhood. \n");
447 result = 0;
449 error_dev_for_each:
450 mutex_unlock(&wlp->nbmutex);
451 return result;
455 * Handle events from UWB stack
457 * We handle events conservatively. If a neighbor goes off the air we
458 * remove it from the neighborhood. If an association process is in
459 * progress this function will block waiting for the nbmutex to become
460 * free. The association process will thus be allowed to complete before it
461 * is removed.
463 static
464 void wlp_uwb_notifs_cb(void *_wlp, struct uwb_dev *uwb_dev,
465 enum uwb_notifs event)
467 struct wlp *wlp = _wlp;
468 struct device *dev = &wlp->rc->uwb_dev.dev;
469 struct wlp_neighbor_e *neighbor, *next;
470 int result;
471 switch (event) {
472 case UWB_NOTIF_ONAIR:
473 result = wlp_eda_create_node(&wlp->eda,
474 uwb_dev->mac_addr.data,
475 &uwb_dev->dev_addr);
476 if (result < 0)
477 dev_err(dev, "WLP: Unable to add new neighbor "
478 "%02x:%02x to EDA cache.\n",
479 uwb_dev->dev_addr.data[1],
480 uwb_dev->dev_addr.data[0]);
481 break;
482 case UWB_NOTIF_OFFAIR:
483 wlp_eda_rm_node(&wlp->eda, &uwb_dev->dev_addr);
484 mutex_lock(&wlp->nbmutex);
485 list_for_each_entry_safe(neighbor, next, &wlp->neighbors, node) {
486 if (neighbor->uwb_dev == uwb_dev)
487 __wlp_neighbor_release(neighbor);
489 mutex_unlock(&wlp->nbmutex);
490 break;
491 default:
492 dev_err(dev, "don't know how to handle event %d from uwb\n",
493 event);
497 static void wlp_channel_changed(struct uwb_pal *pal, int channel)
499 struct wlp *wlp = container_of(pal, struct wlp, pal);
501 if (channel < 0)
502 netif_carrier_off(wlp->ndev);
503 else
504 netif_carrier_on(wlp->ndev);
507 int wlp_setup(struct wlp *wlp, struct uwb_rc *rc, struct net_device *ndev)
509 int result;
511 BUG_ON(wlp->fill_device_info == NULL);
512 BUG_ON(wlp->xmit_frame == NULL);
513 BUG_ON(wlp->stop_queue == NULL);
514 BUG_ON(wlp->start_queue == NULL);
516 wlp->rc = rc;
517 wlp->ndev = ndev;
518 wlp_eda_init(&wlp->eda);/* Set up address cache */
519 wlp->uwb_notifs_handler.cb = wlp_uwb_notifs_cb;
520 wlp->uwb_notifs_handler.data = wlp;
521 uwb_notifs_register(rc, &wlp->uwb_notifs_handler);
523 uwb_pal_init(&wlp->pal);
524 wlp->pal.rc = rc;
525 wlp->pal.channel_changed = wlp_channel_changed;
526 result = uwb_pal_register(&wlp->pal);
527 if (result < 0)
528 uwb_notifs_deregister(wlp->rc, &wlp->uwb_notifs_handler);
530 return result;
532 EXPORT_SYMBOL_GPL(wlp_setup);
534 void wlp_remove(struct wlp *wlp)
536 wlp_neighbors_release(wlp);
537 uwb_pal_unregister(&wlp->pal);
538 uwb_notifs_deregister(wlp->rc, &wlp->uwb_notifs_handler);
539 wlp_eda_release(&wlp->eda);
540 mutex_lock(&wlp->mutex);
541 if (wlp->dev_info != NULL)
542 kfree(wlp->dev_info);
543 mutex_unlock(&wlp->mutex);
544 wlp->rc = NULL;
546 EXPORT_SYMBOL_GPL(wlp_remove);
549 * wlp_reset_all - reset the WLP hardware
550 * @wlp: the WLP device to reset.
552 * This schedules a full hardware reset of the WLP device. The radio
553 * controller and any other PALs will also be reset.
555 void wlp_reset_all(struct wlp *wlp)
557 uwb_rc_reset_all(wlp->rc);
559 EXPORT_SYMBOL_GPL(wlp_reset_all);