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 */