1 /*
   2  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
   3  * Use is subject to license terms.
   4  */
   5 
   6 /*
   7  * Copyright (c) 2006
   8  *      Damien Bergamini <damien.bergamini@free.fr>
   9  *
  10  * Permission to use, copy, modify, and distribute this software for any
  11  * purpose with or without fee is hereby granted, provided that the above
  12  * copyright notice and this permission notice appear in all copies.
  13  *
  14  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  15  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  16  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
  17  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  18  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  19  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  20  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  21  */
  22 
  23 /*
  24  * Driver for Intel PRO/Wireless 3945ABG 802.11 network adapters.
  25  */
  26 
  27 #include <sys/types.h>
  28 #include <sys/byteorder.h>
  29 #include <sys/conf.h>
  30 #include <sys/cmn_err.h>
  31 #include <sys/stat.h>
  32 #include <sys/ddi.h>
  33 #include <sys/sunddi.h>
  34 #include <sys/strsubr.h>
  35 #include <sys/ethernet.h>
  36 #include <inet/common.h>
  37 #include <inet/nd.h>
  38 #include <inet/mi.h>
  39 #include <sys/note.h>
  40 #include <sys/stream.h>
  41 #include <sys/strsun.h>
  42 #include <sys/modctl.h>
  43 #include <sys/devops.h>
  44 #include <sys/dlpi.h>
  45 #include <sys/mac_provider.h>
  46 #include <sys/mac_wifi.h>
  47 #include <sys/net80211.h>
  48 #include <sys/net80211_proto.h>
  49 #include <sys/varargs.h>
  50 #include <sys/policy.h>
  51 #include <sys/pci.h>
  52 
  53 #include "wpireg.h"
  54 #include "wpivar.h"
  55 #include <inet/wifi_ioctl.h>
  56 
  57 #ifdef DEBUG
  58 #define WPI_DEBUG_80211         (1 << 0)
  59 #define WPI_DEBUG_CMD           (1 << 1)
  60 #define WPI_DEBUG_DMA           (1 << 2)
  61 #define WPI_DEBUG_EEPROM        (1 << 3)
  62 #define WPI_DEBUG_FW            (1 << 4)
  63 #define WPI_DEBUG_HW            (1 << 5)
  64 #define WPI_DEBUG_INTR          (1 << 6)
  65 #define WPI_DEBUG_MRR           (1 << 7)
  66 #define WPI_DEBUG_PIO           (1 << 8)
  67 #define WPI_DEBUG_RX            (1 << 9)
  68 #define WPI_DEBUG_SCAN          (1 << 10)
  69 #define WPI_DEBUG_TX            (1 << 11)
  70 #define WPI_DEBUG_RATECTL       (1 << 12)
  71 #define WPI_DEBUG_RADIO         (1 << 13)
  72 #define WPI_DEBUG_RESUME        (1 << 14)
  73 uint32_t wpi_dbg_flags = 0;
  74 #define WPI_DBG(x) \
  75         wpi_dbg x
  76 #else
  77 #define WPI_DBG(x)
  78 #endif
  79 
  80 static void     *wpi_soft_state_p = NULL;
  81 static uint8_t wpi_fw_bin [] = {
  82 #include "fw-wpi/ipw3945.ucode.hex"
  83 };
  84 
  85 /* DMA attributes for a shared page */
  86 static ddi_dma_attr_t sh_dma_attr = {
  87         DMA_ATTR_V0,    /* version of this structure */
  88         0,              /* lowest usable address */
  89         0xffffffffU,    /* highest usable address */
  90         0xffffffffU,    /* maximum DMAable byte count */
  91         0x1000,         /* alignment in bytes */
  92         0x1000,         /* burst sizes (any?) */
  93         1,              /* minimum transfer */
  94         0xffffffffU,    /* maximum transfer */
  95         0xffffffffU,    /* maximum segment length */
  96         1,              /* maximum number of segments */
  97         1,              /* granularity */
  98         0,              /* flags (reserved) */
  99 };
 100 
 101 /* DMA attributes for a ring descriptor */
 102 static ddi_dma_attr_t ring_desc_dma_attr = {
 103         DMA_ATTR_V0,    /* version of this structure */
 104         0,              /* lowest usable address */
 105         0xffffffffU,    /* highest usable address */
 106         0xffffffffU,    /* maximum DMAable byte count */
 107         0x4000,         /* alignment in bytes */
 108         0x100,          /* burst sizes (any?) */
 109         1,              /* minimum transfer */
 110         0xffffffffU,    /* maximum transfer */
 111         0xffffffffU,    /* maximum segment length */
 112         1,              /* maximum number of segments */
 113         1,              /* granularity */
 114         0,              /* flags (reserved) */
 115 };
 116 
 117 
 118 /* DMA attributes for a tx cmd */
 119 static ddi_dma_attr_t tx_cmd_dma_attr = {
 120         DMA_ATTR_V0,    /* version of this structure */
 121         0,              /* lowest usable address */
 122         0xffffffffU,    /* highest usable address */
 123         0xffffffffU,    /* maximum DMAable byte count */
 124         4,              /* alignment in bytes */
 125         0x100,          /* burst sizes (any?) */
 126         1,              /* minimum transfer */
 127         0xffffffffU,    /* maximum transfer */
 128         0xffffffffU,    /* maximum segment length */
 129         1,              /* maximum number of segments */
 130         1,              /* granularity */
 131         0,              /* flags (reserved) */
 132 };
 133 
 134 /* DMA attributes for a rx buffer */
 135 static ddi_dma_attr_t rx_buffer_dma_attr = {
 136         DMA_ATTR_V0,    /* version of this structure */
 137         0,              /* lowest usable address */
 138         0xffffffffU,    /* highest usable address */
 139         0xffffffffU,    /* maximum DMAable byte count */
 140         1,              /* alignment in bytes */
 141         0x100,          /* burst sizes (any?) */
 142         1,              /* minimum transfer */
 143         0xffffffffU,    /* maximum transfer */
 144         0xffffffffU,    /* maximum segment length */
 145         1,              /* maximum number of segments */
 146         1,              /* granularity */
 147         0,              /* flags (reserved) */
 148 };
 149 
 150 /*
 151  * DMA attributes for a tx buffer.
 152  * the maximum number of segments is 4 for the hardware.
 153  * now all the wifi drivers put the whole frame in a single
 154  * descriptor, so we define the maximum  number of segments 4,
 155  * just the same as the rx_buffer. we consider leverage the HW
 156  * ability in the future, that is why we don't define rx and tx
 157  * buffer_dma_attr as the same.
 158  */
 159 static ddi_dma_attr_t tx_buffer_dma_attr = {
 160         DMA_ATTR_V0,    /* version of this structure */
 161         0,              /* lowest usable address */
 162         0xffffffffU,    /* highest usable address */
 163         0xffffffffU,    /* maximum DMAable byte count */
 164         1,              /* alignment in bytes */
 165         0x100,          /* burst sizes (any?) */
 166         1,              /* minimum transfer */
 167         0xffffffffU,    /* maximum transfer */
 168         0xffffffffU,    /* maximum segment length */
 169         1,              /* maximum number of segments */
 170         1,              /* granularity */
 171         0,              /* flags (reserved) */
 172 };
 173 
 174 /* DMA attributes for a load firmware */
 175 static ddi_dma_attr_t fw_buffer_dma_attr = {
 176         DMA_ATTR_V0,    /* version of this structure */
 177         0,              /* lowest usable address */
 178         0xffffffffU,    /* highest usable address */
 179         0x7fffffff,     /* maximum DMAable byte count */
 180         4,              /* alignment in bytes */
 181         0x100,          /* burst sizes (any?) */
 182         1,              /* minimum transfer */
 183         0xffffffffU,    /* maximum transfer */
 184         0xffffffffU,    /* maximum segment length */
 185         4,              /* maximum number of segments */
 186         1,              /* granularity */
 187         0,              /* flags (reserved) */
 188 };
 189 
 190 /* regs access attributes */
 191 static ddi_device_acc_attr_t wpi_reg_accattr = {
 192         DDI_DEVICE_ATTR_V0,
 193         DDI_STRUCTURE_LE_ACC,
 194         DDI_STRICTORDER_ACC,
 195         DDI_DEFAULT_ACC
 196 };
 197 
 198 /* DMA access attributes */
 199 static ddi_device_acc_attr_t wpi_dma_accattr = {
 200         DDI_DEVICE_ATTR_V0,
 201         DDI_NEVERSWAP_ACC,
 202         DDI_STRICTORDER_ACC,
 203         DDI_DEFAULT_ACC
 204 };
 205 
 206 static int      wpi_ring_init(wpi_sc_t *);
 207 static void     wpi_ring_free(wpi_sc_t *);
 208 static int      wpi_alloc_shared(wpi_sc_t *);
 209 static void     wpi_free_shared(wpi_sc_t *);
 210 static int      wpi_alloc_fw_dma(wpi_sc_t *);
 211 static void     wpi_free_fw_dma(wpi_sc_t *);
 212 static int      wpi_alloc_rx_ring(wpi_sc_t *);
 213 static void     wpi_reset_rx_ring(wpi_sc_t *);
 214 static void     wpi_free_rx_ring(wpi_sc_t *);
 215 static int      wpi_alloc_tx_ring(wpi_sc_t *, wpi_tx_ring_t *, int, int);
 216 static void     wpi_reset_tx_ring(wpi_sc_t *, wpi_tx_ring_t *);
 217 static void     wpi_free_tx_ring(wpi_sc_t *, wpi_tx_ring_t *);
 218 
 219 static ieee80211_node_t *wpi_node_alloc(ieee80211com_t *);
 220 static void     wpi_node_free(ieee80211_node_t *);
 221 static int      wpi_newstate(ieee80211com_t *, enum ieee80211_state, int);
 222 static int      wpi_key_set(ieee80211com_t *, const struct ieee80211_key *,
 223     const uint8_t mac[IEEE80211_ADDR_LEN]);
 224 static void     wpi_mem_lock(wpi_sc_t *);
 225 static void     wpi_mem_unlock(wpi_sc_t *);
 226 static uint32_t wpi_mem_read(wpi_sc_t *, uint16_t);
 227 static void     wpi_mem_write(wpi_sc_t *, uint16_t, uint32_t);
 228 static void     wpi_mem_write_region_4(wpi_sc_t *, uint16_t,
 229                     const uint32_t *, int);
 230 static uint16_t wpi_read_prom_word(wpi_sc_t *, uint32_t);
 231 static int      wpi_load_microcode(wpi_sc_t *);
 232 static int      wpi_load_firmware(wpi_sc_t *, uint32_t);
 233 static void     wpi_rx_intr(wpi_sc_t *, wpi_rx_desc_t *,
 234                     wpi_rx_data_t *);
 235 static void     wpi_tx_intr(wpi_sc_t *, wpi_rx_desc_t *,
 236                     wpi_rx_data_t *);
 237 static void     wpi_cmd_intr(wpi_sc_t *, wpi_rx_desc_t *);
 238 static uint_t   wpi_intr(caddr_t);
 239 static uint_t   wpi_notif_softintr(caddr_t);
 240 static uint8_t  wpi_plcp_signal(int);
 241 static void     wpi_read_eeprom(wpi_sc_t *);
 242 static int      wpi_cmd(wpi_sc_t *, int, const void *, int, int);
 243 static int      wpi_mrr_setup(wpi_sc_t *);
 244 static void     wpi_set_led(wpi_sc_t *, uint8_t, uint8_t, uint8_t);
 245 static int      wpi_auth(wpi_sc_t *);
 246 static int      wpi_scan(wpi_sc_t *);
 247 static int      wpi_config(wpi_sc_t *);
 248 static void     wpi_stop_master(wpi_sc_t *);
 249 static int      wpi_power_up(wpi_sc_t *);
 250 static int      wpi_reset(wpi_sc_t *);
 251 static void     wpi_hw_config(wpi_sc_t *);
 252 static int      wpi_init(wpi_sc_t *);
 253 static void     wpi_stop(wpi_sc_t *);
 254 static int      wpi_quiesce(dev_info_t *dip);
 255 static void     wpi_amrr_init(wpi_amrr_t *);
 256 static void     wpi_amrr_timeout(wpi_sc_t *);
 257 static void     wpi_amrr_ratectl(void *, ieee80211_node_t *);
 258 
 259 static int wpi_attach(dev_info_t *dip, ddi_attach_cmd_t cmd);
 260 static int wpi_detach(dev_info_t *dip, ddi_detach_cmd_t cmd);
 261 
 262 /*
 263  * GLD specific operations
 264  */
 265 static int      wpi_m_stat(void *arg, uint_t stat, uint64_t *val);
 266 static int      wpi_m_start(void *arg);
 267 static void     wpi_m_stop(void *arg);
 268 static int      wpi_m_unicst(void *arg, const uint8_t *macaddr);
 269 static int      wpi_m_multicst(void *arg, boolean_t add, const uint8_t *m);
 270 static int      wpi_m_promisc(void *arg, boolean_t on);
 271 static mblk_t  *wpi_m_tx(void *arg, mblk_t *mp);
 272 static void     wpi_m_ioctl(void *arg, queue_t *wq, mblk_t *mp);
 273 static int      wpi_m_setprop(void *arg, const char *pr_name,
 274     mac_prop_id_t wldp_pr_num, uint_t wldp_length, const void *wldp_buf);
 275 static int      wpi_m_getprop(void *arg, const char *pr_name,
 276     mac_prop_id_t wldp_pr_num, uint_t wldp_lenth, void *wldp_buf);
 277 static void     wpi_m_propinfo(void *arg, const char *pr_name,
 278     mac_prop_id_t wldp_pr_num, mac_prop_info_handle_t mph);
 279 static void     wpi_destroy_locks(wpi_sc_t *sc);
 280 static int      wpi_send(ieee80211com_t *ic, mblk_t *mp, uint8_t type);
 281 static void     wpi_thread(wpi_sc_t *sc);
 282 static int      wpi_fast_recover(wpi_sc_t *sc);
 283 
 284 /*
 285  * Supported rates for 802.11a/b/g modes (in 500Kbps unit).
 286  */
 287 static const struct ieee80211_rateset wpi_rateset_11b =
 288         { 4, { 2, 4, 11, 22 } };
 289 
 290 static const struct ieee80211_rateset wpi_rateset_11g =
 291         { 12, { 2, 4, 11, 22, 12, 18, 24, 36, 48, 72, 96, 108 } };
 292 
 293 static const uint8_t wpi_ridx_to_signal[] = {
 294         /* OFDM: IEEE Std 802.11a-1999, pp. 14 Table 80 */
 295         /* R1-R4 (ral/ural is R4-R1) */
 296         0xd, 0xf, 0x5, 0x7, 0x9, 0xb, 0x1, 0x3,
 297         /* CCK: device-dependent */
 298         10, 20, 55, 110
 299 };
 300 
 301 /*
 302  * For mfthread only
 303  */
 304 extern pri_t minclsyspri;
 305 
 306 /*
 307  * Module Loading Data & Entry Points
 308  */
 309 DDI_DEFINE_STREAM_OPS(wpi_devops, nulldev, nulldev, wpi_attach,
 310     wpi_detach, nodev, NULL, D_MP, NULL, wpi_quiesce);
 311 
 312 static struct modldrv wpi_modldrv = {
 313         &mod_driverops,
 314         "Intel(R) PRO/Wireless 3945ABG driver",
 315         &wpi_devops
 316 };
 317 
 318 static struct modlinkage wpi_modlinkage = {
 319         MODREV_1,
 320         { &wpi_modldrv, NULL }
 321 };
 322 
 323 int
 324 _init(void)
 325 {
 326         int     status;
 327 
 328         status = ddi_soft_state_init(&wpi_soft_state_p,
 329             sizeof (wpi_sc_t), 1);
 330         if (status != DDI_SUCCESS)
 331                 return (status);
 332 
 333         mac_init_ops(&wpi_devops, "wpi");
 334         status = mod_install(&wpi_modlinkage);
 335         if (status != DDI_SUCCESS) {
 336                 mac_fini_ops(&wpi_devops);
 337                 ddi_soft_state_fini(&wpi_soft_state_p);
 338         }
 339 
 340         return (status);
 341 }
 342 
 343 int
 344 _fini(void)
 345 {
 346         int status;
 347 
 348         status = mod_remove(&wpi_modlinkage);
 349         if (status == DDI_SUCCESS) {
 350                 mac_fini_ops(&wpi_devops);
 351                 ddi_soft_state_fini(&wpi_soft_state_p);
 352         }
 353 
 354         return (status);
 355 }
 356 
 357 int
 358 _info(struct modinfo *mip)
 359 {
 360         return (mod_info(&wpi_modlinkage, mip));
 361 }
 362 
 363 /*
 364  * Mac Call Back entries
 365  */
 366 mac_callbacks_t wpi_m_callbacks = {
 367         MC_IOCTL | MC_SETPROP | MC_GETPROP | MC_PROPINFO,
 368         wpi_m_stat,
 369         wpi_m_start,
 370         wpi_m_stop,
 371         wpi_m_promisc,
 372         wpi_m_multicst,
 373         wpi_m_unicst,
 374         wpi_m_tx,
 375         NULL,
 376         wpi_m_ioctl,
 377         NULL,
 378         NULL,
 379         NULL,
 380         wpi_m_setprop,
 381         wpi_m_getprop,
 382         wpi_m_propinfo
 383 };
 384 
 385 #ifdef DEBUG
 386 void
 387 wpi_dbg(uint32_t flags, const char *fmt, ...)
 388 {
 389         va_list ap;
 390 
 391         if (flags & wpi_dbg_flags) {
 392                 va_start(ap, fmt);
 393                 vcmn_err(CE_NOTE, fmt, ap);
 394                 va_end(ap);
 395         }
 396 }
 397 #endif
 398 /*
 399  * device operations
 400  */
 401 int
 402 wpi_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
 403 {
 404         wpi_sc_t                *sc;
 405         ddi_acc_handle_t        cfg_handle;
 406         caddr_t                 cfg_base;
 407         ieee80211com_t  *ic;
 408         int                     instance, err, i;
 409         char                    strbuf[32];
 410         wifi_data_t             wd = { 0 };
 411         mac_register_t          *macp;
 412 
 413         switch (cmd) {
 414         case DDI_ATTACH:
 415                 break;
 416         case DDI_RESUME:
 417                 sc = ddi_get_soft_state(wpi_soft_state_p,
 418                     ddi_get_instance(dip));
 419                 ASSERT(sc != NULL);
 420 
 421                 mutex_enter(&sc->sc_glock);
 422                 sc->sc_flags &= ~WPI_F_SUSPEND;
 423                 mutex_exit(&sc->sc_glock);
 424 
 425                 if (sc->sc_flags & WPI_F_RUNNING)
 426                         (void) wpi_init(sc);
 427 
 428                 mutex_enter(&sc->sc_glock);
 429                 sc->sc_flags |= WPI_F_LAZY_RESUME;
 430                 mutex_exit(&sc->sc_glock);
 431 
 432                 WPI_DBG((WPI_DEBUG_RESUME, "wpi: resume \n"));
 433                 return (DDI_SUCCESS);
 434         default:
 435                 err = DDI_FAILURE;
 436                 goto attach_fail1;
 437         }
 438 
 439         instance = ddi_get_instance(dip);
 440         err = ddi_soft_state_zalloc(wpi_soft_state_p, instance);
 441         if (err != DDI_SUCCESS) {
 442                 cmn_err(CE_WARN,
 443                     "wpi_attach(): failed to allocate soft state\n");
 444                 goto attach_fail1;
 445         }
 446         sc = ddi_get_soft_state(wpi_soft_state_p, instance);
 447         sc->sc_dip = dip;
 448 
 449         err = ddi_regs_map_setup(dip, 0, &cfg_base, 0, 0,
 450             &wpi_reg_accattr, &cfg_handle);
 451         if (err != DDI_SUCCESS) {
 452                 cmn_err(CE_WARN,
 453                     "wpi_attach(): failed to map config spaces regs\n");
 454                 goto attach_fail2;
 455         }
 456         sc->sc_rev = ddi_get8(cfg_handle,
 457             (uint8_t *)(cfg_base + PCI_CONF_REVID));
 458         ddi_put8(cfg_handle, (uint8_t *)(cfg_base + 0x41), 0);
 459         sc->sc_clsz = ddi_get16(cfg_handle,
 460             (uint16_t *)(cfg_base + PCI_CONF_CACHE_LINESZ));
 461         ddi_regs_map_free(&cfg_handle);
 462         if (!sc->sc_clsz)
 463                 sc->sc_clsz = 16;
 464         sc->sc_clsz = (sc->sc_clsz << 2);
 465         sc->sc_dmabuf_sz = roundup(0x1000 + sizeof (struct ieee80211_frame) +
 466             IEEE80211_MTU + IEEE80211_CRC_LEN +
 467             (IEEE80211_WEP_IVLEN + IEEE80211_WEP_KIDLEN +
 468             IEEE80211_WEP_CRCLEN), sc->sc_clsz);
 469         /*
 470          * Map operating registers
 471          */
 472         err = ddi_regs_map_setup(dip, 1, &sc->sc_base,
 473             0, 0, &wpi_reg_accattr, &sc->sc_handle);
 474         if (err != DDI_SUCCESS) {
 475                 cmn_err(CE_WARN,
 476                     "wpi_attach(): failed to map device regs\n");
 477                 goto attach_fail2;
 478         }
 479 
 480         /*
 481          * Allocate shared page.
 482          */
 483         err = wpi_alloc_shared(sc);
 484         if (err != DDI_SUCCESS) {
 485                 cmn_err(CE_WARN, "failed to allocate shared page\n");
 486                 goto attach_fail3;
 487         }
 488 
 489         /*
 490          * Get the hw conf, including MAC address, then init all rings.
 491          */
 492         wpi_read_eeprom(sc);
 493         err = wpi_ring_init(sc);
 494         if (err != DDI_SUCCESS) {
 495                 cmn_err(CE_WARN, "wpi_attach(): "
 496                     "failed to allocate and initialize ring\n");
 497                 goto attach_fail4;
 498         }
 499 
 500         sc->sc_hdr = (const wpi_firmware_hdr_t *)wpi_fw_bin;
 501 
 502         /* firmware image layout: |HDR|<--TEXT-->|<--DATA-->|<--BOOT-->| */
 503         sc->sc_text = (const char *)(sc->sc_hdr + 1);
 504         sc->sc_data = sc->sc_text + LE_32(sc->sc_hdr->textsz);
 505         sc->sc_boot = sc->sc_data + LE_32(sc->sc_hdr->datasz);
 506         err = wpi_alloc_fw_dma(sc);
 507         if (err != DDI_SUCCESS) {
 508                 cmn_err(CE_WARN, "wpi_attach(): "
 509                     "failed to allocate firmware dma\n");
 510                 goto attach_fail5;
 511         }
 512 
 513         /*
 514          * Initialize mutexs and condvars
 515          */
 516         err = ddi_get_iblock_cookie(dip, 0, &sc->sc_iblk);
 517         if (err != DDI_SUCCESS) {
 518                 cmn_err(CE_WARN,
 519                     "wpi_attach(): failed to do ddi_get_iblock_cookie()\n");
 520                 goto attach_fail6;
 521         }
 522         mutex_init(&sc->sc_glock, NULL, MUTEX_DRIVER, sc->sc_iblk);
 523         mutex_init(&sc->sc_tx_lock, NULL, MUTEX_DRIVER, sc->sc_iblk);
 524         cv_init(&sc->sc_fw_cv, NULL, CV_DRIVER, NULL);
 525         cv_init(&sc->sc_cmd_cv, NULL, CV_DRIVER, NULL);
 526 
 527         /*
 528          * initialize the mfthread
 529          */
 530         mutex_init(&sc->sc_mt_lock, NULL, MUTEX_DRIVER,
 531             (void *) sc->sc_iblk);
 532         cv_init(&sc->sc_mt_cv, NULL, CV_DRIVER, NULL);
 533         sc->sc_mf_thread = NULL;
 534         sc->sc_mf_thread_switch = 0;
 535         /*
 536          * Initialize the wifi part, which will be used by
 537          * generic layer
 538          */
 539         ic = &sc->sc_ic;
 540         ic->ic_phytype  = IEEE80211_T_OFDM;
 541         ic->ic_opmode   = IEEE80211_M_STA; /* default to BSS mode */
 542         ic->ic_state    = IEEE80211_S_INIT;
 543         ic->ic_maxrssi  = 70; /* experimental number */
 544         ic->ic_caps = IEEE80211_C_SHPREAMBLE | IEEE80211_C_TXPMGT |
 545             IEEE80211_C_PMGT | IEEE80211_C_SHSLOT;
 546 
 547         /*
 548          * use software WEP and TKIP, hardware CCMP;
 549          */
 550         ic->ic_caps |= IEEE80211_C_AES_CCM;
 551         ic->ic_caps |= IEEE80211_C_WPA; /* Support WPA/WPA2 */
 552 
 553         /* set supported .11b and .11g rates */
 554         ic->ic_sup_rates[IEEE80211_MODE_11B] = wpi_rateset_11b;
 555         ic->ic_sup_rates[IEEE80211_MODE_11G] = wpi_rateset_11g;
 556 
 557         /* set supported .11b and .11g channels (1 through 14) */
 558         for (i = 1; i <= 14; i++) {
 559                 ic->ic_sup_channels[i].ich_freq =
 560                     ieee80211_ieee2mhz(i, IEEE80211_CHAN_2GHZ);
 561                 ic->ic_sup_channels[i].ich_flags =
 562                     IEEE80211_CHAN_CCK | IEEE80211_CHAN_OFDM |
 563                     IEEE80211_CHAN_DYN | IEEE80211_CHAN_2GHZ |
 564                     IEEE80211_CHAN_PASSIVE;
 565         }
 566         ic->ic_ibss_chan = &ic->ic_sup_channels[0];
 567         ic->ic_xmit = wpi_send;
 568         /*
 569          * init Wifi layer
 570          */
 571         ieee80211_attach(ic);
 572 
 573         /* register WPA door */
 574         ieee80211_register_door(ic, ddi_driver_name(dip),
 575             ddi_get_instance(dip));
 576 
 577         /*
 578          * Override 80211 default routines
 579          */
 580         sc->sc_newstate = ic->ic_newstate;
 581         ic->ic_newstate = wpi_newstate;
 582         ic->ic_node_alloc = wpi_node_alloc;
 583         ic->ic_node_free = wpi_node_free;
 584         ic->ic_crypto.cs_key_set = wpi_key_set;
 585         ieee80211_media_init(ic);
 586         /*
 587          * initialize default tx key
 588          */
 589         ic->ic_def_txkey = 0;
 590 
 591         err = ddi_add_softintr(dip, DDI_SOFTINT_LOW,
 592             &sc->sc_notif_softint_id, &sc->sc_iblk, NULL, wpi_notif_softintr,
 593             (caddr_t)sc);
 594         if (err != DDI_SUCCESS) {
 595                 cmn_err(CE_WARN,
 596                     "wpi_attach(): failed to do ddi_add_softintr()\n");
 597                 goto attach_fail7;
 598         }
 599 
 600         /*
 601          * Add the interrupt handler
 602          */
 603         err = ddi_add_intr(dip, 0, &sc->sc_iblk, NULL,
 604             wpi_intr, (caddr_t)sc);
 605         if (err != DDI_SUCCESS) {
 606                 cmn_err(CE_WARN,
 607                     "wpi_attach(): failed to do ddi_add_intr()\n");
 608                 goto attach_fail8;
 609         }
 610 
 611         /*
 612          * Initialize pointer to device specific functions
 613          */
 614         wd.wd_secalloc = WIFI_SEC_NONE;
 615         wd.wd_opmode = ic->ic_opmode;
 616         IEEE80211_ADDR_COPY(wd.wd_bssid, ic->ic_macaddr);
 617 
 618         macp = mac_alloc(MAC_VERSION);
 619         if (err != DDI_SUCCESS) {
 620                 cmn_err(CE_WARN,
 621                     "wpi_attach(): failed to do mac_alloc()\n");
 622                 goto attach_fail9;
 623         }
 624 
 625         macp->m_type_ident   = MAC_PLUGIN_IDENT_WIFI;
 626         macp->m_driver               = sc;
 627         macp->m_dip          = dip;
 628         macp->m_src_addr     = ic->ic_macaddr;
 629         macp->m_callbacks    = &wpi_m_callbacks;
 630         macp->m_min_sdu              = 0;
 631         macp->m_max_sdu              = IEEE80211_MTU;
 632         macp->m_pdata                = &wd;
 633         macp->m_pdata_size   = sizeof (wd);
 634 
 635         /*
 636          * Register the macp to mac
 637          */
 638         err = mac_register(macp, &ic->ic_mach);
 639         mac_free(macp);
 640         if (err != DDI_SUCCESS) {
 641                 cmn_err(CE_WARN,
 642                     "wpi_attach(): failed to do mac_register()\n");
 643                 goto attach_fail9;
 644         }
 645 
 646         /*
 647          * Create minor node of type DDI_NT_NET_WIFI
 648          */
 649         (void) snprintf(strbuf, sizeof (strbuf), "wpi%d", instance);
 650         err = ddi_create_minor_node(dip, strbuf, S_IFCHR,
 651             instance + 1, DDI_NT_NET_WIFI, 0);
 652         if (err != DDI_SUCCESS)
 653                 cmn_err(CE_WARN,
 654                     "wpi_attach(): failed to do ddi_create_minor_node()\n");
 655 
 656         /*
 657          * Notify link is down now
 658          */
 659         mac_link_update(ic->ic_mach, LINK_STATE_DOWN);
 660 
 661         /*
 662          * create the mf thread to handle the link status,
 663          * recovery fatal error, etc.
 664          */
 665 
 666         sc->sc_mf_thread_switch = 1;
 667         if (sc->sc_mf_thread == NULL)
 668                 sc->sc_mf_thread = thread_create((caddr_t)NULL, 0,
 669                     wpi_thread, sc, 0, &p0, TS_RUN, minclsyspri);
 670 
 671         sc->sc_flags |= WPI_F_ATTACHED;
 672 
 673         return (DDI_SUCCESS);
 674 attach_fail9:
 675         ddi_remove_intr(dip, 0, sc->sc_iblk);
 676 attach_fail8:
 677         ddi_remove_softintr(sc->sc_notif_softint_id);
 678         sc->sc_notif_softint_id = NULL;
 679 attach_fail7:
 680         ieee80211_detach(ic);
 681         wpi_destroy_locks(sc);
 682 attach_fail6:
 683         wpi_free_fw_dma(sc);
 684 attach_fail5:
 685         wpi_ring_free(sc);
 686 attach_fail4:
 687         wpi_free_shared(sc);
 688 attach_fail3:
 689         ddi_regs_map_free(&sc->sc_handle);
 690 attach_fail2:
 691         ddi_soft_state_free(wpi_soft_state_p, instance);
 692 attach_fail1:
 693         return (err);
 694 }
 695 
 696 int
 697 wpi_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
 698 {
 699         wpi_sc_t        *sc;
 700         int err;
 701 
 702         sc = ddi_get_soft_state(wpi_soft_state_p, ddi_get_instance(dip));
 703         ASSERT(sc != NULL);
 704 
 705         switch (cmd) {
 706         case DDI_DETACH:
 707                 break;
 708         case DDI_SUSPEND:
 709                 mutex_enter(&sc->sc_glock);
 710                 sc->sc_flags |= WPI_F_SUSPEND;
 711                 mutex_exit(&sc->sc_glock);
 712 
 713                 if (sc->sc_flags & WPI_F_RUNNING) {
 714                         wpi_stop(sc);
 715                 }
 716 
 717                 WPI_DBG((WPI_DEBUG_RESUME, "wpi: suspend \n"));
 718                 return (DDI_SUCCESS);
 719         default:
 720                 return (DDI_FAILURE);
 721         }
 722         if (!(sc->sc_flags & WPI_F_ATTACHED))
 723                 return (DDI_FAILURE);
 724 
 725         err = mac_disable(sc->sc_ic.ic_mach);
 726         if (err != DDI_SUCCESS)
 727                 return (err);
 728 
 729         /*
 730          * Destroy the mf_thread
 731          */
 732         mutex_enter(&sc->sc_mt_lock);
 733         sc->sc_mf_thread_switch = 0;
 734         while (sc->sc_mf_thread != NULL) {
 735                 if (cv_wait_sig(&sc->sc_mt_cv, &sc->sc_mt_lock) == 0)
 736                         break;
 737         }
 738         mutex_exit(&sc->sc_mt_lock);
 739 
 740         wpi_stop(sc);
 741 
 742         /*
 743          * Unregiste from the MAC layer subsystem
 744          */
 745         (void) mac_unregister(sc->sc_ic.ic_mach);
 746 
 747         mutex_enter(&sc->sc_glock);
 748         wpi_free_fw_dma(sc);
 749         wpi_ring_free(sc);
 750         wpi_free_shared(sc);
 751         mutex_exit(&sc->sc_glock);
 752 
 753         ddi_remove_intr(dip, 0, sc->sc_iblk);
 754         ddi_remove_softintr(sc->sc_notif_softint_id);
 755         sc->sc_notif_softint_id = NULL;
 756 
 757         /*
 758          * detach ieee80211
 759          */
 760         ieee80211_detach(&sc->sc_ic);
 761 
 762         wpi_destroy_locks(sc);
 763 
 764         ddi_regs_map_free(&sc->sc_handle);
 765         ddi_remove_minor_node(dip, NULL);
 766         ddi_soft_state_free(wpi_soft_state_p, ddi_get_instance(dip));
 767 
 768         return (DDI_SUCCESS);
 769 }
 770 
 771 static void
 772 wpi_destroy_locks(wpi_sc_t *sc)
 773 {
 774         cv_destroy(&sc->sc_mt_cv);
 775         mutex_destroy(&sc->sc_mt_lock);
 776         cv_destroy(&sc->sc_cmd_cv);
 777         cv_destroy(&sc->sc_fw_cv);
 778         mutex_destroy(&sc->sc_tx_lock);
 779         mutex_destroy(&sc->sc_glock);
 780 }
 781 
 782 /*
 783  * Allocate an area of memory and a DMA handle for accessing it
 784  */
 785 static int
 786 wpi_alloc_dma_mem(wpi_sc_t *sc, size_t memsize, ddi_dma_attr_t *dma_attr_p,
 787         ddi_device_acc_attr_t *acc_attr_p, uint_t dma_flags, wpi_dma_t *dma_p)
 788 {
 789         caddr_t vaddr;
 790         int err;
 791 
 792         /*
 793          * Allocate handle
 794          */
 795         err = ddi_dma_alloc_handle(sc->sc_dip, dma_attr_p,
 796             DDI_DMA_SLEEP, NULL, &dma_p->dma_hdl);
 797         if (err != DDI_SUCCESS) {
 798                 dma_p->dma_hdl = NULL;
 799                 return (DDI_FAILURE);
 800         }
 801 
 802         /*
 803          * Allocate memory
 804          */
 805         err = ddi_dma_mem_alloc(dma_p->dma_hdl, memsize, acc_attr_p,
 806             dma_flags & (DDI_DMA_CONSISTENT | DDI_DMA_STREAMING),
 807             DDI_DMA_SLEEP, NULL, &vaddr, &dma_p->alength, &dma_p->acc_hdl);
 808         if (err != DDI_SUCCESS) {
 809                 ddi_dma_free_handle(&dma_p->dma_hdl);
 810                 dma_p->dma_hdl = NULL;
 811                 dma_p->acc_hdl = NULL;
 812                 return (DDI_FAILURE);
 813         }
 814 
 815         /*
 816          * Bind the two together
 817          */
 818         dma_p->mem_va = vaddr;
 819         err = ddi_dma_addr_bind_handle(dma_p->dma_hdl, NULL,
 820             vaddr, dma_p->alength, dma_flags, DDI_DMA_SLEEP, NULL,
 821             &dma_p->cookie, &dma_p->ncookies);
 822         if (err != DDI_DMA_MAPPED) {
 823                 ddi_dma_mem_free(&dma_p->acc_hdl);
 824                 ddi_dma_free_handle(&dma_p->dma_hdl);
 825                 dma_p->acc_hdl = NULL;
 826                 dma_p->dma_hdl = NULL;
 827                 return (DDI_FAILURE);
 828         }
 829 
 830         dma_p->nslots = ~0U;
 831         dma_p->size = ~0U;
 832         dma_p->token = ~0U;
 833         dma_p->offset = 0;
 834         return (DDI_SUCCESS);
 835 }
 836 
 837 /*
 838  * Free one allocated area of DMAable memory
 839  */
 840 static void
 841 wpi_free_dma_mem(wpi_dma_t *dma_p)
 842 {
 843         if (dma_p->dma_hdl != NULL) {
 844                 if (dma_p->ncookies) {
 845                         (void) ddi_dma_unbind_handle(dma_p->dma_hdl);
 846                         dma_p->ncookies = 0;
 847                 }
 848                 ddi_dma_free_handle(&dma_p->dma_hdl);
 849                 dma_p->dma_hdl = NULL;
 850         }
 851 
 852         if (dma_p->acc_hdl != NULL) {
 853                 ddi_dma_mem_free(&dma_p->acc_hdl);
 854                 dma_p->acc_hdl = NULL;
 855         }
 856 }
 857 
 858 /*
 859  * Allocate an area of dma memory for firmware load.
 860  * Idealy, this allocation should be a one time action, that is,
 861  * the memory will be freed after the firmware is uploaded to the
 862  * card. but since a recovery mechanism for the fatal firmware need
 863  * reload the firmware, and re-allocate dma at run time may be failed,
 864  * so we allocate it at attach and keep it in the whole lifecycle of
 865  * the driver.
 866  */
 867 static int
 868 wpi_alloc_fw_dma(wpi_sc_t *sc)
 869 {
 870         int i, err = DDI_SUCCESS;
 871         wpi_dma_t *dma_p;
 872 
 873         err = wpi_alloc_dma_mem(sc, LE_32(sc->sc_hdr->textsz),
 874             &fw_buffer_dma_attr, &wpi_dma_accattr,
 875             DDI_DMA_RDWR | DDI_DMA_CONSISTENT,
 876             &sc->sc_dma_fw_text);
 877         dma_p = &sc->sc_dma_fw_text;
 878         WPI_DBG((WPI_DEBUG_DMA, "ncookies:%d addr1:%x size1:%x\n",
 879             dma_p->ncookies, dma_p->cookie.dmac_address,
 880             dma_p->cookie.dmac_size));
 881         if (err != DDI_SUCCESS) {
 882                 cmn_err(CE_WARN, "wpi_alloc_fw_dma(): failed to alloc"
 883                     "text dma memory");
 884                 goto fail;
 885         }
 886         for (i = 0; i < dma_p->ncookies; i++) {
 887                 sc->sc_fw_text_cookie[i] = dma_p->cookie;
 888                 ddi_dma_nextcookie(dma_p->dma_hdl, &dma_p->cookie);
 889         }
 890         err = wpi_alloc_dma_mem(sc, LE_32(sc->sc_hdr->datasz),
 891             &fw_buffer_dma_attr, &wpi_dma_accattr,
 892             DDI_DMA_RDWR | DDI_DMA_CONSISTENT,
 893             &sc->sc_dma_fw_data);
 894         dma_p = &sc->sc_dma_fw_data;
 895         WPI_DBG((WPI_DEBUG_DMA, "ncookies:%d addr1:%x size1:%x\n",
 896             dma_p->ncookies, dma_p->cookie.dmac_address,
 897             dma_p->cookie.dmac_size));
 898         if (err != DDI_SUCCESS) {
 899                 cmn_err(CE_WARN, "wpi_alloc_fw_dma(): failed to alloc"
 900                     "data dma memory");
 901                 goto fail;
 902         }
 903         for (i = 0; i < dma_p->ncookies; i++) {
 904                 sc->sc_fw_data_cookie[i] = dma_p->cookie;
 905                 ddi_dma_nextcookie(dma_p->dma_hdl, &dma_p->cookie);
 906         }
 907 fail:
 908         return (err);
 909 }
 910 
 911 static void
 912 wpi_free_fw_dma(wpi_sc_t *sc)
 913 {
 914         wpi_free_dma_mem(&sc->sc_dma_fw_text);
 915         wpi_free_dma_mem(&sc->sc_dma_fw_data);
 916 }
 917 
 918 /*
 919  * Allocate a shared page between host and NIC.
 920  */
 921 static int
 922 wpi_alloc_shared(wpi_sc_t *sc)
 923 {
 924         int err = DDI_SUCCESS;
 925 
 926         /* must be aligned on a 4K-page boundary */
 927         err = wpi_alloc_dma_mem(sc, sizeof (wpi_shared_t),
 928             &sh_dma_attr, &wpi_dma_accattr,
 929             DDI_DMA_RDWR | DDI_DMA_CONSISTENT,
 930             &sc->sc_dma_sh);
 931         if (err != DDI_SUCCESS)
 932                 goto fail;
 933         sc->sc_shared = (wpi_shared_t *)sc->sc_dma_sh.mem_va;
 934         return (err);
 935 
 936 fail:
 937         wpi_free_shared(sc);
 938         return (err);
 939 }
 940 
 941 static void
 942 wpi_free_shared(wpi_sc_t *sc)
 943 {
 944         wpi_free_dma_mem(&sc->sc_dma_sh);
 945 }
 946 
 947 static int
 948 wpi_alloc_rx_ring(wpi_sc_t *sc)
 949 {
 950         wpi_rx_ring_t *ring;
 951         wpi_rx_data_t *data;
 952         int i, err = DDI_SUCCESS;
 953 
 954         ring = &sc->sc_rxq;
 955         ring->cur = 0;
 956 
 957         err = wpi_alloc_dma_mem(sc, WPI_RX_RING_COUNT * sizeof (uint32_t),
 958             &ring_desc_dma_attr, &wpi_dma_accattr,
 959             DDI_DMA_RDWR | DDI_DMA_CONSISTENT,
 960             &ring->dma_desc);
 961         if (err != DDI_SUCCESS) {
 962                 WPI_DBG((WPI_DEBUG_DMA, "dma alloc rx ring desc failed\n"));
 963                 goto fail;
 964         }
 965         ring->desc = (uint32_t *)ring->dma_desc.mem_va;
 966 
 967         /*
 968          * Allocate Rx buffers.
 969          */
 970         for (i = 0; i < WPI_RX_RING_COUNT; i++) {
 971                 data = &ring->data[i];
 972                 err = wpi_alloc_dma_mem(sc, sc->sc_dmabuf_sz,
 973                     &rx_buffer_dma_attr, &wpi_dma_accattr,
 974                     DDI_DMA_READ | DDI_DMA_STREAMING,
 975                     &data->dma_data);
 976                 if (err != DDI_SUCCESS) {
 977                         WPI_DBG((WPI_DEBUG_DMA, "dma alloc rx ring buf[%d] "
 978                             "failed\n", i));
 979                         goto fail;
 980                 }
 981 
 982                 ring->desc[i] = LE_32(data->dma_data.cookie.dmac_address);
 983         }
 984 
 985         WPI_DMA_SYNC(ring->dma_desc, DDI_DMA_SYNC_FORDEV);
 986 
 987         return (err);
 988 
 989 fail:
 990         wpi_free_rx_ring(sc);
 991         return (err);
 992 }
 993 
 994 static void
 995 wpi_reset_rx_ring(wpi_sc_t *sc)
 996 {
 997         int ntries;
 998 
 999         wpi_mem_lock(sc);
1000 
1001         WPI_WRITE(sc, WPI_RX_CONFIG, 0);
1002         for (ntries = 0; ntries < 2000; ntries++) {
1003                 if (WPI_READ(sc, WPI_RX_STATUS) & WPI_RX_IDLE)
1004                         break;
1005                 DELAY(1000);
1006         }
1007         if (ntries == 2000)
1008                 WPI_DBG((WPI_DEBUG_DMA, "timeout resetting Rx ring\n"));
1009 
1010         wpi_mem_unlock(sc);
1011 
1012         sc->sc_rxq.cur = 0;
1013 }
1014 
1015 static void
1016 wpi_free_rx_ring(wpi_sc_t *sc)
1017 {
1018         int i;
1019 
1020         for (i = 0; i < WPI_RX_RING_COUNT; i++) {
1021                 if (sc->sc_rxq.data[i].dma_data.dma_hdl)
1022                         WPI_DMA_SYNC(sc->sc_rxq.data[i].dma_data,
1023                             DDI_DMA_SYNC_FORCPU);
1024                 wpi_free_dma_mem(&sc->sc_rxq.data[i].dma_data);
1025         }
1026 
1027         if (sc->sc_rxq.dma_desc.dma_hdl)
1028                 WPI_DMA_SYNC(sc->sc_rxq.dma_desc, DDI_DMA_SYNC_FORDEV);
1029         wpi_free_dma_mem(&sc->sc_rxq.dma_desc);
1030 }
1031 
1032 static int
1033 wpi_alloc_tx_ring(wpi_sc_t *sc, wpi_tx_ring_t *ring, int count, int qid)
1034 {
1035         wpi_tx_data_t *data;
1036         wpi_tx_desc_t *desc_h;
1037         uint32_t paddr_desc_h;
1038         wpi_tx_cmd_t *cmd_h;
1039         uint32_t paddr_cmd_h;
1040         int i, err = DDI_SUCCESS;
1041 
1042         ring->qid = qid;
1043         ring->count = count;
1044         ring->queued = 0;
1045         ring->cur = 0;
1046 
1047         err = wpi_alloc_dma_mem(sc, count * sizeof (wpi_tx_desc_t),
1048             &ring_desc_dma_attr, &wpi_dma_accattr,
1049             DDI_DMA_RDWR | DDI_DMA_CONSISTENT,
1050             &ring->dma_desc);
1051         if (err != DDI_SUCCESS) {
1052                 WPI_DBG((WPI_DEBUG_DMA, "dma alloc tx ring desc[%d] failed\n",
1053                     qid));
1054                 goto fail;
1055         }
1056 
1057         /* update shared page with ring's base address */
1058         sc->sc_shared->txbase[qid] = ring->dma_desc.cookie.dmac_address;
1059 
1060         desc_h = (wpi_tx_desc_t *)ring->dma_desc.mem_va;
1061         paddr_desc_h = ring->dma_desc.cookie.dmac_address;
1062 
1063         err = wpi_alloc_dma_mem(sc, count * sizeof (wpi_tx_cmd_t),
1064             &tx_cmd_dma_attr, &wpi_dma_accattr,
1065             DDI_DMA_RDWR | DDI_DMA_CONSISTENT,
1066             &ring->dma_cmd);
1067         if (err != DDI_SUCCESS) {
1068                 WPI_DBG((WPI_DEBUG_DMA, "dma alloc tx ring cmd[%d] failed\n",
1069                     qid));
1070                 goto fail;
1071         }
1072 
1073         cmd_h = (wpi_tx_cmd_t *)ring->dma_cmd.mem_va;
1074         paddr_cmd_h = ring->dma_cmd.cookie.dmac_address;
1075 
1076         /*
1077          * Allocate Tx buffers.
1078          */
1079         ring->data = kmem_zalloc(sizeof (wpi_tx_data_t) * count, KM_NOSLEEP);
1080         if (ring->data == NULL) {
1081                 WPI_DBG((WPI_DEBUG_DMA, "could not allocate tx data slots\n"));
1082                 goto fail;
1083         }
1084 
1085         for (i = 0; i < count; i++) {
1086                 data = &ring->data[i];
1087                 err = wpi_alloc_dma_mem(sc, sc->sc_dmabuf_sz,
1088                     &tx_buffer_dma_attr, &wpi_dma_accattr,
1089                     DDI_DMA_WRITE | DDI_DMA_STREAMING,
1090                     &data->dma_data);
1091                 if (err != DDI_SUCCESS) {
1092                         WPI_DBG((WPI_DEBUG_DMA, "dma alloc tx ring buf[%d] "
1093                             "failed\n", i));
1094                         goto fail;
1095                 }
1096 
1097                 data->desc = desc_h + i;
1098                 data->paddr_desc = paddr_desc_h +
1099                     ((uintptr_t)data->desc - (uintptr_t)desc_h);
1100                 data->cmd = cmd_h + i;
1101                 data->paddr_cmd = paddr_cmd_h +
1102                     ((uintptr_t)data->cmd - (uintptr_t)cmd_h);
1103         }
1104 
1105         return (err);
1106 
1107 fail:
1108         wpi_free_tx_ring(sc, ring);
1109         return (err);
1110 }
1111 
1112 static void
1113 wpi_reset_tx_ring(wpi_sc_t *sc, wpi_tx_ring_t *ring)
1114 {
1115         wpi_tx_data_t *data;
1116         int i, ntries;
1117 
1118         wpi_mem_lock(sc);
1119 
1120         WPI_WRITE(sc, WPI_TX_CONFIG(ring->qid), 0);
1121         for (ntries = 0; ntries < 100; ntries++) {
1122                 if (WPI_READ(sc, WPI_TX_STATUS) & WPI_TX_IDLE(ring->qid))
1123                         break;
1124                 DELAY(10);
1125         }
1126 #ifdef DEBUG
1127         if (ntries == 100 && wpi_dbg_flags > 0) {
1128                 WPI_DBG((WPI_DEBUG_DMA, "timeout resetting Tx ring %d\n",
1129                     ring->qid));
1130         }
1131 #endif
1132         wpi_mem_unlock(sc);
1133 
1134         if (!(sc->sc_flags & WPI_F_QUIESCED)) {
1135                 for (i = 0; i < ring->count; i++) {
1136                         data = &ring->data[i];
1137                         WPI_DMA_SYNC(data->dma_data, DDI_DMA_SYNC_FORDEV);
1138                 }
1139         }
1140 
1141         ring->queued = 0;
1142         ring->cur = 0;
1143 }
1144 
1145 /*ARGSUSED*/
1146 static void
1147 wpi_free_tx_ring(wpi_sc_t *sc, wpi_tx_ring_t *ring)
1148 {
1149         int i;
1150 
1151         if (ring->dma_desc.dma_hdl != NULL)
1152                 WPI_DMA_SYNC(ring->dma_desc, DDI_DMA_SYNC_FORDEV);
1153         wpi_free_dma_mem(&ring->dma_desc);
1154 
1155         if (ring->dma_cmd.dma_hdl != NULL)
1156                 WPI_DMA_SYNC(ring->dma_cmd, DDI_DMA_SYNC_FORDEV);
1157         wpi_free_dma_mem(&ring->dma_cmd);
1158 
1159         if (ring->data != NULL) {
1160                 for (i = 0; i < ring->count; i++) {
1161                         if (ring->data[i].dma_data.dma_hdl)
1162                                 WPI_DMA_SYNC(ring->data[i].dma_data,
1163                                     DDI_DMA_SYNC_FORDEV);
1164                         wpi_free_dma_mem(&ring->data[i].dma_data);
1165                 }
1166                 kmem_free(ring->data, ring->count * sizeof (wpi_tx_data_t));
1167                 ring->data = NULL;
1168         }
1169 }
1170 
1171 static int
1172 wpi_ring_init(wpi_sc_t *sc)
1173 {
1174         int i, err = DDI_SUCCESS;
1175 
1176         for (i = 0; i < 4; i++) {
1177                 err = wpi_alloc_tx_ring(sc, &sc->sc_txq[i], WPI_TX_RING_COUNT,
1178                     i);
1179                 if (err != DDI_SUCCESS)
1180                         goto fail;
1181         }
1182         err = wpi_alloc_tx_ring(sc, &sc->sc_cmdq, WPI_CMD_RING_COUNT, 4);
1183         if (err != DDI_SUCCESS)
1184                 goto fail;
1185         err = wpi_alloc_tx_ring(sc, &sc->sc_svcq, WPI_SVC_RING_COUNT, 5);
1186         if (err != DDI_SUCCESS)
1187                 goto fail;
1188         err = wpi_alloc_rx_ring(sc);
1189         if (err != DDI_SUCCESS)
1190                 goto fail;
1191         return (err);
1192 
1193 fail:
1194         return (err);
1195 }
1196 
1197 static void
1198 wpi_ring_free(wpi_sc_t *sc)
1199 {
1200         int i = 4;
1201 
1202         wpi_free_rx_ring(sc);
1203         wpi_free_tx_ring(sc, &sc->sc_svcq);
1204         wpi_free_tx_ring(sc, &sc->sc_cmdq);
1205         while (--i >= 0) {
1206                 wpi_free_tx_ring(sc, &sc->sc_txq[i]);
1207         }
1208 }
1209 
1210 /* ARGSUSED */
1211 static ieee80211_node_t *
1212 wpi_node_alloc(ieee80211com_t *ic)
1213 {
1214         wpi_amrr_t *amrr;
1215 
1216         amrr = kmem_zalloc(sizeof (wpi_amrr_t), KM_SLEEP);
1217         if (amrr != NULL)
1218                 wpi_amrr_init(amrr);
1219         return (&amrr->in);
1220 }
1221 
1222 static void
1223 wpi_node_free(ieee80211_node_t *in)
1224 {
1225         ieee80211com_t *ic = in->in_ic;
1226 
1227         ic->ic_node_cleanup(in);
1228         if (in->in_wpa_ie != NULL)
1229                 ieee80211_free(in->in_wpa_ie);
1230         kmem_free(in, sizeof (wpi_amrr_t));
1231 }
1232 
1233 /*ARGSUSED*/
1234 static int
1235 wpi_newstate(ieee80211com_t *ic, enum ieee80211_state nstate, int arg)
1236 {
1237         wpi_sc_t *sc = (wpi_sc_t *)ic;
1238         ieee80211_node_t *in = ic->ic_bss;
1239         enum ieee80211_state ostate;
1240         int i, err = WPI_SUCCESS;
1241 
1242         mutex_enter(&sc->sc_glock);
1243         ostate = ic->ic_state;
1244         switch (nstate) {
1245         case IEEE80211_S_SCAN:
1246                 switch (ostate) {
1247                 case IEEE80211_S_INIT:
1248                 {
1249                         wpi_node_t node;
1250 
1251                         sc->sc_flags |= WPI_F_SCANNING;
1252                         sc->sc_scan_next = 0;
1253 
1254                         /* make the link LED blink while we're scanning */
1255                         wpi_set_led(sc, WPI_LED_LINK, 20, 2);
1256 
1257                         /*
1258                          * clear association to receive beacons from all
1259                          * BSS'es
1260                          */
1261                         sc->sc_config.state = 0;
1262                         sc->sc_config.filter &= ~LE_32(WPI_FILTER_BSS);
1263 
1264                         WPI_DBG((WPI_DEBUG_80211, "config chan %d flags %x "
1265                             "filter %x\n",
1266                             sc->sc_config.chan, sc->sc_config.flags,
1267                             sc->sc_config.filter));
1268 
1269                         err = wpi_cmd(sc, WPI_CMD_CONFIGURE, &sc->sc_config,
1270                             sizeof (wpi_config_t), 1);
1271                         if (err != WPI_SUCCESS) {
1272                                 cmn_err(CE_WARN,
1273                                     "could not clear association\n");
1274                                 sc->sc_flags &= ~WPI_F_SCANNING;
1275                                 mutex_exit(&sc->sc_glock);
1276                                 return (err);
1277                         }
1278 
1279                         /* add broadcast node to send probe request */
1280                         (void) memset(&node, 0, sizeof (node));
1281                         (void) memset(&node.bssid, 0xff, IEEE80211_ADDR_LEN);
1282                         node.id = WPI_ID_BROADCAST;
1283 
1284                         err = wpi_cmd(sc, WPI_CMD_ADD_NODE, &node,
1285                             sizeof (node), 1);
1286                         if (err != WPI_SUCCESS) {
1287                                 cmn_err(CE_WARN,
1288                                     "could not add broadcast node\n");
1289                                 sc->sc_flags &= ~WPI_F_SCANNING;
1290                                 mutex_exit(&sc->sc_glock);
1291                                 return (err);
1292                         }
1293                         break;
1294                 }
1295                 case IEEE80211_S_SCAN:
1296                         mutex_exit(&sc->sc_glock);
1297                         /* step to next channel before actual FW scan */
1298                         err = sc->sc_newstate(ic, nstate, arg);
1299                         mutex_enter(&sc->sc_glock);
1300                         if ((err != 0) || ((err = wpi_scan(sc)) != 0)) {
1301                                 cmn_err(CE_WARN,
1302                                     "could not initiate scan\n");
1303                                 sc->sc_flags &= ~WPI_F_SCANNING;
1304                                 ieee80211_cancel_scan(ic);
1305                         }
1306                         mutex_exit(&sc->sc_glock);
1307                         return (err);
1308                 default:
1309                         break;
1310                 }
1311                 sc->sc_clk = 0;
1312                 break;
1313 
1314         case IEEE80211_S_AUTH:
1315                 if (ostate == IEEE80211_S_SCAN) {
1316                         sc->sc_flags &= ~WPI_F_SCANNING;
1317                 }
1318 
1319                 /* reset state to handle reassociations correctly */
1320                 sc->sc_config.state = 0;
1321                 sc->sc_config.filter &= ~LE_32(WPI_FILTER_BSS);
1322 
1323                 if ((err = wpi_auth(sc)) != 0) {
1324                         WPI_DBG((WPI_DEBUG_80211,
1325                             "could not send authentication request\n"));
1326                         mutex_exit(&sc->sc_glock);
1327                         return (err);
1328                 }
1329                 break;
1330 
1331         case IEEE80211_S_RUN:
1332                 if (ostate == IEEE80211_S_SCAN) {
1333                         sc->sc_flags &= ~WPI_F_SCANNING;
1334                 }
1335 
1336                 if (ic->ic_opmode == IEEE80211_M_MONITOR) {
1337                         /* link LED blinks while monitoring */
1338                         wpi_set_led(sc, WPI_LED_LINK, 5, 5);
1339                         break;
1340                 }
1341 
1342                 if (ic->ic_opmode != IEEE80211_M_STA) {
1343                         (void) wpi_auth(sc);
1344                         /* need setup beacon here */
1345                 }
1346                 WPI_DBG((WPI_DEBUG_80211, "wpi: associated."));
1347 
1348                 /* update adapter's configuration */
1349                 sc->sc_config.state = LE_16(WPI_CONFIG_ASSOCIATED);
1350                 /* short preamble/slot time are negotiated when associating */
1351                 sc->sc_config.flags &= ~LE_32(WPI_CONFIG_SHPREAMBLE |
1352                     WPI_CONFIG_SHSLOT);
1353                 if (ic->ic_flags & IEEE80211_F_SHSLOT)
1354                         sc->sc_config.flags |= LE_32(WPI_CONFIG_SHSLOT);
1355                 if (ic->ic_flags & IEEE80211_F_SHPREAMBLE)
1356                         sc->sc_config.flags |= LE_32(WPI_CONFIG_SHPREAMBLE);
1357                 sc->sc_config.filter |= LE_32(WPI_FILTER_BSS);
1358                 if (ic->ic_opmode != IEEE80211_M_STA)
1359                         sc->sc_config.filter |= LE_32(WPI_FILTER_BEACON);
1360 
1361                 WPI_DBG((WPI_DEBUG_80211, "config chan %d flags %x\n",
1362                     sc->sc_config.chan, sc->sc_config.flags));
1363                 err = wpi_cmd(sc, WPI_CMD_CONFIGURE, &sc->sc_config,
1364                     sizeof (wpi_config_t), 1);
1365                 if (err != WPI_SUCCESS) {
1366                         WPI_DBG((WPI_DEBUG_80211,
1367                             "could not update configuration\n"));
1368                         mutex_exit(&sc->sc_glock);
1369                         return (err);
1370                 }
1371 
1372                 /* start automatic rate control */
1373                 mutex_enter(&sc->sc_mt_lock);
1374                 if (ic->ic_fixed_rate == IEEE80211_FIXED_RATE_NONE) {
1375                         sc->sc_flags |= WPI_F_RATE_AUTO_CTL;
1376                         /* set rate to some reasonable initial value */
1377                         i = in->in_rates.ir_nrates - 1;
1378                         while (i > 0 && IEEE80211_RATE(i) > 72)
1379                                 i--;
1380                         in->in_txrate = i;
1381                 } else {
1382                         sc->sc_flags &= ~WPI_F_RATE_AUTO_CTL;
1383                 }
1384                 mutex_exit(&sc->sc_mt_lock);
1385 
1386                 /* link LED always on while associated */
1387                 wpi_set_led(sc, WPI_LED_LINK, 0, 1);
1388                 break;
1389 
1390         case IEEE80211_S_INIT:
1391                 sc->sc_flags &= ~WPI_F_SCANNING;
1392                 break;
1393 
1394         case IEEE80211_S_ASSOC:
1395                 sc->sc_flags &= ~WPI_F_SCANNING;
1396                 break;
1397         }
1398 
1399         mutex_exit(&sc->sc_glock);
1400         return (sc->sc_newstate(ic, nstate, arg));
1401 }
1402 
1403 /*ARGSUSED*/
1404 static int wpi_key_set(ieee80211com_t *ic, const struct ieee80211_key *k,
1405     const uint8_t mac[IEEE80211_ADDR_LEN])
1406 {
1407         wpi_sc_t *sc = (wpi_sc_t *)ic;
1408         wpi_node_t node;
1409         int err;
1410 
1411         switch (k->wk_cipher->ic_cipher) {
1412         case IEEE80211_CIPHER_WEP:
1413         case IEEE80211_CIPHER_TKIP:
1414                 return (1); /* sofeware do it. */
1415         case IEEE80211_CIPHER_AES_CCM:
1416                 break;
1417         default:
1418                 return (0);
1419         }
1420         sc->sc_config.filter &= ~(WPI_FILTER_NODECRYPTUNI |
1421             WPI_FILTER_NODECRYPTMUL);
1422 
1423         mutex_enter(&sc->sc_glock);
1424 
1425         /* update ap/multicast node */
1426         (void) memset(&node, 0, sizeof (node));
1427         if (IEEE80211_IS_MULTICAST(mac)) {
1428                 (void) memset(node.bssid, 0xff, 6);
1429                 node.id = WPI_ID_BROADCAST;
1430         } else {
1431                 IEEE80211_ADDR_COPY(node.bssid, ic->ic_bss->in_bssid);
1432                 node.id = WPI_ID_BSS;
1433         }
1434         if (k->wk_flags & IEEE80211_KEY_XMIT) {
1435                 node.key_flags = 0;
1436                 node.keyp = k->wk_keyix;
1437         } else {
1438                 node.key_flags = (1 << 14);
1439                 node.keyp = k->wk_keyix + 4;
1440         }
1441         (void) memcpy(node.key, k->wk_key, k->wk_keylen);
1442         node.key_flags |= (2 | (1 << 3) | (k->wk_keyix << 8));
1443         node.sta_mask = 1;
1444         node.control = 1;
1445         err = wpi_cmd(sc, WPI_CMD_ADD_NODE, &node, sizeof (node), 1);
1446         if (err != WPI_SUCCESS) {
1447                 cmn_err(CE_WARN, "wpi_key_set():"
1448                     "failed to update ap node\n");
1449                 mutex_exit(&sc->sc_glock);
1450                 return (0);
1451         }
1452         mutex_exit(&sc->sc_glock);
1453         return (1);
1454 }
1455 
1456 /*
1457  * Grab exclusive access to NIC memory.
1458  */
1459 static void
1460 wpi_mem_lock(wpi_sc_t *sc)
1461 {
1462         uint32_t tmp;
1463         int ntries;
1464 
1465         tmp = WPI_READ(sc, WPI_GPIO_CTL);
1466         WPI_WRITE(sc, WPI_GPIO_CTL, tmp | WPI_GPIO_MAC);
1467 
1468         /* spin until we actually get the lock */
1469         for (ntries = 0; ntries < 1000; ntries++) {
1470                 if ((WPI_READ(sc, WPI_GPIO_CTL) &
1471                     (WPI_GPIO_CLOCK | WPI_GPIO_SLEEP)) == WPI_GPIO_CLOCK)
1472                         break;
1473                 DELAY(10);
1474         }
1475         if (ntries == 1000)
1476                 WPI_DBG((WPI_DEBUG_PIO, "could not lock memory\n"));
1477 }
1478 
1479 /*
1480  * Release lock on NIC memory.
1481  */
1482 static void
1483 wpi_mem_unlock(wpi_sc_t *sc)
1484 {
1485         uint32_t tmp = WPI_READ(sc, WPI_GPIO_CTL);
1486         WPI_WRITE(sc, WPI_GPIO_CTL, tmp & ~WPI_GPIO_MAC);
1487 }
1488 
1489 static uint32_t
1490 wpi_mem_read(wpi_sc_t *sc, uint16_t addr)
1491 {
1492         WPI_WRITE(sc, WPI_READ_MEM_ADDR, WPI_MEM_4 | addr);
1493         return (WPI_READ(sc, WPI_READ_MEM_DATA));
1494 }
1495 
1496 static void
1497 wpi_mem_write(wpi_sc_t *sc, uint16_t addr, uint32_t data)
1498 {
1499         WPI_WRITE(sc, WPI_WRITE_MEM_ADDR, WPI_MEM_4 | addr);
1500         WPI_WRITE(sc, WPI_WRITE_MEM_DATA, data);
1501 }
1502 
1503 static void
1504 wpi_mem_write_region_4(wpi_sc_t *sc, uint16_t addr,
1505     const uint32_t *data, int wlen)
1506 {
1507         for (; wlen > 0; wlen--, data++, addr += 4)
1508                 wpi_mem_write(sc, addr, *data);
1509 }
1510 
1511 /*
1512  * Read 16 bits from the EEPROM.  We access EEPROM through the MAC instead of
1513  * using the traditional bit-bang method.
1514  */
1515 static uint16_t
1516 wpi_read_prom_word(wpi_sc_t *sc, uint32_t addr)
1517 {
1518         uint32_t val;
1519         int ntries;
1520 
1521         WPI_WRITE(sc, WPI_EEPROM_CTL, addr << 2);
1522 
1523         wpi_mem_lock(sc);
1524         for (ntries = 0; ntries < 10; ntries++) {
1525                 if ((val = WPI_READ(sc, WPI_EEPROM_CTL)) & WPI_EEPROM_READY)
1526                         break;
1527                 DELAY(10);
1528         }
1529         wpi_mem_unlock(sc);
1530 
1531         if (ntries == 10) {
1532                 WPI_DBG((WPI_DEBUG_PIO, "could not read EEPROM\n"));
1533                 return (0xdead);
1534         }
1535         return (val >> 16);
1536 }
1537 
1538 /*
1539  * The firmware boot code is small and is intended to be copied directly into
1540  * the NIC internal memory.
1541  */
1542 static int
1543 wpi_load_microcode(wpi_sc_t *sc)
1544 {
1545         const char *ucode;
1546         int size;
1547 
1548         ucode = sc->sc_boot;
1549         size = LE_32(sc->sc_hdr->bootsz);
1550         /* check that microcode size is a multiple of 4 */
1551         if (size & 3)
1552                 return (EINVAL);
1553 
1554         size /= sizeof (uint32_t);
1555 
1556         wpi_mem_lock(sc);
1557 
1558         /* copy microcode image into NIC memory */
1559         wpi_mem_write_region_4(sc, WPI_MEM_UCODE_BASE, (const uint32_t *)ucode,
1560             size);
1561 
1562         wpi_mem_write(sc, WPI_MEM_UCODE_SRC, 0);
1563         wpi_mem_write(sc, WPI_MEM_UCODE_DST, WPI_FW_TEXT);
1564         wpi_mem_write(sc, WPI_MEM_UCODE_SIZE, size);
1565 
1566         /* run microcode */
1567         wpi_mem_write(sc, WPI_MEM_UCODE_CTL, WPI_UC_RUN);
1568 
1569         wpi_mem_unlock(sc);
1570 
1571         return (WPI_SUCCESS);
1572 }
1573 
1574 /*
1575  * The firmware text and data segments are transferred to the NIC using DMA.
1576  * The driver just copies the firmware into DMA-safe memory and tells the NIC
1577  * where to find it.  Once the NIC has copied the firmware into its internal
1578  * memory, we can free our local copy in the driver.
1579  */
1580 static int
1581 wpi_load_firmware(wpi_sc_t *sc, uint32_t target)
1582 {
1583         const char *fw;
1584         int size;
1585         wpi_dma_t *dma_p;
1586         ddi_dma_cookie_t *cookie;
1587         wpi_tx_desc_t desc;
1588         int i, ntries, err = WPI_SUCCESS;
1589 
1590         /* only text and data here */
1591         if (target == WPI_FW_TEXT) {
1592                 fw = sc->sc_text;
1593                 size = LE_32(sc->sc_hdr->textsz);
1594                 dma_p = &sc->sc_dma_fw_text;
1595                 cookie = sc->sc_fw_text_cookie;
1596         } else {
1597                 fw = sc->sc_data;
1598                 size = LE_32(sc->sc_hdr->datasz);
1599                 dma_p = &sc->sc_dma_fw_data;
1600                 cookie = sc->sc_fw_data_cookie;
1601         }
1602 
1603         /* copy firmware image to DMA-safe memory */
1604         (void) memcpy(dma_p->mem_va, fw, size);
1605 
1606         /* make sure the adapter will get up-to-date values */
1607         (void) ddi_dma_sync(dma_p->dma_hdl, 0, size, DDI_DMA_SYNC_FORDEV);
1608 
1609         (void) memset(&desc, 0, sizeof (desc));
1610         desc.flags = LE_32(WPI_PAD32(size) << 28 | dma_p->ncookies << 24);
1611         for (i = 0; i < dma_p->ncookies; i++) {
1612                 WPI_DBG((WPI_DEBUG_DMA, "cookie%d addr:%x size:%x\n",
1613                     i, cookie[i].dmac_address, cookie[i].dmac_size));
1614                 desc.segs[i].addr = cookie[i].dmac_address;
1615                 desc.segs[i].len = (uint32_t)cookie[i].dmac_size;
1616         }
1617 
1618         wpi_mem_lock(sc);
1619 
1620         /* tell adapter where to copy image in its internal memory */
1621         WPI_WRITE(sc, WPI_FW_TARGET, target);
1622 
1623         WPI_WRITE(sc, WPI_TX_CONFIG(6), 0);
1624 
1625         /* copy firmware descriptor into NIC memory */
1626         WPI_WRITE_REGION_4(sc, WPI_TX_DESC(6), (uint32_t *)&desc,
1627             sizeof desc / sizeof (uint32_t));
1628 
1629         WPI_WRITE(sc, WPI_TX_CREDIT(6), 0xfffff);
1630         WPI_WRITE(sc, WPI_TX_STATE(6), 0x4001);
1631         WPI_WRITE(sc, WPI_TX_CONFIG(6), 0x80000001);
1632 
1633         /* wait while the adapter is busy copying the firmware */
1634         for (ntries = 0; ntries < 100; ntries++) {
1635                 if (WPI_READ(sc, WPI_TX_STATUS) & WPI_TX_IDLE(6))
1636                         break;
1637                 DELAY(1000);
1638         }
1639         if (ntries == 100) {
1640                 WPI_DBG((WPI_DEBUG_FW, "timeout transferring firmware\n"));
1641                 err = ETIMEDOUT;
1642         }
1643 
1644         WPI_WRITE(sc, WPI_TX_CREDIT(6), 0);
1645 
1646         wpi_mem_unlock(sc);
1647 
1648         return (err);
1649 }
1650 
1651 /*ARGSUSED*/
1652 static void
1653 wpi_rx_intr(wpi_sc_t *sc, wpi_rx_desc_t *desc, wpi_rx_data_t *data)
1654 {
1655         ieee80211com_t *ic = &sc->sc_ic;
1656         wpi_rx_ring_t *ring = &sc->sc_rxq;
1657         wpi_rx_stat_t *stat;
1658         wpi_rx_head_t *head;
1659         wpi_rx_tail_t *tail;
1660         ieee80211_node_t *in;
1661         struct ieee80211_frame *wh;
1662         mblk_t *mp;
1663         uint16_t len;
1664 
1665         stat = (wpi_rx_stat_t *)(desc + 1);
1666 
1667         if (stat->len > WPI_STAT_MAXLEN) {
1668                 WPI_DBG((WPI_DEBUG_RX, "invalid rx statistic header\n"));
1669                 return;
1670         }
1671 
1672         head = (wpi_rx_head_t *)((caddr_t)(stat + 1) + stat->len);
1673         tail = (wpi_rx_tail_t *)((caddr_t)(head + 1) + LE_16(head->len));
1674 
1675         len = LE_16(head->len);
1676 
1677         WPI_DBG((WPI_DEBUG_RX, "rx intr: idx=%d len=%d stat len=%d rssi=%d "
1678             "rate=%x chan=%d tstamp=%llu", ring->cur, LE_32(desc->len),
1679             len, (int8_t)stat->rssi, head->rate, head->chan,
1680             LE_64(tail->tstamp)));
1681 
1682         if ((len < 20) || (len > sc->sc_dmabuf_sz)) {
1683                 sc->sc_rx_err++;
1684                 return;
1685         }
1686 
1687         /*
1688          * Discard Rx frames with bad CRC early
1689          */
1690         if ((LE_32(tail->flags) & WPI_RX_NOERROR) != WPI_RX_NOERROR) {
1691                 WPI_DBG((WPI_DEBUG_RX, "rx tail flags error %x\n",
1692                     LE_32(tail->flags)));
1693                 sc->sc_rx_err++;
1694                 return;
1695         }
1696 
1697         /* update Rx descriptor */
1698         /* ring->desc[ring->cur] = LE_32(data->dma_data.cookie.dmac_address); */
1699 
1700 #ifdef WPI_BPF
1701 #ifndef WPI_CURRENT
1702         if (sc->sc_drvbpf != NULL) {
1703 #else
1704         if (bpf_peers_present(sc->sc_drvbpf)) {
1705 #endif
1706                 struct wpi_rx_radiotap_header *tap = &sc->sc_rxtap;
1707 
1708                 tap->wr_flags = 0;
1709                 tap->wr_rate = head->rate;
1710                 tap->wr_chan_freq =
1711                     LE_16(ic->ic_channels[head->chan].ic_freq);
1712                 tap->wr_chan_flags =
1713                     LE_16(ic->ic_channels[head->chan].ic_flags);
1714                 tap->wr_dbm_antsignal = (int8_t)(stat->rssi - WPI_RSSI_OFFSET);
1715                 tap->wr_dbm_antnoise = (int8_t)LE_16(stat->noise);
1716                 tap->wr_tsft = tail->tstamp;
1717                 tap->wr_antenna = (LE_16(head->flags) >> 4) & 0xf;
1718                 switch (head->rate) {
1719                 /* CCK rates */
1720                 case  10: tap->wr_rate =   2; break;
1721                 case  20: tap->wr_rate =   4; break;
1722                 case  55: tap->wr_rate =  11; break;
1723                 case 110: tap->wr_rate =  22; break;
1724                 /* OFDM rates */
1725                 case 0xd: tap->wr_rate =  12; break;
1726                 case 0xf: tap->wr_rate =  18; break;
1727                 case 0x5: tap->wr_rate =  24; break;
1728                 case 0x7: tap->wr_rate =  36; break;
1729                 case 0x9: tap->wr_rate =  48; break;
1730                 case 0xb: tap->wr_rate =  72; break;
1731                 case 0x1: tap->wr_rate =  96; break;
1732                 case 0x3: tap->wr_rate = 108; break;
1733                 /* unknown rate: should not happen */
1734                 default:  tap->wr_rate =   0;
1735                 }
1736                 if (LE_16(head->flags) & 0x4)
1737                         tap->wr_flags |= IEEE80211_RADIOTAP_F_SHORTPRE;
1738 
1739                 bpf_mtap2(sc->sc_drvbpf, tap, sc->sc_rxtap_len, m);
1740         }
1741 #endif
1742         /* grab a reference to the source node */
1743         wh = (struct ieee80211_frame *)(head + 1);
1744 
1745 #ifdef DEBUG
1746         if (wpi_dbg_flags & WPI_DEBUG_RX)
1747                 ieee80211_dump_pkt((uint8_t *)wh, len, 0, 0);
1748 #endif
1749 
1750         in = ieee80211_find_rxnode(ic, wh);
1751         mp = allocb(len, BPRI_MED);
1752         if (mp) {
1753                 (void) memcpy(mp->b_wptr, wh, len);
1754                 mp->b_wptr += len;
1755 
1756                 /* send the frame to the 802.11 layer */
1757                 (void) ieee80211_input(ic, mp, in, stat->rssi, 0);
1758         } else {
1759                 sc->sc_rx_nobuf++;
1760                 WPI_DBG((WPI_DEBUG_RX,
1761                     "wpi_rx_intr(): alloc rx buf failed\n"));
1762         }
1763         /* release node reference */
1764         ieee80211_free_node(in);
1765 }
1766 
1767 /*ARGSUSED*/
1768 static void
1769 wpi_tx_intr(wpi_sc_t *sc, wpi_rx_desc_t *desc, wpi_rx_data_t *data)
1770 {
1771         ieee80211com_t *ic = &sc->sc_ic;
1772         wpi_tx_ring_t *ring = &sc->sc_txq[desc->qid & 0x3];
1773         /* wpi_tx_data_t *txdata = &ring->data[desc->idx]; */
1774         wpi_tx_stat_t *stat = (wpi_tx_stat_t *)(desc + 1);
1775         wpi_amrr_t *amrr = (wpi_amrr_t *)ic->ic_bss;
1776 
1777         WPI_DBG((WPI_DEBUG_TX, "tx done: qid=%d idx=%d retries=%d nkill=%d "
1778             "rate=%x duration=%d status=%x\n",
1779             desc->qid, desc->idx, stat->ntries, stat->nkill, stat->rate,
1780             LE_32(stat->duration), LE_32(stat->status)));
1781 
1782         amrr->txcnt++;
1783         WPI_DBG((WPI_DEBUG_RATECTL, "tx: %d cnt\n", amrr->txcnt));
1784         if (stat->ntries > 0) {
1785                 amrr->retrycnt++;
1786                 sc->sc_tx_retries++;
1787                 WPI_DBG((WPI_DEBUG_RATECTL, "tx: %d retries\n",
1788                     amrr->retrycnt));
1789         }
1790 
1791         sc->sc_tx_timer = 0;
1792 
1793         mutex_enter(&sc->sc_tx_lock);
1794         ring->queued--;
1795         if (ring->queued < 0)
1796                 ring->queued = 0;
1797         if ((sc->sc_need_reschedule) && (ring->queued <= (ring->count << 3))) {
1798                 sc->sc_need_reschedule = 0;
1799                 mutex_exit(&sc->sc_tx_lock);
1800                 mac_tx_update(ic->ic_mach);
1801                 mutex_enter(&sc->sc_tx_lock);
1802         }
1803         mutex_exit(&sc->sc_tx_lock);
1804 }
1805 
1806 static void
1807 wpi_cmd_intr(wpi_sc_t *sc, wpi_rx_desc_t *desc)
1808 {
1809         if ((desc->qid & 7) != 4) {
1810                 return; /* not a command ack */
1811         }
1812         mutex_enter(&sc->sc_glock);
1813         sc->sc_flags |= WPI_F_CMD_DONE;
1814         cv_signal(&sc->sc_cmd_cv);
1815         mutex_exit(&sc->sc_glock);
1816 }
1817 
1818 static uint_t
1819 wpi_notif_softintr(caddr_t arg)
1820 {
1821         wpi_sc_t *sc = (wpi_sc_t *)arg;
1822         wpi_rx_desc_t *desc;
1823         wpi_rx_data_t *data;
1824         uint32_t hw;
1825 
1826         mutex_enter(&sc->sc_glock);
1827         if (sc->sc_notif_softint_pending != 1) {
1828                 mutex_exit(&sc->sc_glock);
1829                 return (DDI_INTR_UNCLAIMED);
1830         }
1831         mutex_exit(&sc->sc_glock);
1832 
1833         hw = LE_32(sc->sc_shared->next);
1834 
1835         while (sc->sc_rxq.cur != hw) {
1836                 data = &sc->sc_rxq.data[sc->sc_rxq.cur];
1837                 desc = (wpi_rx_desc_t *)data->dma_data.mem_va;
1838 
1839                 WPI_DBG((WPI_DEBUG_INTR, "rx notification hw = %d cur = %d "
1840                     "qid=%x idx=%d flags=%x type=%d len=%d\n",
1841                     hw, sc->sc_rxq.cur, desc->qid, desc->idx, desc->flags,
1842                     desc->type, LE_32(desc->len)));
1843 
1844                 if (!(desc->qid & 0x80)) /* reply to a command */
1845                         wpi_cmd_intr(sc, desc);
1846 
1847                 switch (desc->type) {
1848                 case WPI_RX_DONE:
1849                         /* a 802.11 frame was received */
1850                         wpi_rx_intr(sc, desc, data);
1851                         break;
1852 
1853                 case WPI_TX_DONE:
1854                         /* a 802.11 frame has been transmitted */
1855                         wpi_tx_intr(sc, desc, data);
1856                         break;
1857 
1858                 case WPI_UC_READY:
1859                 {
1860                         wpi_ucode_info_t *uc =
1861                             (wpi_ucode_info_t *)(desc + 1);
1862 
1863                         /* the microcontroller is ready */
1864                         WPI_DBG((WPI_DEBUG_FW,
1865                             "microcode alive notification version %x "
1866                             "alive %x\n", LE_32(uc->version),
1867                             LE_32(uc->valid)));
1868 
1869                         if (LE_32(uc->valid) != 1) {
1870                                 WPI_DBG((WPI_DEBUG_FW,
1871                                     "microcontroller initialization failed\n"));
1872                         }
1873                         break;
1874                 }
1875                 case WPI_STATE_CHANGED:
1876                 {
1877                         uint32_t *status = (uint32_t *)(desc + 1);
1878 
1879                         /* enabled/disabled notification */
1880                         WPI_DBG((WPI_DEBUG_RADIO, "state changed to %x\n",
1881                             LE_32(*status)));
1882 
1883                         if (LE_32(*status) & 1) {
1884                                 /*
1885                                  * the radio button has to be pushed(OFF). It
1886                                  * is considered as a hw error, the
1887                                  * wpi_thread() tries to recover it after the
1888                                  * button is pushed again(ON)
1889                                  */
1890                                 cmn_err(CE_NOTE,
1891                                     "wpi: Radio transmitter is off\n");
1892                                 sc->sc_ostate = sc->sc_ic.ic_state;
1893                                 ieee80211_new_state(&sc->sc_ic,
1894                                     IEEE80211_S_INIT, -1);
1895                                 sc->sc_flags |=
1896                                     (WPI_F_HW_ERR_RECOVER | WPI_F_RADIO_OFF);
1897                         }
1898                         break;
1899                 }
1900                 case WPI_START_SCAN:
1901                 {
1902                         wpi_start_scan_t *scan =
1903                             (wpi_start_scan_t *)(desc + 1);
1904 
1905                         WPI_DBG((WPI_DEBUG_SCAN,
1906                             "scanning channel %d status %x\n",
1907                             scan->chan, LE_32(scan->status)));
1908 
1909                         break;
1910                 }
1911                 case WPI_STOP_SCAN:
1912                 {
1913                         wpi_stop_scan_t *scan =
1914                             (wpi_stop_scan_t *)(desc + 1);
1915 
1916                         WPI_DBG((WPI_DEBUG_SCAN,
1917                             "completed channel %d (burst of %d) status %02x\n",
1918                             scan->chan, scan->nchan, scan->status));
1919 
1920                         sc->sc_scan_pending = 0;
1921                         sc->sc_scan_next++;
1922                         break;
1923                 }
1924                 default:
1925                         break;
1926                 }
1927 
1928                 sc->sc_rxq.cur = (sc->sc_rxq.cur + 1) % WPI_RX_RING_COUNT;
1929         }
1930 
1931         /* tell the firmware what we have processed */
1932         hw = (hw == 0) ? WPI_RX_RING_COUNT - 1 : hw - 1;
1933         WPI_WRITE(sc, WPI_RX_WIDX, hw & (~7));
1934         mutex_enter(&sc->sc_glock);
1935         sc->sc_notif_softint_pending = 0;
1936         mutex_exit(&sc->sc_glock);
1937 
1938         return (DDI_INTR_CLAIMED);
1939 }
1940 
1941 static uint_t
1942 wpi_intr(caddr_t arg)
1943 {
1944         wpi_sc_t *sc = (wpi_sc_t *)arg;
1945         uint32_t r, rfh;
1946 
1947         mutex_enter(&sc->sc_glock);
1948         if (sc->sc_flags & WPI_F_SUSPEND) {
1949                 mutex_exit(&sc->sc_glock);
1950                 return (DDI_INTR_UNCLAIMED);
1951         }
1952 
1953         r = WPI_READ(sc, WPI_INTR);
1954         if (r == 0 || r == 0xffffffff) {
1955                 mutex_exit(&sc->sc_glock);
1956                 return (DDI_INTR_UNCLAIMED);
1957         }
1958 
1959         WPI_DBG((WPI_DEBUG_INTR, "interrupt reg %x\n", r));
1960 
1961         rfh = WPI_READ(sc, WPI_INTR_STATUS);
1962         /* disable interrupts */
1963         WPI_WRITE(sc, WPI_MASK, 0);
1964         /* ack interrupts */
1965         WPI_WRITE(sc, WPI_INTR, r);
1966         WPI_WRITE(sc, WPI_INTR_STATUS, rfh);
1967 
1968         if (sc->sc_notif_softint_id == NULL) {
1969                 mutex_exit(&sc->sc_glock);
1970                 return (DDI_INTR_CLAIMED);
1971         }
1972 
1973         if (r & (WPI_SW_ERROR | WPI_HW_ERROR)) {
1974                 WPI_DBG((WPI_DEBUG_FW, "fatal firmware error\n"));
1975                 mutex_exit(&sc->sc_glock);
1976                 wpi_stop(sc);
1977                 if (!(sc->sc_flags & WPI_F_HW_ERR_RECOVER)) {
1978                         sc->sc_ostate = sc->sc_ic.ic_state;
1979                 }
1980 
1981                 /* not capable of fast recovery */
1982                 if (!WPI_CHK_FAST_RECOVER(sc))
1983                         ieee80211_new_state(&sc->sc_ic, IEEE80211_S_INIT, -1);
1984 
1985                 sc->sc_flags |= WPI_F_HW_ERR_RECOVER;
1986                 return (DDI_INTR_CLAIMED);
1987         }
1988 
1989         if ((r & (WPI_RX_INTR | WPI_RX_SWINT)) ||
1990             (rfh & 0x40070000)) {
1991                 sc->sc_notif_softint_pending = 1;
1992                 ddi_trigger_softintr(sc->sc_notif_softint_id);
1993         }
1994 
1995         if (r & WPI_ALIVE_INTR)     { /* firmware initialized */
1996                 sc->sc_flags |= WPI_F_FW_INIT;
1997                 cv_signal(&sc->sc_fw_cv);
1998         }
1999 
2000         /* re-enable interrupts */
2001         WPI_WRITE(sc, WPI_MASK, WPI_INTR_MASK);
2002         mutex_exit(&sc->sc_glock);
2003 
2004         return (DDI_INTR_CLAIMED);
2005 }
2006 
2007 static uint8_t
2008 wpi_plcp_signal(int rate)
2009 {
2010         switch (rate) {
2011         /* CCK rates (returned values are device-dependent) */
2012         case 2:         return (10);
2013         case 4:         return (20);
2014         case 11:        return (55);
2015         case 22:        return (110);
2016 
2017         /* OFDM rates (cf IEEE Std 802.11a-1999, pp. 14 Table 80) */
2018         /* R1-R4 (ral/ural is R4-R1) */
2019         case 12:        return (0xd);
2020         case 18:        return (0xf);
2021         case 24:        return (0x5);
2022         case 36:        return (0x7);
2023         case 48:        return (0x9);
2024         case 72:        return (0xb);
2025         case 96:        return (0x1);
2026         case 108:       return (0x3);
2027 
2028         /* unsupported rates (should not get there) */
2029         default:        return (0);
2030         }
2031 }
2032 
2033 static mblk_t *
2034 wpi_m_tx(void *arg, mblk_t *mp)
2035 {
2036         wpi_sc_t        *sc = (wpi_sc_t *)arg;
2037         ieee80211com_t  *ic = &sc->sc_ic;
2038         mblk_t                  *next;
2039 
2040         if (sc->sc_flags & WPI_F_SUSPEND) {
2041                 freemsgchain(mp);
2042                 return (NULL);
2043         }
2044 
2045         if (ic->ic_state != IEEE80211_S_RUN) {
2046                 freemsgchain(mp);
2047                 return (NULL);
2048         }
2049 
2050         if ((sc->sc_flags & WPI_F_HW_ERR_RECOVER) &&
2051             WPI_CHK_FAST_RECOVER(sc)) {
2052                 WPI_DBG((WPI_DEBUG_FW, "wpi_m_tx(): hold queue\n"));
2053                 return (mp);
2054         }
2055 
2056         while (mp != NULL) {
2057                 next = mp->b_next;
2058                 mp->b_next = NULL;
2059                 if (wpi_send(ic, mp, IEEE80211_FC0_TYPE_DATA) != 0) {
2060                         mp->b_next = next;
2061                         break;
2062                 }
2063                 mp = next;
2064         }
2065         return (mp);
2066 }
2067 
2068 /* ARGSUSED */
2069 static int
2070 wpi_send(ieee80211com_t *ic, mblk_t *mp, uint8_t type)
2071 {
2072         wpi_sc_t *sc = (wpi_sc_t *)ic;
2073         wpi_tx_ring_t *ring;
2074         wpi_tx_desc_t *desc;
2075         wpi_tx_data_t *data;
2076         wpi_tx_cmd_t *cmd;
2077         wpi_cmd_data_t *tx;
2078         ieee80211_node_t *in;
2079         struct ieee80211_frame *wh;
2080         struct ieee80211_key *k;
2081         mblk_t *m, *m0;
2082         int rate, hdrlen, len, mblen, off, err = WPI_SUCCESS;
2083 
2084         ring = ((type & IEEE80211_FC0_TYPE_MASK) != IEEE80211_FC0_TYPE_DATA) ?
2085             (&sc->sc_txq[0]) : (&sc->sc_txq[1]);
2086         data = &ring->data[ring->cur];
2087         desc = data->desc;
2088         cmd = data->cmd;
2089         bzero(desc, sizeof (*desc));
2090         bzero(cmd, sizeof (*cmd));
2091 
2092         mutex_enter(&sc->sc_tx_lock);
2093         if (sc->sc_flags & WPI_F_SUSPEND) {
2094                 mutex_exit(&sc->sc_tx_lock);
2095                 if ((type & IEEE80211_FC0_TYPE_MASK) !=
2096                     IEEE80211_FC0_TYPE_DATA) {
2097                         freemsg(mp);
2098                 }
2099                 err = ENXIO;
2100                 goto exit;
2101         }
2102 
2103         if (ring->queued > ring->count - 64) {
2104                 WPI_DBG((WPI_DEBUG_TX, "wpi_send(): no txbuf\n"));
2105                 sc->sc_need_reschedule = 1;
2106                 mutex_exit(&sc->sc_tx_lock);
2107                 if ((type & IEEE80211_FC0_TYPE_MASK) !=
2108                     IEEE80211_FC0_TYPE_DATA) {
2109                         freemsg(mp);
2110                 }
2111                 sc->sc_tx_nobuf++;
2112                 err = ENOMEM;
2113                 goto exit;
2114         }
2115         mutex_exit(&sc->sc_tx_lock);
2116 
2117         hdrlen = sizeof (struct ieee80211_frame);
2118 
2119         m = allocb(msgdsize(mp) + 32, BPRI_MED);
2120         if (m == NULL) { /* can not alloc buf, drop this package */
2121                 cmn_err(CE_WARN,
2122                     "wpi_send(): failed to allocate msgbuf\n");
2123                 freemsg(mp);
2124                 err = WPI_SUCCESS;
2125                 goto exit;
2126         }
2127         for (off = 0, m0 = mp; m0 != NULL; m0 = m0->b_cont) {
2128                 mblen = MBLKL(m0);
2129                 (void) memcpy(m->b_rptr + off, m0->b_rptr, mblen);
2130                 off += mblen;
2131         }
2132         m->b_wptr += off;
2133         freemsg(mp);
2134 
2135         wh = (struct ieee80211_frame *)m->b_rptr;
2136 
2137         in = ieee80211_find_txnode(ic, wh->i_addr1);
2138         if (in == NULL) {
2139                 cmn_err(CE_WARN, "wpi_send(): failed to find tx node\n");
2140                 freemsg(m);
2141                 sc->sc_tx_err++;
2142                 err = WPI_SUCCESS;
2143                 goto exit;
2144         }
2145 
2146         (void) ieee80211_encap(ic, m, in);
2147 
2148         cmd->code = WPI_CMD_TX_DATA;
2149         cmd->flags = 0;
2150         cmd->qid = ring->qid;
2151         cmd->idx = ring->cur;
2152 
2153         tx = (wpi_cmd_data_t *)cmd->data;
2154         tx->flags = 0;
2155         if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) {
2156                 tx->flags |= LE_32(WPI_TX_NEED_ACK);
2157         } else {
2158                 tx->flags &= ~(LE_32(WPI_TX_NEED_ACK));
2159         }
2160 
2161         if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
2162                 k = ieee80211_crypto_encap(ic, m);
2163                 if (k == NULL) {
2164                         freemsg(m);
2165                         sc->sc_tx_err++;
2166                         err = WPI_SUCCESS;
2167                         goto exit;
2168                 }
2169 
2170                 if (k->wk_cipher->ic_cipher == IEEE80211_CIPHER_AES_CCM) {
2171                         tx->security = 2; /* for CCMP */
2172                         tx->flags |= LE_32(WPI_TX_NEED_ACK);
2173                         (void) memcpy(&tx->key, k->wk_key, k->wk_keylen);
2174                 }
2175 
2176                 /* packet header may have moved, reset our local pointer */
2177                 wh = (struct ieee80211_frame *)m->b_rptr;
2178         }
2179 
2180         len = msgdsize(m);
2181 
2182 #ifdef DEBUG
2183         if (wpi_dbg_flags & WPI_DEBUG_TX)
2184                 ieee80211_dump_pkt((uint8_t *)wh, hdrlen, 0, 0);
2185 #endif
2186 
2187         /* pickup a rate */
2188         if ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) ==
2189             IEEE80211_FC0_TYPE_MGT) {
2190                 /* mgmt frames are sent at the lowest available bit-rate */
2191                 rate = 2;
2192         } else {
2193                 if (ic->ic_fixed_rate != IEEE80211_FIXED_RATE_NONE) {
2194                         rate = ic->ic_fixed_rate;
2195                 } else
2196                         rate = in->in_rates.ir_rates[in->in_txrate];
2197         }
2198         rate &= IEEE80211_RATE_VAL;
2199         WPI_DBG((WPI_DEBUG_RATECTL, "tx rate[%d of %d] = %x",
2200             in->in_txrate, in->in_rates.ir_nrates, rate));
2201 #ifdef WPI_BPF
2202 #ifndef WPI_CURRENT
2203         if (sc->sc_drvbpf != NULL) {
2204 #else
2205         if (bpf_peers_present(sc->sc_drvbpf)) {
2206 #endif
2207                 struct wpi_tx_radiotap_header *tap = &sc->sc_txtap;
2208 
2209                 tap->wt_flags = 0;
2210                 tap->wt_chan_freq = LE_16(ic->ic_curchan->ic_freq);
2211                 tap->wt_chan_flags = LE_16(ic->ic_curchan->ic_flags);
2212                 tap->wt_rate = rate;
2213                 if (wh->i_fc[1] & IEEE80211_FC1_WEP)
2214                         tap->wt_flags |= IEEE80211_RADIOTAP_F_WEP;
2215 
2216                 bpf_mtap2(sc->sc_drvbpf, tap, sc->sc_txtap_len, m0);
2217         }
2218 #endif
2219 
2220         tx->flags |= (LE_32(WPI_TX_AUTO_SEQ));
2221         tx->flags |= LE_32(WPI_TX_BT_DISABLE | WPI_TX_CALIBRATION);
2222 
2223         /* retrieve destination node's id */
2224         tx->id = IEEE80211_IS_MULTICAST(wh->i_addr1) ? WPI_ID_BROADCAST :
2225             WPI_ID_BSS;
2226 
2227         if ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) ==
2228             IEEE80211_FC0_TYPE_MGT) {
2229                 /* tell h/w to set timestamp in probe responses */
2230                 if ((wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK) ==
2231                     IEEE80211_FC0_SUBTYPE_PROBE_RESP)
2232                         tx->flags |= LE_32(WPI_TX_INSERT_TSTAMP);
2233 
2234                 if (((wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK) ==
2235                     IEEE80211_FC0_SUBTYPE_ASSOC_REQ) ||
2236                     ((wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK) ==
2237                     IEEE80211_FC0_SUBTYPE_REASSOC_REQ))
2238                         tx->timeout = 3;
2239                 else
2240                         tx->timeout = 2;
2241         } else
2242                 tx->timeout = 0;
2243 
2244         tx->rate = wpi_plcp_signal(rate);
2245 
2246         /* be very persistant at sending frames out */
2247         tx->rts_ntries = 7;
2248         tx->data_ntries = 15;
2249 
2250         tx->cck_mask  = 0x0f;
2251         tx->ofdm_mask = 0xff;
2252         tx->lifetime  = LE_32(0xffffffff);
2253 
2254         tx->len = LE_16(len);
2255 
2256         /* save and trim IEEE802.11 header */
2257         (void) memcpy(tx + 1, m->b_rptr, hdrlen);
2258         m->b_rptr += hdrlen;
2259         (void) memcpy(data->dma_data.mem_va, m->b_rptr, len - hdrlen);
2260 
2261         WPI_DBG((WPI_DEBUG_TX, "sending data: qid=%d idx=%d len=%d", ring->qid,
2262             ring->cur, len));
2263 
2264         /* first scatter/gather segment is used by the tx data command */
2265         desc->flags = LE_32(WPI_PAD32(len) << 28 | (2) << 24);
2266         desc->segs[0].addr = LE_32(data->paddr_cmd);
2267         desc->segs[0].len  = LE_32(
2268             roundup(4 + sizeof (wpi_cmd_data_t) + hdrlen, 4));
2269         desc->segs[1].addr = LE_32(data->dma_data.cookie.dmac_address);
2270         desc->segs[1].len  = LE_32(len - hdrlen);
2271 
2272         WPI_DMA_SYNC(data->dma_data, DDI_DMA_SYNC_FORDEV);
2273         WPI_DMA_SYNC(ring->dma_desc, DDI_DMA_SYNC_FORDEV);
2274 
2275         mutex_enter(&sc->sc_tx_lock);
2276         ring->queued++;
2277         mutex_exit(&sc->sc_tx_lock);
2278 
2279         /* kick ring */
2280         ring->cur = (ring->cur + 1) % WPI_TX_RING_COUNT;
2281         WPI_WRITE(sc, WPI_TX_WIDX, ring->qid << 8 | ring->cur);
2282         freemsg(m);
2283         /* release node reference */
2284         ieee80211_free_node(in);
2285 
2286         ic->ic_stats.is_tx_bytes += len;
2287         ic->ic_stats.is_tx_frags++;
2288 
2289         if (sc->sc_tx_timer == 0)
2290                 sc->sc_tx_timer = 5;
2291 exit:
2292         return (err);
2293 }
2294 
2295 static void
2296 wpi_m_ioctl(void* arg, queue_t *wq, mblk_t *mp)
2297 {
2298         wpi_sc_t        *sc  = (wpi_sc_t *)arg;
2299         ieee80211com_t  *ic = &sc->sc_ic;
2300         int             err;
2301 
2302         err = ieee80211_ioctl(ic, wq, mp);
2303         if (err == ENETRESET) {
2304                 /*
2305                  * This is special for the hidden AP connection.
2306                  * In any case, we should make sure only one 'scan'
2307                  * in the driver for a 'connect' CLI command. So
2308                  * when connecting to a hidden AP, the scan is just
2309                  * sent out to the air when we know the desired
2310                  * essid of the AP we want to connect.
2311                  */
2312                 if (ic->ic_des_esslen) {
2313                         if (sc->sc_flags & WPI_F_RUNNING) {
2314                                 wpi_m_stop(sc);
2315                                 (void) wpi_m_start(sc);
2316                                 (void) ieee80211_new_state(ic,
2317                                     IEEE80211_S_SCAN, -1);
2318                         }
2319                 }
2320         }
2321 }
2322 
2323 /*
2324  * Callback functions for get/set properties
2325  */
2326 /* ARGSUSED */
2327 static int
2328 wpi_m_getprop(void *arg, const char *pr_name, mac_prop_id_t wldp_pr_name,
2329     uint_t wldp_length, void *wldp_buf)
2330 {
2331         int             err = 0;
2332         wpi_sc_t        *sc = (wpi_sc_t *)arg;
2333 
2334         err = ieee80211_getprop(&sc->sc_ic, pr_name, wldp_pr_name,
2335             wldp_length, wldp_buf);
2336 
2337         return (err);
2338 }
2339 
2340 static void
2341 wpi_m_propinfo(void *arg, const char *pr_name, mac_prop_id_t wldp_pr_num,
2342     mac_prop_info_handle_t mph)
2343 {
2344         wpi_sc_t        *sc = (wpi_sc_t *)arg;
2345 
2346         ieee80211_propinfo(&sc->sc_ic, pr_name, wldp_pr_num, mph);
2347 }
2348 
2349 static int
2350 wpi_m_setprop(void *arg, const char *pr_name, mac_prop_id_t wldp_pr_name,
2351     uint_t wldp_length, const void *wldp_buf)
2352 {
2353         int             err;
2354         wpi_sc_t        *sc = (wpi_sc_t *)arg;
2355         ieee80211com_t  *ic = &sc->sc_ic;
2356 
2357         err = ieee80211_setprop(ic, pr_name, wldp_pr_name,
2358             wldp_length, wldp_buf);
2359 
2360         if (err == ENETRESET) {
2361                 if (ic->ic_des_esslen) {
2362                         if (sc->sc_flags & WPI_F_RUNNING) {
2363                                 wpi_m_stop(sc);
2364                                 (void) wpi_m_start(sc);
2365                                 (void) ieee80211_new_state(ic,
2366                                     IEEE80211_S_SCAN, -1);
2367                         }
2368                 }
2369 
2370                 err = 0;
2371         }
2372 
2373         return (err);
2374 }
2375 
2376 /*ARGSUSED*/
2377 static int
2378 wpi_m_stat(void *arg, uint_t stat, uint64_t *val)
2379 {
2380         wpi_sc_t        *sc  = (wpi_sc_t *)arg;
2381         ieee80211com_t  *ic = &sc->sc_ic;
2382         ieee80211_node_t *in;
2383 
2384         mutex_enter(&sc->sc_glock);
2385         switch (stat) {
2386         case MAC_STAT_IFSPEED:
2387                 in = ic->ic_bss;
2388                 *val = ((ic->ic_fixed_rate == IEEE80211_FIXED_RATE_NONE) ?
2389                     IEEE80211_RATE(in->in_txrate) :
2390                     ic->ic_fixed_rate) / 2 * 1000000;
2391                 break;
2392         case MAC_STAT_NOXMTBUF:
2393                 *val = sc->sc_tx_nobuf;
2394                 break;
2395         case MAC_STAT_NORCVBUF:
2396                 *val = sc->sc_rx_nobuf;
2397                 break;
2398         case MAC_STAT_IERRORS:
2399                 *val = sc->sc_rx_err;
2400                 break;
2401         case MAC_STAT_RBYTES:
2402                 *val = ic->ic_stats.is_rx_bytes;
2403                 break;
2404         case MAC_STAT_IPACKETS:
2405                 *val = ic->ic_stats.is_rx_frags;
2406                 break;
2407         case MAC_STAT_OBYTES:
2408                 *val = ic->ic_stats.is_tx_bytes;
2409                 break;
2410         case MAC_STAT_OPACKETS:
2411                 *val = ic->ic_stats.is_tx_frags;
2412                 break;
2413         case MAC_STAT_OERRORS:
2414         case WIFI_STAT_TX_FAILED:
2415                 *val = sc->sc_tx_err;
2416                 break;
2417         case WIFI_STAT_TX_RETRANS:
2418                 *val = sc->sc_tx_retries;
2419                 break;
2420         case WIFI_STAT_FCS_ERRORS:
2421         case WIFI_STAT_WEP_ERRORS:
2422         case WIFI_STAT_TX_FRAGS:
2423         case WIFI_STAT_MCAST_TX:
2424         case WIFI_STAT_RTS_SUCCESS:
2425         case WIFI_STAT_RTS_FAILURE:
2426         case WIFI_STAT_ACK_FAILURE:
2427         case WIFI_STAT_RX_FRAGS:
2428         case WIFI_STAT_MCAST_RX:
2429         case WIFI_STAT_RX_DUPS:
2430                 mutex_exit(&sc->sc_glock);
2431                 return (ieee80211_stat(ic, stat, val));
2432         default:
2433                 mutex_exit(&sc->sc_glock);
2434                 return (ENOTSUP);
2435         }
2436         mutex_exit(&sc->sc_glock);
2437 
2438         return (WPI_SUCCESS);
2439 
2440 }
2441 
2442 static int
2443 wpi_m_start(void *arg)
2444 {
2445         wpi_sc_t *sc = (wpi_sc_t *)arg;
2446         ieee80211com_t  *ic = &sc->sc_ic;
2447         int err;
2448 
2449         err = wpi_init(sc);
2450         if (err != WPI_SUCCESS) {
2451                 wpi_stop(sc);
2452                 DELAY(1000000);
2453                 err = wpi_init(sc);
2454         }
2455 
2456         if (err) {
2457                 /*
2458                  * The hw init err(eg. RF is OFF). Return Success to make
2459                  * the 'plumb' succeed. The wpi_thread() tries to re-init
2460                  * background.
2461                  */
2462                 mutex_enter(&sc->sc_glock);
2463                 sc->sc_flags |= WPI_F_HW_ERR_RECOVER;
2464                 mutex_exit(&sc->sc_glock);
2465                 return (WPI_SUCCESS);
2466         }
2467         ieee80211_new_state(ic, IEEE80211_S_INIT, -1);
2468         mutex_enter(&sc->sc_glock);
2469         sc->sc_flags |= WPI_F_RUNNING;
2470         mutex_exit(&sc->sc_glock);
2471 
2472         return (WPI_SUCCESS);
2473 }
2474 
2475 static void
2476 wpi_m_stop(void *arg)
2477 {
2478         wpi_sc_t *sc = (wpi_sc_t *)arg;
2479         ieee80211com_t  *ic = &sc->sc_ic;
2480 
2481         wpi_stop(sc);
2482         ieee80211_new_state(ic, IEEE80211_S_INIT, -1);
2483         mutex_enter(&sc->sc_mt_lock);
2484         sc->sc_flags &= ~WPI_F_HW_ERR_RECOVER;
2485         sc->sc_flags &= ~WPI_F_RATE_AUTO_CTL;
2486         mutex_exit(&sc->sc_mt_lock);
2487         mutex_enter(&sc->sc_glock);
2488         sc->sc_flags &= ~WPI_F_RUNNING;
2489         mutex_exit(&sc->sc_glock);
2490 }
2491 
2492 /*ARGSUSED*/
2493 static int
2494 wpi_m_unicst(void *arg, const uint8_t *macaddr)
2495 {
2496         wpi_sc_t *sc = (wpi_sc_t *)arg;
2497         ieee80211com_t  *ic = &sc->sc_ic;
2498         int err;
2499 
2500         if (!IEEE80211_ADDR_EQ(ic->ic_macaddr, macaddr)) {
2501                 IEEE80211_ADDR_COPY(ic->ic_macaddr, macaddr);
2502                 mutex_enter(&sc->sc_glock);
2503                 err = wpi_config(sc);
2504                 mutex_exit(&sc->sc_glock);
2505                 if (err != WPI_SUCCESS) {
2506                         cmn_err(CE_WARN,
2507                             "wpi_m_unicst(): "
2508                             "failed to configure device\n");
2509                         goto fail;
2510                 }
2511         }
2512         return (WPI_SUCCESS);
2513 fail:
2514         return (err);
2515 }
2516 
2517 /*ARGSUSED*/
2518 static int
2519 wpi_m_multicst(void *arg, boolean_t add, const uint8_t *m)
2520 {
2521         return (WPI_SUCCESS);
2522 }
2523 
2524 /*ARGSUSED*/
2525 static int
2526 wpi_m_promisc(void *arg, boolean_t on)
2527 {
2528         return (WPI_SUCCESS);
2529 }
2530 
2531 static void
2532 wpi_thread(wpi_sc_t *sc)
2533 {
2534         ieee80211com_t  *ic = &sc->sc_ic;
2535         clock_t clk;
2536         int times = 0, err, n = 0, timeout = 0;
2537         uint32_t tmp;
2538 
2539         mutex_enter(&sc->sc_mt_lock);
2540         while (sc->sc_mf_thread_switch) {
2541                 tmp = WPI_READ(sc, WPI_GPIO_CTL);
2542                 if (tmp & WPI_GPIO_HW_RF_KILL) {
2543                         sc->sc_flags &= ~WPI_F_RADIO_OFF;
2544                 } else {
2545                         sc->sc_flags |= WPI_F_RADIO_OFF;
2546                 }
2547                 /*
2548                  * If in SUSPEND or the RF is OFF, do nothing
2549                  */
2550                 if ((sc->sc_flags & WPI_F_SUSPEND) ||
2551                     (sc->sc_flags & WPI_F_RADIO_OFF)) {
2552                         mutex_exit(&sc->sc_mt_lock);
2553                         delay(drv_usectohz(100000));
2554                         mutex_enter(&sc->sc_mt_lock);
2555                         continue;
2556                 }
2557 
2558                 /*
2559                  * recovery fatal error
2560                  */
2561                 if (ic->ic_mach &&
2562                     (sc->sc_flags & WPI_F_HW_ERR_RECOVER)) {
2563 
2564                         WPI_DBG((WPI_DEBUG_FW,
2565                             "wpi_thread(): "
2566                             "try to recover fatal hw error: %d\n", times++));
2567 
2568                         wpi_stop(sc);
2569 
2570                         if (WPI_CHK_FAST_RECOVER(sc)) {
2571                                 /* save runtime configuration */
2572                                 bcopy(&sc->sc_config, &sc->sc_config_save,
2573                                     sizeof (sc->sc_config));
2574                         } else {
2575                                 mutex_exit(&sc->sc_mt_lock);
2576                                 ieee80211_new_state(ic, IEEE80211_S_INIT, -1);
2577                                 delay(drv_usectohz(2000000));
2578                                 mutex_enter(&sc->sc_mt_lock);
2579                         }
2580 
2581                         err = wpi_init(sc);
2582                         if (err != WPI_SUCCESS) {
2583                                 n++;
2584                                 if (n < 3)
2585                                         continue;
2586                         }
2587                         n = 0;
2588                         if (!err)
2589                                 sc->sc_flags |= WPI_F_RUNNING;
2590 
2591                         if (!WPI_CHK_FAST_RECOVER(sc) ||
2592                             wpi_fast_recover(sc) != WPI_SUCCESS) {
2593                                 sc->sc_flags &= ~WPI_F_HW_ERR_RECOVER;
2594 
2595                                 mutex_exit(&sc->sc_mt_lock);
2596                                 delay(drv_usectohz(2000000));
2597                                 if (sc->sc_ostate != IEEE80211_S_INIT)
2598                                         ieee80211_new_state(ic,
2599                                             IEEE80211_S_SCAN, 0);
2600                                 mutex_enter(&sc->sc_mt_lock);
2601                         }
2602                 }
2603 
2604                 if (ic->ic_mach && (sc->sc_flags & WPI_F_LAZY_RESUME)) {
2605                         WPI_DBG((WPI_DEBUG_RESUME,
2606                             "wpi_thread(): "
2607                             "lazy resume\n"));
2608                         sc->sc_flags &= ~WPI_F_LAZY_RESUME;
2609                         mutex_exit(&sc->sc_mt_lock);
2610                         /*
2611                          * NB: under WPA mode, this call hangs (door problem?)
2612                          * when called in wpi_attach() and wpi_detach() while
2613                          * system is in the procedure of CPR. To be safe, let
2614                          * the thread do this.
2615                          */
2616                         ieee80211_new_state(&sc->sc_ic, IEEE80211_S_INIT, -1);
2617                         mutex_enter(&sc->sc_mt_lock);
2618                 }
2619 
2620                 /*
2621                  * scan next channel
2622                  */
2623                 if (ic->ic_mach &&
2624                     (sc->sc_flags & WPI_F_SCANNING) && sc->sc_scan_next) {
2625 
2626                         WPI_DBG((WPI_DEBUG_SCAN,
2627                             "wpi_thread(): "
2628                             "wait for probe response\n"));
2629 
2630                         sc->sc_scan_next--;
2631                         mutex_exit(&sc->sc_mt_lock);
2632                         delay(drv_usectohz(200000));
2633                         if (sc->sc_flags & WPI_F_SCANNING)
2634                                 ieee80211_next_scan(ic);
2635                         mutex_enter(&sc->sc_mt_lock);
2636                 }
2637 
2638                 /*
2639                  * rate ctl
2640                  */
2641                 if (ic->ic_mach &&
2642                     (sc->sc_flags & WPI_F_RATE_AUTO_CTL)) {
2643                         clk = ddi_get_lbolt();
2644                         if (clk > sc->sc_clk + drv_usectohz(500000)) {
2645                                 wpi_amrr_timeout(sc);
2646                         }
2647                 }
2648                 mutex_exit(&sc->sc_mt_lock);
2649                 delay(drv_usectohz(100000));
2650                 mutex_enter(&sc->sc_mt_lock);
2651                 if (sc->sc_tx_timer) {
2652                         timeout++;
2653                         if (timeout == 10) {
2654                                 sc->sc_tx_timer--;
2655                                 if (sc->sc_tx_timer == 0) {
2656                                         sc->sc_flags |= WPI_F_HW_ERR_RECOVER;
2657                                         sc->sc_ostate = IEEE80211_S_RUN;
2658                                         WPI_DBG((WPI_DEBUG_FW,
2659                                             "wpi_thread(): send fail\n"));
2660                                 }
2661                                 timeout = 0;
2662                         }
2663                 }
2664         }
2665         sc->sc_mf_thread = NULL;
2666         cv_signal(&sc->sc_mt_cv);
2667         mutex_exit(&sc->sc_mt_lock);
2668 }
2669 
2670 /*
2671  * Extract various information from EEPROM.
2672  */
2673 static void
2674 wpi_read_eeprom(wpi_sc_t *sc)
2675 {
2676         ieee80211com_t *ic = &sc->sc_ic;
2677         uint16_t val;
2678         int i;
2679 
2680         /* read MAC address */
2681         val = wpi_read_prom_word(sc, WPI_EEPROM_MAC + 0);
2682         ic->ic_macaddr[0] = val & 0xff;
2683         ic->ic_macaddr[1] = val >> 8;
2684         val = wpi_read_prom_word(sc, WPI_EEPROM_MAC + 1);
2685         ic->ic_macaddr[2] = val & 0xff;
2686         ic->ic_macaddr[3] = val >> 8;
2687         val = wpi_read_prom_word(sc, WPI_EEPROM_MAC + 2);
2688         ic->ic_macaddr[4] = val & 0xff;
2689         ic->ic_macaddr[5] = val >> 8;
2690 
2691         WPI_DBG((WPI_DEBUG_EEPROM,
2692             "mac:%2x:%2x:%2x:%2x:%2x:%2x\n",
2693             ic->ic_macaddr[0], ic->ic_macaddr[1],
2694             ic->ic_macaddr[2], ic->ic_macaddr[3],
2695             ic->ic_macaddr[4], ic->ic_macaddr[5]));
2696         /* read power settings for 2.4GHz channels */
2697         for (i = 0; i < 14; i++) {
2698                 sc->sc_pwr1[i] = wpi_read_prom_word(sc, WPI_EEPROM_PWR1 + i);
2699                 sc->sc_pwr2[i] = wpi_read_prom_word(sc, WPI_EEPROM_PWR2 + i);
2700                 WPI_DBG((WPI_DEBUG_EEPROM,
2701                     "channel %d pwr1 0x%04x pwr2 0x%04x\n", i + 1,
2702                     sc->sc_pwr1[i], sc->sc_pwr2[i]));
2703         }
2704 }
2705 
2706 /*
2707  * Send a command to the firmware.
2708  */
2709 static int
2710 wpi_cmd(wpi_sc_t *sc, int code, const void *buf, int size, int async)
2711 {
2712         wpi_tx_ring_t *ring = &sc->sc_cmdq;
2713         wpi_tx_desc_t *desc;
2714         wpi_tx_cmd_t *cmd;
2715 
2716         ASSERT(size <= sizeof (cmd->data));
2717         ASSERT(mutex_owned(&sc->sc_glock));
2718 
2719         WPI_DBG((WPI_DEBUG_CMD, "wpi_cmd() # code[%d]", code));
2720         desc = ring->data[ring->cur].desc;
2721         cmd = ring->data[ring->cur].cmd;
2722 
2723         cmd->code = (uint8_t)code;
2724         cmd->flags = 0;
2725         cmd->qid = ring->qid;
2726         cmd->idx = ring->cur;
2727         (void) memcpy(cmd->data, buf, size);
2728 
2729         desc->flags = LE_32(WPI_PAD32(size) << 28 | 1 << 24);
2730         desc->segs[0].addr = ring->data[ring->cur].paddr_cmd;
2731         desc->segs[0].len  = 4 + size;
2732 
2733         /* kick cmd ring */
2734         ring->cur = (ring->cur + 1) % WPI_CMD_RING_COUNT;
2735         WPI_WRITE(sc, WPI_TX_WIDX, ring->qid << 8 | ring->cur);
2736 
2737         if (async)
2738                 return (WPI_SUCCESS);
2739         else {
2740                 clock_t clk;
2741                 sc->sc_flags &= ~WPI_F_CMD_DONE;
2742                 clk = ddi_get_lbolt() + drv_usectohz(2000000);
2743                 while (!(sc->sc_flags & WPI_F_CMD_DONE)) {
2744                         if (cv_timedwait(&sc->sc_cmd_cv, &sc->sc_glock, clk)
2745                             < 0)
2746                                 break;
2747                 }
2748                 if (sc->sc_flags & WPI_F_CMD_DONE)
2749                         return (WPI_SUCCESS);
2750                 else
2751                         return (WPI_FAIL);
2752         }
2753 }
2754 
2755 /*
2756  * Configure h/w multi-rate retries.
2757  */
2758 static int
2759 wpi_mrr_setup(wpi_sc_t *sc)
2760 {
2761         wpi_mrr_setup_t mrr;
2762         int i, err;
2763 
2764         /* CCK rates (not used with 802.11a) */
2765         for (i = WPI_CCK1; i <= WPI_CCK11; i++) {
2766                 mrr.rates[i].flags = 0;
2767                 mrr.rates[i].signal = wpi_ridx_to_signal[i];
2768                 /* fallback to the immediate lower CCK rate (if any) */
2769                 mrr.rates[i].next = (i == WPI_CCK1) ? WPI_CCK1 : i - 1;
2770                 /* try one time at this rate before falling back to "next" */
2771                 mrr.rates[i].ntries = 1;
2772         }
2773 
2774         /* OFDM rates (not used with 802.11b) */
2775         for (i = WPI_OFDM6; i <= WPI_OFDM54; i++) {
2776                 mrr.rates[i].flags = 0;
2777                 mrr.rates[i].signal = wpi_ridx_to_signal[i];
2778                 /* fallback to the immediate lower OFDM rate (if any) */
2779                 mrr.rates[i].next = (i == WPI_OFDM6) ? WPI_OFDM6 : i - 1;
2780                 /* try one time at this rate before falling back to "next" */
2781                 mrr.rates[i].ntries = 1;
2782         }
2783 
2784         /* setup MRR for control frames */
2785         mrr.which = LE_32(WPI_MRR_CTL);
2786         err = wpi_cmd(sc, WPI_CMD_MRR_SETUP, &mrr, sizeof (mrr), 1);
2787         if (err != WPI_SUCCESS) {
2788                 WPI_DBG((WPI_DEBUG_MRR,
2789                     "could not setup MRR for control frames\n"));
2790                 return (err);
2791         }
2792 
2793         /* setup MRR for data frames */
2794         mrr.which = LE_32(WPI_MRR_DATA);
2795         err = wpi_cmd(sc, WPI_CMD_MRR_SETUP, &mrr, sizeof (mrr), 1);
2796         if (err != WPI_SUCCESS) {
2797                 WPI_DBG((WPI_DEBUG_MRR,
2798                     "could not setup MRR for data frames\n"));
2799                 return (err);
2800         }
2801 
2802         return (WPI_SUCCESS);
2803 }
2804 
2805 static void
2806 wpi_set_led(wpi_sc_t *sc, uint8_t which, uint8_t off, uint8_t on)
2807 {
2808         wpi_cmd_led_t led;
2809 
2810         led.which = which;
2811         led.unit = LE_32(100000);       /* on/off in unit of 100ms */
2812         led.off = off;
2813         led.on = on;
2814 
2815         (void) wpi_cmd(sc, WPI_CMD_SET_LED, &led, sizeof (led), 1);
2816 }
2817 
2818 static int
2819 wpi_auth(wpi_sc_t *sc)
2820 {
2821         ieee80211com_t *ic = &sc->sc_ic;
2822         ieee80211_node_t *in = ic->ic_bss;
2823         wpi_node_t node;
2824         int err;
2825 
2826         /* update adapter's configuration */
2827         IEEE80211_ADDR_COPY(sc->sc_config.bssid, in->in_bssid);
2828         sc->sc_config.chan = ieee80211_chan2ieee(ic, in->in_chan);
2829         if (ic->ic_curmode == IEEE80211_MODE_11B) {
2830                 sc->sc_config.cck_mask  = 0x03;
2831                 sc->sc_config.ofdm_mask = 0;
2832         } else if ((in->in_chan != IEEE80211_CHAN_ANYC) &&
2833             (IEEE80211_IS_CHAN_5GHZ(in->in_chan))) {
2834                 sc->sc_config.cck_mask  = 0;
2835                 sc->sc_config.ofdm_mask = 0x15;
2836         } else {        /* assume 802.11b/g */
2837                 sc->sc_config.cck_mask  = 0x0f;
2838                 sc->sc_config.ofdm_mask = 0xff;
2839         }
2840 
2841         WPI_DBG((WPI_DEBUG_80211, "config chan %d flags %x cck %x ofdm %x"
2842             " bssid:%02x:%02x:%02x:%02x:%02x:%2x\n",
2843             sc->sc_config.chan, sc->sc_config.flags,
2844             sc->sc_config.cck_mask, sc->sc_config.ofdm_mask,
2845             sc->sc_config.bssid[0], sc->sc_config.bssid[1],
2846             sc->sc_config.bssid[2], sc->sc_config.bssid[3],
2847             sc->sc_config.bssid[4], sc->sc_config.bssid[5]));
2848         err = wpi_cmd(sc, WPI_CMD_CONFIGURE, &sc->sc_config,
2849             sizeof (wpi_config_t), 1);
2850         if (err != WPI_SUCCESS) {
2851                 cmn_err(CE_WARN, "wpi_auth(): failed to configurate chan%d\n",
2852                     sc->sc_config.chan);
2853                 return (err);
2854         }
2855 
2856         /* add default node */
2857         (void) memset(&node, 0, sizeof (node));
2858         IEEE80211_ADDR_COPY(node.bssid, in->in_bssid);
2859         node.id = WPI_ID_BSS;
2860         node.rate = wpi_plcp_signal(2);
2861         err = wpi_cmd(sc, WPI_CMD_ADD_NODE, &node, sizeof (node), 1);
2862         if (err != WPI_SUCCESS) {
2863                 cmn_err(CE_WARN, "wpi_auth(): failed to add BSS node\n");
2864                 return (err);
2865         }
2866 
2867         err = wpi_mrr_setup(sc);
2868         if (err != WPI_SUCCESS) {
2869                 cmn_err(CE_WARN, "wpi_auth(): failed to setup MRR\n");
2870                 return (err);
2871         }
2872 
2873         return (WPI_SUCCESS);
2874 }
2875 
2876 /*
2877  * Send a scan request to the firmware.
2878  */
2879 static int
2880 wpi_scan(wpi_sc_t *sc)
2881 {
2882         ieee80211com_t *ic = &sc->sc_ic;
2883         wpi_tx_ring_t *ring = &sc->sc_cmdq;
2884         wpi_tx_desc_t *desc;
2885         wpi_tx_data_t *data;
2886         wpi_tx_cmd_t *cmd;
2887         wpi_scan_hdr_t *hdr;
2888         wpi_scan_chan_t *chan;
2889         struct ieee80211_frame *wh;
2890         ieee80211_node_t *in = ic->ic_bss;
2891         uint8_t essid[IEEE80211_NWID_LEN+1];
2892         struct ieee80211_rateset *rs;
2893         enum ieee80211_phymode mode;
2894         uint8_t *frm;
2895         int i, pktlen, nrates;
2896 
2897         /* previous scan not completed */
2898         if (sc->sc_scan_pending) {
2899                 WPI_DBG((WPI_DEBUG_SCAN, "previous scan not completed\n"));
2900                 return (WPI_SUCCESS);
2901         }
2902 
2903         data = &ring->data[ring->cur];
2904         desc = data->desc;
2905         cmd = (wpi_tx_cmd_t *)data->dma_data.mem_va;
2906 
2907         cmd->code = WPI_CMD_SCAN;
2908         cmd->flags = 0;
2909         cmd->qid = ring->qid;
2910         cmd->idx = ring->cur;
2911 
2912         hdr = (wpi_scan_hdr_t *)cmd->data;
2913         (void) memset(hdr, 0, sizeof (wpi_scan_hdr_t));
2914         hdr->first = 1;
2915         hdr->nchan = 1;
2916         hdr->len = hdr->nchan * sizeof (wpi_scan_chan_t);
2917         hdr->quiet = LE_16(50);
2918         hdr->threshold = LE_16(1);
2919         hdr->filter = LE_32(5);
2920         hdr->rate = wpi_plcp_signal(2);
2921         hdr->id = WPI_ID_BROADCAST;
2922         hdr->mask = LE_32(0xffffffff);
2923         hdr->esslen = ic->ic_des_esslen;
2924 
2925         if (ic->ic_des_esslen) {
2926                 bcopy(ic->ic_des_essid, essid, ic->ic_des_esslen);
2927                 essid[ic->ic_des_esslen] = '\0';
2928                 WPI_DBG((WPI_DEBUG_SCAN, "directed scan %s\n", essid));
2929 
2930                 bcopy(ic->ic_des_essid, hdr->essid, ic->ic_des_esslen);
2931         } else {
2932                 bzero(hdr->essid, sizeof (hdr->essid));
2933         }
2934 
2935         /*
2936          * Build a probe request frame.  Most of the following code is a
2937          * copy & paste of what is done in net80211.  Unfortunately, the
2938          * functions to add IEs are static and thus can't be reused here.
2939          */
2940         wh = (struct ieee80211_frame *)(hdr + 1);
2941         wh->i_fc[0] = IEEE80211_FC0_VERSION_0 | IEEE80211_FC0_TYPE_MGT |
2942             IEEE80211_FC0_SUBTYPE_PROBE_REQ;
2943         wh->i_fc[1] = IEEE80211_FC1_DIR_NODS;
2944         (void) memset(wh->i_addr1, 0xff, 6);
2945         IEEE80211_ADDR_COPY(wh->i_addr2, ic->ic_macaddr);
2946         (void) memset(wh->i_addr3, 0xff, 6);
2947         *(uint16_t *)&wh->i_dur[0] = 0;  /* filled by h/w */
2948         *(uint16_t *)&wh->i_seq[0] = 0;  /* filled by h/w */
2949 
2950         frm = (uint8_t *)(wh + 1);
2951 
2952         /* add essid IE */
2953         if (in->in_esslen) {
2954                 bcopy(in->in_essid, essid, in->in_esslen);
2955                 essid[in->in_esslen] = '\0';
2956                 WPI_DBG((WPI_DEBUG_SCAN, "probe with ESSID %s\n",
2957                     essid));
2958         }
2959         *frm++ = IEEE80211_ELEMID_SSID;
2960         *frm++ = in->in_esslen;
2961         (void) memcpy(frm, in->in_essid, in->in_esslen);
2962         frm += in->in_esslen;
2963 
2964         mode = ieee80211_chan2mode(ic, ic->ic_curchan);
2965         rs = &ic->ic_sup_rates[mode];
2966 
2967         /* add supported rates IE */
2968         *frm++ = IEEE80211_ELEMID_RATES;
2969         nrates = rs->ir_nrates;
2970         if (nrates > IEEE80211_RATE_SIZE)
2971                 nrates = IEEE80211_RATE_SIZE;
2972         *frm++ = (uint8_t)nrates;
2973         (void) memcpy(frm, rs->ir_rates, nrates);
2974         frm += nrates;
2975 
2976         /* add supported xrates IE */
2977         if (rs->ir_nrates > IEEE80211_RATE_SIZE) {
2978                 nrates = rs->ir_nrates - IEEE80211_RATE_SIZE;
2979                 *frm++ = IEEE80211_ELEMID_XRATES;
2980                 *frm++ = (uint8_t)nrates;
2981                 (void) memcpy(frm, rs->ir_rates + IEEE80211_RATE_SIZE, nrates);
2982                 frm += nrates;
2983         }
2984 
2985         /* add optionnal IE (usually an RSN IE) */
2986         if (ic->ic_opt_ie != NULL) {
2987                 (void) memcpy(frm, ic->ic_opt_ie, ic->ic_opt_ie_len);
2988                 frm += ic->ic_opt_ie_len;
2989         }
2990 
2991         /* setup length of probe request */
2992         hdr->pbrlen = LE_16((uintptr_t)frm - (uintptr_t)wh);
2993 
2994         /* align on a 4-byte boundary */
2995         chan = (wpi_scan_chan_t *)frm;
2996         for (i = 1; i <= hdr->nchan; i++, chan++) {
2997                 if (ic->ic_des_esslen) {
2998                         chan->flags = 0x3;
2999                 } else {
3000                         chan->flags = 0x1;
3001                 }
3002                 chan->chan = ieee80211_chan2ieee(ic, ic->ic_curchan);
3003                 chan->magic = LE_16(0x62ab);
3004                 chan->active = LE_16(50);
3005                 chan->passive = LE_16(120);
3006 
3007                 frm += sizeof (wpi_scan_chan_t);
3008         }
3009 
3010         pktlen = (uintptr_t)frm - (uintptr_t)cmd;
3011 
3012         desc->flags = LE_32(WPI_PAD32(pktlen) << 28 | 1 << 24);
3013         desc->segs[0].addr = LE_32(data->dma_data.cookie.dmac_address);
3014         desc->segs[0].len  = LE_32(pktlen);
3015 
3016         WPI_DMA_SYNC(data->dma_data, DDI_DMA_SYNC_FORDEV);
3017         WPI_DMA_SYNC(ring->dma_desc, DDI_DMA_SYNC_FORDEV);
3018 
3019         /* kick cmd ring */
3020         ring->cur = (ring->cur + 1) % WPI_CMD_RING_COUNT;
3021         WPI_WRITE(sc, WPI_TX_WIDX, ring->qid << 8 | ring->cur);
3022 
3023         sc->sc_scan_pending = 1;
3024 
3025         return (WPI_SUCCESS);   /* will be notified async. of failure/success */
3026 }
3027 
3028 static int
3029 wpi_config(wpi_sc_t *sc)
3030 {
3031         ieee80211com_t *ic = &sc->sc_ic;
3032         wpi_txpower_t txpower;
3033         wpi_power_t power;
3034 #ifdef WPI_BLUE_COEXISTENCE
3035         wpi_bluetooth_t bluetooth;
3036 #endif
3037         wpi_node_t node;
3038         int err;
3039 
3040         /* Intel's binary only daemon is a joke.. */
3041 
3042         /* set Tx power for 2.4GHz channels (values read from EEPROM) */
3043         (void) memset(&txpower, 0, sizeof (txpower));
3044         (void) memcpy(txpower.pwr1, sc->sc_pwr1, 14 * sizeof (uint16_t));
3045         (void) memcpy(txpower.pwr2, sc->sc_pwr2, 14 * sizeof (uint16_t));
3046         err = wpi_cmd(sc, WPI_CMD_TXPOWER, &txpower, sizeof (txpower), 0);
3047         if (err != WPI_SUCCESS) {
3048                 cmn_err(CE_WARN, "wpi_config(): failed to set txpower\n");
3049                 return (err);
3050         }
3051 
3052         /* set power mode */
3053         (void) memset(&power, 0, sizeof (power));
3054         power.flags = LE_32(0x8);
3055         err = wpi_cmd(sc, WPI_CMD_SET_POWER_MODE, &power, sizeof (power), 0);
3056         if (err != WPI_SUCCESS) {
3057                 cmn_err(CE_WARN, "wpi_config(): failed to set power mode\n");
3058                 return (err);
3059         }
3060 #ifdef WPI_BLUE_COEXISTENCE
3061         /* configure bluetooth coexistence */
3062         (void) memset(&bluetooth, 0, sizeof (bluetooth));
3063         bluetooth.flags = 3;
3064         bluetooth.lead = 0xaa;
3065         bluetooth.kill = 1;
3066         err = wpi_cmd(sc, WPI_CMD_BLUETOOTH, &bluetooth,
3067             sizeof (bluetooth), 0);
3068         if (err != WPI_SUCCESS) {
3069                 cmn_err(CE_WARN,
3070                     "wpi_config(): "
3071                     "failed to configurate bluetooth coexistence\n");
3072                 return (err);
3073         }
3074 #endif
3075         /* configure adapter */
3076         (void) memset(&sc->sc_config, 0, sizeof (wpi_config_t));
3077         IEEE80211_ADDR_COPY(sc->sc_config.myaddr, ic->ic_macaddr);
3078         sc->sc_config.chan = ieee80211_chan2ieee(ic, ic->ic_curchan);
3079         sc->sc_config.flags = LE_32(WPI_CONFIG_TSF | WPI_CONFIG_AUTO |
3080             WPI_CONFIG_24GHZ);
3081         sc->sc_config.filter = 0;
3082         switch (ic->ic_opmode) {
3083         case IEEE80211_M_STA:
3084                 sc->sc_config.mode = WPI_MODE_STA;
3085                 sc->sc_config.filter |= LE_32(WPI_FILTER_MULTICAST);
3086                 break;
3087         case IEEE80211_M_IBSS:
3088         case IEEE80211_M_AHDEMO:
3089                 sc->sc_config.mode = WPI_MODE_IBSS;
3090                 break;
3091         case IEEE80211_M_HOSTAP:
3092                 sc->sc_config.mode = WPI_MODE_HOSTAP;
3093                 break;
3094         case IEEE80211_M_MONITOR:
3095                 sc->sc_config.mode = WPI_MODE_MONITOR;
3096                 sc->sc_config.filter |= LE_32(WPI_FILTER_MULTICAST |
3097                     WPI_FILTER_CTL | WPI_FILTER_PROMISC);
3098                 break;
3099         }
3100         sc->sc_config.cck_mask  = 0x0f;      /* not yet negotiated */
3101         sc->sc_config.ofdm_mask = 0xff;      /* not yet negotiated */
3102         err = wpi_cmd(sc, WPI_CMD_CONFIGURE, &sc->sc_config,
3103             sizeof (wpi_config_t), 0);
3104         if (err != WPI_SUCCESS) {
3105                 cmn_err(CE_WARN, "wpi_config(): "
3106                     "failed to set configure command\n");
3107                 return (err);
3108         }
3109 
3110         /* add broadcast node */
3111         (void) memset(&node, 0, sizeof (node));
3112         (void) memset(node.bssid, 0xff, 6);
3113         node.id = WPI_ID_BROADCAST;
3114         node.rate = wpi_plcp_signal(2);
3115         err = wpi_cmd(sc, WPI_CMD_ADD_NODE, &node, sizeof (node), 0);
3116         if (err != WPI_SUCCESS) {
3117                 cmn_err(CE_WARN, "wpi_config(): "
3118                     "failed to add broadcast node\n");
3119                 return (err);
3120         }
3121 
3122         return (WPI_SUCCESS);
3123 }
3124 
3125 static void
3126 wpi_stop_master(wpi_sc_t *sc)
3127 {
3128         uint32_t tmp;
3129         int ntries;
3130 
3131         tmp = WPI_READ(sc, WPI_RESET);
3132         WPI_WRITE(sc, WPI_RESET, tmp | WPI_STOP_MASTER);
3133 
3134         tmp = WPI_READ(sc, WPI_GPIO_CTL);
3135         if ((tmp & WPI_GPIO_PWR_STATUS) == WPI_GPIO_PWR_SLEEP)
3136                 return; /* already asleep */
3137 
3138         for (ntries = 0; ntries < 2000; ntries++) {
3139                 if (WPI_READ(sc, WPI_RESET) & WPI_MASTER_DISABLED)
3140                         break;
3141                 DELAY(1000);
3142         }
3143         if (ntries == 2000)
3144                 WPI_DBG((WPI_DEBUG_HW, "timeout waiting for master\n"));
3145 }
3146 
3147 static int
3148 wpi_power_up(wpi_sc_t *sc)
3149 {
3150         uint32_t tmp;
3151         int ntries;
3152 
3153         wpi_mem_lock(sc);
3154         tmp = wpi_mem_read(sc, WPI_MEM_POWER);
3155         wpi_mem_write(sc, WPI_MEM_POWER, tmp & ~0x03000000);
3156         wpi_mem_unlock(sc);
3157 
3158         for (ntries = 0; ntries < 5000; ntries++) {
3159                 if (WPI_READ(sc, WPI_GPIO_STATUS) & WPI_POWERED)
3160                         break;
3161                 DELAY(10);
3162         }
3163         if (ntries == 5000) {
3164                 cmn_err(CE_WARN,
3165                     "wpi_power_up(): timeout waiting for NIC to power up\n");
3166                 return (ETIMEDOUT);
3167         }
3168         return (WPI_SUCCESS);
3169 }
3170 
3171 static int
3172 wpi_reset(wpi_sc_t *sc)
3173 {
3174         uint32_t tmp;
3175         int ntries;
3176 
3177         /* clear any pending interrupts */
3178         WPI_WRITE(sc, WPI_INTR, 0xffffffff);
3179 
3180         tmp = WPI_READ(sc, WPI_PLL_CTL);
3181         WPI_WRITE(sc, WPI_PLL_CTL, tmp | WPI_PLL_INIT);
3182 
3183         tmp = WPI_READ(sc, WPI_CHICKEN);
3184         WPI_WRITE(sc, WPI_CHICKEN, tmp | WPI_CHICKEN_RXNOLOS);
3185 
3186         tmp = WPI_READ(sc, WPI_GPIO_CTL);
3187         WPI_WRITE(sc, WPI_GPIO_CTL, tmp | WPI_GPIO_INIT);
3188 
3189         /* wait for clock stabilization */
3190         for (ntries = 0; ntries < 1000; ntries++) {
3191                 if (WPI_READ(sc, WPI_GPIO_CTL) & WPI_GPIO_CLOCK)
3192                         break;
3193                 DELAY(10);
3194         }
3195         if (ntries == 1000) {
3196                 cmn_err(CE_WARN,
3197                     "wpi_reset(): timeout waiting for clock stabilization\n");
3198                 return (ETIMEDOUT);
3199         }
3200 
3201         /* initialize EEPROM */
3202         tmp = WPI_READ(sc, WPI_EEPROM_STATUS);
3203         if ((tmp & WPI_EEPROM_VERSION) == 0) {
3204                 cmn_err(CE_WARN, "wpi_reset(): EEPROM not found\n");
3205                 return (EIO);
3206         }
3207         WPI_WRITE(sc, WPI_EEPROM_STATUS, tmp & ~WPI_EEPROM_LOCKED);
3208 
3209         return (WPI_SUCCESS);
3210 }
3211 
3212 static void
3213 wpi_hw_config(wpi_sc_t *sc)
3214 {
3215         uint16_t val;
3216         uint32_t hw;
3217 
3218         /* voodoo from the Linux "driver".. */
3219         hw = WPI_READ(sc, WPI_HWCONFIG);
3220 
3221         if ((sc->sc_rev & 0xc0) == 0x40)
3222                 hw |= WPI_HW_ALM_MB;
3223         else if (!(sc->sc_rev & 0x80))
3224                 hw |= WPI_HW_ALM_MM;
3225 
3226         val = wpi_read_prom_word(sc, WPI_EEPROM_CAPABILITIES);
3227         if ((val & 0xff) == 0x80)
3228                 hw |= WPI_HW_SKU_MRC;
3229 
3230         val = wpi_read_prom_word(sc, WPI_EEPROM_REVISION);
3231         hw &= ~WPI_HW_REV_D;
3232         if ((val & 0xf0) == 0xd0)
3233                 hw |= WPI_HW_REV_D;
3234 
3235         val = wpi_read_prom_word(sc, WPI_EEPROM_TYPE);
3236         if ((val & 0xff) > 1)
3237                 hw |= WPI_HW_TYPE_B;
3238 
3239         WPI_DBG((WPI_DEBUG_HW, "setting h/w config %x\n", hw));
3240         WPI_WRITE(sc, WPI_HWCONFIG, hw);
3241 }
3242 
3243 static int
3244 wpi_init(wpi_sc_t *sc)
3245 {
3246         uint32_t tmp;
3247         int qid, ntries, err;
3248         clock_t clk;
3249 
3250         mutex_enter(&sc->sc_glock);
3251         sc->sc_flags &= ~WPI_F_FW_INIT;
3252 
3253         (void) wpi_reset(sc);
3254 
3255         wpi_mem_lock(sc);
3256         wpi_mem_write(sc, WPI_MEM_CLOCK1, 0xa00);
3257         DELAY(20);
3258         tmp = wpi_mem_read(sc, WPI_MEM_PCIDEV);
3259         wpi_mem_write(sc, WPI_MEM_PCIDEV, tmp | 0x800);
3260         wpi_mem_unlock(sc);
3261 
3262         (void) wpi_power_up(sc);
3263         wpi_hw_config(sc);
3264 
3265         tmp = WPI_READ(sc, WPI_GPIO_CTL);
3266         if (!(tmp & WPI_GPIO_HW_RF_KILL)) {
3267                 cmn_err(CE_WARN, "wpi_init(): Radio transmitter is off\n");
3268                 goto fail1;
3269         }
3270 
3271         /* init Rx ring */
3272         wpi_mem_lock(sc);
3273         WPI_WRITE(sc, WPI_RX_BASE, sc->sc_rxq.dma_desc.cookie.dmac_address);
3274         WPI_WRITE(sc, WPI_RX_RIDX_PTR,
3275             (uint32_t)(sc->sc_dma_sh.cookie.dmac_address +
3276             offsetof(wpi_shared_t, next)));
3277         WPI_WRITE(sc, WPI_RX_WIDX, (WPI_RX_RING_COUNT - 1) & (~7));
3278         WPI_WRITE(sc, WPI_RX_CONFIG, 0xa9601010);
3279         wpi_mem_unlock(sc);
3280 
3281         /* init Tx rings */
3282         wpi_mem_lock(sc);
3283         wpi_mem_write(sc, WPI_MEM_MODE, 2);     /* bypass mode */
3284         wpi_mem_write(sc, WPI_MEM_RA, 1);       /* enable RA0 */
3285         wpi_mem_write(sc, WPI_MEM_TXCFG, 0x3f); /* enable all 6 Tx rings */
3286         wpi_mem_write(sc, WPI_MEM_BYPASS1, 0x10000);
3287         wpi_mem_write(sc, WPI_MEM_BYPASS2, 0x30002);
3288         wpi_mem_write(sc, WPI_MEM_MAGIC4, 4);
3289         wpi_mem_write(sc, WPI_MEM_MAGIC5, 5);
3290 
3291         WPI_WRITE(sc, WPI_TX_BASE_PTR, sc->sc_dma_sh.cookie.dmac_address);
3292         WPI_WRITE(sc, WPI_MSG_CONFIG, 0xffff05a5);
3293 
3294         for (qid = 0; qid < 6; qid++) {
3295                 WPI_WRITE(sc, WPI_TX_CTL(qid), 0);
3296                 WPI_WRITE(sc, WPI_TX_BASE(qid), 0);
3297                 WPI_WRITE(sc, WPI_TX_CONFIG(qid), 0x80200008);
3298         }
3299         wpi_mem_unlock(sc);
3300 
3301         /* clear "radio off" and "disable command" bits (reversed logic) */
3302         WPI_WRITE(sc, WPI_UCODE_CLR, WPI_RADIO_OFF);
3303         WPI_WRITE(sc, WPI_UCODE_CLR, WPI_DISABLE_CMD);
3304 
3305         /* clear any pending interrupts */
3306         WPI_WRITE(sc, WPI_INTR, 0xffffffff);
3307 
3308         /* enable interrupts */
3309         WPI_WRITE(sc, WPI_MASK, WPI_INTR_MASK);
3310 
3311         /* load firmware boot code into NIC */
3312         err = wpi_load_microcode(sc);
3313         if (err != WPI_SUCCESS) {
3314                 cmn_err(CE_WARN, "wpi_init(): failed to load microcode\n");
3315                 goto fail1;
3316         }
3317 
3318         /* load firmware .text segment into NIC */
3319         err = wpi_load_firmware(sc, WPI_FW_TEXT);
3320         if (err != WPI_SUCCESS) {
3321                 cmn_err(CE_WARN, "wpi_init(): "
3322                     "failed to load firmware(text)\n");
3323                 goto fail1;
3324         }
3325 
3326         /* load firmware .data segment into NIC */
3327         err = wpi_load_firmware(sc, WPI_FW_DATA);
3328         if (err != WPI_SUCCESS) {
3329                 cmn_err(CE_WARN, "wpi_init(): "
3330                     "failed to load firmware(data)\n");
3331                 goto fail1;
3332         }
3333 
3334         /* now press "execute" ;-) */
3335         tmp = WPI_READ(sc, WPI_RESET);
3336         tmp &= ~(WPI_MASTER_DISABLED | WPI_STOP_MASTER | WPI_NEVO_RESET);
3337         WPI_WRITE(sc, WPI_RESET, tmp);
3338 
3339         /* ..and wait at most one second for adapter to initialize */
3340         clk = ddi_get_lbolt() + drv_usectohz(2000000);
3341         while (!(sc->sc_flags & WPI_F_FW_INIT)) {
3342                 if (cv_timedwait(&sc->sc_fw_cv, &sc->sc_glock, clk) < 0)
3343                         break;
3344         }
3345         if (!(sc->sc_flags & WPI_F_FW_INIT)) {
3346                 cmn_err(CE_WARN,
3347                     "wpi_init(): timeout waiting for firmware init\n");
3348                 goto fail1;
3349         }
3350 
3351         /* wait for thermal sensors to calibrate */
3352         for (ntries = 0; ntries < 1000; ntries++) {
3353                 if (WPI_READ(sc, WPI_TEMPERATURE) != 0)
3354                         break;
3355                 DELAY(10);
3356         }
3357 
3358         if (ntries == 1000) {
3359                 WPI_DBG((WPI_DEBUG_HW,
3360                     "wpi_init(): timeout waiting for thermal sensors "
3361                     "calibration\n"));
3362         }
3363 
3364         WPI_DBG((WPI_DEBUG_HW, "temperature %d\n",
3365             (int)WPI_READ(sc, WPI_TEMPERATURE)));
3366 
3367         err = wpi_config(sc);
3368         if (err) {
3369                 cmn_err(CE_WARN, "wpi_init(): failed to configure device\n");
3370                 goto fail1;
3371         }
3372 
3373         mutex_exit(&sc->sc_glock);
3374         return (WPI_SUCCESS);
3375 
3376 fail1:
3377         err = WPI_FAIL;
3378         mutex_exit(&sc->sc_glock);
3379         return (err);
3380 }
3381 
3382 static int
3383 wpi_fast_recover(wpi_sc_t *sc)
3384 {
3385         ieee80211com_t *ic = &sc->sc_ic;
3386         int err;
3387 
3388         mutex_enter(&sc->sc_glock);
3389 
3390         /* restore runtime configuration */
3391         bcopy(&sc->sc_config_save, &sc->sc_config,
3392             sizeof (sc->sc_config));
3393 
3394         sc->sc_config.state = 0;
3395         sc->sc_config.filter &= ~LE_32(WPI_FILTER_BSS);
3396 
3397         if ((err = wpi_auth(sc)) != 0) {
3398                 cmn_err(CE_WARN, "wpi_fast_recover(): "
3399                     "failed to setup authentication\n");
3400                 mutex_exit(&sc->sc_glock);
3401                 return (err);
3402         }
3403 
3404         sc->sc_config.state = LE_16(WPI_CONFIG_ASSOCIATED);
3405         sc->sc_config.flags &= ~LE_32(WPI_CONFIG_SHPREAMBLE |
3406             WPI_CONFIG_SHSLOT);
3407         if (ic->ic_flags & IEEE80211_F_SHSLOT)
3408                 sc->sc_config.flags |= LE_32(WPI_CONFIG_SHSLOT);
3409         if (ic->ic_flags & IEEE80211_F_SHPREAMBLE)
3410                 sc->sc_config.flags |= LE_32(WPI_CONFIG_SHPREAMBLE);
3411         sc->sc_config.filter |= LE_32(WPI_FILTER_BSS);
3412         if (ic->ic_opmode != IEEE80211_M_STA)
3413                 sc->sc_config.filter |= LE_32(WPI_FILTER_BEACON);
3414 
3415         WPI_DBG((WPI_DEBUG_80211, "config chan %d flags %x\n",
3416             sc->sc_config.chan, sc->sc_config.flags));
3417         err = wpi_cmd(sc, WPI_CMD_CONFIGURE, &sc->sc_config,
3418             sizeof (wpi_config_t), 1);
3419         if (err != WPI_SUCCESS) {
3420                 cmn_err(CE_WARN, "failed to setup association\n");
3421                 mutex_exit(&sc->sc_glock);
3422                 return (err);
3423         }
3424         /* link LED on */
3425         wpi_set_led(sc, WPI_LED_LINK, 0, 1);
3426 
3427         mutex_exit(&sc->sc_glock);
3428 
3429         /* update keys */
3430         if (ic->ic_flags & IEEE80211_F_PRIVACY) {
3431                 for (int i = 0; i < IEEE80211_KEY_MAX; i++) {
3432                         if (ic->ic_nw_keys[i].wk_keyix == IEEE80211_KEYIX_NONE)
3433                                 continue;
3434                         err = wpi_key_set(ic, &ic->ic_nw_keys[i],
3435                             ic->ic_bss->in_macaddr);
3436                         /* failure */
3437                         if (err == 0) {
3438                                 cmn_err(CE_WARN, "wpi_fast_recover(): "
3439                                     "failed to setup hardware keys\n");
3440                                 return (WPI_FAIL);
3441                         }
3442                 }
3443         }
3444 
3445         sc->sc_flags &= ~WPI_F_HW_ERR_RECOVER;
3446 
3447         /* start queue */
3448         WPI_DBG((WPI_DEBUG_FW, "wpi_fast_recover(): resume xmit\n"));
3449         mac_tx_update(ic->ic_mach);
3450 
3451         return (WPI_SUCCESS);
3452 }
3453 
3454 /*
3455  * quiesce(9E) entry point.
3456  * This function is called when the system is single-threaded at high
3457  * PIL with preemption disabled. Therefore, this function must not be
3458  * blocked.
3459  * This function returns DDI_SUCCESS on success, or DDI_FAILURE on failure.
3460  * DDI_FAILURE indicates an error condition and should almost never happen.
3461  */
3462 static int
3463 wpi_quiesce(dev_info_t *dip)
3464 {
3465         wpi_sc_t *sc;
3466 
3467         sc = ddi_get_soft_state(wpi_soft_state_p, ddi_get_instance(dip));
3468         if (sc == NULL)
3469                 return (DDI_FAILURE);
3470 
3471 #ifdef DEBUG
3472         /* by pass any messages, if it's quiesce */
3473         wpi_dbg_flags = 0;
3474 #endif
3475 
3476         /*
3477          * No more blocking is allowed while we are in the
3478          * quiesce(9E) entry point.
3479          */
3480         sc->sc_flags |= WPI_F_QUIESCED;
3481 
3482         /*
3483          * Disable and mask all interrupts.
3484          */
3485         wpi_stop(sc);
3486         return (DDI_SUCCESS);
3487 }
3488 
3489 static void
3490 wpi_stop(wpi_sc_t *sc)
3491 {
3492         uint32_t tmp;
3493         int ac;
3494 
3495         /* no mutex operation, if it's quiesced */
3496         if (!(sc->sc_flags & WPI_F_QUIESCED))
3497                 mutex_enter(&sc->sc_glock);
3498 
3499         /* disable interrupts */
3500         WPI_WRITE(sc, WPI_MASK, 0);
3501         WPI_WRITE(sc, WPI_INTR, WPI_INTR_MASK);
3502         WPI_WRITE(sc, WPI_INTR_STATUS, 0xff);
3503         WPI_WRITE(sc, WPI_INTR_STATUS, 0x00070000);
3504 
3505         wpi_mem_lock(sc);
3506         wpi_mem_write(sc, WPI_MEM_MODE, 0);
3507         wpi_mem_unlock(sc);
3508 
3509         /* reset all Tx rings */
3510         for (ac = 0; ac < 4; ac++)
3511                 wpi_reset_tx_ring(sc, &sc->sc_txq[ac]);
3512         wpi_reset_tx_ring(sc, &sc->sc_cmdq);
3513         wpi_reset_tx_ring(sc, &sc->sc_svcq);
3514 
3515         /* reset Rx ring */
3516         wpi_reset_rx_ring(sc);
3517 
3518         wpi_mem_lock(sc);
3519         wpi_mem_write(sc, WPI_MEM_CLOCK2, 0x200);
3520         wpi_mem_unlock(sc);
3521 
3522         DELAY(5);
3523 
3524         wpi_stop_master(sc);
3525 
3526         sc->sc_tx_timer = 0;
3527         sc->sc_flags &= ~WPI_F_SCANNING;
3528         sc->sc_scan_pending = 0;
3529         sc->sc_scan_next = 0;
3530 
3531         tmp = WPI_READ(sc, WPI_RESET);
3532         WPI_WRITE(sc, WPI_RESET, tmp | WPI_SW_RESET);
3533 
3534         /* no mutex operation, if it's quiesced */
3535         if (!(sc->sc_flags & WPI_F_QUIESCED))
3536                 mutex_exit(&sc->sc_glock);
3537 }
3538 
3539 /*
3540  * Naive implementation of the Adaptive Multi Rate Retry algorithm:
3541  * "IEEE 802.11 Rate Adaptation: A Practical Approach"
3542  * Mathieu Lacage, Hossein Manshaei, Thierry Turletti
3543  * INRIA Sophia - Projet Planete
3544  * http://www-sop.inria.fr/rapports/sophia/RR-5208.html
3545  */
3546 #define is_success(amrr)        \
3547         ((amrr)->retrycnt < (amrr)->txcnt / 10)
3548 #define is_failure(amrr)        \
3549         ((amrr)->retrycnt > (amrr)->txcnt / 3)
3550 #define is_enough(amrr)         \
3551         ((amrr)->txcnt > 100)
3552 #define is_min_rate(in)         \
3553         ((in)->in_txrate == 0)
3554 #define is_max_rate(in)         \
3555         ((in)->in_txrate == (in)->in_rates.ir_nrates - 1)
3556 #define increase_rate(in)       \
3557         ((in)->in_txrate++)
3558 #define decrease_rate(in)       \
3559         ((in)->in_txrate--)
3560 #define reset_cnt(amrr)         \
3561         { (amrr)->txcnt = (amrr)->retrycnt = 0; }
3562 
3563 #define WPI_AMRR_MIN_SUCCESS_THRESHOLD   1
3564 #define WPI_AMRR_MAX_SUCCESS_THRESHOLD  15
3565 
3566 static void
3567 wpi_amrr_init(wpi_amrr_t *amrr)
3568 {
3569         amrr->success = 0;
3570         amrr->recovery = 0;
3571         amrr->txcnt = amrr->retrycnt = 0;
3572         amrr->success_threshold = WPI_AMRR_MIN_SUCCESS_THRESHOLD;
3573 }
3574 
3575 static void
3576 wpi_amrr_timeout(wpi_sc_t *sc)
3577 {
3578         ieee80211com_t *ic = &sc->sc_ic;
3579 
3580         WPI_DBG((WPI_DEBUG_RATECTL, "wpi_amrr_timeout() enter\n"));
3581         if (ic->ic_opmode == IEEE80211_M_STA)
3582                 wpi_amrr_ratectl(NULL, ic->ic_bss);
3583         else
3584                 ieee80211_iterate_nodes(&ic->ic_sta, wpi_amrr_ratectl, NULL);
3585         sc->sc_clk = ddi_get_lbolt();
3586 }
3587 
3588 /* ARGSUSED */
3589 static void
3590 wpi_amrr_ratectl(void *arg, ieee80211_node_t *in)
3591 {
3592         wpi_amrr_t *amrr = (wpi_amrr_t *)in;
3593         int need_change = 0;
3594 
3595         if (is_success(amrr) && is_enough(amrr)) {
3596                 amrr->success++;
3597                 if (amrr->success >= amrr->success_threshold &&
3598                     !is_max_rate(in)) {
3599                         amrr->recovery = 1;
3600                         amrr->success = 0;
3601                         increase_rate(in);
3602                         WPI_DBG((WPI_DEBUG_RATECTL,
3603                             "AMRR increasing rate %d (txcnt=%d retrycnt=%d)\n",
3604                             in->in_txrate, amrr->txcnt, amrr->retrycnt));
3605                         need_change = 1;
3606                 } else {
3607                         amrr->recovery = 0;
3608                 }
3609         } else if (is_failure(amrr)) {
3610                 amrr->success = 0;
3611                 if (!is_min_rate(in)) {
3612                         if (amrr->recovery) {
3613                                 amrr->success_threshold++;
3614                                 if (amrr->success_threshold >
3615                                     WPI_AMRR_MAX_SUCCESS_THRESHOLD)
3616                                         amrr->success_threshold =
3617                                             WPI_AMRR_MAX_SUCCESS_THRESHOLD;
3618                         } else {
3619                                 amrr->success_threshold =
3620                                     WPI_AMRR_MIN_SUCCESS_THRESHOLD;
3621                         }
3622                         decrease_rate(in);
3623                         WPI_DBG((WPI_DEBUG_RATECTL,
3624                             "AMRR decreasing rate %d (txcnt=%d retrycnt=%d)\n",
3625                             in->in_txrate, amrr->txcnt, amrr->retrycnt));
3626                         need_change = 1;
3627                 }
3628                 amrr->recovery = 0;  /* paper is incorrect */
3629         }
3630 
3631         if (is_enough(amrr) || need_change)
3632                 reset_cnt(amrr);
3633 }