1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
24 */
25
26 #ifndef _SYS_UWB_UWBA_H
27 #define _SYS_UWB_UWBA_H
28
29 #ifdef __cplusplus
30 extern "C" {
31 #endif
32
33
34 /*
35 * UWBA private header file.
36 */
37
38 #include <sys/note.h>
39 #include <sys/sunddi.h>
40 #include <sys/types.h>
41 #include <sys/list.h>
42 #include <sys/bitset.h>
43 #include <sys/bitmap.h>
44
45 #include <sys/uwb/uwb.h>
46 #include <sys/uwb/uwbai.h>
47
48 /* For logging. */
49 #define UWBA_LOG_DEBUG 2
50 #define UWBA_LOG_LOG 1
51 #define UWBA_LOG_CONSOLE 0
52
53 #define offsetof(s, m) ((size_t)(&(((s *)0)->m)))
54 #define isdigit(ch) ((ch >= '0') && (ch <= '9'))
55
56 #define UWB_RAW_RESULT_CODE_SIZE 5 /* size of RCEB + bResultCode */
57 #define UWB_RAW_RCCB_HEAD_SIZE 4 /* size of RCCB */
58
59 #define UWB_RAW_BEVENTTYPE_OFFSET 0 /* offset of bEventType */
60 #define UWB_RAW_WEVENT_OFFSET 1 /* offset of wEvent */
61 #define UWB_RAW_BEVENTCONTEXT_OFFSET 3 /* offset of bEventContext */
62 #define UWB_RAW_BRESULTCODE_OFFSET 4 /* offset of bResultCode */
63
64
65
66 #define UWB_CTXT_ID_TOP 0xfe /* top context id */
67 #define UWB_CTXT_ID_BOTTOM 0x1 /* bottom context id */
68 #define UWB_CTXT_ID_NOTIF 0x0 /* notification context id */
69 #define UWB_CTXT_ID_UNVALID 0xff /* invalid context id */
70
71
72 #define UWB_INVALID_EVT_CODE 0x7ffe /* invalid evt/notif code */
73 #define UWB_INVALID_EVT_SIZE 0x7fff /* invalid evt length */
74
75 #define UWB_MAX_NOTIF_NUMBER 10 /* Max notifications in a notif_list */
76
77 #define UWB_MAX_CDEV_NUMBER 32 /* Max client radio device */
78
79 /*
80 * Offset of data rates Bits in PHY Capability Bitmap.
81 * [ECMA, 16.8.16, table 112]
82 */
83 #define UWB_RATE_OFFSET_BASE 16
84 /* the offset of data rate 53.3Mbps in PHY capability bitmap */
85 #define UWB_RATE_OFFSET_53 UWB_RATE_OFFSET_BASE
86 #define UWB_RATE_OFFSET_80 (UWB_RATE_OFFSET_BASE + 1) /* 80Mbps */
87 #define UWB_RATE_OFFSET_106 (UWB_RATE_OFFSET_BASE + 2)
88 #define UWB_RATE_OFFSET_160 (UWB_RATE_OFFSET_BASE + 3)
89 #define UWB_RATE_OFFSET_200 (UWB_RATE_OFFSET_BASE + 4)
90 #define UWB_RATE_OFFSET_320 (UWB_RATE_OFFSET_BASE + 5)
91 #define UWB_RATE_OFFSET_400 (UWB_RATE_OFFSET_BASE + 6)
92 #define UWB_RATE_OFFSET_480 (UWB_RATE_OFFSET_BASE + 7)
93
94 typedef int (*uwb_rccb_handler_t)(uwb_dev_handle_t, uwb_rccb_cmd_t *);
95 #define UWB_RCCB_NULL_HANDLER ((uwb_rccb_handler_t)0)
96
97 #define UWB_STATE_IDLE 0
98 #define UWB_STATE_BEACON 1
99 #define UWB_STATE_SCAN 2
100
101 /* radio client device */
102 typedef struct uwba_client_dev {
103 uint8_t bChannelNumber;
104 uint8_t bBeaconType;
105 uint16_t wBPSTOffset;
106 uwb_beacon_frame_t beacon_frame;
107 list_node_t dev_node;
108 } uwba_client_dev_t;
109
110 /* Command result from the radio controller */
111 typedef struct uwb_cmd_result {
112 uwb_rceb_head_t rceb;
113
114 /* Cmd result data from device when cmd is finished. */
115 uint8_t buf[1];
116 } uwb_cmd_result_t;
117
118
119 typedef struct uwb_cmd_result_wrapper {
120 /* Length of a uwb cmd_result */
121 int length;
122
123 uwb_cmd_result_t *cmd_result;
124 } uwb_cmd_result_wrapper_t;
125
126 typedef struct uwb_notif_wrapper {
127 /* Length of uwb notifcation */
128 int length;
129 uwb_rceb_notif_t *notif;
130
131 list_node_t notif_node;
132 } uwb_notif_wrapper_t;
133
134
135
136 typedef struct uwba_dev {
137 /* dip of the uwb radio controller device */
138 dev_info_t *dip;
139
140 /* Dev and instance */
141 char *devinst;
142
143 kmutex_t dev_mutex;
144
145 /* send cmd to the device */
146 int (*send_cmd)(uwb_dev_handle_t, mblk_t *, uint16_t);
147
148 /* current command block */
149 uwb_rccb_cmd_t curr_rccb;
150
151 /* wait for cmd complete and the cmd result available */
152 kcondvar_t cmd_result_cv;
153 kcondvar_t cmd_handler_cv;
154
155 /* filled by uwb_fill_cmd_result in rc driver's cmd call back */
156 uwb_cmd_result_wrapper_t cmd_result_wrap;
157
158 /*
159 * set to TRUE when start to do cmd ioctl;
160 * set to FALSE when put_cmd and exit cmd ioctl
161 */
162 boolean_t cmd_busy;
163
164 /* Device state */
165 uint8_t dev_state;
166
167 /* Beacon or scan channel */
168 uint8_t channel;
169
170 /* Device address */
171 uint16_t dev_addr;
172
173 /* notifications from radio controller device */
174 list_t notif_list;
175
176 /* the current number of notifications in the notif_list */
177 int notif_cnt;
178
179 /* client radio devices found through beacons by this radio host */
180 list_t client_dev_list;
181
182 /* the current number of devices in dev_list */
183 int client_dev_cnt;
184
185 /* context id is maintained by uwba */
186 uint8_t ctxt_id; /* current command context id */
187 bitset_t ctxt_bits; /* command context bit map */
188
189 /* PHY capability bitmap, saved from PHY capability IE */
190 ulong_t phy_cap_bm;
191
192 /* list node of a uwb radio host device */
193 list_node_t uwba_dev_node;
194 } uwba_dev_t;
195
196 _NOTE(MUTEX_PROTECTS_DATA(uwba_dev_t::dev_mutex, uwba_dev_t))
197 _NOTE(DATA_READABLE_WITHOUT_LOCK(uwba_dev_t::{
198 dip
199 devinst
200 send_cmd
201 phy_cap_bm
202 notif_cnt
203 dev_state
204 dip
205 ctxt_id
206 ctxt_bits
207 notif_list
208 cmd_result_wrap
209 client_dev_cnt
210 channel
211 dev_addr
212 }))
213
214
215 typedef struct uwba_evt_size {
216 /* length of a evt/notif structure, impact by alignment */
217 uint8_t struct_len;
218
219 /*
220 * offset of the length member of an event/notif struct.
221 * if zero, means there is no variable buf length member
222 * in this struct
223 */
224 uint16_t buf_len_offset;
225 } uwba_evt_size_t;
226 typedef struct uwba_channel_range {
227 /* First channel in the specific bandgroup */
228 uint8_t base;
229
230 /* Length since this first channel in the bandgroup */
231 uint8_t offset;
232 } uwba_channel_range_t;
233
234 #define UWB_RESULT_CODE_SIZE (sizeof (uwb_rceb_result_code_t))
235
236 /* str_t is the struct type of the notif/evt */
237 #define UWB_EVT_RCEB_SZ (sizeof (uwb_rceb_t))
238
239 /* the size after excluded the rceb head */
240 #define UWB_EVT_END_SZ(stru_t) (sizeof (stru_t) - sizeof (uwb_rceb_t))
241
242 #define UWB_EVT_NO_BUF_LEN_OFFSET 0
243
244 /* Offset of wBeaconInfoLength in uwb_rceb_beacon_t */
245 #define UWB_BEACONINFOLEN_OFFSET 10
246
247 /* Offset of BeaconInfo from bChannelNumber in uwb_rceb_beacon_t */
248 #define UWB_BEACONINFO_OFFSET 8
249
250 /*
251 * UWB radio controller device list
252 */
253 void uwba_dev_add_to_list(uwba_dev_t *);
254 void uwba_dev_rm_from_list(uwba_dev_t *);
255 void uwba_alloc_uwb_dev(dev_info_t *, uwba_dev_t **, uint_t);
256 void uwba_free_uwb_dev(uwba_dev_t *);
257 uwb_dev_handle_t uwba_dev_search(dev_info_t *);
258
259 /*
260 * Context ID operations
261 */
262 void uwba_init_ctxt_id(uwba_dev_t *);
263 void uwba_fini_ctxt_id(uwba_dev_t *);
264 uint8_t uwba_get_ctxt_id(uwba_dev_t *);
265 void uwba_free_ctxt_id(uwba_dev_t *, uint8_t);
266
267 void uwba_fill_rccb_head(uwba_dev_t *, uint16_t, mblk_t *);
268 uint16_t uwba_get_evt_code(uint8_t *, int);
269 uint16_t uwba_get_evt_size(uint8_t *, int, uint16_t);
270
271 void uwba_put_cmd_result(uwba_dev_t *, void *, uint16_t);
272 int uwba_add_notif_to_list(uwba_dev_t *, void *, uint16_t);
273
274 /*
275 * Parse events/notifications from radio controller device
276 */
277 int uwba_parse_data(char *, uchar_t *, size_t, void *, size_t);
278 int uwba_parse_rceb(uint8_t *, size_t, void *, size_t);
279 int uwba_parse_dev_addr_mgmt(uint8_t *, int, uwb_rceb_dev_addr_mgmt_t *);
280 int uwba_parse_get_ie(uwb_dev_handle_t, uint8_t *,
281 int, uwb_rceb_get_ie_t *);
282 int uwba_parse_beacon_rcv(uwb_dev_handle_t, uint8_t *,
283 int, uwb_rceb_beacon_t *);
284 int uwba_parse_bpoie_chg(uwb_dev_handle_t, uint8_t *,
285 int, uwb_rceb_bpoie_change_t *);
286 uint8_t uwba_allocate_channel(uwb_dev_handle_t);
287 uint8_t *uwba_find_ie(uwb_dev_handle_t, uint_t, uint8_t *, uint16_t);
288
289 void uwba_copy_rccb(uwb_rccb_cmd_t *, uwb_rccb_cmd_t *);
290
291 uwba_client_dev_t *uwba_find_cdev_by_channel(uwba_dev_t *, uint8_t);
292
293 /* Debug/message log */
294 void uwba_log(uwba_dev_t *, uint_t, char *, ...);
295 const char *uwba_event_msg(uint16_t);
296
297 /* Turn a little endian byte array to a uint32_t */
298 #define LE_TO_UINT32(src, off, des) \
299 { \
300 uint32_t tmp; \
301 des = src[off + 3]; \
302 des = des << 24; \
303 tmp = src[off + 2]; \
304 des |= tmp << 16; \
305 tmp = src[off + 1]; \
306 des |= tmp << 8; \
307 des |= src[off]; \
308 }
309
310 /* Turn a uint32_t to a little endian byte array */
311 #define UINT32_TO_LE(src, off, des) \
312 { \
313 des[off + 0] = 0xff & src; \
314 des[off + 1] = 0xff & (src >> 8); \
315 des[off + 2] = 0xff & (src >> 16); \
316 des[off + 3] = 0xff & (src >> 24); \
317 }
318
319 /* Turn a little endian byte array to a uint16_t */
320 #define LE_TO_UINT16(src, off, des) \
321 { \
322 des = src[off + 1]; \
323 des = des << 8; \
324 des |= src[off]; \
325 }
326
327 /* Turn a uint16_t to alittle endian byte array */
328 #define UINT16_TO_LE(src, off, des) \
329 { \
330 des[off + 0] = 0xff & src; \
331 des[off + 1] = 0xff & (src >> 8); \
332 }
333
334
335 /* Max string length for the driver name and instance number. */
336 #define UWB_MAXSTRINGLEN 255
337
338
339 #ifdef __cplusplus
340 }
341 #endif
342
343 #endif /* _SYS_UWB_UWBA_H */