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