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