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