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