1 /* 2 * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 3 * Use is subject to license terms. 4 */ 5 6 /* 7 * Copyright (c) 2008 by Ben Taylor <bentaylor.solx86@gmail.com> 8 * Copyright (c) 2007 by Lukas Turek <turek@ksvi.mff.cuni.cz> 9 * Copyright (c) 2007 by Jiri Svoboda <jirik.svoboda@seznam.cz> 10 * Copyright (c) 2007 by Martin Krulis <martin.krulis@matfyz.cz> 11 * Copyright (c) 2006 by Damien Bergamini <damien.bergamini@free.fr> 12 * Copyright (c) 2006 by Florian Stoehr <ich@florian-stoehr.de> 13 * 14 * Permission to use, copy, modify, and distribute this software for any 15 * purpose with or without fee is hereby granted, provided that the above 16 * copyright notice and this permission notice appear in all copies. 17 * 18 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 19 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 20 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 21 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 22 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 23 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 24 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 25 * 26 */ 27 28 #ifndef _ZYD_H 29 #define _ZYD_H 30 31 #ifdef __cplusplus 32 extern "C" { 33 #endif 34 35 #include <sys/sysmacros.h> 36 #include <sys/net80211.h> 37 38 #define USBDRV_MAJOR_VER 2 39 #define USBDRV_MINOR_VER 0 40 #include <sys/usb/usba.h> 41 #include <sys/usb/usba/usba_types.h> 42 43 #define ZYD_DRV_NAME "zyd" 44 #define ZYD_DRV_DESC "Zydas ZD1211(B)" 45 #define ZYD_DRV_REV "V1.1" 46 47 /* Return the number of fields of an array */ 48 #define ZYD_ARRAY_LENGTH(arr) (sizeof (arr) / sizeof ((arr)[0])) 49 50 /* 51 * Result type: all functions beginning with zyd_ 52 * should use this to indicate success or failure. 53 * (except for public funcions, of course) 54 * 55 * Detecting error: always use (value != ZYD_SUCCESS) 56 * Indicating error: return ZYD_FAILURE 57 */ 58 typedef enum { 59 ZYD_SUCCESS, 60 ZYD_FAILURE 61 } zyd_res; 62 63 /* 64 * Chip revision ID 65 */ 66 typedef enum { 67 ZYD_UNKNOWN, 68 ZYD_ZD1211, 69 ZYD_ZD1211B 70 } zyd_mac_rev_t; 71 72 /* 73 * USB-safe mutual exclusion object. 74 */ 75 typedef struct { 76 boolean_t initialized; /* B_TRUE if properly initialized */ 77 boolean_t held; /* B_TRUE if the object is held */ 78 kmutex_t lock; /* serialize access */ 79 kcondvar_t wait; /* for waiting on release */ 80 } zyd_serial_t; 81 82 /* 83 * Holds an ioread request status. 84 */ 85 struct zyd_ioread { 86 volatile boolean_t pending; /* ioread is in progress */ 87 volatile boolean_t done; /* response has been received */ 88 volatile boolean_t exc; /* an exception has occured */ 89 90 void *buffer; /* response buffer */ 91 int buf_len; /* buffer size (bytes) */ 92 }; 93 94 /* 95 * USB state. 96 */ 97 struct zyd_usb { 98 /* Copy of sc->dip */ 99 dev_info_t *dip; 100 101 /* Device configuration information */ 102 usb_client_dev_data_t *cdata; 103 104 boolean_t connected; 105 106 /* Communication pipe handles */ 107 usb_pipe_handle_t pipe_data_in; 108 usb_pipe_handle_t pipe_data_out; 109 usb_pipe_handle_t pipe_cmd_in; 110 usb_pipe_handle_t pipe_cmd_out; 111 112 /* Communication endpoint data (copied from descriptor tree) */ 113 usb_ep_data_t ep_data_in; 114 usb_ep_data_t ep_data_out; 115 usb_ep_data_t ep_cmd_in; 116 usb_ep_data_t ep_cmd_out; 117 118 /* Current ioread request (if any) */ 119 struct zyd_ioread io_read; 120 }; 121 122 struct zyd_softc; /* forward declaration */ 123 124 struct zyd_rf { 125 /* RF methods */ 126 zyd_res (*init)(struct zyd_rf *); 127 zyd_res (*switch_radio)(struct zyd_rf *, boolean_t); 128 zyd_res (*set_channel)(struct zyd_rf *, uint8_t); 129 130 /* RF attributes */ 131 struct zyd_softc *rf_sc; /* back-pointer */ 132 int width; 133 }; 134 135 /* 136 * per-instance soft-state structure 137 */ 138 struct zyd_softc { 139 /* Serialize access to the soft_state/device */ 140 zyd_serial_t serial; 141 struct zyd_rf sc_rf; 142 143 dev_info_t *dip; 144 145 /* timeout for scanning */ 146 timeout_id_t timeout_id; 147 148 /* USB-specific data */ 149 struct zyd_usb usb; 150 151 /* Chip revision ZYD1211/ZYD1211B */ 152 zyd_mac_rev_t mac_rev; 153 154 /* MAC address */ 155 uint8_t macaddr[IEEE80211_ADDR_LEN]; 156 157 /* net80211 data */ 158 struct ieee80211com ic; 159 160 boolean_t running; 161 boolean_t suspended; 162 boolean_t resched; 163 uint8_t tx_queued; 164 165 /* Data from EEPROM */ 166 uint16_t fwbase; 167 uint8_t regdomain; 168 uint16_t fw_rev; 169 uint8_t rf_rev; 170 uint8_t pa_rev; 171 uint8_t fix_cr47; 172 uint8_t fix_cr157; 173 uint8_t pwr_cal[14]; 174 uint8_t pwr_int[14]; 175 uint8_t ofdm36_cal[14]; 176 uint8_t ofdm48_cal[14]; 177 uint8_t ofdm54_cal[14]; 178 179 /* kstats */ 180 uint32_t tx_nobuf; 181 uint32_t rx_nobuf; 182 uint32_t tx_err; 183 uint32_t rx_err; 184 185 /* net80211 original state change handler */ 186 int (*newstate)(ieee80211com_t *, 187 enum ieee80211_state, int); 188 }; 189 190 /* RF-config request */ 191 struct zyd_rfwrite { 192 uint16_t code; 193 uint16_t width; 194 uint16_t bit[32]; 195 }; 196 197 /* 16-bit I/O register write request */ 198 struct zyd_iowrite16 { 199 uint16_t reg; 200 uint16_t value; 201 }; 202 203 #pragma pack(1) 204 205 /* Generic usb command to the ZD chip */ 206 struct zyd_cmd { 207 uint16_t cmd_code; 208 uint8_t data[64]; 209 }; 210 211 /* ZD prepends this header to an incoming frame. */ 212 struct zyd_plcphdr { 213 uint8_t signal; 214 uint8_t reserved[2]; 215 uint16_t service; /* unaligned! */ 216 }; 217 218 /* ZD appends this footer to an incoming frame. */ 219 struct zyd_rx_stat { 220 uint8_t rssi; 221 uint8_t signal_cck; 222 uint8_t signal_ofdm; 223 uint8_t cipher; 224 uint8_t flags; 225 }; 226 227 /* this structure may be unaligned */ 228 struct zyd_rx_desc { 229 #define ZYD_MAX_RXFRAMECNT 3 230 uint16_t len[ZYD_MAX_RXFRAMECNT]; 231 uint16_t tag; 232 #define ZYD_TAG_MULTIFRAME 0x697e 233 }; 234 235 /* 236 * Prepended to the 802.11 frame when sending to data_out. 237 */ 238 struct zyd_tx_header { 239 uint8_t rate_mod_flags; 240 uint16_t frame_size; 241 uint8_t type_flags; 242 uint16_t packet_size; 243 uint16_t frame_duration; 244 uint8_t service; 245 uint16_t next_frame_duration; 246 }; 247 248 #pragma pack() 249 250 /* 251 * Map USB id to 1211/1211B chip 252 */ 253 typedef struct zyd_usb_info { 254 uint16_t vendor_id; 255 uint16_t product_id; 256 zyd_mac_rev_t mac_rev; 257 } zyd_usb_info_t; 258 259 /* 260 * Simple lock for callback-waiting. This lock should be used in situations when 261 * one needs to wait for a callback function. It sipmply encapsulates one mutex 262 * and one conditional variable. 263 */ 264 struct zyd_cb_lock { 265 boolean_t done; 266 kmutex_t mutex; 267 kcondvar_t cv; 268 }; 269 270 /* Bits for rate_mod_flags */ 271 #define ZYD_TX_RMF_RATE(rmf) ((rmf) & 0x0f) 272 #define ZYD_TX_RMF_OFDM 0x10 273 #define ZYD_TX_RMF_SH_PREAMBLE 0x20 /* CCK */ 274 #define ZYD_TX_RMF_5GHZ 0x40 /* OFDM */ 275 276 /* Bits for type_flags */ 277 #define ZYD_TX_FLAG_BACKOFF 0x01 278 #define ZYD_TX_FLAG_MULTICAST 0x02 279 #define ZYD_TX_FLAG_TYPE(t) (((t) & 0x3) << 2) 280 #define ZYD_TX_TYPE_DATA 0 281 #define ZYD_TX_TYPE_PS_POLL 1 282 #define ZYD_TX_TYPE_MGMT 2 283 #define ZYD_TX_TYPE_CTL 3 284 285 #define ZYD_TX_FLAG_WAKEUP 0x10 286 #define ZYD_TX_FLAG_RTS 0x20 287 #define ZYD_TX_FLAG_ENCRYPT 0x40 288 #define ZYD_TX_FLAG_CTS_TO_SELF 0x80 289 290 #define ZYD_TX_SERVICE_LENGTH_EXTENSION 0x80 291 292 #define ZYD_TX_LIST_COUNT 0x8 293 #define ZYD_RX_LIST_COUNT 0x8 294 #define ZYD_USB_REQ_COUNT 0x8 295 296 /* 297 * Time in miliseconds to stay on one channel during scan. 298 */ 299 #define ZYD_DWELL_TIME 200000 300 301 #define ZYD_SER_SIG B_TRUE 302 #define ZYD_NO_SIG B_FALSE 303 304 /* Location in the endpoint descriptor tree used by the device */ 305 #define ZYD_USB_CONFIG_NUMBER 1 306 #define ZYD_USB_IFACE_INDEX 0 307 #define ZYD_USB_ALT_IF_INDEX 0 308 309 #define ZYD_DBG_HW (1<<0) 310 #define ZYD_DBG_FW (1<<1) 311 #define ZYD_DBG_USB (1<<2) 312 #define ZYD_DBG_TX (1<<3) 313 #define ZYD_DBG_RX (1<<4) 314 #define ZYD_DBG_SCAN (1<<5) 315 #define ZYD_DBG_GLD (1<<6) 316 #define ZYD_DBG_80211 (1<<7) 317 #define ZYD_DBG_RESUME (1<<8) 318 319 #define ZYD_RX_BUF_SIZE (sizeof (struct zyd_rx_desc) + \ 320 ((IEEE80211_MAX_LEN + 3) & ~3) * ZYD_MAX_RXFRAMECNT) 321 322 /* quickly determine if a given rate is CCK or OFDM */ 323 #define ZYD_RATE_IS_OFDM(rate) ((rate) >= 12 && (rate) != 22) 324 325 /* 326 * Calculate the byte offset of a struct member 327 */ 328 #define ZYD_IC_TO_SOFTC(ic)\ 329 (\ 330 (struct zyd_softc *)(\ 331 (uintptr_t)(ic) - offsetof(struct zyd_softc, ic)\ 332 )\ 333 ) 334 335 /* 336 * The 'struct zyd_usb usb' is stored inside 'struct zyd_softc'. 337 * Using the knowledge of the usb member position, 338 * convert a pointer to 'usb' to a pointer to the zyd_softc. 339 */ 340 #define ZYD_USB_TO_SOFTC(usbp)\ 341 (\ 342 (struct zyd_softc *)(\ 343 (uintptr_t)(usbp) - offsetof(struct zyd_softc, usb)\ 344 )\ 345 ) 346 347 /* Debugging macros */ 348 #ifdef DEBUG 349 #define ZYD_DEBUG(x) zyd_dbg x 350 #else 351 #define ZYD_DEBUG(x) 352 #endif 353 #define ZYD_WARN zyd_warn 354 355 extern void *zyd_ssp; 356 357 #ifdef DEBUG 358 extern uint32_t zyd_dbg_flags; 359 void zyd_dbg(uint32_t dbg_mask, const char *fmt, ...); 360 #endif 361 void zyd_warn(const char *fmt, ...); 362 /* 363 * Functions needed for initializing radios and switching channels 364 */ 365 extern zyd_res zyd_read32(struct zyd_softc *, uint16_t, uint32_t *); 366 extern zyd_res zyd_write32(struct zyd_softc *, uint16_t, uint32_t); 367 extern zyd_res zyd_read16(struct zyd_softc *, uint16_t, uint16_t *); 368 extern zyd_res zyd_write16a(struct zyd_softc *, const struct zyd_iowrite16 *, 369 int); 370 extern zyd_res zyd_write16(struct zyd_softc *, uint16_t, uint16_t); 371 /* 372 * Zydas's own USB-safe synchronization primitive. There are many USB API 373 * functions which forbids that caller holds a mutex. So we're avoiding that 374 * by using out own primitive (it consist of ) 375 */ 376 void zyd_serial_init(struct zyd_softc *sc); 377 zyd_res zyd_serial_enter(struct zyd_softc *sc, boolean_t wait_sig); 378 void zyd_serial_exit(struct zyd_softc *sc); 379 void zyd_serial_deinit(struct zyd_softc *sc); 380 381 void zyd_cb_lock_init(struct zyd_cb_lock *lock); 382 void zyd_cb_lock_destroy(struct zyd_cb_lock *lock); 383 zyd_res zyd_cb_lock_wait(struct zyd_cb_lock *lock, clock_t timeout); 384 void zyd_cb_lock_signal(struct zyd_cb_lock *lock); 385 386 /* chipset specific routines */ 387 void zyd_hw_set_channel(struct zyd_softc *sc, uint8_t chan); 388 zyd_res zyd_hw_init(struct zyd_softc *sc); 389 void zyd_hw_deinit(struct zyd_softc *sc); 390 zyd_res zyd_hw_start(struct zyd_softc *sc); 391 void zyd_hw_stop(struct zyd_softc *sc); 392 393 /* USB specific routines */ 394 zyd_res zyd_usb_init(struct zyd_softc *sc); 395 void zyd_usb_deinit(struct zyd_softc *sc); 396 zyd_res zyd_usb_open_pipes(struct zyd_usb *uc); 397 void zyd_usb_close_pipes(struct zyd_usb *uc); 398 zyd_res zyd_usb_cmd_in_start_polling(struct zyd_usb *uc); 399 void zyd_usb_cmd_in_stop_polling(struct zyd_usb *uc); 400 zyd_res zyd_usb_data_in_enable(struct zyd_usb *uc); 401 void zyd_usb_data_in_disable(struct zyd_usb *uc); 402 zyd_res zyd_usb_cmd_send(struct zyd_usb *uc, uint16_t code, 403 const void *data, size_t len); 404 zyd_res zyd_usb_ioread_req(struct zyd_usb *uc, const void *in_data, 405 size_t in_len, void *out_data, size_t out_len); 406 zyd_res zyd_usb_send_packet(struct zyd_usb *uc, mblk_t *mp); 407 zyd_mac_rev_t zyd_usb_mac_rev(uint16_t vendor, uint16_t product); 408 zyd_res zyd_usb_loadfirmware(struct zyd_usb *uc, uint8_t *fw, 409 size_t size); 410 411 void zyd_receive(struct zyd_softc *sc, const uint8_t *buf, uint16_t len); 412 int zyd_resume(struct zyd_softc *sc); 413 int zyd_suspend(struct zyd_softc *sc); 414 415 extern uint8_t zd1211_firmware[]; 416 extern size_t zd1211_firmware_size; 417 extern uint8_t zd1211b_firmware[]; 418 extern size_t zd1211b_firmware_size; 419 420 #ifdef __cplusplus 421 } 422 #endif 423 424 #endif /* _ZYD_H */ 425