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