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