diff options
author | Stefano Panella <stefano.panella@csr.com> | 2008-11-04 09:06:31 -0500 |
---|---|---|
committer | David Vrabel <david.vrabel@csr.com> | 2008-11-04 10:53:29 -0500 |
commit | c5995bd2819dc577d0b32b26be0836d16c977e24 (patch) | |
tree | 2cc5122623ace2571b7b3080b1b9a61f8282cfd4 | |
parent | f88518d122f1b007f47a46aff37ca2885126a923 (diff) |
uwb: infrastructure for handling Relinquish Request IEs
The structures and event handler needed to handle Relinish Request IEs
received from neighbors. Nothing is done with these IEs yet.
Signed-off-by: Stefano Panella <stefano.panella@csr.com>
Signed-off-by: David Vrabel <david.vrabel@csr.com>
-rw-r--r-- | drivers/uwb/Makefile | 1 | ||||
-rw-r--r-- | drivers/uwb/ie-rcv.c | 55 | ||||
-rw-r--r-- | drivers/uwb/uwb-internal.h | 1 | ||||
-rw-r--r-- | drivers/uwb/uwbd.c | 4 | ||||
-rw-r--r-- | include/linux/uwb/spec.h | 28 |
5 files changed, 89 insertions, 0 deletions
diff --git a/drivers/uwb/Makefile b/drivers/uwb/Makefile index 257e6908304c..2b99c3e61671 100644 --- a/drivers/uwb/Makefile +++ b/drivers/uwb/Makefile | |||
@@ -13,6 +13,7 @@ uwb-objs := \ | |||
13 | drp-ie.o \ | 13 | drp-ie.o \ |
14 | est.o \ | 14 | est.o \ |
15 | ie.o \ | 15 | ie.o \ |
16 | ie-rcv.o \ | ||
16 | lc-dev.o \ | 17 | lc-dev.o \ |
17 | lc-rc.o \ | 18 | lc-rc.o \ |
18 | neh.o \ | 19 | neh.o \ |
diff --git a/drivers/uwb/ie-rcv.c b/drivers/uwb/ie-rcv.c new file mode 100644 index 000000000000..917e6d78a798 --- /dev/null +++ b/drivers/uwb/ie-rcv.c | |||
@@ -0,0 +1,55 @@ | |||
1 | /* | ||
2 | * Ultra Wide Band | ||
3 | * IE Received notification handling. | ||
4 | * | ||
5 | * Copyright (C) 2008 Cambridge Silicon Radio Ltd. | ||
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, see <http://www.gnu.org/licenses/>. | ||
18 | */ | ||
19 | |||
20 | #include <linux/errno.h> | ||
21 | #include <linux/module.h> | ||
22 | #include <linux/device.h> | ||
23 | #include <linux/bitmap.h> | ||
24 | #include "uwb-internal.h" | ||
25 | |||
26 | /* | ||
27 | * Process an incoming IE Received notification. | ||
28 | */ | ||
29 | int uwbd_evt_handle_rc_ie_rcv(struct uwb_event *evt) | ||
30 | { | ||
31 | int result = -EINVAL; | ||
32 | struct device *dev = &evt->rc->uwb_dev.dev; | ||
33 | struct uwb_rc_evt_ie_rcv *iercv; | ||
34 | size_t iesize; | ||
35 | |||
36 | /* Is there enough data to decode it? */ | ||
37 | if (evt->notif.size < sizeof(*iercv)) { | ||
38 | dev_err(dev, "IE Received notification: Not enough data to " | ||
39 | "decode (%zu vs %zu bytes needed)\n", | ||
40 | evt->notif.size, sizeof(*iercv)); | ||
41 | goto error; | ||
42 | } | ||
43 | iercv = container_of(evt->notif.rceb, struct uwb_rc_evt_ie_rcv, rceb); | ||
44 | iesize = le16_to_cpu(iercv->wIELength); | ||
45 | |||
46 | dev_dbg(dev, "IE received, element ID=%d\n", iercv->IEData[0]); | ||
47 | |||
48 | if (iercv->IEData[0] == UWB_RELINQUISH_REQUEST_IE) { | ||
49 | dev_warn(dev, "unhandled Relinquish Request IE\n"); | ||
50 | } | ||
51 | |||
52 | return 0; | ||
53 | error: | ||
54 | return result; | ||
55 | } | ||
diff --git a/drivers/uwb/uwb-internal.h b/drivers/uwb/uwb-internal.h index 983ebc4dd8d5..031e8a885681 100644 --- a/drivers/uwb/uwb-internal.h +++ b/drivers/uwb/uwb-internal.h | |||
@@ -167,6 +167,7 @@ extern void uwbd_event_queue(struct uwb_event *); | |||
167 | void uwbd_flush(struct uwb_rc *rc); | 167 | void uwbd_flush(struct uwb_rc *rc); |
168 | 168 | ||
169 | /* UWB event handlers */ | 169 | /* UWB event handlers */ |
170 | extern int uwbd_evt_handle_rc_ie_rcv(struct uwb_event *); | ||
170 | extern int uwbd_evt_handle_rc_beacon(struct uwb_event *); | 171 | extern int uwbd_evt_handle_rc_beacon(struct uwb_event *); |
171 | extern int uwbd_evt_handle_rc_beacon_size(struct uwb_event *); | 172 | extern int uwbd_evt_handle_rc_beacon_size(struct uwb_event *); |
172 | extern int uwbd_evt_handle_rc_bpoie_change(struct uwb_event *); | 173 | extern int uwbd_evt_handle_rc_bpoie_change(struct uwb_event *); |
diff --git a/drivers/uwb/uwbd.c b/drivers/uwb/uwbd.c index 78908416e42c..f75113571f4a 100644 --- a/drivers/uwb/uwbd.c +++ b/drivers/uwb/uwbd.c | |||
@@ -104,6 +104,10 @@ struct uwbd_event { | |||
104 | /** Table of handlers for and properties of the UWBD Radio Control Events */ | 104 | /** Table of handlers for and properties of the UWBD Radio Control Events */ |
105 | static | 105 | static |
106 | struct uwbd_event uwbd_events[] = { | 106 | struct uwbd_event uwbd_events[] = { |
107 | [UWB_RC_EVT_IE_RCV] = { | ||
108 | .handler = uwbd_evt_handle_rc_ie_rcv, | ||
109 | .name = "IE_RECEIVED" | ||
110 | }, | ||
107 | [UWB_RC_EVT_BEACON] = { | 111 | [UWB_RC_EVT_BEACON] = { |
108 | .handler = uwbd_evt_handle_rc_beacon, | 112 | .handler = uwbd_evt_handle_rc_beacon, |
109 | .name = "BEACON_RECEIVED" | 113 | .name = "BEACON_RECEIVED" |
diff --git a/include/linux/uwb/spec.h b/include/linux/uwb/spec.h index 198c15f8e251..a30436ea53aa 100644 --- a/include/linux/uwb/spec.h +++ b/include/linux/uwb/spec.h | |||
@@ -200,6 +200,12 @@ enum uwb_drp_reason { | |||
200 | UWB_DRP_REASON_MODIFIED, | 200 | UWB_DRP_REASON_MODIFIED, |
201 | }; | 201 | }; |
202 | 202 | ||
203 | /** Relinquish Request Reason Codes ([ECMA-368] table 113) */ | ||
204 | enum uwb_relinquish_req_reason { | ||
205 | UWB_RELINQUISH_REQ_REASON_NON_SPECIFIC = 0, | ||
206 | UWB_RELINQUISH_REQ_REASON_OVER_ALLOCATION, | ||
207 | }; | ||
208 | |||
203 | /** | 209 | /** |
204 | * DRP Notification Reason Codes (WHCI 0.95 [3.1.4.9]) | 210 | * DRP Notification Reason Codes (WHCI 0.95 [3.1.4.9]) |
205 | */ | 211 | */ |
@@ -252,6 +258,7 @@ enum uwb_ie { | |||
252 | UWB_APP_SPEC_PROBE_IE = 15, | 258 | UWB_APP_SPEC_PROBE_IE = 15, |
253 | UWB_IDENTIFICATION_IE = 19, | 259 | UWB_IDENTIFICATION_IE = 19, |
254 | UWB_MASTER_KEY_ID_IE = 20, | 260 | UWB_MASTER_KEY_ID_IE = 20, |
261 | UWB_RELINQUISH_REQUEST_IE = 21, | ||
255 | UWB_IE_WLP = 250, /* WiMedia Logical Link Control Protocol WLP 0.99 */ | 262 | UWB_IE_WLP = 250, /* WiMedia Logical Link Control Protocol WLP 0.99 */ |
256 | UWB_APP_SPEC_IE = 255, | 263 | UWB_APP_SPEC_IE = 255, |
257 | }; | 264 | }; |
@@ -365,6 +372,27 @@ struct uwb_ie_drp_avail { | |||
365 | DECLARE_BITMAP(bmp, UWB_NUM_MAS); | 372 | DECLARE_BITMAP(bmp, UWB_NUM_MAS); |
366 | } __attribute__((packed)); | 373 | } __attribute__((packed)); |
367 | 374 | ||
375 | /* Relinqish Request IE ([ECMA-368] section 16.8.19). */ | ||
376 | struct uwb_relinquish_request_ie { | ||
377 | struct uwb_ie_hdr hdr; | ||
378 | __le16 relinquish_req_control; | ||
379 | struct uwb_dev_addr dev_addr; | ||
380 | struct uwb_drp_alloc allocs[]; | ||
381 | } __attribute__((packed)); | ||
382 | |||
383 | static inline int uwb_ie_relinquish_req_reason_code(struct uwb_relinquish_request_ie *ie) | ||
384 | { | ||
385 | return (le16_to_cpu(ie->relinquish_req_control) >> 0) & 0xf; | ||
386 | } | ||
387 | |||
388 | static inline void uwb_ie_relinquish_req_set_reason_code(struct uwb_relinquish_request_ie *ie, | ||
389 | int reason_code) | ||
390 | { | ||
391 | u16 ctrl = le16_to_cpu(ie->relinquish_req_control); | ||
392 | ctrl = (ctrl & ~(0xf << 0)) | (reason_code << 0); | ||
393 | ie->relinquish_req_control = cpu_to_le16(ctrl); | ||
394 | } | ||
395 | |||
368 | /** | 396 | /** |
369 | * The Vendor ID is set to an OUI that indicates the vendor of the device. | 397 | * The Vendor ID is set to an OUI that indicates the vendor of the device. |
370 | * ECMA-368 [16.8.10] | 398 | * ECMA-368 [16.8.10] |