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