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