uwb: add the WiMedia LLC Protocol stack
[pandora-kernel.git] / drivers / uwb / wlp / wlp-lc.c
1 /*
2  * WiMedia Logical Link Control Protocol (WLP)
3  *
4  * Copyright (C) 2005-2006 Intel Corporation
5  * Reinette Chatre <reinette.chatre@intel.com>
6  *
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.
10  *
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.
15  *
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.
20  *
21  *
22  * FIXME: docs
23  */
24
25 #include <linux/wlp.h>
26 #define D_LOCAL 6
27 #include <linux/uwb/debug.h>
28 #include "wlp-internal.h"
29
30
31 static
32 void wlp_neighbor_init(struct wlp_neighbor_e *neighbor)
33 {
34         INIT_LIST_HEAD(&neighbor->wssid);
35 }
36
37 /**
38  * Create area for device information storage
39  *
40  * wlp->mutex must be held
41  */
42 int __wlp_alloc_device_info(struct wlp *wlp)
43 {
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");
50                 return -ENOMEM;
51         }
52         return 0;
53 }
54
55
56 /**
57  * Fill in device information using function provided by driver
58  *
59  * wlp->mutex must be held
60  */
61 static
62 void __wlp_fill_device_info(struct wlp *wlp)
63 {
64         struct device *dev = &wlp->rc->uwb_dev.dev;
65
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);
70 }
71
72 /**
73  * Setup device information
74  *
75  * Allocate area for device information and populate it.
76  *
77  * wlp->mutex must be held
78  */
79 int __wlp_setup_device_info(struct wlp *wlp)
80 {
81         int result;
82         struct device *dev = &wlp->rc->uwb_dev.dev;
83
84         result = __wlp_alloc_device_info(wlp);
85         if (result < 0) {
86                 dev_err(dev, "WLP: Unable to allocate area for "
87                         "device information.\n");
88                 return result;
89         }
90         __wlp_fill_device_info(wlp);
91         return 0;
92 }
93
94 /**
95  * Remove information about neighbor stored temporarily
96  *
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.
100  *
101  * We are only interested in keeping neighbor WSS information if that
102  * neighbor is accepting enrollment.
103  *
104  * should be called with wlp->nbmutex held
105  */
106 void wlp_remove_neighbor_tmp_info(struct wlp_neighbor_e *neighbor)
107 {
108         struct wlp_wssid_e *wssid_e, *next;
109         u8 keep;
110         if (!list_empty(&neighbor->wssid)) {
111                 list_for_each_entry_safe(wssid_e, next, &neighbor->wssid,
112                                          node) {
113                         if (wssid_e->info != NULL) {
114                                 keep = wssid_e->info->accept_enroll;
115                                 kfree(wssid_e->info);
116                                 wssid_e->info = NULL;
117                                 if (!keep) {
118                                         list_del(&wssid_e->node);
119                                         kfree(wssid_e);
120                                 }
121                         }
122                 }
123         }
124         if (neighbor->info != NULL) {
125                 kfree(neighbor->info);
126                 neighbor->info = NULL;
127         }
128 }
129
130 /**
131  * Populate WLP neighborhood cache with neighbor information
132  *
133  * A new neighbor is found. If it is discoverable then we add it to the
134  * neighborhood cache.
135  *
136  */
137 static
138 int wlp_add_neighbor(struct wlp *wlp, struct uwb_dev *dev)
139 {
140         int result = 0;
141         int discoverable;
142         struct wlp_neighbor_e *neighbor;
143
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]);
147         /**
148          * FIXME:
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.
153          */
154         discoverable = 1; /* will be changed when FIXME disappears */
155         if (discoverable) {
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 "
160                                 "new neighbor. \n");
161                         result = -ENOMEM;
162                         goto error_no_mem;
163                 }
164                 wlp_neighbor_init(neighbor);
165                 uwb_dev_get(dev);
166                 neighbor->uwb_dev = dev;
167                 list_add(&neighbor->node, &wlp->neighbors);
168         }
169 error_no_mem:
170         d_fnend(6, &dev->dev, "uwb %p, result = %d \n", dev, result);
171         return result;
172 }
173
174 /**
175  * Remove one neighbor from cache
176  */
177 static
178 void __wlp_neighbor_release(struct wlp_neighbor_e *neighbor)
179 {
180         struct wlp_wssid_e *wssid_e, *next_wssid_e;
181
182         list_for_each_entry_safe(wssid_e, next_wssid_e,
183                                  &neighbor->wssid, node) {
184                 list_del(&wssid_e->node);
185                 kfree(wssid_e);
186         }
187         uwb_dev_put(neighbor->uwb_dev);
188         list_del(&neighbor->node);
189         kfree(neighbor);
190 }
191
192 /**
193  * Clear entire neighborhood cache.
194  */
195 static
196 void __wlp_neighbors_release(struct wlp *wlp)
197 {
198         struct wlp_neighbor_e *neighbor, *next;
199         if (list_empty(&wlp->neighbors))
200                 return;
201         list_for_each_entry_safe(neighbor, next, &wlp->neighbors, node) {
202                 __wlp_neighbor_release(neighbor);
203         }
204 }
205
206 static
207 void wlp_neighbors_release(struct wlp *wlp)
208 {
209         mutex_lock(&wlp->nbmutex);
210         __wlp_neighbors_release(wlp);
211         mutex_unlock(&wlp->nbmutex);
212 }
213
214
215
216 /**
217  * Send D1 message to neighbor, receive D2 message
218  *
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
222  *            want to enroll
223  *
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.
230  *
231  * &wss->mutex is held
232  */
233 static
234 int wlp_d1d2_exchange(struct wlp *wlp, struct wlp_neighbor_e *neighbor,
235                       struct wlp_wss *wss, struct wlp_uuid *wssid)
236 {
237         int result;
238         struct device *dev = &wlp->rc->uwb_dev.dev;
239         DECLARE_COMPLETION_ONSTACK(completion);
240         struct wlp_session session;
241         struct sk_buff  *skb;
242         struct wlp_frame_assoc *resp;
243         struct uwb_dev_addr *dev_addr = &neighbor->uwb_dev->dev_addr;
244
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 "
248                         "proceed.\n");
249                 result = -ENXIO;
250                 goto out;
251         }
252         /* Send D1 association frame */
253         result = wlp_send_assoc_frame(wlp, wss, dev_addr, WLP_ASSOC_D1);
254         if (result < 0) {
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");
260                 goto out;
261         }
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);
272         if (result == 0) {
273                 result = -ETIMEDOUT;
274                 dev_err(dev, "Timeout while sending D1 to neighbor "
275                              "%02x:%02x.\n", dev_addr->data[1],
276                              dev_addr->data[0]);
277                 goto error_session;
278         }
279         if (result < 0) {
280                 dev_err(dev, "Unable to discover/enroll neighbor %02x:%02x.\n",
281                         dev_addr->data[1], dev_addr->data[0]);
282                 goto error_session;
283         }
284         /* Parse message in session->data: it will be either D2 or F0 */
285         skb = session.data;
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);
289
290         if (resp->type == WLP_ASSOC_F0) {
291                 result = wlp_parse_f0(wlp, skb);
292                 if (result < 0)
293                         dev_err(dev, "WLP: Unable to parse F0 from neighbor "
294                                 "%02x:%02x.\n", dev_addr->data[1],
295                                 dev_addr->data[0]);
296                 result = -EINVAL;
297                 goto error_resp_parse;
298         }
299         if (wss == NULL) {
300                 /* Discovery */
301                 result = wlp_parse_d2_frame_to_cache(wlp, skb, neighbor);
302                 if (result < 0) {
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;
307                 }
308         } else {
309                 /* Enrollment */
310                 result = wlp_parse_d2_frame_to_enroll(wss, skb, neighbor,
311                                                       wssid);
312                 if (result < 0) {
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;
317                 }
318         }
319 error_resp_parse:
320         kfree_skb(skb);
321 error_session:
322         wlp->session = NULL;
323 out:
324         mutex_unlock(&wlp->mutex);
325         return result;
326 }
327
328 /**
329  * Enroll into WSS of provided WSSID by using neighbor as registrar
330  *
331  * &wss->mutex is held
332  */
333 int wlp_enroll_neighbor(struct wlp *wlp, struct wlp_neighbor_e *neighbor,
334                         struct wlp_wss *wss, struct wlp_uuid *wssid)
335 {
336         int result = 0;
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);
345         if (result < 0) {
346                 dev_err(dev, "WLP: D1/D2 message exchange for enrollment "
347                         "failed. result = %d \n", result);
348                 goto out;
349         }
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]);
354                 result = -EINVAL;
355                 goto out;
356         }
357         if (wss->secure_status == WLP_WSS_SECURE) {
358                 dev_err(dev, "FIXME: need to complete secure enrollment.\n");
359                 result = -EINVAL;
360                 goto error;
361         } else {
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]);
366         }
367
368         d_fnend(6, dev, "wlp %p, neighbor %p, wss %p, wssid %p (%s)\n",
369                   wlp, neighbor, wss, wssid, buf);
370 out:
371         return result;
372 error:
373         wlp_wss_reset(wss);
374         return result;
375 }
376
377 /**
378  * Discover WSS information of neighbor's active WSS
379  */
380 static
381 int wlp_discover_neighbor(struct wlp *wlp,
382                           struct wlp_neighbor_e *neighbor)
383 {
384         return wlp_d1d2_exchange(wlp, neighbor, NULL, NULL);
385 }
386
387
388 /**
389  * Each neighbor in the neighborhood cache is discoverable. Discover it.
390  *
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.
394  *
395  * The discovery is not done in parallel. This is simple and enables us to
396  * maintain only one association context.
397  *
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.
400  */
401 static
402 int wlp_discover_all_neighbors(struct wlp *wlp)
403 {
404         int result = 0;
405         struct device *dev = &wlp->rc->uwb_dev.dev;
406         struct wlp_neighbor_e *neighbor, *next;
407
408         list_for_each_entry_safe(neighbor, next, &wlp->neighbors, node) {
409                 result = wlp_discover_neighbor(wlp, neighbor);
410                 if (result < 0) {
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);
416                 }
417         }
418         return result;
419 }
420
421 static int wlp_add_neighbor_helper(struct device *dev, void *priv)
422 {
423         struct wlp *wlp = priv;
424         struct uwb_dev *uwb_dev = to_uwb_dev(dev);
425
426         return wlp_add_neighbor(wlp, uwb_dev);
427 }
428
429 /**
430  * Discover WLP neighborhood
431  *
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
436  * requests.
437  *
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
440  * memory if needed.
441  *
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.
446  */
447 ssize_t wlp_discover(struct wlp *wlp)
448 {
449         int result = 0;
450         struct device *dev = &wlp->rc->uwb_dev.dev;
451
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);
458         if (result < 0) {
459                 /* May have partial neighbor information, release all. */
460                 __wlp_neighbors_release(wlp);
461                 goto error_dev_for_each;
462         }
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. */
466         if (result < 0) {
467                 dev_err(dev, "Unable to fully discover neighborhood. \n");
468                 result = 0;
469         }
470 error_dev_for_each:
471         mutex_unlock(&wlp->nbmutex);
472         d_fnend(6, dev, "wlp %p \n", wlp);
473         return result;
474 }
475
476 /**
477  * Handle events from UWB stack
478  *
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
483  * is removed.
484  */
485 static
486 void wlp_uwb_notifs_cb(void *_wlp, struct uwb_dev *uwb_dev,
487                        enum uwb_notifs event)
488 {
489         struct wlp *wlp = _wlp;
490         struct device *dev = &wlp->rc->uwb_dev.dev;
491         struct wlp_neighbor_e *neighbor, *next;
492         int result;
493         switch (event) {
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,
500                                              &uwb_dev->dev_addr);
501                 if (result < 0)
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]);
506                 break;
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,
514                                          node) {
515                         if (neighbor->uwb_dev == uwb_dev) {
516                                 d_printf(6, dev, "Removing device from "
517                                          "neighborhood.\n");
518                                 __wlp_neighbor_release(neighbor);
519                         }
520                 }
521                 mutex_unlock(&wlp->nbmutex);
522                 break;
523         default:
524                 dev_err(dev, "don't know how to handle event %d from uwb\n",
525                                 event);
526         }
527 }
528
529 int wlp_setup(struct wlp *wlp, struct uwb_rc *rc)
530 {
531         struct device *dev = &rc->uwb_dev.dev;
532         int result;
533
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);
539         wlp->rc = rc;
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);
544
545         uwb_pal_init(&wlp->pal);
546         result = uwb_pal_register(rc, &wlp->pal);
547         if (result < 0)
548                 uwb_notifs_deregister(wlp->rc, &wlp->uwb_notifs_handler);
549
550         d_fnend(6, dev, "wlp %p, result = %d\n", wlp, result);
551         return result;
552 }
553 EXPORT_SYMBOL_GPL(wlp_setup);
554
555 void wlp_remove(struct wlp *wlp)
556 {
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);
567         wlp->rc = NULL;
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);
571 }
572 EXPORT_SYMBOL_GPL(wlp_remove);
573
574 /**
575  * wlp_reset_all - reset the WLP hardware
576  * @wlp: the WLP device to reset.
577  *
578  * This schedules a full hardware reset of the WLP device.  The radio
579  * controller and any other PALs will also be reset.
580  */
581 void wlp_reset_all(struct wlp *wlp)
582 {
583         uwb_rc_reset_all(wlp->rc);
584 }
585 EXPORT_SYMBOL_GPL(wlp_reset_all);