GUI: Fix Tomato RAF theme for all builds. Compilation typo.
[tomato.git] / release / src-rt-6.x.4708 / linux / linux-2.6.36 / drivers / uwb / wlp / wlp-lc.c
blobf59674ab14b808205845f45ea0861713e778e44e
2 #include <linux/wlp.h>
3 #include <linux/slab.h>
5 #include "wlp-internal.h"
7 static
8 void wlp_neighbor_init(struct wlp_neighbor_e *neighbor)
10 INIT_LIST_HEAD(&neighbor->wssid);
13 /**
14 * Create area for device information storage
16 * wlp->mutex must be held
18 int __wlp_alloc_device_info(struct wlp *wlp)
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;
28 return 0;
32 /**
33 * Fill in device information using function provided by driver
35 * wlp->mutex must be held
37 static
38 void __wlp_fill_device_info(struct wlp *wlp)
40 wlp->fill_device_info(wlp, wlp->dev_info);
43 /**
44 * Setup device information
46 * Allocate area for device information and populate it.
48 * wlp->mutex must be held
50 int __wlp_setup_device_info(struct wlp *wlp)
52 int result;
53 struct device *dev = &wlp->rc->uwb_dev.dev;
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;
61 __wlp_fill_device_info(wlp);
62 return 0;
65 /**
66 * Remove information about neighbor stored temporarily
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.
72 * We are only interested in keeping neighbor WSS information if that
73 * neighbor is accepting enrollment.
75 * should be called with wlp->nbmutex held
77 void wlp_remove_neighbor_tmp_info(struct wlp_neighbor_e *neighbor)
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);
95 if (neighbor->info != NULL) {
96 kfree(neighbor->info);
97 neighbor->info = NULL;
102 * Populate WLP neighborhood cache with neighbor information
104 * A new neighbor is found. If it is discoverable then we add it to the
105 * neighborhood cache.
108 static
109 int wlp_add_neighbor(struct wlp *wlp, struct uwb_dev *dev)
111 int result = 0;
112 int discoverable;
113 struct wlp_neighbor_e *neighbor;
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;
125 wlp_neighbor_init(neighbor);
126 uwb_dev_get(dev);
127 neighbor->uwb_dev = dev;
128 list_add(&neighbor->node, &wlp->neighbors);
130 error_no_mem:
131 return result;
135 * Remove one neighbor from cache
137 static
138 void __wlp_neighbor_release(struct wlp_neighbor_e *neighbor)
140 struct wlp_wssid_e *wssid_e, *next_wssid_e;
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);
147 uwb_dev_put(neighbor->uwb_dev);
148 list_del(&neighbor->node);
149 kfree(neighbor);
153 * Clear entire neighborhood cache.
155 static
156 void __wlp_neighbors_release(struct wlp *wlp)
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);
166 static
167 void wlp_neighbors_release(struct wlp *wlp)
169 mutex_lock(&wlp->nbmutex);
170 __wlp_neighbors_release(wlp);
171 mutex_unlock(&wlp->nbmutex);
177 * Send D1 message to neighbor, receive D2 message
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
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.
191 * &wss->mutex is held
193 static
194 int wlp_d1d2_exchange(struct wlp *wlp, struct wlp_neighbor_e *neighbor,
195 struct wlp_wss *wss, struct wlp_uuid *wssid)
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;
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;
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;
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;
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;
242 /* Parse message in session->data: it will be either D2 or F0 */
243 skb = session.data;
244 resp = (void *) skb->data;
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;
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;
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;
275 error_resp_parse:
276 kfree_skb(skb);
277 error_session:
278 wlp->session = NULL;
279 out:
280 mutex_unlock(&wlp->mutex);
281 return result;
285 * Enroll into WSS of provided WSSID by using neighbor as registrar
287 * &wss->mutex is held
289 int wlp_enroll_neighbor(struct wlp *wlp, struct wlp_neighbor_e *neighbor,
290 struct wlp_wss *wss, struct wlp_uuid *wssid)
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;
297 wlp_wss_uuid_print(buf, sizeof(buf), wssid);
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;
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;
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]);
322 out:
323 return result;
324 error:
325 wlp_wss_reset(wss);
326 return result;
330 * Discover WSS information of neighbor's active WSS
332 static
333 int wlp_discover_neighbor(struct wlp *wlp,
334 struct wlp_neighbor_e *neighbor)
336 return wlp_d1d2_exchange(wlp, neighbor, NULL, NULL);
341 * Each neighbor in the neighborhood cache is discoverable. Discover it.
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.
347 * The discovery is not done in parallel. This is simple and enables us to
348 * maintain only one association context.
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.
353 static
354 int wlp_discover_all_neighbors(struct wlp *wlp)
356 int result = 0;
357 struct device *dev = &wlp->rc->uwb_dev.dev;
358 struct wlp_neighbor_e *neighbor, *next;
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);
370 return result;
373 static int wlp_add_neighbor_helper(struct device *dev, void *priv)
375 struct wlp *wlp = priv;
376 struct uwb_dev *uwb_dev = to_uwb_dev(dev);
378 return wlp_add_neighbor(wlp, uwb_dev);
382 * Discover WLP neighborhood
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.
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.
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.
399 ssize_t wlp_discover(struct wlp *wlp)
401 int result = 0;
402 struct device *dev = &wlp->rc->uwb_dev.dev;
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;
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;
421 error_dev_for_each:
422 mutex_unlock(&wlp->nbmutex);
423 return result;
427 * Handle events from UWB stack
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.
435 static
436 void wlp_uwb_notifs_cb(void *_wlp, struct uwb_dev *uwb_dev,
437 enum uwb_notifs event)
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);
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);
469 static void wlp_channel_changed(struct uwb_pal *pal, int channel)
471 struct wlp *wlp = container_of(pal, struct wlp, pal);
473 if (channel < 0)
474 netif_carrier_off(wlp->ndev);
475 else
476 netif_carrier_on(wlp->ndev);
479 int wlp_setup(struct wlp *wlp, struct uwb_rc *rc, struct net_device *ndev)
481 int result;
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);
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);
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);
502 return result;
504 EXPORT_SYMBOL_GPL(wlp_setup);
506 void wlp_remove(struct wlp *wlp)
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;
518 EXPORT_SYMBOL_GPL(wlp_remove);
521 * wlp_reset_all - reset the WLP hardware
522 * @wlp: the WLP device to reset.
524 * This schedules a full hardware reset of the WLP device. The radio
525 * controller and any other PALs will also be reset.
527 void wlp_reset_all(struct wlp *wlp)
529 uwb_rc_reset_all(wlp->rc);
531 EXPORT_SYMBOL_GPL(wlp_reset_all);