1 /* 2 * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 3 * Use is subject to license terms. 4 */ 5 6 /* 7 * Copyright (c) 2009, Intel Corporation 8 * All rights reserved. 9 */ 10 11 /* 12 * Copyright (c) 2006 13 * Copyright (c) 2007 14 * Damien Bergamini <damien.bergamini@free.fr> 15 * 16 * Permission to use, copy, modify, and distribute this software for any 17 * purpose with or without fee is hereby granted, provided that the above 18 * copyright notice and this permission notice appear in all copies. 19 * 20 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 21 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 22 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 23 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 24 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 25 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 26 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 27 */ 28 29 /* 30 * Intel(R) WiFi Link 6000 Driver 31 */ 32 33 #include <sys/types.h> 34 #include <sys/byteorder.h> 35 #include <sys/conf.h> 36 #include <sys/cmn_err.h> 37 #include <sys/stat.h> 38 #include <sys/ddi.h> 39 #include <sys/sunddi.h> 40 #include <sys/strsubr.h> 41 #include <sys/ethernet.h> 42 #include <inet/common.h> 43 #include <inet/nd.h> 44 #include <inet/mi.h> 45 #include <sys/note.h> 46 #include <sys/stream.h> 47 #include <sys/strsun.h> 48 #include <sys/modctl.h> 49 #include <sys/devops.h> 50 #include <sys/dlpi.h> 51 #include <sys/mac_provider.h> 52 #include <sys/mac_wifi.h> 53 #include <sys/net80211.h> 54 #include <sys/net80211_proto.h> 55 #include <sys/varargs.h> 56 #include <sys/policy.h> 57 #include <sys/pci.h> 58 59 #include "iwp_calibration.h" 60 #include "iwp_hw.h" 61 #include "iwp_eeprom.h" 62 #include "iwp_var.h" 63 #include <inet/wifi_ioctl.h> 64 65 #ifdef DEBUG 66 #define IWP_DEBUG_80211 (1 << 0) 67 #define IWP_DEBUG_CMD (1 << 1) 68 #define IWP_DEBUG_DMA (1 << 2) 69 #define IWP_DEBUG_EEPROM (1 << 3) 70 #define IWP_DEBUG_FW (1 << 4) 71 #define IWP_DEBUG_HW (1 << 5) 72 #define IWP_DEBUG_INTR (1 << 6) 73 #define IWP_DEBUG_MRR (1 << 7) 74 #define IWP_DEBUG_PIO (1 << 8) 75 #define IWP_DEBUG_RX (1 << 9) 76 #define IWP_DEBUG_SCAN (1 << 10) 77 #define IWP_DEBUG_TX (1 << 11) 78 #define IWP_DEBUG_RATECTL (1 << 12) 79 #define IWP_DEBUG_RADIO (1 << 13) 80 #define IWP_DEBUG_RESUME (1 << 14) 81 #define IWP_DEBUG_CALIBRATION (1 << 15) 82 /* 83 * if want to see debug message of a given section, 84 * please set this flag to one of above values 85 */ 86 uint32_t iwp_dbg_flags = 0; 87 #define IWP_DBG(x) \ 88 iwp_dbg x 89 #else 90 #define IWP_DBG(x) 91 #endif 92 93 static void *iwp_soft_state_p = NULL; 94 95 /* 96 * ucode will be compiled into driver image 97 */ 98 static uint8_t iwp_fw_bin [] = { 99 #include "fw-iw/iwp.ucode" 100 }; 101 102 /* 103 * DMA attributes for a shared page 104 */ 105 static ddi_dma_attr_t sh_dma_attr = { 106 DMA_ATTR_V0, /* version of this structure */ 107 0, /* lowest usable address */ 108 0xffffffffU, /* highest usable address */ 109 0xffffffffU, /* maximum DMAable byte count */ 110 0x1000, /* alignment in bytes */ 111 0x1000, /* burst sizes (any?) */ 112 1, /* minimum transfer */ 113 0xffffffffU, /* maximum transfer */ 114 0xffffffffU, /* maximum segment length */ 115 1, /* maximum number of segments */ 116 1, /* granularity */ 117 0, /* flags (reserved) */ 118 }; 119 120 /* 121 * DMA attributes for a keep warm DRAM descriptor 122 */ 123 static ddi_dma_attr_t kw_dma_attr = { 124 DMA_ATTR_V0, /* version of this structure */ 125 0, /* lowest usable address */ 126 0xffffffffU, /* highest usable address */ 127 0xffffffffU, /* maximum DMAable byte count */ 128 0x1000, /* alignment in bytes */ 129 0x1000, /* burst sizes (any?) */ 130 1, /* minimum transfer */ 131 0xffffffffU, /* maximum transfer */ 132 0xffffffffU, /* maximum segment length */ 133 1, /* maximum number of segments */ 134 1, /* granularity */ 135 0, /* flags (reserved) */ 136 }; 137 138 /* 139 * DMA attributes for a ring descriptor 140 */ 141 static ddi_dma_attr_t ring_desc_dma_attr = { 142 DMA_ATTR_V0, /* version of this structure */ 143 0, /* lowest usable address */ 144 0xffffffffU, /* highest usable address */ 145 0xffffffffU, /* maximum DMAable byte count */ 146 0x100, /* alignment in bytes */ 147 0x100, /* burst sizes (any?) */ 148 1, /* minimum transfer */ 149 0xffffffffU, /* maximum transfer */ 150 0xffffffffU, /* maximum segment length */ 151 1, /* maximum number of segments */ 152 1, /* granularity */ 153 0, /* flags (reserved) */ 154 }; 155 156 /* 157 * DMA attributes for a cmd 158 */ 159 static ddi_dma_attr_t cmd_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 4, /* 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 /* 175 * DMA attributes for a rx buffer 176 */ 177 static ddi_dma_attr_t rx_buffer_dma_attr = { 178 DMA_ATTR_V0, /* version of this structure */ 179 0, /* lowest usable address */ 180 0xffffffffU, /* highest usable address */ 181 0xffffffffU, /* maximum DMAable byte count */ 182 0x100, /* alignment in bytes */ 183 0x100, /* burst sizes (any?) */ 184 1, /* minimum transfer */ 185 0xffffffffU, /* maximum transfer */ 186 0xffffffffU, /* maximum segment length */ 187 1, /* maximum number of segments */ 188 1, /* granularity */ 189 0, /* flags (reserved) */ 190 }; 191 192 /* 193 * DMA attributes for a tx buffer. 194 * the maximum number of segments is 4 for the hardware. 195 * now all the wifi drivers put the whole frame in a single 196 * descriptor, so we define the maximum number of segments 1, 197 * just the same as the rx_buffer. we consider leverage the HW 198 * ability in the future, that is why we don't define rx and tx 199 * buffer_dma_attr as the same. 200 */ 201 static ddi_dma_attr_t tx_buffer_dma_attr = { 202 DMA_ATTR_V0, /* version of this structure */ 203 0, /* lowest usable address */ 204 0xffffffffU, /* highest usable address */ 205 0xffffffffU, /* maximum DMAable byte count */ 206 4, /* alignment in bytes */ 207 0x100, /* burst sizes (any?) */ 208 1, /* minimum transfer */ 209 0xffffffffU, /* maximum transfer */ 210 0xffffffffU, /* maximum segment length */ 211 1, /* maximum number of segments */ 212 1, /* granularity */ 213 0, /* flags (reserved) */ 214 }; 215 216 /* 217 * DMA attributes for text and data part in the firmware 218 */ 219 static ddi_dma_attr_t fw_dma_attr = { 220 DMA_ATTR_V0, /* version of this structure */ 221 0, /* lowest usable address */ 222 0xffffffffU, /* highest usable address */ 223 0x7fffffff, /* maximum DMAable byte count */ 224 0x10, /* alignment in bytes */ 225 0x100, /* burst sizes (any?) */ 226 1, /* minimum transfer */ 227 0xffffffffU, /* maximum transfer */ 228 0xffffffffU, /* maximum segment length */ 229 1, /* maximum number of segments */ 230 1, /* granularity */ 231 0, /* flags (reserved) */ 232 }; 233 234 /* 235 * regs access attributes 236 */ 237 static ddi_device_acc_attr_t iwp_reg_accattr = { 238 DDI_DEVICE_ATTR_V0, 239 DDI_STRUCTURE_LE_ACC, 240 DDI_STRICTORDER_ACC, 241 DDI_DEFAULT_ACC 242 }; 243 244 /* 245 * DMA access attributes for descriptor 246 */ 247 static ddi_device_acc_attr_t iwp_dma_descattr = { 248 DDI_DEVICE_ATTR_V0, 249 DDI_STRUCTURE_LE_ACC, 250 DDI_STRICTORDER_ACC, 251 DDI_DEFAULT_ACC 252 }; 253 254 /* 255 * DMA access attributes 256 */ 257 static ddi_device_acc_attr_t iwp_dma_accattr = { 258 DDI_DEVICE_ATTR_V0, 259 DDI_NEVERSWAP_ACC, 260 DDI_STRICTORDER_ACC, 261 DDI_DEFAULT_ACC 262 }; 263 264 static int iwp_ring_init(iwp_sc_t *); 265 static void iwp_ring_free(iwp_sc_t *); 266 static int iwp_alloc_shared(iwp_sc_t *); 267 static void iwp_free_shared(iwp_sc_t *); 268 static int iwp_alloc_kw(iwp_sc_t *); 269 static void iwp_free_kw(iwp_sc_t *); 270 static int iwp_alloc_fw_dma(iwp_sc_t *); 271 static void iwp_free_fw_dma(iwp_sc_t *); 272 static int iwp_alloc_rx_ring(iwp_sc_t *); 273 static void iwp_reset_rx_ring(iwp_sc_t *); 274 static void iwp_free_rx_ring(iwp_sc_t *); 275 static int iwp_alloc_tx_ring(iwp_sc_t *, iwp_tx_ring_t *, 276 int, int); 277 static void iwp_reset_tx_ring(iwp_sc_t *, iwp_tx_ring_t *); 278 static void iwp_free_tx_ring(iwp_tx_ring_t *); 279 static ieee80211_node_t *iwp_node_alloc(ieee80211com_t *); 280 static void iwp_node_free(ieee80211_node_t *); 281 static int iwp_newstate(ieee80211com_t *, enum ieee80211_state, int); 282 static void iwp_mac_access_enter(iwp_sc_t *); 283 static void iwp_mac_access_exit(iwp_sc_t *); 284 static uint32_t iwp_reg_read(iwp_sc_t *, uint32_t); 285 static void iwp_reg_write(iwp_sc_t *, uint32_t, uint32_t); 286 static int iwp_load_init_firmware(iwp_sc_t *); 287 static int iwp_load_run_firmware(iwp_sc_t *); 288 static void iwp_tx_intr(iwp_sc_t *, iwp_rx_desc_t *); 289 static void iwp_cmd_intr(iwp_sc_t *, iwp_rx_desc_t *); 290 static uint_t iwp_intr(caddr_t, caddr_t); 291 static int iwp_eep_load(iwp_sc_t *); 292 static void iwp_get_mac_from_eep(iwp_sc_t *); 293 static int iwp_eep_sem_down(iwp_sc_t *); 294 static void iwp_eep_sem_up(iwp_sc_t *); 295 static uint_t iwp_rx_softintr(caddr_t, caddr_t); 296 static uint8_t iwp_rate_to_plcp(int); 297 static int iwp_cmd(iwp_sc_t *, int, const void *, int, int); 298 static void iwp_set_led(iwp_sc_t *, uint8_t, uint8_t, uint8_t); 299 static int iwp_hw_set_before_auth(iwp_sc_t *); 300 static int iwp_scan(iwp_sc_t *); 301 static int iwp_config(iwp_sc_t *); 302 static void iwp_stop_master(iwp_sc_t *); 303 static int iwp_power_up(iwp_sc_t *); 304 static int iwp_preinit(iwp_sc_t *); 305 static int iwp_init(iwp_sc_t *); 306 static void iwp_stop(iwp_sc_t *); 307 static int iwp_quiesce(dev_info_t *t); 308 static void iwp_amrr_init(iwp_amrr_t *); 309 static void iwp_amrr_timeout(iwp_sc_t *); 310 static void iwp_amrr_ratectl(void *, ieee80211_node_t *); 311 static void iwp_ucode_alive(iwp_sc_t *, iwp_rx_desc_t *); 312 static void iwp_rx_phy_intr(iwp_sc_t *, iwp_rx_desc_t *); 313 static void iwp_rx_mpdu_intr(iwp_sc_t *, iwp_rx_desc_t *); 314 static void iwp_release_calib_buffer(iwp_sc_t *); 315 static int iwp_init_common(iwp_sc_t *); 316 static uint8_t *iwp_eep_addr_trans(iwp_sc_t *, uint32_t); 317 static int iwp_put_seg_fw(iwp_sc_t *, uint32_t, uint32_t, uint32_t); 318 static int iwp_alive_common(iwp_sc_t *); 319 static void iwp_save_calib_result(iwp_sc_t *, iwp_rx_desc_t *); 320 static int iwp_attach(dev_info_t *, ddi_attach_cmd_t); 321 static int iwp_detach(dev_info_t *, ddi_detach_cmd_t); 322 static void iwp_destroy_locks(iwp_sc_t *); 323 static int iwp_send(ieee80211com_t *, mblk_t *, uint8_t); 324 static void iwp_thread(iwp_sc_t *); 325 static int iwp_run_state_config(iwp_sc_t *); 326 static int iwp_fast_recover(iwp_sc_t *); 327 static void iwp_overwrite_ic_default(iwp_sc_t *); 328 static int iwp_add_ap_sta(iwp_sc_t *); 329 static int iwp_alloc_dma_mem(iwp_sc_t *, size_t, 330 ddi_dma_attr_t *, ddi_device_acc_attr_t *, 331 uint_t, iwp_dma_t *); 332 static void iwp_free_dma_mem(iwp_dma_t *); 333 static int iwp_eep_ver_chk(iwp_sc_t *); 334 static void iwp_set_chip_param(iwp_sc_t *); 335 336 /* 337 * GLD specific operations 338 */ 339 static int iwp_m_stat(void *, uint_t, uint64_t *); 340 static int iwp_m_start(void *); 341 static void iwp_m_stop(void *); 342 static int iwp_m_unicst(void *, const uint8_t *); 343 static int iwp_m_multicst(void *, boolean_t, const uint8_t *); 344 static int iwp_m_promisc(void *, boolean_t); 345 static mblk_t *iwp_m_tx(void *, mblk_t *); 346 static void iwp_m_ioctl(void *, queue_t *, mblk_t *); 347 static int iwp_m_setprop(void *arg, const char *pr_name, 348 mac_prop_id_t wldp_pr_num, uint_t wldp_length, const void *wldp_buf); 349 static int iwp_m_getprop(void *arg, const char *pr_name, 350 mac_prop_id_t wldp_pr_num, uint_t pr_flags, uint_t wldp_length, 351 void *wldp_buf, uint_t *perm); 352 353 /* 354 * Supported rates for 802.11b/g modes (in 500Kbps unit). 355 */ 356 static const struct ieee80211_rateset iwp_rateset_11b = 357 { 4, { 2, 4, 11, 22 } }; 358 359 static const struct ieee80211_rateset iwp_rateset_11g = 360 { 12, { 2, 4, 11, 22, 12, 18, 24, 36, 48, 72, 96, 108 } }; 361 362 /* 363 * For mfthread only 364 */ 365 extern pri_t minclsyspri; 366 367 #define DRV_NAME_SP "iwp" 368 369 /* 370 * Module Loading Data & Entry Points 371 */ 372 DDI_DEFINE_STREAM_OPS(iwp_devops, nulldev, nulldev, iwp_attach, 373 iwp_detach, nodev, NULL, D_MP, NULL, iwp_quiesce); 374 375 static struct modldrv iwp_modldrv = { 376 &mod_driverops, 377 "Intel(R) PumaPeak driver(N)", 378 &iwp_devops 379 }; 380 381 static struct modlinkage iwp_modlinkage = { 382 MODREV_1, 383 &iwp_modldrv, 384 NULL 385 }; 386 387 int 388 _init(void) 389 { 390 int status; 391 392 status = ddi_soft_state_init(&iwp_soft_state_p, 393 sizeof (iwp_sc_t), 1); 394 if (status != DDI_SUCCESS) { 395 return (status); 396 } 397 398 mac_init_ops(&iwp_devops, DRV_NAME_SP); 399 status = mod_install(&iwp_modlinkage); 400 if (status != DDI_SUCCESS) { 401 mac_fini_ops(&iwp_devops); 402 ddi_soft_state_fini(&iwp_soft_state_p); 403 } 404 405 return (status); 406 } 407 408 int 409 _fini(void) 410 { 411 int status; 412 413 status = mod_remove(&iwp_modlinkage); 414 if (DDI_SUCCESS == status) { 415 mac_fini_ops(&iwp_devops); 416 ddi_soft_state_fini(&iwp_soft_state_p); 417 } 418 419 return (status); 420 } 421 422 int 423 _info(struct modinfo *mip) 424 { 425 return (mod_info(&iwp_modlinkage, mip)); 426 } 427 428 /* 429 * Mac Call Back entries 430 */ 431 mac_callbacks_t iwp_m_callbacks = { 432 MC_IOCTL | MC_SETPROP | MC_GETPROP, 433 iwp_m_stat, 434 iwp_m_start, 435 iwp_m_stop, 436 iwp_m_promisc, 437 iwp_m_multicst, 438 iwp_m_unicst, 439 iwp_m_tx, 440 iwp_m_ioctl, 441 NULL, 442 NULL, 443 NULL, 444 iwp_m_setprop, 445 iwp_m_getprop 446 }; 447 448 #ifdef DEBUG 449 void 450 iwp_dbg(uint32_t flags, const char *fmt, ...) 451 { 452 va_list ap; 453 454 if (flags & iwp_dbg_flags) { 455 va_start(ap, fmt); 456 vcmn_err(CE_NOTE, fmt, ap); 457 va_end(ap); 458 } 459 } 460 #endif /* DEBUG */ 461 462 /* 463 * device operations 464 */ 465 int 466 iwp_attach(dev_info_t *dip, ddi_attach_cmd_t cmd) 467 { 468 iwp_sc_t *sc; 469 ieee80211com_t *ic; 470 int instance, i; 471 char strbuf[32]; 472 wifi_data_t wd = { 0 }; 473 mac_register_t *macp; 474 int intr_type; 475 int intr_count; 476 int intr_actual; 477 int err = DDI_FAILURE; 478 479 switch (cmd) { 480 case DDI_ATTACH: 481 break; 482 case DDI_RESUME: 483 instance = ddi_get_instance(dip); 484 sc = ddi_get_soft_state(iwp_soft_state_p, 485 instance); 486 ASSERT(sc != NULL); 487 488 if (sc->sc_flags & IWP_F_RUNNING) { 489 (void) iwp_init(sc); 490 } 491 492 atomic_and_32(&sc->sc_flags, ~IWP_F_SUSPEND); 493 494 IWP_DBG((IWP_DEBUG_RESUME, "iwp_attach(): " 495 "resume\n")); 496 return (DDI_SUCCESS); 497 default: 498 goto attach_fail1; 499 } 500 501 instance = ddi_get_instance(dip); 502 err = ddi_soft_state_zalloc(iwp_soft_state_p, instance); 503 if (err != DDI_SUCCESS) { 504 cmn_err(CE_WARN, "iwp_attach(): " 505 "failed to allocate soft state\n"); 506 goto attach_fail1; 507 } 508 509 sc = ddi_get_soft_state(iwp_soft_state_p, instance); 510 ASSERT(sc != NULL); 511 512 sc->sc_dip = dip; 513 514 /* 515 * map configure space 516 */ 517 err = ddi_regs_map_setup(dip, 0, &sc->sc_cfg_base, 0, 0, 518 &iwp_reg_accattr, &sc->sc_cfg_handle); 519 if (err != DDI_SUCCESS) { 520 cmn_err(CE_WARN, "iwp_attach(): " 521 "failed to map config spaces regs\n"); 522 goto attach_fail2; 523 } 524 525 sc->sc_dev_id = ddi_get16(sc->sc_cfg_handle, 526 (uint16_t *)(sc->sc_cfg_base + PCI_CONF_DEVID)); 527 if ((sc->sc_dev_id != 0x422B) && 528 (sc->sc_dev_id != 0x422C) && 529 (sc->sc_dev_id != 0x4238) && 530 (sc->sc_dev_id != 0x4239) && 531 (sc->sc_dev_id != 0x008d) && 532 (sc->sc_dev_id != 0x008e)) { 533 cmn_err(CE_WARN, "iwp_attach(): " 534 "Do not support this device\n"); 535 goto attach_fail3; 536 } 537 538 iwp_set_chip_param(sc); 539 540 sc->sc_rev = ddi_get8(sc->sc_cfg_handle, 541 (uint8_t *)(sc->sc_cfg_base + PCI_CONF_REVID)); 542 543 /* 544 * keep from disturbing C3 state of CPU 545 */ 546 ddi_put8(sc->sc_cfg_handle, (uint8_t *)(sc->sc_cfg_base + 547 PCI_CFG_RETRY_TIMEOUT), 0); 548 549 /* 550 * determine the size of buffer for frame and command to ucode 551 */ 552 sc->sc_clsz = ddi_get16(sc->sc_cfg_handle, 553 (uint16_t *)(sc->sc_cfg_base + PCI_CONF_CACHE_LINESZ)); 554 if (!sc->sc_clsz) { 555 sc->sc_clsz = 16; 556 } 557 sc->sc_clsz = (sc->sc_clsz << 2); 558 559 sc->sc_dmabuf_sz = roundup(0x1000 + sizeof (struct ieee80211_frame) + 560 IEEE80211_MTU + IEEE80211_CRC_LEN + 561 (IEEE80211_WEP_IVLEN + IEEE80211_WEP_KIDLEN + 562 IEEE80211_WEP_CRCLEN), sc->sc_clsz); 563 564 /* 565 * Map operating registers 566 */ 567 err = ddi_regs_map_setup(dip, 1, &sc->sc_base, 568 0, 0, &iwp_reg_accattr, &sc->sc_handle); 569 if (err != DDI_SUCCESS) { 570 cmn_err(CE_WARN, "iwp_attach(): " 571 "failed to map device regs\n"); 572 goto attach_fail3; 573 } 574 575 /* 576 * this is used to differentiate type of hardware 577 */ 578 sc->sc_hw_rev = IWP_READ(sc, CSR_HW_REV); 579 580 err = ddi_intr_get_supported_types(dip, &intr_type); 581 if ((err != DDI_SUCCESS) || (!(intr_type & DDI_INTR_TYPE_FIXED))) { 582 cmn_err(CE_WARN, "iwp_attach(): " 583 "fixed type interrupt is not supported\n"); 584 goto attach_fail4; 585 } 586 587 err = ddi_intr_get_nintrs(dip, DDI_INTR_TYPE_FIXED, &intr_count); 588 if ((err != DDI_SUCCESS) || (intr_count != 1)) { 589 cmn_err(CE_WARN, "iwp_attach(): " 590 "no fixed interrupts\n"); 591 goto attach_fail4; 592 } 593 594 sc->sc_intr_htable = kmem_zalloc(sizeof (ddi_intr_handle_t), KM_SLEEP); 595 596 err = ddi_intr_alloc(dip, sc->sc_intr_htable, DDI_INTR_TYPE_FIXED, 0, 597 intr_count, &intr_actual, 0); 598 if ((err != DDI_SUCCESS) || (intr_actual != 1)) { 599 cmn_err(CE_WARN, "iwp_attach(): " 600 "ddi_intr_alloc() failed 0x%x\n", err); 601 goto attach_fail5; 602 } 603 604 err = ddi_intr_get_pri(sc->sc_intr_htable[0], &sc->sc_intr_pri); 605 if (err != DDI_SUCCESS) { 606 cmn_err(CE_WARN, "iwp_attach(): " 607 "ddi_intr_get_pri() failed 0x%x\n", err); 608 goto attach_fail6; 609 } 610 611 mutex_init(&sc->sc_glock, NULL, MUTEX_DRIVER, 612 DDI_INTR_PRI(sc->sc_intr_pri)); 613 mutex_init(&sc->sc_tx_lock, NULL, MUTEX_DRIVER, 614 DDI_INTR_PRI(sc->sc_intr_pri)); 615 mutex_init(&sc->sc_mt_lock, NULL, MUTEX_DRIVER, 616 DDI_INTR_PRI(sc->sc_intr_pri)); 617 618 cv_init(&sc->sc_cmd_cv, NULL, CV_DRIVER, NULL); 619 cv_init(&sc->sc_put_seg_cv, NULL, CV_DRIVER, NULL); 620 cv_init(&sc->sc_ucode_cv, NULL, CV_DRIVER, NULL); 621 622 /* 623 * initialize the mfthread 624 */ 625 cv_init(&sc->sc_mt_cv, NULL, CV_DRIVER, NULL); 626 sc->sc_mf_thread = NULL; 627 sc->sc_mf_thread_switch = 0; 628 629 /* 630 * Allocate shared buffer for communication between driver and ucode. 631 */ 632 err = iwp_alloc_shared(sc); 633 if (err != DDI_SUCCESS) { 634 cmn_err(CE_WARN, "iwp_attach(): " 635 "failed to allocate shared page\n"); 636 goto attach_fail7; 637 } 638 639 (void) memset(sc->sc_shared, 0, sizeof (iwp_shared_t)); 640 641 /* 642 * Allocate keep warm page. 643 */ 644 err = iwp_alloc_kw(sc); 645 if (err != DDI_SUCCESS) { 646 cmn_err(CE_WARN, "iwp_attach(): " 647 "failed to allocate keep warm page\n"); 648 goto attach_fail8; 649 } 650 651 /* 652 * Do some necessary hardware initializations. 653 */ 654 err = iwp_preinit(sc); 655 if (err != IWP_SUCCESS) { 656 cmn_err(CE_WARN, "iwp_attach(): " 657 "failed to initialize hardware\n"); 658 goto attach_fail9; 659 } 660 661 /* 662 * get hardware configurations from eeprom 663 */ 664 err = iwp_eep_load(sc); 665 if (err != IWP_SUCCESS) { 666 cmn_err(CE_WARN, "iwp_attach(): " 667 "failed to load eeprom\n"); 668 goto attach_fail9; 669 } 670 671 /* 672 * calibration information from EEPROM 673 */ 674 sc->sc_eep_calib = (struct iwp_eep_calibration *) 675 iwp_eep_addr_trans(sc, EEP_CALIBRATION); 676 677 err = iwp_eep_ver_chk(sc); 678 if (err != IWP_SUCCESS) { 679 goto attach_fail9; 680 } 681 682 /* 683 * get MAC address of this chipset 684 */ 685 iwp_get_mac_from_eep(sc); 686 687 688 /* 689 * initialize TX and RX ring buffers 690 */ 691 err = iwp_ring_init(sc); 692 if (err != DDI_SUCCESS) { 693 cmn_err(CE_WARN, "iwp_attach(): " 694 "failed to allocate and initialize ring\n"); 695 goto attach_fail9; 696 } 697 698 sc->sc_hdr = (iwp_firmware_hdr_t *)iwp_fw_bin; 699 700 /* 701 * copy ucode to dma buffer 702 */ 703 err = iwp_alloc_fw_dma(sc); 704 if (err != DDI_SUCCESS) { 705 cmn_err(CE_WARN, "iwp_attach(): " 706 "failed to allocate firmware dma\n"); 707 goto attach_fail10; 708 } 709 710 /* 711 * Initialize the wifi part, which will be used by 712 * 802.11 module 713 */ 714 ic = &sc->sc_ic; 715 ic->ic_phytype = IEEE80211_T_OFDM; 716 ic->ic_opmode = IEEE80211_M_STA; /* default to BSS mode */ 717 ic->ic_state = IEEE80211_S_INIT; 718 ic->ic_maxrssi = 100; /* experimental number */ 719 ic->ic_caps = IEEE80211_C_SHPREAMBLE | IEEE80211_C_TXPMGT | 720 IEEE80211_C_PMGT | IEEE80211_C_SHSLOT; 721 722 /* 723 * Support WPA/WPA2 724 */ 725 ic->ic_caps |= IEEE80211_C_WPA; 726 727 /* 728 * set supported .11b and .11g rates 729 */ 730 ic->ic_sup_rates[IEEE80211_MODE_11B] = iwp_rateset_11b; 731 ic->ic_sup_rates[IEEE80211_MODE_11G] = iwp_rateset_11g; 732 733 /* 734 * set supported .11b and .11g channels (1 through 11) 735 */ 736 for (i = 1; i <= 11; i++) { 737 ic->ic_sup_channels[i].ich_freq = 738 ieee80211_ieee2mhz(i, IEEE80211_CHAN_2GHZ); 739 ic->ic_sup_channels[i].ich_flags = 740 IEEE80211_CHAN_CCK | IEEE80211_CHAN_OFDM | 741 IEEE80211_CHAN_DYN | IEEE80211_CHAN_2GHZ | 742 IEEE80211_CHAN_PASSIVE; 743 } 744 745 ic->ic_ibss_chan = &ic->ic_sup_channels[0]; 746 ic->ic_xmit = iwp_send; 747 748 /* 749 * attach to 802.11 module 750 */ 751 ieee80211_attach(ic); 752 753 /* 754 * different instance has different WPA door 755 */ 756 (void) snprintf(ic->ic_wpadoor, MAX_IEEE80211STR, "%s_%s%d", WPA_DOOR, 757 ddi_driver_name(dip), 758 ddi_get_instance(dip)); 759 760 /* 761 * Overwrite 80211 default configurations. 762 */ 763 iwp_overwrite_ic_default(sc); 764 765 /* 766 * initialize 802.11 module 767 */ 768 ieee80211_media_init(ic); 769 770 /* 771 * initialize default tx key 772 */ 773 ic->ic_def_txkey = 0; 774 775 err = ddi_intr_add_softint(dip, &sc->sc_soft_hdl, DDI_INTR_SOFTPRI_MAX, 776 iwp_rx_softintr, (caddr_t)sc); 777 if (err != DDI_SUCCESS) { 778 cmn_err(CE_WARN, "iwp_attach(): " 779 "add soft interrupt failed\n"); 780 goto attach_fail12; 781 } 782 783 err = ddi_intr_add_handler(sc->sc_intr_htable[0], iwp_intr, 784 (caddr_t)sc, NULL); 785 if (err != DDI_SUCCESS) { 786 cmn_err(CE_WARN, "iwp_attach(): " 787 "ddi_intr_add_handle() failed\n"); 788 goto attach_fail13; 789 } 790 791 err = ddi_intr_enable(sc->sc_intr_htable[0]); 792 if (err != DDI_SUCCESS) { 793 cmn_err(CE_WARN, "iwp_attach(): " 794 "ddi_intr_enable() failed\n"); 795 goto attach_fail14; 796 } 797 798 /* 799 * Initialize pointer to device specific functions 800 */ 801 wd.wd_secalloc = WIFI_SEC_NONE; 802 wd.wd_opmode = ic->ic_opmode; 803 IEEE80211_ADDR_COPY(wd.wd_bssid, ic->ic_macaddr); 804 805 /* 806 * create relation to GLD 807 */ 808 macp = mac_alloc(MAC_VERSION); 809 if (NULL == macp) { 810 cmn_err(CE_WARN, "iwp_attach(): " 811 "failed to do mac_alloc()\n"); 812 goto attach_fail15; 813 } 814 815 macp->m_type_ident = MAC_PLUGIN_IDENT_WIFI; 816 macp->m_driver = sc; 817 macp->m_dip = dip; 818 macp->m_src_addr = ic->ic_macaddr; 819 macp->m_callbacks = &iwp_m_callbacks; 820 macp->m_min_sdu = 0; 821 macp->m_max_sdu = IEEE80211_MTU; 822 macp->m_pdata = &wd; 823 macp->m_pdata_size = sizeof (wd); 824 825 /* 826 * Register the macp to mac 827 */ 828 err = mac_register(macp, &ic->ic_mach); 829 mac_free(macp); 830 if (err != DDI_SUCCESS) { 831 cmn_err(CE_WARN, "iwp_attach(): " 832 "failed to do mac_register()\n"); 833 goto attach_fail15; 834 } 835 836 /* 837 * Create minor node of type DDI_NT_NET_WIFI 838 */ 839 (void) snprintf(strbuf, sizeof (strbuf), DRV_NAME_SP"%d", instance); 840 err = ddi_create_minor_node(dip, strbuf, S_IFCHR, 841 instance + 1, DDI_NT_NET_WIFI, 0); 842 if (err != DDI_SUCCESS) { 843 cmn_err(CE_WARN, "iwp_attach(): " 844 "failed to do ddi_create_minor_node()\n"); 845 } 846 847 /* 848 * Notify link is down now 849 */ 850 mac_link_update(ic->ic_mach, LINK_STATE_DOWN); 851 852 /* 853 * create the mf thread to handle the link status, 854 * recovery fatal error, etc. 855 */ 856 sc->sc_mf_thread_switch = 1; 857 if (NULL == sc->sc_mf_thread) { 858 sc->sc_mf_thread = thread_create((caddr_t)NULL, 0, 859 iwp_thread, sc, 0, &p0, TS_RUN, minclsyspri); 860 } 861 862 atomic_or_32(&sc->sc_flags, IWP_F_ATTACHED); 863 864 return (DDI_SUCCESS); 865 866 attach_fail15: 867 (void) ddi_intr_disable(sc->sc_intr_htable[0]); 868 attach_fail14: 869 (void) ddi_intr_remove_handler(sc->sc_intr_htable[0]); 870 attach_fail13: 871 (void) ddi_intr_remove_softint(sc->sc_soft_hdl); 872 sc->sc_soft_hdl = NULL; 873 attach_fail12: 874 ieee80211_detach(ic); 875 attach_fail11: 876 iwp_free_fw_dma(sc); 877 attach_fail10: 878 iwp_ring_free(sc); 879 attach_fail9: 880 iwp_free_kw(sc); 881 attach_fail8: 882 iwp_free_shared(sc); 883 attach_fail7: 884 iwp_destroy_locks(sc); 885 attach_fail6: 886 (void) ddi_intr_free(sc->sc_intr_htable[0]); 887 attach_fail5: 888 kmem_free(sc->sc_intr_htable, sizeof (ddi_intr_handle_t)); 889 attach_fail4: 890 ddi_regs_map_free(&sc->sc_handle); 891 attach_fail3: 892 ddi_regs_map_free(&sc->sc_cfg_handle); 893 attach_fail2: 894 ddi_soft_state_free(iwp_soft_state_p, instance); 895 attach_fail1: 896 return (DDI_FAILURE); 897 } 898 899 int 900 iwp_detach(dev_info_t *dip, ddi_detach_cmd_t cmd) 901 { 902 iwp_sc_t *sc; 903 ieee80211com_t *ic; 904 int err; 905 906 sc = ddi_get_soft_state(iwp_soft_state_p, ddi_get_instance(dip)); 907 ASSERT(sc != NULL); 908 ic = &sc->sc_ic; 909 910 switch (cmd) { 911 case DDI_DETACH: 912 break; 913 case DDI_SUSPEND: 914 atomic_and_32(&sc->sc_flags, ~IWP_F_HW_ERR_RECOVER); 915 atomic_and_32(&sc->sc_flags, ~IWP_F_RATE_AUTO_CTL); 916 917 atomic_or_32(&sc->sc_flags, IWP_F_SUSPEND); 918 919 if (sc->sc_flags & IWP_F_RUNNING) { 920 iwp_stop(sc); 921 ieee80211_new_state(ic, IEEE80211_S_INIT, -1); 922 923 } 924 925 IWP_DBG((IWP_DEBUG_RESUME, "iwp_detach(): " 926 "suspend\n")); 927 return (DDI_SUCCESS); 928 default: 929 return (DDI_FAILURE); 930 } 931 932 if (!(sc->sc_flags & IWP_F_ATTACHED)) { 933 return (DDI_FAILURE); 934 } 935 936 /* 937 * Destroy the mf_thread 938 */ 939 sc->sc_mf_thread_switch = 0; 940 941 mutex_enter(&sc->sc_mt_lock); 942 while (sc->sc_mf_thread != NULL) { 943 if (cv_wait_sig(&sc->sc_mt_cv, &sc->sc_mt_lock) == 0) { 944 break; 945 } 946 } 947 mutex_exit(&sc->sc_mt_lock); 948 949 err = mac_disable(sc->sc_ic.ic_mach); 950 if (err != DDI_SUCCESS) { 951 return (err); 952 } 953 954 /* 955 * stop chipset 956 */ 957 iwp_stop(sc); 958 959 DELAY(500000); 960 961 /* 962 * release buffer for calibration 963 */ 964 iwp_release_calib_buffer(sc); 965 966 /* 967 * Unregiste from GLD 968 */ 969 (void) mac_unregister(sc->sc_ic.ic_mach); 970 971 mutex_enter(&sc->sc_glock); 972 iwp_free_fw_dma(sc); 973 iwp_ring_free(sc); 974 iwp_free_kw(sc); 975 iwp_free_shared(sc); 976 mutex_exit(&sc->sc_glock); 977 978 (void) ddi_intr_disable(sc->sc_intr_htable[0]); 979 (void) ddi_intr_remove_handler(sc->sc_intr_htable[0]); 980 (void) ddi_intr_free(sc->sc_intr_htable[0]); 981 kmem_free(sc->sc_intr_htable, sizeof (ddi_intr_handle_t)); 982 983 (void) ddi_intr_remove_softint(sc->sc_soft_hdl); 984 sc->sc_soft_hdl = NULL; 985 986 /* 987 * detach from 80211 module 988 */ 989 ieee80211_detach(&sc->sc_ic); 990 991 iwp_destroy_locks(sc); 992 993 ddi_regs_map_free(&sc->sc_handle); 994 ddi_regs_map_free(&sc->sc_cfg_handle); 995 ddi_remove_minor_node(dip, NULL); 996 ddi_soft_state_free(iwp_soft_state_p, ddi_get_instance(dip)); 997 998 return (DDI_SUCCESS); 999 } 1000 1001 /* 1002 * destroy all locks 1003 */ 1004 static void 1005 iwp_destroy_locks(iwp_sc_t *sc) 1006 { 1007 cv_destroy(&sc->sc_mt_cv); 1008 cv_destroy(&sc->sc_cmd_cv); 1009 cv_destroy(&sc->sc_put_seg_cv); 1010 cv_destroy(&sc->sc_ucode_cv); 1011 mutex_destroy(&sc->sc_mt_lock); 1012 mutex_destroy(&sc->sc_tx_lock); 1013 mutex_destroy(&sc->sc_glock); 1014 } 1015 1016 /* 1017 * Allocate an area of memory and a DMA handle for accessing it 1018 */ 1019 static int 1020 iwp_alloc_dma_mem(iwp_sc_t *sc, size_t memsize, 1021 ddi_dma_attr_t *dma_attr_p, ddi_device_acc_attr_t *acc_attr_p, 1022 uint_t dma_flags, iwp_dma_t *dma_p) 1023 { 1024 caddr_t vaddr; 1025 int err = DDI_FAILURE; 1026 1027 /* 1028 * Allocate handle 1029 */ 1030 err = ddi_dma_alloc_handle(sc->sc_dip, dma_attr_p, 1031 DDI_DMA_SLEEP, NULL, &dma_p->dma_hdl); 1032 if (err != DDI_SUCCESS) { 1033 dma_p->dma_hdl = NULL; 1034 return (DDI_FAILURE); 1035 } 1036 1037 /* 1038 * Allocate memory 1039 */ 1040 err = ddi_dma_mem_alloc(dma_p->dma_hdl, memsize, acc_attr_p, 1041 dma_flags & (DDI_DMA_CONSISTENT | DDI_DMA_STREAMING), 1042 DDI_DMA_SLEEP, NULL, &vaddr, &dma_p->alength, &dma_p->acc_hdl); 1043 if (err != DDI_SUCCESS) { 1044 ddi_dma_free_handle(&dma_p->dma_hdl); 1045 dma_p->dma_hdl = NULL; 1046 dma_p->acc_hdl = NULL; 1047 return (DDI_FAILURE); 1048 } 1049 1050 /* 1051 * Bind the two together 1052 */ 1053 dma_p->mem_va = vaddr; 1054 err = ddi_dma_addr_bind_handle(dma_p->dma_hdl, NULL, 1055 vaddr, dma_p->alength, dma_flags, DDI_DMA_SLEEP, NULL, 1056 &dma_p->cookie, &dma_p->ncookies); 1057 if (err != DDI_DMA_MAPPED) { 1058 ddi_dma_mem_free(&dma_p->acc_hdl); 1059 ddi_dma_free_handle(&dma_p->dma_hdl); 1060 dma_p->acc_hdl = NULL; 1061 dma_p->dma_hdl = NULL; 1062 return (DDI_FAILURE); 1063 } 1064 1065 dma_p->nslots = ~0U; 1066 dma_p->size = ~0U; 1067 dma_p->token = ~0U; 1068 dma_p->offset = 0; 1069 return (DDI_SUCCESS); 1070 } 1071 1072 /* 1073 * Free one allocated area of DMAable memory 1074 */ 1075 static void 1076 iwp_free_dma_mem(iwp_dma_t *dma_p) 1077 { 1078 if (dma_p->dma_hdl != NULL) { 1079 if (dma_p->ncookies) { 1080 (void) ddi_dma_unbind_handle(dma_p->dma_hdl); 1081 dma_p->ncookies = 0; 1082 } 1083 ddi_dma_free_handle(&dma_p->dma_hdl); 1084 dma_p->dma_hdl = NULL; 1085 } 1086 1087 if (dma_p->acc_hdl != NULL) { 1088 ddi_dma_mem_free(&dma_p->acc_hdl); 1089 dma_p->acc_hdl = NULL; 1090 } 1091 } 1092 1093 /* 1094 * copy ucode into dma buffers 1095 */ 1096 static int 1097 iwp_alloc_fw_dma(iwp_sc_t *sc) 1098 { 1099 int err = DDI_FAILURE; 1100 iwp_dma_t *dma_p; 1101 char *t; 1102 1103 /* 1104 * firmware image layout: 1105 * |HDR|<-TEXT->|<-DATA->|<-INIT_TEXT->|<-INIT_DATA->|<-BOOT->| 1106 */ 1107 1108 /* 1109 * Check firmware image size. 1110 */ 1111 if (LE_32(sc->sc_hdr->init_textsz) > RTC_INST_SIZE) { 1112 cmn_err(CE_WARN, "iwp_alloc_fw_dma(): " 1113 "firmware init text size 0x%x is too large\n", 1114 LE_32(sc->sc_hdr->init_textsz)); 1115 1116 goto fail; 1117 } 1118 1119 if (LE_32(sc->sc_hdr->init_datasz) > RTC_DATA_SIZE) { 1120 cmn_err(CE_WARN, "iwp_alloc_fw_dma(): " 1121 "firmware init data size 0x%x is too large\n", 1122 LE_32(sc->sc_hdr->init_datasz)); 1123 1124 goto fail; 1125 } 1126 1127 if (LE_32(sc->sc_hdr->textsz) > RTC_INST_SIZE) { 1128 cmn_err(CE_WARN, "iwp_alloc_fw_dma(): " 1129 "firmware text size 0x%x is too large\n", 1130 LE_32(sc->sc_hdr->textsz)); 1131 1132 goto fail; 1133 } 1134 1135 if (LE_32(sc->sc_hdr->datasz) > RTC_DATA_SIZE) { 1136 cmn_err(CE_WARN, "iwp_alloc_fw_dma(): " 1137 "firmware data size 0x%x is too large\n", 1138 LE_32(sc->sc_hdr->datasz)); 1139 1140 goto fail; 1141 } 1142 1143 /* 1144 * copy text of runtime ucode 1145 */ 1146 t = (char *)(sc->sc_hdr + 1); 1147 err = iwp_alloc_dma_mem(sc, LE_32(sc->sc_hdr->textsz), 1148 &fw_dma_attr, &iwp_dma_accattr, 1149 DDI_DMA_RDWR | DDI_DMA_CONSISTENT, 1150 &sc->sc_dma_fw_text); 1151 if (err != DDI_SUCCESS) { 1152 cmn_err(CE_WARN, "iwp_alloc_fw_dma(): " 1153 "failed to allocate text dma memory.\n"); 1154 goto fail; 1155 } 1156 1157 dma_p = &sc->sc_dma_fw_text; 1158 1159 IWP_DBG((IWP_DEBUG_DMA, "iwp_alloc_fw_dma(): " 1160 "text[ncookies:%d addr:%lx size:%lx]\n", 1161 dma_p->ncookies, dma_p->cookie.dmac_address, 1162 dma_p->cookie.dmac_size)); 1163 1164 (void) memcpy(dma_p->mem_va, t, LE_32(sc->sc_hdr->textsz)); 1165 1166 /* 1167 * copy data and bak-data of runtime ucode 1168 */ 1169 t += LE_32(sc->sc_hdr->textsz); 1170 err = iwp_alloc_dma_mem(sc, LE_32(sc->sc_hdr->datasz), 1171 &fw_dma_attr, &iwp_dma_accattr, 1172 DDI_DMA_RDWR | DDI_DMA_CONSISTENT, 1173 &sc->sc_dma_fw_data); 1174 if (err != DDI_SUCCESS) { 1175 cmn_err(CE_WARN, "iwp_alloc_fw_dma(): " 1176 "failed to allocate data dma memory\n"); 1177 goto fail; 1178 } 1179 1180 dma_p = &sc->sc_dma_fw_data; 1181 1182 IWP_DBG((IWP_DEBUG_DMA, "iwp_alloc_fw_dma(): " 1183 "data[ncookies:%d addr:%lx size:%lx]\n", 1184 dma_p->ncookies, dma_p->cookie.dmac_address, 1185 dma_p->cookie.dmac_size)); 1186 1187 (void) memcpy(dma_p->mem_va, t, LE_32(sc->sc_hdr->datasz)); 1188 1189 err = iwp_alloc_dma_mem(sc, LE_32(sc->sc_hdr->datasz), 1190 &fw_dma_attr, &iwp_dma_accattr, 1191 DDI_DMA_RDWR | DDI_DMA_CONSISTENT, 1192 &sc->sc_dma_fw_data_bak); 1193 if (err != DDI_SUCCESS) { 1194 cmn_err(CE_WARN, "iwp_alloc_fw_dma(): " 1195 "failed to allocate data bakup dma memory\n"); 1196 goto fail; 1197 } 1198 1199 dma_p = &sc->sc_dma_fw_data_bak; 1200 1201 IWP_DBG((IWP_DEBUG_DMA, "iwp_alloc_fw_dma(): " 1202 "data_bak[ncookies:%d addr:%lx " 1203 "size:%lx]\n", 1204 dma_p->ncookies, dma_p->cookie.dmac_address, 1205 dma_p->cookie.dmac_size)); 1206 1207 (void) memcpy(dma_p->mem_va, t, LE_32(sc->sc_hdr->datasz)); 1208 1209 /* 1210 * copy text of init ucode 1211 */ 1212 t += LE_32(sc->sc_hdr->datasz); 1213 err = iwp_alloc_dma_mem(sc, LE_32(sc->sc_hdr->init_textsz), 1214 &fw_dma_attr, &iwp_dma_accattr, 1215 DDI_DMA_RDWR | DDI_DMA_CONSISTENT, 1216 &sc->sc_dma_fw_init_text); 1217 if (err != DDI_SUCCESS) { 1218 cmn_err(CE_WARN, "iwp_alloc_fw_dma(): " 1219 "failed to allocate init text dma memory\n"); 1220 goto fail; 1221 } 1222 1223 dma_p = &sc->sc_dma_fw_init_text; 1224 1225 IWP_DBG((IWP_DEBUG_DMA, "iwp_alloc_fw_dma(): " 1226 "init_text[ncookies:%d addr:%lx " 1227 "size:%lx]\n", 1228 dma_p->ncookies, dma_p->cookie.dmac_address, 1229 dma_p->cookie.dmac_size)); 1230 1231 (void) memcpy(dma_p->mem_va, t, LE_32(sc->sc_hdr->init_textsz)); 1232 1233 /* 1234 * copy data of init ucode 1235 */ 1236 t += LE_32(sc->sc_hdr->init_textsz); 1237 err = iwp_alloc_dma_mem(sc, LE_32(sc->sc_hdr->init_datasz), 1238 &fw_dma_attr, &iwp_dma_accattr, 1239 DDI_DMA_RDWR | DDI_DMA_CONSISTENT, 1240 &sc->sc_dma_fw_init_data); 1241 if (err != DDI_SUCCESS) { 1242 cmn_err(CE_WARN, "iwp_alloc_fw_dma(): " 1243 "failed to allocate init data dma memory\n"); 1244 goto fail; 1245 } 1246 1247 dma_p = &sc->sc_dma_fw_init_data; 1248 1249 IWP_DBG((IWP_DEBUG_DMA, "iwp_alloc_fw_dma(): " 1250 "init_data[ncookies:%d addr:%lx " 1251 "size:%lx]\n", 1252 dma_p->ncookies, dma_p->cookie.dmac_address, 1253 dma_p->cookie.dmac_size)); 1254 1255 (void) memcpy(dma_p->mem_va, t, LE_32(sc->sc_hdr->init_datasz)); 1256 1257 sc->sc_boot = t + LE_32(sc->sc_hdr->init_datasz); 1258 fail: 1259 return (err); 1260 } 1261 1262 static void 1263 iwp_free_fw_dma(iwp_sc_t *sc) 1264 { 1265 iwp_free_dma_mem(&sc->sc_dma_fw_text); 1266 iwp_free_dma_mem(&sc->sc_dma_fw_data); 1267 iwp_free_dma_mem(&sc->sc_dma_fw_data_bak); 1268 iwp_free_dma_mem(&sc->sc_dma_fw_init_text); 1269 iwp_free_dma_mem(&sc->sc_dma_fw_init_data); 1270 } 1271 1272 /* 1273 * Allocate a shared buffer between host and NIC. 1274 */ 1275 static int 1276 iwp_alloc_shared(iwp_sc_t *sc) 1277 { 1278 #ifdef DEBUG 1279 iwp_dma_t *dma_p; 1280 #endif 1281 int err = DDI_FAILURE; 1282 1283 /* 1284 * must be aligned on a 4K-page boundary 1285 */ 1286 err = iwp_alloc_dma_mem(sc, sizeof (iwp_shared_t), 1287 &sh_dma_attr, &iwp_dma_descattr, 1288 DDI_DMA_RDWR | DDI_DMA_CONSISTENT, 1289 &sc->sc_dma_sh); 1290 if (err != DDI_SUCCESS) { 1291 goto fail; 1292 } 1293 1294 sc->sc_shared = (iwp_shared_t *)sc->sc_dma_sh.mem_va; 1295 1296 #ifdef DEBUG 1297 dma_p = &sc->sc_dma_sh; 1298 #endif 1299 IWP_DBG((IWP_DEBUG_DMA, "iwp_alloc_shared(): " 1300 "sh[ncookies:%d addr:%lx size:%lx]\n", 1301 dma_p->ncookies, dma_p->cookie.dmac_address, 1302 dma_p->cookie.dmac_size)); 1303 1304 return (err); 1305 fail: 1306 iwp_free_shared(sc); 1307 return (err); 1308 } 1309 1310 static void 1311 iwp_free_shared(iwp_sc_t *sc) 1312 { 1313 iwp_free_dma_mem(&sc->sc_dma_sh); 1314 } 1315 1316 /* 1317 * Allocate a keep warm page. 1318 */ 1319 static int 1320 iwp_alloc_kw(iwp_sc_t *sc) 1321 { 1322 #ifdef DEBUG 1323 iwp_dma_t *dma_p; 1324 #endif 1325 int err = DDI_FAILURE; 1326 1327 /* 1328 * must be aligned on a 4K-page boundary 1329 */ 1330 err = iwp_alloc_dma_mem(sc, IWP_KW_SIZE, 1331 &kw_dma_attr, &iwp_dma_descattr, 1332 DDI_DMA_RDWR | DDI_DMA_CONSISTENT, 1333 &sc->sc_dma_kw); 1334 if (err != DDI_SUCCESS) { 1335 goto fail; 1336 } 1337 1338 #ifdef DEBUG 1339 dma_p = &sc->sc_dma_kw; 1340 #endif 1341 IWP_DBG((IWP_DEBUG_DMA, "iwp_alloc_kw(): " 1342 "kw[ncookies:%d addr:%lx size:%lx]\n", 1343 dma_p->ncookies, dma_p->cookie.dmac_address, 1344 dma_p->cookie.dmac_size)); 1345 1346 return (err); 1347 fail: 1348 iwp_free_kw(sc); 1349 return (err); 1350 } 1351 1352 static void 1353 iwp_free_kw(iwp_sc_t *sc) 1354 { 1355 iwp_free_dma_mem(&sc->sc_dma_kw); 1356 } 1357 1358 /* 1359 * initialize RX ring buffers 1360 */ 1361 static int 1362 iwp_alloc_rx_ring(iwp_sc_t *sc) 1363 { 1364 iwp_rx_ring_t *ring; 1365 iwp_rx_data_t *data; 1366 #ifdef DEBUG 1367 iwp_dma_t *dma_p; 1368 #endif 1369 int i, err = DDI_FAILURE; 1370 1371 ring = &sc->sc_rxq; 1372 ring->cur = 0; 1373 1374 /* 1375 * allocate RX description ring buffer 1376 */ 1377 err = iwp_alloc_dma_mem(sc, RX_QUEUE_SIZE * sizeof (uint32_t), 1378 &ring_desc_dma_attr, &iwp_dma_descattr, 1379 DDI_DMA_RDWR | DDI_DMA_CONSISTENT, 1380 &ring->dma_desc); 1381 if (err != DDI_SUCCESS) { 1382 IWP_DBG((IWP_DEBUG_DMA, "iwp_alloc_rx_ring(): " 1383 "dma alloc rx ring desc " 1384 "failed\n")); 1385 goto fail; 1386 } 1387 1388 ring->desc = (uint32_t *)ring->dma_desc.mem_va; 1389 #ifdef DEBUG 1390 dma_p = &ring->dma_desc; 1391 #endif 1392 IWP_DBG((IWP_DEBUG_DMA, "iwp_alloc_rx_ring(): " 1393 "rx bd[ncookies:%d addr:%lx size:%lx]\n", 1394 dma_p->ncookies, dma_p->cookie.dmac_address, 1395 dma_p->cookie.dmac_size)); 1396 1397 /* 1398 * Allocate Rx frame buffers. 1399 */ 1400 for (i = 0; i < RX_QUEUE_SIZE; i++) { 1401 data = &ring->data[i]; 1402 err = iwp_alloc_dma_mem(sc, sc->sc_dmabuf_sz, 1403 &rx_buffer_dma_attr, &iwp_dma_accattr, 1404 DDI_DMA_READ | DDI_DMA_STREAMING, 1405 &data->dma_data); 1406 if (err != DDI_SUCCESS) { 1407 IWP_DBG((IWP_DEBUG_DMA, "iwp_alloc_rx_ring(): " 1408 "dma alloc rx ring " 1409 "buf[%d] failed\n", i)); 1410 goto fail; 1411 } 1412 /* 1413 * the physical address bit [8-36] are used, 1414 * instead of bit [0-31] in 3945. 1415 */ 1416 ring->desc[i] = (uint32_t) 1417 (data->dma_data.cookie.dmac_address >> 8); 1418 } 1419 1420 #ifdef DEBUG 1421 dma_p = &ring->data[0].dma_data; 1422 #endif 1423 IWP_DBG((IWP_DEBUG_DMA, "iwp_alloc_rx_ring(): " 1424 "rx buffer[0][ncookies:%d addr:%lx " 1425 "size:%lx]\n", 1426 dma_p->ncookies, dma_p->cookie.dmac_address, 1427 dma_p->cookie.dmac_size)); 1428 1429 IWP_DMA_SYNC(ring->dma_desc, DDI_DMA_SYNC_FORDEV); 1430 1431 return (err); 1432 1433 fail: 1434 iwp_free_rx_ring(sc); 1435 return (err); 1436 } 1437 1438 /* 1439 * disable RX ring 1440 */ 1441 static void 1442 iwp_reset_rx_ring(iwp_sc_t *sc) 1443 { 1444 int n; 1445 1446 iwp_mac_access_enter(sc); 1447 IWP_WRITE(sc, FH_MEM_RCSR_CHNL0_CONFIG_REG, 0); 1448 for (n = 0; n < 2000; n++) { 1449 if (IWP_READ(sc, FH_MEM_RSSR_RX_STATUS_REG) & (1 << 24)) { 1450 break; 1451 } 1452 DELAY(1000); 1453 } 1454 #ifdef DEBUG 1455 if (2000 == n) { 1456 IWP_DBG((IWP_DEBUG_DMA, "iwp_reset_rx_ring(): " 1457 "timeout resetting Rx ring\n")); 1458 } 1459 #endif 1460 iwp_mac_access_exit(sc); 1461 1462 sc->sc_rxq.cur = 0; 1463 } 1464 1465 static void 1466 iwp_free_rx_ring(iwp_sc_t *sc) 1467 { 1468 int i; 1469 1470 for (i = 0; i < RX_QUEUE_SIZE; i++) { 1471 if (sc->sc_rxq.data[i].dma_data.dma_hdl) { 1472 IWP_DMA_SYNC(sc->sc_rxq.data[i].dma_data, 1473 DDI_DMA_SYNC_FORCPU); 1474 } 1475 1476 iwp_free_dma_mem(&sc->sc_rxq.data[i].dma_data); 1477 } 1478 1479 if (sc->sc_rxq.dma_desc.dma_hdl) { 1480 IWP_DMA_SYNC(sc->sc_rxq.dma_desc, DDI_DMA_SYNC_FORDEV); 1481 } 1482 1483 iwp_free_dma_mem(&sc->sc_rxq.dma_desc); 1484 } 1485 1486 /* 1487 * initialize TX ring buffers 1488 */ 1489 static int 1490 iwp_alloc_tx_ring(iwp_sc_t *sc, iwp_tx_ring_t *ring, 1491 int slots, int qid) 1492 { 1493 iwp_tx_data_t *data; 1494 iwp_tx_desc_t *desc_h; 1495 uint32_t paddr_desc_h; 1496 iwp_cmd_t *cmd_h; 1497 uint32_t paddr_cmd_h; 1498 #ifdef DEBUG 1499 iwp_dma_t *dma_p; 1500 #endif 1501 int i, err = DDI_FAILURE; 1502 ring->qid = qid; 1503 ring->count = TFD_QUEUE_SIZE_MAX; 1504 ring->window = slots; 1505 ring->queued = 0; 1506 ring->cur = 0; 1507 ring->desc_cur = 0; 1508 1509 /* 1510 * allocate buffer for TX descriptor ring 1511 */ 1512 err = iwp_alloc_dma_mem(sc, 1513 TFD_QUEUE_SIZE_MAX * sizeof (iwp_tx_desc_t), 1514 &ring_desc_dma_attr, &iwp_dma_descattr, 1515 DDI_DMA_RDWR | DDI_DMA_CONSISTENT, 1516 &ring->dma_desc); 1517 if (err != DDI_SUCCESS) { 1518 IWP_DBG((IWP_DEBUG_DMA, "iwp_alloc_tx_ring(): " 1519 "dma alloc tx ring desc[%d] " 1520 "failed\n", qid)); 1521 goto fail; 1522 } 1523 1524 #ifdef DEBUG 1525 dma_p = &ring->dma_desc; 1526 #endif 1527 IWP_DBG((IWP_DEBUG_DMA, "iwp_alloc_tx_ring(): " 1528 "tx bd[ncookies:%d addr:%lx size:%lx]\n", 1529 dma_p->ncookies, dma_p->cookie.dmac_address, 1530 dma_p->cookie.dmac_size)); 1531 1532 desc_h = (iwp_tx_desc_t *)ring->dma_desc.mem_va; 1533 paddr_desc_h = ring->dma_desc.cookie.dmac_address; 1534 1535 /* 1536 * allocate buffer for ucode command 1537 */ 1538 err = iwp_alloc_dma_mem(sc, 1539 TFD_QUEUE_SIZE_MAX * sizeof (iwp_cmd_t), 1540 &cmd_dma_attr, &iwp_dma_accattr, 1541 DDI_DMA_RDWR | DDI_DMA_CONSISTENT, 1542 &ring->dma_cmd); 1543 if (err != DDI_SUCCESS) { 1544 IWP_DBG((IWP_DEBUG_DMA, "iwp_alloc_tx_ring(): " 1545 "dma alloc tx ring cmd[%d]" 1546 " failed\n", qid)); 1547 goto fail; 1548 } 1549 1550 #ifdef DEBUG 1551 dma_p = &ring->dma_cmd; 1552 #endif 1553 IWP_DBG((IWP_DEBUG_DMA, "iwp_alloc_tx_ring(): " 1554 "tx cmd[ncookies:%d addr:%lx size:%lx]\n", 1555 dma_p->ncookies, dma_p->cookie.dmac_address, 1556 dma_p->cookie.dmac_size)); 1557 1558 cmd_h = (iwp_cmd_t *)ring->dma_cmd.mem_va; 1559 paddr_cmd_h = ring->dma_cmd.cookie.dmac_address; 1560 1561 /* 1562 * Allocate Tx frame buffers. 1563 */ 1564 ring->data = kmem_zalloc(sizeof (iwp_tx_data_t) * TFD_QUEUE_SIZE_MAX, 1565 KM_NOSLEEP); 1566 if (NULL == ring->data) { 1567 IWP_DBG((IWP_DEBUG_DMA, "iwp_alloc_tx_ring(): " 1568 "could not allocate " 1569 "tx data slots\n")); 1570 goto fail; 1571 } 1572 1573 for (i = 0; i < TFD_QUEUE_SIZE_MAX; i++) { 1574 data = &ring->data[i]; 1575 err = iwp_alloc_dma_mem(sc, sc->sc_dmabuf_sz, 1576 &tx_buffer_dma_attr, &iwp_dma_accattr, 1577 DDI_DMA_WRITE | DDI_DMA_STREAMING, 1578 &data->dma_data); 1579 if (err != DDI_SUCCESS) { 1580 IWP_DBG((IWP_DEBUG_DMA, "iwp_alloc_tx_ring(): " 1581 "dma alloc tx " 1582 "ring buf[%d] failed\n", i)); 1583 goto fail; 1584 } 1585 1586 data->desc = desc_h + i; 1587 data->paddr_desc = paddr_desc_h + 1588 _PTRDIFF(data->desc, desc_h); 1589 data->cmd = cmd_h + i; 1590 data->paddr_cmd = paddr_cmd_h + 1591 _PTRDIFF(data->cmd, cmd_h); 1592 } 1593 #ifdef DEBUG 1594 dma_p = &ring->data[0].dma_data; 1595 #endif 1596 IWP_DBG((IWP_DEBUG_DMA, "iwp_alloc_tx_ring(): " 1597 "tx buffer[0][ncookies:%d addr:%lx " 1598 "size:%lx]\n", 1599 dma_p->ncookies, dma_p->cookie.dmac_address, 1600 dma_p->cookie.dmac_size)); 1601 1602 return (err); 1603 1604 fail: 1605 iwp_free_tx_ring(ring); 1606 1607 return (err); 1608 } 1609 1610 /* 1611 * disable TX ring 1612 */ 1613 static void 1614 iwp_reset_tx_ring(iwp_sc_t *sc, iwp_tx_ring_t *ring) 1615 { 1616 iwp_tx_data_t *data; 1617 int i, n; 1618 1619 iwp_mac_access_enter(sc); 1620 1621 IWP_WRITE(sc, IWP_FH_TCSR_CHNL_TX_CONFIG_REG(ring->qid), 0); 1622 for (n = 0; n < 200; n++) { 1623 if (IWP_READ(sc, IWP_FH_TSSR_TX_STATUS_REG) & 1624 IWP_FH_TSSR_TX_STATUS_REG_MSK_CHNL_IDLE(ring->qid)) { 1625 break; 1626 } 1627 DELAY(10); 1628 } 1629 1630 #ifdef DEBUG 1631 if (200 == n) { 1632 IWP_DBG((IWP_DEBUG_DMA, "iwp_reset_tx_ring(): " 1633 "timeout reset tx ring %d\n", 1634 ring->qid)); 1635 } 1636 #endif 1637 1638 iwp_mac_access_exit(sc); 1639 1640 /* by pass, if it's quiesce */ 1641 if (!(sc->sc_flags & IWP_F_QUIESCED)) { 1642 for (i = 0; i < ring->count; i++) { 1643 data = &ring->data[i]; 1644 IWP_DMA_SYNC(data->dma_data, DDI_DMA_SYNC_FORDEV); 1645 } 1646 } 1647 1648 ring->queued = 0; 1649 ring->cur = 0; 1650 ring->desc_cur = 0; 1651 } 1652 1653 static void 1654 iwp_free_tx_ring(iwp_tx_ring_t *ring) 1655 { 1656 int i; 1657 1658 if (ring->dma_desc.dma_hdl != NULL) { 1659 IWP_DMA_SYNC(ring->dma_desc, DDI_DMA_SYNC_FORDEV); 1660 } 1661 iwp_free_dma_mem(&ring->dma_desc); 1662 1663 if (ring->dma_cmd.dma_hdl != NULL) { 1664 IWP_DMA_SYNC(ring->dma_cmd, DDI_DMA_SYNC_FORDEV); 1665 } 1666 iwp_free_dma_mem(&ring->dma_cmd); 1667 1668 if (ring->data != NULL) { 1669 for (i = 0; i < ring->count; i++) { 1670 if (ring->data[i].dma_data.dma_hdl) { 1671 IWP_DMA_SYNC(ring->data[i].dma_data, 1672 DDI_DMA_SYNC_FORDEV); 1673 } 1674 iwp_free_dma_mem(&ring->data[i].dma_data); 1675 } 1676 kmem_free(ring->data, ring->count * sizeof (iwp_tx_data_t)); 1677 } 1678 } 1679 1680 /* 1681 * initialize TX and RX ring 1682 */ 1683 static int 1684 iwp_ring_init(iwp_sc_t *sc) 1685 { 1686 int i, err = DDI_FAILURE; 1687 1688 for (i = 0; i < IWP_NUM_QUEUES; i++) { 1689 if (IWP_CMD_QUEUE_NUM == i) { 1690 continue; 1691 } 1692 1693 err = iwp_alloc_tx_ring(sc, &sc->sc_txq[i], TFD_TX_CMD_SLOTS, 1694 i); 1695 if (err != DDI_SUCCESS) { 1696 goto fail; 1697 } 1698 } 1699 1700 /* 1701 * initialize command queue 1702 */ 1703 err = iwp_alloc_tx_ring(sc, &sc->sc_txq[IWP_CMD_QUEUE_NUM], 1704 TFD_CMD_SLOTS, IWP_CMD_QUEUE_NUM); 1705 if (err != DDI_SUCCESS) { 1706 goto fail; 1707 } 1708 1709 err = iwp_alloc_rx_ring(sc); 1710 if (err != DDI_SUCCESS) { 1711 goto fail; 1712 } 1713 1714 fail: 1715 return (err); 1716 } 1717 1718 static void 1719 iwp_ring_free(iwp_sc_t *sc) 1720 { 1721 int i = IWP_NUM_QUEUES; 1722 1723 iwp_free_rx_ring(sc); 1724 while (--i >= 0) { 1725 iwp_free_tx_ring(&sc->sc_txq[i]); 1726 } 1727 } 1728 1729 /* ARGSUSED */ 1730 static ieee80211_node_t * 1731 iwp_node_alloc(ieee80211com_t *ic) 1732 { 1733 iwp_amrr_t *amrr; 1734 1735 amrr = kmem_zalloc(sizeof (iwp_amrr_t), KM_SLEEP); 1736 if (NULL == amrr) { 1737 cmn_err(CE_WARN, "iwp_node_alloc(): " 1738 "failed to allocate memory for amrr structure\n"); 1739 return (NULL); 1740 } 1741 1742 iwp_amrr_init(amrr); 1743 1744 return (&amrr->in); 1745 } 1746 1747 static void 1748 iwp_node_free(ieee80211_node_t *in) 1749 { 1750 ieee80211com_t *ic; 1751 1752 if ((NULL == in) || 1753 (NULL == in->in_ic)) { 1754 cmn_err(CE_WARN, "iwp_node_free() " 1755 "Got a NULL point from Net80211 module\n"); 1756 return; 1757 } 1758 ic = in->in_ic; 1759 1760 if (ic->ic_node_cleanup != NULL) { 1761 ic->ic_node_cleanup(in); 1762 } 1763 1764 if (in->in_wpa_ie != NULL) { 1765 ieee80211_free(in->in_wpa_ie); 1766 } 1767 1768 if (in->in_wme_ie != NULL) { 1769 ieee80211_free(in->in_wme_ie); 1770 } 1771 1772 if (in->in_htcap_ie != NULL) { 1773 ieee80211_free(in->in_htcap_ie); 1774 } 1775 1776 kmem_free(in, sizeof (iwp_amrr_t)); 1777 } 1778 1779 1780 /* 1781 * change station's state. this function will be invoked by 80211 module 1782 * when need to change staton's state. 1783 */ 1784 static int 1785 iwp_newstate(ieee80211com_t *ic, enum ieee80211_state nstate, int arg) 1786 { 1787 iwp_sc_t *sc; 1788 ieee80211_node_t *in; 1789 enum ieee80211_state ostate; 1790 iwp_add_sta_t node; 1791 int i, err = IWP_FAIL; 1792 1793 if (NULL == ic) { 1794 return (err); 1795 } 1796 sc = (iwp_sc_t *)ic; 1797 in = ic->ic_bss; 1798 ostate = ic->ic_state; 1799 1800 mutex_enter(&sc->sc_glock); 1801 1802 switch (nstate) { 1803 case IEEE80211_S_SCAN: 1804 switch (ostate) { 1805 case IEEE80211_S_INIT: 1806 atomic_or_32(&sc->sc_flags, IWP_F_SCANNING); 1807 iwp_set_led(sc, 2, 10, 2); 1808 1809 /* 1810 * clear association to receive beacons from 1811 * all BSS'es 1812 */ 1813 sc->sc_config.assoc_id = 0; 1814 sc->sc_config.filter_flags &= 1815 ~LE_32(RXON_FILTER_ASSOC_MSK); 1816 1817 IWP_DBG((IWP_DEBUG_80211, "iwp_newstate(): " 1818 "config chan %d " 1819 "flags %x filter_flags %x\n", 1820 LE_16(sc->sc_config.chan), 1821 LE_32(sc->sc_config.flags), 1822 LE_32(sc->sc_config.filter_flags))); 1823 1824 err = iwp_cmd(sc, REPLY_RXON, &sc->sc_config, 1825 sizeof (iwp_rxon_cmd_t), 1); 1826 if (err != IWP_SUCCESS) { 1827 cmn_err(CE_WARN, "iwp_newstate(): " 1828 "could not clear association\n"); 1829 atomic_and_32(&sc->sc_flags, ~IWP_F_SCANNING); 1830 mutex_exit(&sc->sc_glock); 1831 return (err); 1832 } 1833 1834 /* add broadcast node to send probe request */ 1835 (void) memset(&node, 0, sizeof (node)); 1836 (void) memset(&node.sta.addr, 0xff, IEEE80211_ADDR_LEN); 1837 node.sta.sta_id = IWP_BROADCAST_ID; 1838 err = iwp_cmd(sc, REPLY_ADD_STA, &node, 1839 sizeof (node), 1); 1840 if (err != IWP_SUCCESS) { 1841 cmn_err(CE_WARN, "iwp_newstate(): " 1842 "could not add broadcast node\n"); 1843 atomic_and_32(&sc->sc_flags, ~IWP_F_SCANNING); 1844 mutex_exit(&sc->sc_glock); 1845 return (err); 1846 } 1847 break; 1848 case IEEE80211_S_SCAN: 1849 mutex_exit(&sc->sc_glock); 1850 /* step to next channel before actual FW scan */ 1851 err = sc->sc_newstate(ic, nstate, arg); 1852 mutex_enter(&sc->sc_glock); 1853 if ((err != 0) || ((err = iwp_scan(sc)) != 0)) { 1854 cmn_err(CE_WARN, "iwp_newstate(): " 1855 "could not initiate scan\n"); 1856 atomic_and_32(&sc->sc_flags, ~IWP_F_SCANNING); 1857 ieee80211_cancel_scan(ic); 1858 } 1859 mutex_exit(&sc->sc_glock); 1860 return (err); 1861 default: 1862 break; 1863 } 1864 sc->sc_clk = 0; 1865 break; 1866 1867 case IEEE80211_S_AUTH: 1868 if (ostate == IEEE80211_S_SCAN) { 1869 atomic_and_32(&sc->sc_flags, ~IWP_F_SCANNING); 1870 } 1871 1872 /* 1873 * reset state to handle reassociations correctly 1874 */ 1875 sc->sc_config.assoc_id = 0; 1876 sc->sc_config.filter_flags &= ~LE_32(RXON_FILTER_ASSOC_MSK); 1877 1878 /* 1879 * before sending authentication and association request frame, 1880 * we need do something in the hardware, such as setting the 1881 * channel same to the target AP... 1882 */ 1883 if ((err = iwp_hw_set_before_auth(sc)) != 0) { 1884 IWP_DBG((IWP_DEBUG_80211, "iwp_newstate(): " 1885 "could not send authentication request\n")); 1886 mutex_exit(&sc->sc_glock); 1887 return (err); 1888 } 1889 break; 1890 1891 case IEEE80211_S_RUN: 1892 if (ostate == IEEE80211_S_SCAN) { 1893 atomic_and_32(&sc->sc_flags, ~IWP_F_SCANNING); 1894 } 1895 1896 if (IEEE80211_M_MONITOR == ic->ic_opmode) { 1897 /* let LED blink when monitoring */ 1898 iwp_set_led(sc, 2, 10, 10); 1899 break; 1900 } 1901 1902 IWP_DBG((IWP_DEBUG_80211, "iwp_newstate(): " 1903 "associated.\n")); 1904 1905 err = iwp_run_state_config(sc); 1906 if (err != IWP_SUCCESS) { 1907 cmn_err(CE_WARN, "iwp_newstate(): " 1908 "failed to set up association\n"); 1909 mutex_exit(&sc->sc_glock); 1910 return (err); 1911 } 1912 1913 /* 1914 * start automatic rate control 1915 */ 1916 if (IEEE80211_FIXED_RATE_NONE == ic->ic_fixed_rate) { 1917 atomic_or_32(&sc->sc_flags, IWP_F_RATE_AUTO_CTL); 1918 1919 /* 1920 * set rate to some reasonable initial value 1921 */ 1922 i = in->in_rates.ir_nrates - 1; 1923 while (i > 0 && IEEE80211_RATE(i) > 72) { 1924 i--; 1925 } 1926 in->in_txrate = i; 1927 1928 } else { 1929 atomic_and_32(&sc->sc_flags, ~IWP_F_RATE_AUTO_CTL); 1930 } 1931 1932 /* 1933 * set LED on after associated 1934 */ 1935 iwp_set_led(sc, 2, 0, 1); 1936 break; 1937 1938 case IEEE80211_S_INIT: 1939 if (ostate == IEEE80211_S_SCAN) { 1940 atomic_and_32(&sc->sc_flags, ~IWP_F_SCANNING); 1941 } 1942 /* 1943 * set LED off after init 1944 */ 1945 iwp_set_led(sc, 2, 1, 0); 1946 break; 1947 1948 case IEEE80211_S_ASSOC: 1949 if (ostate == IEEE80211_S_SCAN) { 1950 atomic_and_32(&sc->sc_flags, ~IWP_F_SCANNING); 1951 } 1952 break; 1953 } 1954 1955 mutex_exit(&sc->sc_glock); 1956 1957 return (sc->sc_newstate(ic, nstate, arg)); 1958 } 1959 1960 /* 1961 * exclusive access to mac begin. 1962 */ 1963 static void 1964 iwp_mac_access_enter(iwp_sc_t *sc) 1965 { 1966 uint32_t tmp; 1967 int n; 1968 1969 tmp = IWP_READ(sc, CSR_GP_CNTRL); 1970 IWP_WRITE(sc, CSR_GP_CNTRL, 1971 tmp | CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); 1972 1973 /* wait until we succeed */ 1974 for (n = 0; n < 1000; n++) { 1975 if ((IWP_READ(sc, CSR_GP_CNTRL) & 1976 (CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY | 1977 CSR_GP_CNTRL_REG_FLAG_GOING_TO_SLEEP)) == 1978 CSR_GP_CNTRL_REG_VAL_MAC_ACCESS_EN) { 1979 break; 1980 } 1981 DELAY(10); 1982 } 1983 1984 #ifdef DEBUG 1985 if (1000 == n) { 1986 IWP_DBG((IWP_DEBUG_PIO, "iwp_mac_access_enter(): " 1987 "could not lock memory\n")); 1988 } 1989 #endif 1990 } 1991 1992 /* 1993 * exclusive access to mac end. 1994 */ 1995 static void 1996 iwp_mac_access_exit(iwp_sc_t *sc) 1997 { 1998 uint32_t tmp = IWP_READ(sc, CSR_GP_CNTRL); 1999 IWP_WRITE(sc, CSR_GP_CNTRL, 2000 tmp & ~CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); 2001 } 2002 2003 /* 2004 * this function defined here for future use. 2005 * static uint32_t 2006 * iwp_mem_read(iwp_sc_t *sc, uint32_t addr) 2007 * { 2008 * IWP_WRITE(sc, HBUS_TARG_MEM_RADDR, addr); 2009 * return (IWP_READ(sc, HBUS_TARG_MEM_RDAT)); 2010 * } 2011 */ 2012 2013 /* 2014 * write mac memory 2015 */ 2016 static void 2017 iwp_mem_write(iwp_sc_t *sc, uint32_t addr, uint32_t data) 2018 { 2019 IWP_WRITE(sc, HBUS_TARG_MEM_WADDR, addr); 2020 IWP_WRITE(sc, HBUS_TARG_MEM_WDAT, data); 2021 } 2022 2023 /* 2024 * read mac register 2025 */ 2026 static uint32_t 2027 iwp_reg_read(iwp_sc_t *sc, uint32_t addr) 2028 { 2029 IWP_WRITE(sc, HBUS_TARG_PRPH_RADDR, addr | (3 << 24)); 2030 return (IWP_READ(sc, HBUS_TARG_PRPH_RDAT)); 2031 } 2032 2033 /* 2034 * write mac register 2035 */ 2036 static void 2037 iwp_reg_write(iwp_sc_t *sc, uint32_t addr, uint32_t data) 2038 { 2039 IWP_WRITE(sc, HBUS_TARG_PRPH_WADDR, addr | (3 << 24)); 2040 IWP_WRITE(sc, HBUS_TARG_PRPH_WDAT, data); 2041 } 2042 2043 2044 /* 2045 * steps of loading ucode: 2046 * load init ucode=>init alive=>calibrate=> 2047 * receive calibration result=>reinitialize NIC=> 2048 * load runtime ucode=>runtime alive=> 2049 * send calibration result=>running. 2050 */ 2051 static int 2052 iwp_load_init_firmware(iwp_sc_t *sc) 2053 { 2054 int err = IWP_FAIL; 2055 clock_t clk; 2056 2057 atomic_and_32(&sc->sc_flags, ~IWP_F_PUT_SEG); 2058 2059 /* 2060 * load init_text section of uCode to hardware 2061 */ 2062 err = iwp_put_seg_fw(sc, sc->sc_dma_fw_init_text.cookie.dmac_address, 2063 RTC_INST_LOWER_BOUND, sc->sc_dma_fw_init_text.cookie.dmac_size); 2064 if (err != IWP_SUCCESS) { 2065 cmn_err(CE_WARN, "iwp_load_init_firmware(): " 2066 "failed to write init uCode.\n"); 2067 return (err); 2068 } 2069 2070 clk = ddi_get_lbolt() + drv_usectohz(1000000); 2071 2072 /* wait loading init_text until completed or timeout */ 2073 while (!(sc->sc_flags & IWP_F_PUT_SEG)) { 2074 if (cv_timedwait(&sc->sc_put_seg_cv, &sc->sc_glock, clk) < 0) { 2075 break; 2076 } 2077 } 2078 2079 if (!(sc->sc_flags & IWP_F_PUT_SEG)) { 2080 cmn_err(CE_WARN, "iwp_load_init_firmware(): " 2081 "timeout waiting for init uCode load.\n"); 2082 return (IWP_FAIL); 2083 } 2084 2085 atomic_and_32(&sc->sc_flags, ~IWP_F_PUT_SEG); 2086 2087 /* 2088 * load init_data section of uCode to hardware 2089 */ 2090 err = iwp_put_seg_fw(sc, sc->sc_dma_fw_init_data.cookie.dmac_address, 2091 RTC_DATA_LOWER_BOUND, sc->sc_dma_fw_init_data.cookie.dmac_size); 2092 if (err != IWP_SUCCESS) { 2093 cmn_err(CE_WARN, "iwp_load_init_firmware(): " 2094 "failed to write init_data uCode.\n"); 2095 return (err); 2096 } 2097 2098 clk = ddi_get_lbolt() + drv_usectohz(1000000); 2099 2100 /* 2101 * wait loading init_data until completed or timeout 2102 */ 2103 while (!(sc->sc_flags & IWP_F_PUT_SEG)) { 2104 if (cv_timedwait(&sc->sc_put_seg_cv, &sc->sc_glock, clk) < 0) { 2105 break; 2106 } 2107 } 2108 2109 if (!(sc->sc_flags & IWP_F_PUT_SEG)) { 2110 cmn_err(CE_WARN, "iwp_load_init_firmware(): " 2111 "timeout waiting for init_data uCode load.\n"); 2112 return (IWP_FAIL); 2113 } 2114 2115 atomic_and_32(&sc->sc_flags, ~IWP_F_PUT_SEG); 2116 2117 return (err); 2118 } 2119 2120 static int 2121 iwp_load_run_firmware(iwp_sc_t *sc) 2122 { 2123 int err = IWP_FAIL; 2124 clock_t clk; 2125 2126 atomic_and_32(&sc->sc_flags, ~IWP_F_PUT_SEG); 2127 2128 /* 2129 * load init_text section of uCode to hardware 2130 */ 2131 err = iwp_put_seg_fw(sc, sc->sc_dma_fw_text.cookie.dmac_address, 2132 RTC_INST_LOWER_BOUND, sc->sc_dma_fw_text.cookie.dmac_size); 2133 if (err != IWP_SUCCESS) { 2134 cmn_err(CE_WARN, "iwp_load_run_firmware(): " 2135 "failed to write run uCode.\n"); 2136 return (err); 2137 } 2138 2139 clk = ddi_get_lbolt() + drv_usectohz(1000000); 2140 2141 /* wait loading run_text until completed or timeout */ 2142 while (!(sc->sc_flags & IWP_F_PUT_SEG)) { 2143 if (cv_timedwait(&sc->sc_put_seg_cv, &sc->sc_glock, clk) < 0) { 2144 break; 2145 } 2146 } 2147 2148 if (!(sc->sc_flags & IWP_F_PUT_SEG)) { 2149 cmn_err(CE_WARN, "iwp_load_run_firmware(): " 2150 "timeout waiting for run uCode load.\n"); 2151 return (IWP_FAIL); 2152 } 2153 2154 atomic_and_32(&sc->sc_flags, ~IWP_F_PUT_SEG); 2155 2156 /* 2157 * load run_data section of uCode to hardware 2158 */ 2159 err = iwp_put_seg_fw(sc, sc->sc_dma_fw_data_bak.cookie.dmac_address, 2160 RTC_DATA_LOWER_BOUND, sc->sc_dma_fw_data.cookie.dmac_size); 2161 if (err != IWP_SUCCESS) { 2162 cmn_err(CE_WARN, "iwp_load_run_firmware(): " 2163 "failed to write run_data uCode.\n"); 2164 return (err); 2165 } 2166 2167 clk = ddi_get_lbolt() + drv_usectohz(1000000); 2168 2169 /* 2170 * wait loading run_data until completed or timeout 2171 */ 2172 while (!(sc->sc_flags & IWP_F_PUT_SEG)) { 2173 if (cv_timedwait(&sc->sc_put_seg_cv, &sc->sc_glock, clk) < 0) { 2174 break; 2175 } 2176 } 2177 2178 if (!(sc->sc_flags & IWP_F_PUT_SEG)) { 2179 cmn_err(CE_WARN, "iwp_load_run_firmware(): " 2180 "timeout waiting for run_data uCode load.\n"); 2181 return (IWP_FAIL); 2182 } 2183 2184 atomic_and_32(&sc->sc_flags, ~IWP_F_PUT_SEG); 2185 2186 return (err); 2187 } 2188 2189 /* 2190 * this function will be invoked to receive phy information 2191 * when a frame is received. 2192 */ 2193 static void 2194 iwp_rx_phy_intr(iwp_sc_t *sc, iwp_rx_desc_t *desc) 2195 { 2196 2197 sc->sc_rx_phy_res.flag = 1; 2198 2199 (void) memcpy(sc->sc_rx_phy_res.buf, (uint8_t *)(desc + 1), 2200 sizeof (iwp_rx_phy_res_t)); 2201 } 2202 2203 /* 2204 * this function will be invoked to receive body of frame when 2205 * a frame is received. 2206 */ 2207 static void 2208 iwp_rx_mpdu_intr(iwp_sc_t *sc, iwp_rx_desc_t *desc) 2209 { 2210 ieee80211com_t *ic = &sc->sc_ic; 2211 #ifdef DEBUG 2212 iwp_rx_ring_t *ring = &sc->sc_rxq; 2213 #endif 2214 struct ieee80211_frame *wh; 2215 struct iwp_rx_non_cfg_phy *phyinfo; 2216 struct iwp_rx_mpdu_body_size *mpdu_size; 2217 2218 mblk_t *mp; 2219 int16_t t; 2220 uint16_t len, rssi, agc; 2221 uint32_t temp, crc, *tail; 2222 uint32_t arssi, brssi, crssi, mrssi; 2223 iwp_rx_phy_res_t *stat; 2224 ieee80211_node_t *in; 2225 2226 /* 2227 * assuming not 11n here. cope with 11n in phase-II 2228 */ 2229 mpdu_size = (struct iwp_rx_mpdu_body_size *)(desc + 1); 2230 stat = (iwp_rx_phy_res_t *)sc->sc_rx_phy_res.buf; 2231 if (stat->cfg_phy_cnt > 20) { 2232 return; 2233 } 2234 2235 phyinfo = (struct iwp_rx_non_cfg_phy *)stat->non_cfg_phy; 2236 temp = LE_32(phyinfo->non_cfg_phy[IWP_RX_RES_AGC_IDX]); 2237 agc = (temp & IWP_OFDM_AGC_MSK) >> IWP_OFDM_AGC_BIT_POS; 2238 2239 temp = LE_32(phyinfo->non_cfg_phy[IWP_RX_RES_RSSI_AB_IDX]); 2240 arssi = (temp & IWP_OFDM_RSSI_A_MSK) >> IWP_OFDM_RSSI_A_BIT_POS; 2241 brssi = (temp & IWP_OFDM_RSSI_B_MSK) >> IWP_OFDM_RSSI_B_BIT_POS; 2242 2243 temp = LE_32(phyinfo->non_cfg_phy[IWP_RX_RES_RSSI_C_IDX]); 2244 crssi = (temp & IWP_OFDM_RSSI_C_MSK) >> IWP_OFDM_RSSI_C_BIT_POS; 2245 2246 mrssi = MAX(arssi, brssi); 2247 mrssi = MAX(mrssi, crssi); 2248 2249 t = mrssi - agc - IWP_RSSI_OFFSET; 2250 /* 2251 * convert dBm to percentage 2252 */ 2253 rssi = (100 * 75 * 75 - (-20 - t) * (15 * 75 + 62 * (-20 - t))) 2254 / (75 * 75); 2255 if (rssi > 100) { 2256 rssi = 100; 2257 } 2258 if (rssi < 1) { 2259 rssi = 1; 2260 } 2261 2262 /* 2263 * size of frame, not include FCS 2264 */ 2265 len = LE_16(mpdu_size->byte_count); 2266 tail = (uint32_t *)((uint8_t *)(desc + 1) + 2267 sizeof (struct iwp_rx_mpdu_body_size) + len); 2268 bcopy(tail, &crc, 4); 2269 2270 IWP_DBG((IWP_DEBUG_RX, "iwp_rx_mpdu_intr(): " 2271 "rx intr: idx=%d phy_len=%x len=%d " 2272 "rate=%x chan=%d tstamp=%x non_cfg_phy_count=%x " 2273 "cfg_phy_count=%x tail=%x", ring->cur, sizeof (*stat), 2274 len, stat->rate.r.s.rate, stat->channel, 2275 LE_32(stat->timestampl), stat->non_cfg_phy_cnt, 2276 stat->cfg_phy_cnt, LE_32(crc))); 2277 2278 if ((len < 16) || (len > sc->sc_dmabuf_sz)) { 2279 IWP_DBG((IWP_DEBUG_RX, "iwp_rx_mpdu_intr(): " 2280 "rx frame oversize\n")); 2281 return; 2282 } 2283 2284 /* 2285 * discard Rx frames with bad CRC 2286 */ 2287 if ((LE_32(crc) & 2288 (RX_RES_STATUS_NO_CRC32_ERROR | RX_RES_STATUS_NO_RXE_OVERFLOW)) != 2289 (RX_RES_STATUS_NO_CRC32_ERROR | RX_RES_STATUS_NO_RXE_OVERFLOW)) { 2290 IWP_DBG((IWP_DEBUG_RX, "iwp_rx_mpdu_intr(): " 2291 "rx crc error tail: %x\n", 2292 LE_32(crc))); 2293 sc->sc_rx_err++; 2294 return; 2295 } 2296 2297 wh = (struct ieee80211_frame *) 2298 ((uint8_t *)(desc + 1)+ sizeof (struct iwp_rx_mpdu_body_size)); 2299 2300 if (IEEE80211_FC0_SUBTYPE_ASSOC_RESP == *(uint8_t *)wh) { 2301 sc->sc_assoc_id = *((uint16_t *)(wh + 1) + 2); 2302 IWP_DBG((IWP_DEBUG_RX, "iwp_rx_mpdu_intr(): " 2303 "rx : association id = %x\n", 2304 sc->sc_assoc_id)); 2305 } 2306 2307 #ifdef DEBUG 2308 if (iwp_dbg_flags & IWP_DEBUG_RX) { 2309 ieee80211_dump_pkt((uint8_t *)wh, len, 0, 0); 2310 } 2311 #endif 2312 2313 in = ieee80211_find_rxnode(ic, wh); 2314 mp = allocb(len, BPRI_MED); 2315 if (mp) { 2316 (void) memcpy(mp->b_wptr, wh, len); 2317 mp->b_wptr += len; 2318 2319 /* 2320 * send the frame to the 802.11 layer 2321 */ 2322 (void) ieee80211_input(ic, mp, in, rssi, 0); 2323 } else { 2324 sc->sc_rx_nobuf++; 2325 IWP_DBG((IWP_DEBUG_RX, "iwp_rx_mpdu_intr(): " 2326 "alloc rx buf failed\n")); 2327 } 2328 2329 /* 2330 * release node reference 2331 */ 2332 ieee80211_free_node(in); 2333 } 2334 2335 /* 2336 * process correlative affairs after a frame is sent. 2337 */ 2338 static void 2339 iwp_tx_intr(iwp_sc_t *sc, iwp_rx_desc_t *desc) 2340 { 2341 ieee80211com_t *ic = &sc->sc_ic; 2342 iwp_tx_ring_t *ring = &sc->sc_txq[desc->hdr.qid & 0x3]; 2343 iwp_tx_stat_t *stat = (iwp_tx_stat_t *)(desc + 1); 2344 iwp_amrr_t *amrr; 2345 2346 if (NULL == ic->ic_bss) { 2347 return; 2348 } 2349 2350 amrr = (iwp_amrr_t *)ic->ic_bss; 2351 2352 amrr->txcnt++; 2353 IWP_DBG((IWP_DEBUG_RATECTL, "iwp_tx_intr(): " 2354 "tx: %d cnt\n", amrr->txcnt)); 2355 2356 if (stat->ntries > 0) { 2357 amrr->retrycnt++; 2358 sc->sc_tx_retries++; 2359 IWP_DBG((IWP_DEBUG_TX, "iwp_tx_intr(): " 2360 "tx: %d retries\n", 2361 sc->sc_tx_retries)); 2362 } 2363 2364 mutex_enter(&sc->sc_mt_lock); 2365 sc->sc_tx_timer = 0; 2366 mutex_exit(&sc->sc_mt_lock); 2367 2368 mutex_enter(&sc->sc_tx_lock); 2369 2370 ring->queued--; 2371 if (ring->queued < 0) { 2372 ring->queued = 0; 2373 } 2374 2375 if ((sc->sc_need_reschedule) && (ring->queued <= (ring->count >> 3))) { 2376 sc->sc_need_reschedule = 0; 2377 mutex_exit(&sc->sc_tx_lock); 2378 mac_tx_update(ic->ic_mach); 2379 mutex_enter(&sc->sc_tx_lock); 2380 } 2381 2382 mutex_exit(&sc->sc_tx_lock); 2383 } 2384 2385 /* 2386 * inform a given command has been executed 2387 */ 2388 static void 2389 iwp_cmd_intr(iwp_sc_t *sc, iwp_rx_desc_t *desc) 2390 { 2391 if ((desc->hdr.qid & 7) != 4) { 2392 return; 2393 } 2394 2395 if (sc->sc_cmd_accum > 0) { 2396 sc->sc_cmd_accum--; 2397 return; 2398 } 2399 2400 mutex_enter(&sc->sc_glock); 2401 2402 sc->sc_cmd_flag = SC_CMD_FLG_DONE; 2403 2404 cv_signal(&sc->sc_cmd_cv); 2405 2406 mutex_exit(&sc->sc_glock); 2407 2408 IWP_DBG((IWP_DEBUG_CMD, "iwp_cmd_intr(): " 2409 "qid=%x idx=%d flags=%x type=0x%x\n", 2410 desc->hdr.qid, desc->hdr.idx, desc->hdr.flags, 2411 desc->hdr.type)); 2412 } 2413 2414 /* 2415 * this function will be invoked when alive notification occur. 2416 */ 2417 static void 2418 iwp_ucode_alive(iwp_sc_t *sc, iwp_rx_desc_t *desc) 2419 { 2420 uint32_t rv; 2421 struct iwp_calib_cfg_cmd cmd; 2422 struct iwp_alive_resp *ar = 2423 (struct iwp_alive_resp *)(desc + 1); 2424 struct iwp_calib_results *res_p = &sc->sc_calib_results; 2425 2426 /* 2427 * the microcontroller is ready 2428 */ 2429 IWP_DBG((IWP_DEBUG_FW, "iwp_ucode_alive(): " 2430 "microcode alive notification minor: %x major: %x type: " 2431 "%x subtype: %x\n", 2432 ar->ucode_minor, ar->ucode_minor, ar->ver_type, ar->ver_subtype)); 2433 2434 #ifdef DEBUG 2435 if (LE_32(ar->is_valid) != UCODE_VALID_OK) { 2436 IWP_DBG((IWP_DEBUG_FW, "iwp_ucode_alive(): " 2437 "microcontroller initialization failed\n")); 2438 } 2439 #endif 2440 2441 /* 2442 * determine if init alive or runtime alive. 2443 */ 2444 if (INITIALIZE_SUBTYPE == ar->ver_subtype) { 2445 IWP_DBG((IWP_DEBUG_FW, "iwp_ucode_alive(): " 2446 "initialization alive received.\n")); 2447 2448 (void) memcpy(&sc->sc_card_alive_init, ar, 2449 sizeof (struct iwp_init_alive_resp)); 2450 2451 /* 2452 * necessary configuration to NIC 2453 */ 2454 mutex_enter(&sc->sc_glock); 2455 2456 rv = iwp_alive_common(sc); 2457 if (rv != IWP_SUCCESS) { 2458 cmn_err(CE_WARN, "iwp_ucode_alive(): " 2459 "common alive process failed in init alive.\n"); 2460 mutex_exit(&sc->sc_glock); 2461 return; 2462 } 2463 2464 (void) memset(&cmd, 0, sizeof (cmd)); 2465 2466 cmd.ucd_calib_cfg.once.is_enable = IWP_CALIB_INIT_CFG_ALL; 2467 cmd.ucd_calib_cfg.once.start = IWP_CALIB_INIT_CFG_ALL; 2468 cmd.ucd_calib_cfg.once.send_res = IWP_CALIB_INIT_CFG_ALL; 2469 cmd.ucd_calib_cfg.flags = IWP_CALIB_INIT_CFG_ALL; 2470 2471 /* 2472 * require ucode execute calibration 2473 */ 2474 rv = iwp_cmd(sc, CALIBRATION_CFG_CMD, &cmd, sizeof (cmd), 1); 2475 if (rv != IWP_SUCCESS) { 2476 cmn_err(CE_WARN, "iwp_ucode_alive(): " 2477 "failed to send calibration configure command.\n"); 2478 mutex_exit(&sc->sc_glock); 2479 return; 2480 } 2481 2482 mutex_exit(&sc->sc_glock); 2483 2484 } else { /* runtime alive */ 2485 2486 IWP_DBG((IWP_DEBUG_FW, "iwp_ucode_alive(): " 2487 "runtime alive received.\n")); 2488 2489 (void) memcpy(&sc->sc_card_alive_run, ar, 2490 sizeof (struct iwp_alive_resp)); 2491 2492 mutex_enter(&sc->sc_glock); 2493 2494 /* 2495 * necessary configuration to NIC 2496 */ 2497 rv = iwp_alive_common(sc); 2498 if (rv != IWP_SUCCESS) { 2499 cmn_err(CE_WARN, "iwp_ucode_alive(): " 2500 "common alive process failed in run alive.\n"); 2501 mutex_exit(&sc->sc_glock); 2502 return; 2503 } 2504 2505 /* 2506 * send the result of local oscilator calibration to uCode. 2507 */ 2508 if (res_p->lo_res != NULL) { 2509 rv = iwp_cmd(sc, REPLY_PHY_CALIBRATION_CMD, 2510 res_p->lo_res, res_p->lo_res_len, 1); 2511 if (rv != IWP_SUCCESS) { 2512 cmn_err(CE_WARN, "iwp_ucode_alive(): " 2513 "failed to send local" 2514 "oscilator calibration command.\n"); 2515 mutex_exit(&sc->sc_glock); 2516 return; 2517 } 2518 2519 DELAY(1000); 2520 } 2521 2522 /* 2523 * send the result of TX IQ calibration to uCode. 2524 */ 2525 if (res_p->tx_iq_res != NULL) { 2526 rv = iwp_cmd(sc, REPLY_PHY_CALIBRATION_CMD, 2527 res_p->tx_iq_res, res_p->tx_iq_res_len, 1); 2528 if (rv != IWP_SUCCESS) { 2529 cmn_err(CE_WARN, "iwp_ucode_alive(): " 2530 "failed to send TX IQ" 2531 "calibration command.\n"); 2532 mutex_exit(&sc->sc_glock); 2533 return; 2534 } 2535 2536 DELAY(1000); 2537 } 2538 2539 /* 2540 * send the result of TX IQ perd calibration to uCode. 2541 */ 2542 if (res_p->tx_iq_perd_res != NULL) { 2543 rv = iwp_cmd(sc, REPLY_PHY_CALIBRATION_CMD, 2544 res_p->tx_iq_perd_res, 2545 res_p->tx_iq_perd_res_len, 1); 2546 if (rv != IWP_SUCCESS) { 2547 cmn_err(CE_WARN, "iwp_ucode_alive(): " 2548 "failed to send TX IQ perd" 2549 "calibration command.\n"); 2550 mutex_exit(&sc->sc_glock); 2551 return; 2552 } 2553 2554 DELAY(1000); 2555 } 2556 2557 /* 2558 * send the result of Base Band calibration to uCode. 2559 */ 2560 if (res_p->base_band_res != NULL) { 2561 rv = iwp_cmd(sc, REPLY_PHY_CALIBRATION_CMD, 2562 res_p->base_band_res, 2563 res_p->base_band_res_len, 1); 2564 if (rv != IWP_SUCCESS) { 2565 cmn_err(CE_WARN, "iwp_ucode_alive(): " 2566 "failed to send Base Band" 2567 "calibration command.\n"); 2568 mutex_exit(&sc->sc_glock); 2569 return; 2570 } 2571 2572 DELAY(1000); 2573 } 2574 2575 atomic_or_32(&sc->sc_flags, IWP_F_FW_INIT); 2576 cv_signal(&sc->sc_ucode_cv); 2577 2578 mutex_exit(&sc->sc_glock); 2579 } 2580 2581 } 2582 2583 /* 2584 * deal with receiving frames, command response 2585 * and all notifications from ucode. 2586 */ 2587 /* ARGSUSED */ 2588 static uint_t 2589 iwp_rx_softintr(caddr_t arg, caddr_t unused) 2590 { 2591 iwp_sc_t *sc; 2592 ieee80211com_t *ic; 2593 iwp_rx_desc_t *desc; 2594 iwp_rx_data_t *data; 2595 uint32_t index; 2596 2597 if (NULL == arg) { 2598 return (DDI_INTR_UNCLAIMED); 2599 } 2600 sc = (iwp_sc_t *)arg; 2601 ic = &sc->sc_ic; 2602 2603 /* 2604 * firmware has moved the index of the rx queue, driver get it, 2605 * and deal with it. 2606 */ 2607 index = (sc->sc_shared->val0) & 0xfff; 2608 2609 while (sc->sc_rxq.cur != index) { 2610 data = &sc->sc_rxq.data[sc->sc_rxq.cur]; 2611 desc = (iwp_rx_desc_t *)data->dma_data.mem_va; 2612 2613 IWP_DBG((IWP_DEBUG_INTR, "iwp_rx_softintr(): " 2614 "rx notification index = %d" 2615 " cur = %d qid=%x idx=%d flags=%x type=%x len=%d\n", 2616 index, sc->sc_rxq.cur, desc->hdr.qid, desc->hdr.idx, 2617 desc->hdr.flags, desc->hdr.type, LE_32(desc->len))); 2618 2619 /* 2620 * a command other than a tx need to be replied 2621 */ 2622 if (!(desc->hdr.qid & 0x80) && 2623 (desc->hdr.type != REPLY_SCAN_CMD) && 2624 (desc->hdr.type != REPLY_TX)) { 2625 iwp_cmd_intr(sc, desc); 2626 } 2627 2628 switch (desc->hdr.type) { 2629 case REPLY_RX_PHY_CMD: 2630 iwp_rx_phy_intr(sc, desc); 2631 break; 2632 2633 case REPLY_RX_MPDU_CMD: 2634 iwp_rx_mpdu_intr(sc, desc); 2635 break; 2636 2637 case REPLY_TX: 2638 iwp_tx_intr(sc, desc); 2639 break; 2640 2641 case REPLY_ALIVE: 2642 iwp_ucode_alive(sc, desc); 2643 break; 2644 2645 case CARD_STATE_NOTIFICATION: 2646 { 2647 uint32_t *status = (uint32_t *)(desc + 1); 2648 2649 IWP_DBG((IWP_DEBUG_RADIO, "iwp_rx_softintr(): " 2650 "state changed to %x\n", 2651 LE_32(*status))); 2652 2653 if (LE_32(*status) & 1) { 2654 /* 2655 * the radio button has to be pushed(OFF). It 2656 * is considered as a hw error, the 2657 * iwp_thread() tries to recover it after the 2658 * button is pushed again(ON) 2659 */ 2660 cmn_err(CE_NOTE, "iwp_rx_softintr(): " 2661 "radio transmitter is off\n"); 2662 sc->sc_ostate = sc->sc_ic.ic_state; 2663 ieee80211_new_state(&sc->sc_ic, 2664 IEEE80211_S_INIT, -1); 2665 atomic_or_32(&sc->sc_flags, 2666 IWP_F_HW_ERR_RECOVER | IWP_F_RADIO_OFF); 2667 } 2668 2669 break; 2670 } 2671 2672 case SCAN_START_NOTIFICATION: 2673 { 2674 iwp_start_scan_t *scan = 2675 (iwp_start_scan_t *)(desc + 1); 2676 2677 IWP_DBG((IWP_DEBUG_SCAN, "iwp_rx_softintr(): " 2678 "scanning channel %d status %x\n", 2679 scan->chan, LE_32(scan->status))); 2680 2681 ic->ic_curchan = &ic->ic_sup_channels[scan->chan]; 2682 break; 2683 } 2684 2685 case SCAN_COMPLETE_NOTIFICATION: 2686 { 2687 #ifdef DEBUG 2688 iwp_stop_scan_t *scan = 2689 (iwp_stop_scan_t *)(desc + 1); 2690 2691 IWP_DBG((IWP_DEBUG_SCAN, "iwp_rx_softintr(): " 2692 "completed channel %d (burst of %d) status %02x\n", 2693 scan->chan, scan->nchan, scan->status)); 2694 #endif 2695 2696 sc->sc_scan_pending++; 2697 break; 2698 } 2699 2700 case STATISTICS_NOTIFICATION: 2701 { 2702 /* 2703 * handle statistics notification 2704 */ 2705 break; 2706 } 2707 2708 case CALIBRATION_RES_NOTIFICATION: 2709 iwp_save_calib_result(sc, desc); 2710 break; 2711 2712 case CALIBRATION_COMPLETE_NOTIFICATION: 2713 mutex_enter(&sc->sc_glock); 2714 atomic_or_32(&sc->sc_flags, IWP_F_FW_INIT); 2715 cv_signal(&sc->sc_ucode_cv); 2716 mutex_exit(&sc->sc_glock); 2717 break; 2718 2719 case MISSED_BEACONS_NOTIFICATION: 2720 { 2721 struct iwp_beacon_missed *miss = 2722 (struct iwp_beacon_missed *)(desc + 1); 2723 2724 if ((ic->ic_state == IEEE80211_S_RUN) && 2725 (LE_32(miss->consecutive) > 50)) { 2726 cmn_err(CE_NOTE, "iwp: iwp_rx_softintr(): " 2727 "beacon missed %d/%d\n", 2728 LE_32(miss->consecutive), 2729 LE_32(miss->total)); 2730 (void) ieee80211_new_state(ic, 2731 IEEE80211_S_INIT, -1); 2732 } 2733 break; 2734 } 2735 } 2736 2737 sc->sc_rxq.cur = (sc->sc_rxq.cur + 1) % RX_QUEUE_SIZE; 2738 } 2739 2740 /* 2741 * driver dealt with what received in rx queue and tell the information 2742 * to the firmware. 2743 */ 2744 index = (0 == index) ? RX_QUEUE_SIZE - 1 : index - 1; 2745 IWP_WRITE(sc, FH_RSCSR_CHNL0_RBDCB_WPTR_REG, index & (~7)); 2746 2747 /* 2748 * re-enable interrupts 2749 */ 2750 IWP_WRITE(sc, CSR_INT_MASK, CSR_INI_SET_MASK); 2751 2752 return (DDI_INTR_CLAIMED); 2753 } 2754 2755 /* 2756 * the handle of interrupt 2757 */ 2758 /* ARGSUSED */ 2759 static uint_t 2760 iwp_intr(caddr_t arg, caddr_t unused) 2761 { 2762 iwp_sc_t *sc; 2763 uint32_t r, rfh; 2764 2765 if (NULL == arg) { 2766 return (DDI_INTR_UNCLAIMED); 2767 } 2768 sc = (iwp_sc_t *)arg; 2769 2770 r = IWP_READ(sc, CSR_INT); 2771 if (0 == r || 0xffffffff == r) { 2772 return (DDI_INTR_UNCLAIMED); 2773 } 2774 2775 IWP_DBG((IWP_DEBUG_INTR, "iwp_intr(): " 2776 "interrupt reg %x\n", r)); 2777 2778 rfh = IWP_READ(sc, CSR_FH_INT_STATUS); 2779 2780 IWP_DBG((IWP_DEBUG_INTR, "iwp_intr(): " 2781 "FH interrupt reg %x\n", rfh)); 2782 2783 /* 2784 * disable interrupts 2785 */ 2786 IWP_WRITE(sc, CSR_INT_MASK, 0); 2787 2788 /* 2789 * ack interrupts 2790 */ 2791 IWP_WRITE(sc, CSR_INT, r); 2792 IWP_WRITE(sc, CSR_FH_INT_STATUS, rfh); 2793 2794 if (r & (BIT_INT_SWERROR | BIT_INT_ERR)) { 2795 IWP_DBG((IWP_DEBUG_FW, "iwp_intr(): " 2796 "fatal firmware error\n")); 2797 iwp_stop(sc); 2798 sc->sc_ostate = sc->sc_ic.ic_state; 2799 2800 /* notify upper layer */ 2801 if (!IWP_CHK_FAST_RECOVER(sc)) { 2802 ieee80211_new_state(&sc->sc_ic, IEEE80211_S_INIT, -1); 2803 } 2804 2805 atomic_or_32(&sc->sc_flags, IWP_F_HW_ERR_RECOVER); 2806 return (DDI_INTR_CLAIMED); 2807 } 2808 2809 if (r & BIT_INT_RF_KILL) { 2810 uint32_t tmp = IWP_READ(sc, CSR_GP_CNTRL); 2811 if (tmp & (1 << 27)) { 2812 cmn_err(CE_NOTE, "RF switch: radio on\n"); 2813 } 2814 } 2815 2816 if ((r & (BIT_INT_FH_RX | BIT_INT_SW_RX)) || 2817 (rfh & FH_INT_RX_MASK)) { 2818 (void) ddi_intr_trigger_softint(sc->sc_soft_hdl, NULL); 2819 return (DDI_INTR_CLAIMED); 2820 } 2821 2822 if (r & BIT_INT_FH_TX) { 2823 mutex_enter(&sc->sc_glock); 2824 atomic_or_32(&sc->sc_flags, IWP_F_PUT_SEG); 2825 cv_signal(&sc->sc_put_seg_cv); 2826 mutex_exit(&sc->sc_glock); 2827 } 2828 2829 #ifdef DEBUG 2830 if (r & BIT_INT_ALIVE) { 2831 IWP_DBG((IWP_DEBUG_FW, "iwp_intr(): " 2832 "firmware initialized.\n")); 2833 } 2834 #endif 2835 2836 /* 2837 * re-enable interrupts 2838 */ 2839 IWP_WRITE(sc, CSR_INT_MASK, CSR_INI_SET_MASK); 2840 2841 return (DDI_INTR_CLAIMED); 2842 } 2843 2844 static uint8_t 2845 iwp_rate_to_plcp(int rate) 2846 { 2847 uint8_t ret; 2848 2849 switch (rate) { 2850 /* 2851 * CCK rates 2852 */ 2853 case 2: 2854 ret = 0xa; 2855 break; 2856 2857 case 4: 2858 ret = 0x14; 2859 break; 2860 2861 case 11: 2862 ret = 0x37; 2863 break; 2864 2865 case 22: 2866 ret = 0x6e; 2867 break; 2868 2869 /* 2870 * OFDM rates 2871 */ 2872 case 12: 2873 ret = 0xd; 2874 break; 2875 2876 case 18: 2877 ret = 0xf; 2878 break; 2879 2880 case 24: 2881 ret = 0x5; 2882 break; 2883 2884 case 36: 2885 ret = 0x7; 2886 break; 2887 2888 case 48: 2889 ret = 0x9; 2890 break; 2891 2892 case 72: 2893 ret = 0xb; 2894 break; 2895 2896 case 96: 2897 ret = 0x1; 2898 break; 2899 2900 case 108: 2901 ret = 0x3; 2902 break; 2903 2904 default: 2905 ret = 0; 2906 break; 2907 } 2908 2909 return (ret); 2910 } 2911 2912 /* 2913 * invoked by GLD send frames 2914 */ 2915 static mblk_t * 2916 iwp_m_tx(void *arg, mblk_t *mp) 2917 { 2918 iwp_sc_t *sc; 2919 ieee80211com_t *ic; 2920 mblk_t *next; 2921 2922 if (NULL == arg) { 2923 return (NULL); 2924 } 2925 sc = (iwp_sc_t *)arg; 2926 ic = &sc->sc_ic; 2927 2928 if (sc->sc_flags & IWP_F_SUSPEND) { 2929 freemsgchain(mp); 2930 return (NULL); 2931 } 2932 2933 if (ic->ic_state != IEEE80211_S_RUN) { 2934 freemsgchain(mp); 2935 return (NULL); 2936 } 2937 2938 if ((sc->sc_flags & IWP_F_HW_ERR_RECOVER) && 2939 IWP_CHK_FAST_RECOVER(sc)) { 2940 IWP_DBG((IWP_DEBUG_FW, "iwp_m_tx(): " 2941 "hold queue\n")); 2942 return (mp); 2943 } 2944 2945 2946 while (mp != NULL) { 2947 next = mp->b_next; 2948 mp->b_next = NULL; 2949 if (iwp_send(ic, mp, IEEE80211_FC0_TYPE_DATA) != 0) { 2950 mp->b_next = next; 2951 break; 2952 } 2953 mp = next; 2954 } 2955 2956 return (mp); 2957 } 2958 2959 /* 2960 * send frames 2961 */ 2962 static int 2963 iwp_send(ieee80211com_t *ic, mblk_t *mp, uint8_t type) 2964 { 2965 iwp_sc_t *sc; 2966 iwp_tx_ring_t *ring; 2967 iwp_tx_desc_t *desc; 2968 iwp_tx_data_t *data; 2969 iwp_tx_data_t *desc_data; 2970 iwp_cmd_t *cmd; 2971 iwp_tx_cmd_t *tx; 2972 ieee80211_node_t *in; 2973 struct ieee80211_frame *wh; 2974 struct ieee80211_key *k = NULL; 2975 mblk_t *m, *m0; 2976 int hdrlen, len, len0, mblen, off, err = IWP_SUCCESS; 2977 uint16_t masks = 0; 2978 uint32_t rate, s_id = 0; 2979 2980 if (NULL == ic) { 2981 return (IWP_FAIL); 2982 } 2983 sc = (iwp_sc_t *)ic; 2984 2985 if (sc->sc_flags & IWP_F_SUSPEND) { 2986 if ((type & IEEE80211_FC0_TYPE_MASK) != 2987 IEEE80211_FC0_TYPE_DATA) { 2988 freemsg(mp); 2989 } 2990 err = IWP_FAIL; 2991 goto exit; 2992 } 2993 2994 mutex_enter(&sc->sc_tx_lock); 2995 ring = &sc->sc_txq[0]; 2996 data = &ring->data[ring->cur]; 2997 cmd = data->cmd; 2998 bzero(cmd, sizeof (*cmd)); 2999 3000 ring->cur = (ring->cur + 1) % ring->count; 3001 3002 /* 3003 * Need reschedule TX if TX buffer is full. 3004 */ 3005 if (ring->queued > ring->count - IWP_MAX_WIN_SIZE) { 3006 IWP_DBG((IWP_DEBUG_TX, "iwp_send(): " 3007 "no txbuf\n")); 3008 3009 sc->sc_need_reschedule = 1; 3010 mutex_exit(&sc->sc_tx_lock); 3011 3012 if ((type & IEEE80211_FC0_TYPE_MASK) != 3013 IEEE80211_FC0_TYPE_DATA) { 3014 freemsg(mp); 3015 } 3016 sc->sc_tx_nobuf++; 3017 err = IWP_FAIL; 3018 goto exit; 3019 } 3020 3021 ring->queued++; 3022 3023 mutex_exit(&sc->sc_tx_lock); 3024 3025 hdrlen = ieee80211_hdrspace(ic, mp->b_rptr); 3026 3027 m = allocb(msgdsize(mp) + 32, BPRI_MED); 3028 if (NULL == m) { /* can not alloc buf, drop this package */ 3029 cmn_err(CE_WARN, "iwp_send(): " 3030 "failed to allocate msgbuf\n"); 3031 freemsg(mp); 3032 3033 mutex_enter(&sc->sc_tx_lock); 3034 ring->queued--; 3035 if ((sc->sc_need_reschedule) && (ring->queued <= 0)) { 3036 sc->sc_need_reschedule = 0; 3037 mutex_exit(&sc->sc_tx_lock); 3038 mac_tx_update(ic->ic_mach); 3039 mutex_enter(&sc->sc_tx_lock); 3040 } 3041 mutex_exit(&sc->sc_tx_lock); 3042 3043 err = IWP_SUCCESS; 3044 goto exit; 3045 } 3046 3047 for (off = 0, m0 = mp; m0 != NULL; m0 = m0->b_cont) { 3048 mblen = MBLKL(m0); 3049 (void) memcpy(m->b_rptr + off, m0->b_rptr, mblen); 3050 off += mblen; 3051 } 3052 3053 m->b_wptr += off; 3054 3055 wh = (struct ieee80211_frame *)m->b_rptr; 3056 3057 /* 3058 * determine send which AP or station in IBSS 3059 */ 3060 in = ieee80211_find_txnode(ic, wh->i_addr1); 3061 if (NULL == in) { 3062 cmn_err(CE_WARN, "iwp_send(): " 3063 "failed to find tx node\n"); 3064 freemsg(mp); 3065 freemsg(m); 3066 sc->sc_tx_err++; 3067 3068 mutex_enter(&sc->sc_tx_lock); 3069 ring->queued--; 3070 if ((sc->sc_need_reschedule) && (ring->queued <= 0)) { 3071 sc->sc_need_reschedule = 0; 3072 mutex_exit(&sc->sc_tx_lock); 3073 mac_tx_update(ic->ic_mach); 3074 mutex_enter(&sc->sc_tx_lock); 3075 } 3076 mutex_exit(&sc->sc_tx_lock); 3077 3078 err = IWP_SUCCESS; 3079 goto exit; 3080 } 3081 3082 /* 3083 * Net80211 module encapsulate outbound data frames. 3084 * Add some feilds of 80211 frame. 3085 */ 3086 if ((type & IEEE80211_FC0_TYPE_MASK) == 3087 IEEE80211_FC0_TYPE_DATA) { 3088 (void) ieee80211_encap(ic, m, in); 3089 } 3090 3091 freemsg(mp); 3092 3093 cmd->hdr.type = REPLY_TX; 3094 cmd->hdr.flags = 0; 3095 cmd->hdr.qid = ring->qid; 3096 3097 tx = (iwp_tx_cmd_t *)cmd->data; 3098 tx->tx_flags = 0; 3099 3100 if (IEEE80211_IS_MULTICAST(wh->i_addr1)) { 3101 tx->tx_flags &= ~(LE_32(TX_CMD_FLG_ACK_MSK)); 3102 } else { 3103 tx->tx_flags |= LE_32(TX_CMD_FLG_ACK_MSK); 3104 } 3105 3106 if (wh->i_fc[1] & IEEE80211_FC1_WEP) { 3107 k = ieee80211_crypto_encap(ic, m); 3108 if (NULL == k) { 3109 freemsg(m); 3110 sc->sc_tx_err++; 3111 3112 mutex_enter(&sc->sc_tx_lock); 3113 ring->queued--; 3114 if ((sc->sc_need_reschedule) && (ring->queued <= 0)) { 3115 sc->sc_need_reschedule = 0; 3116 mutex_exit(&sc->sc_tx_lock); 3117 mac_tx_update(ic->ic_mach); 3118 mutex_enter(&sc->sc_tx_lock); 3119 } 3120 mutex_exit(&sc->sc_tx_lock); 3121 3122 err = IWP_SUCCESS; 3123 goto exit; 3124 } 3125 3126 /* packet header may have moved, reset our local pointer */ 3127 wh = (struct ieee80211_frame *)m->b_rptr; 3128 } 3129 3130 len = msgdsize(m); 3131 3132 #ifdef DEBUG 3133 if (iwp_dbg_flags & IWP_DEBUG_TX) { 3134 ieee80211_dump_pkt((uint8_t *)wh, hdrlen, 0, 0); 3135 } 3136 #endif 3137 3138 tx->rts_retry_limit = IWP_TX_RTS_RETRY_LIMIT; 3139 tx->data_retry_limit = IWP_TX_DATA_RETRY_LIMIT; 3140 3141 /* 3142 * specific TX parameters for management frames 3143 */ 3144 if ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) == 3145 IEEE80211_FC0_TYPE_MGT) { 3146 /* 3147 * mgmt frames are sent at 1M 3148 */ 3149 if ((in->in_rates.ir_rates[0] & 3150 IEEE80211_RATE_VAL) != 0) { 3151 rate = in->in_rates.ir_rates[0] & IEEE80211_RATE_VAL; 3152 } else { 3153 rate = 2; 3154 } 3155 3156 tx->tx_flags |= LE_32(TX_CMD_FLG_SEQ_CTL_MSK); 3157 3158 /* 3159 * tell h/w to set timestamp in probe responses 3160 */ 3161 if ((wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK) == 3162 IEEE80211_FC0_SUBTYPE_PROBE_RESP) { 3163 tx->tx_flags |= LE_32(TX_CMD_FLG_TSF_MSK); 3164 3165 tx->data_retry_limit = 3; 3166 if (tx->data_retry_limit < tx->rts_retry_limit) { 3167 tx->rts_retry_limit = tx->data_retry_limit; 3168 } 3169 } 3170 3171 if (((wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK) == 3172 IEEE80211_FC0_SUBTYPE_ASSOC_REQ) || 3173 ((wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK) == 3174 IEEE80211_FC0_SUBTYPE_REASSOC_REQ)) { 3175 tx->timeout.pm_frame_timeout = LE_16(3); 3176 } else { 3177 tx->timeout.pm_frame_timeout = LE_16(2); 3178 } 3179 3180 } else { 3181 /* 3182 * do it here for the software way rate scaling. 3183 * later for rate scaling in hardware. 3184 * 3185 * now the txrate is determined in tx cmd flags, set to the 3186 * max value 54M for 11g and 11M for 11b originally. 3187 */ 3188 if (ic->ic_fixed_rate != IEEE80211_FIXED_RATE_NONE) { 3189 rate = ic->ic_fixed_rate; 3190 } else { 3191 if ((in->in_rates.ir_rates[in->in_txrate] & 3192 IEEE80211_RATE_VAL) != 0) { 3193 rate = in->in_rates. 3194 ir_rates[in->in_txrate] & 3195 IEEE80211_RATE_VAL; 3196 } 3197 } 3198 3199 tx->tx_flags |= LE_32(TX_CMD_FLG_SEQ_CTL_MSK); 3200 3201 tx->timeout.pm_frame_timeout = 0; 3202 } 3203 3204 IWP_DBG((IWP_DEBUG_TX, "iwp_send(): " 3205 "tx rate[%d of %d] = %x", 3206 in->in_txrate, in->in_rates.ir_nrates, rate)); 3207 3208 len0 = roundup(4 + sizeof (iwp_tx_cmd_t) + hdrlen, 4); 3209 if (len0 != (4 + sizeof (iwp_tx_cmd_t) + hdrlen)) { 3210 tx->tx_flags |= LE_32(TX_CMD_FLG_MH_PAD_MSK); 3211 } 3212 3213 /* 3214 * retrieve destination node's id 3215 */ 3216 if (IEEE80211_IS_MULTICAST(wh->i_addr1)) { 3217 tx->sta_id = IWP_BROADCAST_ID; 3218 } else { 3219 tx->sta_id = IWP_AP_ID; 3220 } 3221 3222 if (2 == rate || 4 == rate || 11 == rate || 22 == rate) { 3223 masks |= RATE_MCS_CCK_MSK; 3224 } 3225 3226 masks |= RATE_MCS_ANT_B_MSK; 3227 tx->rate.r.rate_n_flags = LE_32(iwp_rate_to_plcp(rate) | masks); 3228 3229 IWP_DBG((IWP_DEBUG_TX, "iwp_send(): " 3230 "tx flag = %x", 3231 tx->tx_flags)); 3232 3233 tx->stop_time.life_time = LE_32(0xffffffff); 3234 3235 tx->len = LE_16(len); 3236 3237 tx->dram_lsb_ptr = 3238 LE_32(data->paddr_cmd + 4 + offsetof(iwp_tx_cmd_t, scratch)); 3239 tx->dram_msb_ptr = 0; 3240 tx->driver_txop = 0; 3241 tx->next_frame_len = 0; 3242 3243 (void) memcpy(tx + 1, m->b_rptr, hdrlen); 3244 m->b_rptr += hdrlen; 3245 (void) memcpy(data->dma_data.mem_va, m->b_rptr, len - hdrlen); 3246 3247 IWP_DBG((IWP_DEBUG_TX, "iwp_send(): " 3248 "sending data: qid=%d idx=%d len=%d", 3249 ring->qid, ring->cur, len)); 3250 3251 /* 3252 * first segment includes the tx cmd plus the 802.11 header, 3253 * the second includes the remaining of the 802.11 frame. 3254 */ 3255 mutex_enter(&sc->sc_tx_lock); 3256 3257 cmd->hdr.idx = ring->desc_cur; 3258 3259 desc_data = &ring->data[ring->desc_cur]; 3260 desc = desc_data->desc; 3261 bzero(desc, sizeof (*desc)); 3262 desc->val0 = 2 << 24; 3263 desc->pa[0].tb1_addr = data->paddr_cmd; 3264 desc->pa[0].val1 = ((len0 << 4) & 0xfff0) | 3265 ((data->dma_data.cookie.dmac_address & 0xffff) << 16); 3266 desc->pa[0].val2 = 3267 ((data->dma_data.cookie.dmac_address & 0xffff0000) >> 16) | 3268 ((len - hdrlen) << 20); 3269 IWP_DBG((IWP_DEBUG_TX, "iwp_send(): " 3270 "phy addr1 = 0x%x phy addr2 = 0x%x " 3271 "len1 = 0x%x, len2 = 0x%x val1 = 0x%x val2 = 0x%x", 3272 data->paddr_cmd, data->dma_data.cookie.dmac_address, 3273 len0, len - hdrlen, desc->pa[0].val1, desc->pa[0].val2)); 3274 3275 /* 3276 * kick ring 3277 */ 3278 s_id = tx->sta_id; 3279 3280 sc->sc_shared->queues_byte_cnt_tbls[ring->qid]. 3281 tfd_offset[ring->desc_cur].val = 3282 (8 + len) | (s_id << 12); 3283 if (ring->desc_cur < IWP_MAX_WIN_SIZE) { 3284 sc->sc_shared->queues_byte_cnt_tbls[ring->qid]. 3285 tfd_offset[IWP_QUEUE_SIZE + ring->desc_cur].val = 3286 (8 + len) | (s_id << 12); 3287 } 3288 3289 IWP_DMA_SYNC(data->dma_data, DDI_DMA_SYNC_FORDEV); 3290 IWP_DMA_SYNC(ring->dma_desc, DDI_DMA_SYNC_FORDEV); 3291 3292 ring->desc_cur = (ring->desc_cur + 1) % ring->count; 3293 IWP_WRITE(sc, HBUS_TARG_WRPTR, ring->qid << 8 | ring->desc_cur); 3294 3295 mutex_exit(&sc->sc_tx_lock); 3296 freemsg(m); 3297 3298 /* 3299 * release node reference 3300 */ 3301 ieee80211_free_node(in); 3302 3303 ic->ic_stats.is_tx_bytes += len; 3304 ic->ic_stats.is_tx_frags++; 3305 3306 mutex_enter(&sc->sc_mt_lock); 3307 if (0 == sc->sc_tx_timer) { 3308 sc->sc_tx_timer = 4; 3309 } 3310 mutex_exit(&sc->sc_mt_lock); 3311 3312 exit: 3313 return (err); 3314 } 3315 3316 /* 3317 * invoked by GLD to deal with IOCTL affaires 3318 */ 3319 static void 3320 iwp_m_ioctl(void* arg, queue_t *wq, mblk_t *mp) 3321 { 3322 iwp_sc_t *sc; 3323 ieee80211com_t *ic; 3324 int err = EINVAL; 3325 3326 if (NULL == arg) { 3327 return; 3328 } 3329 sc = (iwp_sc_t *)arg; 3330 ic = &sc->sc_ic; 3331 3332 err = ieee80211_ioctl(ic, wq, mp); 3333 if (ENETRESET == err) { 3334 /* 3335 * This is special for the hidden AP connection. 3336 * In any case, we should make sure only one 'scan' 3337 * in the driver for a 'connect' CLI command. So 3338 * when connecting to a hidden AP, the scan is just 3339 * sent out to the air when we know the desired 3340 * essid of the AP we want to connect. 3341 */ 3342 if (ic->ic_des_esslen) { 3343 if (sc->sc_flags & IWP_F_RUNNING) { 3344 iwp_m_stop(sc); 3345 (void) iwp_m_start(sc); 3346 (void) ieee80211_new_state(ic, 3347 IEEE80211_S_SCAN, -1); 3348 } 3349 } 3350 } 3351 } 3352 3353 /* 3354 * Call back functions for get/set proporty 3355 */ 3356 static int 3357 iwp_m_getprop(void *arg, const char *pr_name, mac_prop_id_t wldp_pr_num, 3358 uint_t pr_flags, uint_t wldp_length, void *wldp_buf, uint_t *perm) 3359 { 3360 iwp_sc_t *sc; 3361 int err = EINVAL; 3362 3363 if (NULL == arg) { 3364 return (EINVAL); 3365 } 3366 sc = (iwp_sc_t *)arg; 3367 3368 err = ieee80211_getprop(&sc->sc_ic, pr_name, wldp_pr_num, 3369 pr_flags, wldp_length, wldp_buf, perm); 3370 3371 return (err); 3372 } 3373 3374 static int 3375 iwp_m_setprop(void *arg, const char *pr_name, mac_prop_id_t wldp_pr_num, 3376 uint_t wldp_length, const void *wldp_buf) 3377 { 3378 iwp_sc_t *sc; 3379 ieee80211com_t *ic; 3380 int err = EINVAL; 3381 3382 if (NULL == arg) { 3383 return (EINVAL); 3384 } 3385 sc = (iwp_sc_t *)arg; 3386 ic = &sc->sc_ic; 3387 3388 err = ieee80211_setprop(ic, pr_name, wldp_pr_num, wldp_length, 3389 wldp_buf); 3390 3391 if (err == ENETRESET) { 3392 if (ic->ic_des_esslen) { 3393 if (sc->sc_flags & IWP_F_RUNNING) { 3394 iwp_m_stop(sc); 3395 (void) iwp_m_start(sc); 3396 (void) ieee80211_new_state(ic, 3397 IEEE80211_S_SCAN, -1); 3398 } 3399 } 3400 err = 0; 3401 } 3402 return (err); 3403 } 3404 3405 /* 3406 * invoked by GLD supply statistics NIC and driver 3407 */ 3408 static int 3409 iwp_m_stat(void *arg, uint_t stat, uint64_t *val) 3410 { 3411 iwp_sc_t *sc; 3412 ieee80211com_t *ic; 3413 ieee80211_node_t *in; 3414 3415 if (NULL == arg) { 3416 return (EINVAL); 3417 } 3418 sc = (iwp_sc_t *)arg; 3419 ic = &sc->sc_ic; 3420 3421 mutex_enter(&sc->sc_glock); 3422 3423 switch (stat) { 3424 case MAC_STAT_IFSPEED: 3425 in = ic->ic_bss; 3426 *val = ((IEEE80211_FIXED_RATE_NONE == ic->ic_fixed_rate) ? 3427 IEEE80211_RATE(in->in_txrate) : 3428 ic->ic_fixed_rate) / 2 * 1000000; 3429 break; 3430 case MAC_STAT_NOXMTBUF: 3431 *val = sc->sc_tx_nobuf; 3432 break; 3433 case MAC_STAT_NORCVBUF: 3434 *val = sc->sc_rx_nobuf; 3435 break; 3436 case MAC_STAT_IERRORS: 3437 *val = sc->sc_rx_err; 3438 break; 3439 case MAC_STAT_RBYTES: 3440 *val = ic->ic_stats.is_rx_bytes; 3441 break; 3442 case MAC_STAT_IPACKETS: 3443 *val = ic->ic_stats.is_rx_frags; 3444 break; 3445 case MAC_STAT_OBYTES: 3446 *val = ic->ic_stats.is_tx_bytes; 3447 break; 3448 case MAC_STAT_OPACKETS: 3449 *val = ic->ic_stats.is_tx_frags; 3450 break; 3451 case MAC_STAT_OERRORS: 3452 case WIFI_STAT_TX_FAILED: 3453 *val = sc->sc_tx_err; 3454 break; 3455 case WIFI_STAT_TX_RETRANS: 3456 *val = sc->sc_tx_retries; 3457 break; 3458 case WIFI_STAT_FCS_ERRORS: 3459 case WIFI_STAT_WEP_ERRORS: 3460 case WIFI_STAT_TX_FRAGS: 3461 case WIFI_STAT_MCAST_TX: 3462 case WIFI_STAT_RTS_SUCCESS: 3463 case WIFI_STAT_RTS_FAILURE: 3464 case WIFI_STAT_ACK_FAILURE: 3465 case WIFI_STAT_RX_FRAGS: 3466 case WIFI_STAT_MCAST_RX: 3467 case WIFI_STAT_RX_DUPS: 3468 mutex_exit(&sc->sc_glock); 3469 return (ieee80211_stat(ic, stat, val)); 3470 default: 3471 mutex_exit(&sc->sc_glock); 3472 return (ENOTSUP); 3473 } 3474 3475 mutex_exit(&sc->sc_glock); 3476 3477 return (IWP_SUCCESS); 3478 3479 } 3480 3481 /* 3482 * invoked by GLD to start or open NIC 3483 */ 3484 static int 3485 iwp_m_start(void *arg) 3486 { 3487 iwp_sc_t *sc; 3488 ieee80211com_t *ic; 3489 int err = IWP_FAIL; 3490 3491 if (NULL == arg) { 3492 return (EINVAL); 3493 } 3494 sc = (iwp_sc_t *)arg; 3495 ic = &sc->sc_ic; 3496 3497 err = iwp_init(sc); 3498 if (err != IWP_SUCCESS) { 3499 /* 3500 * The hw init err(eg. RF is OFF). Return Success to make 3501 * the 'plumb' succeed. The iwp_thread() tries to re-init 3502 * background. 3503 */ 3504 atomic_or_32(&sc->sc_flags, IWP_F_HW_ERR_RECOVER); 3505 return (IWP_SUCCESS); 3506 } 3507 3508 ieee80211_new_state(ic, IEEE80211_S_INIT, -1); 3509 3510 atomic_or_32(&sc->sc_flags, IWP_F_RUNNING); 3511 3512 return (IWP_SUCCESS); 3513 } 3514 3515 /* 3516 * invoked by GLD to stop or down NIC 3517 */ 3518 static void 3519 iwp_m_stop(void *arg) 3520 { 3521 iwp_sc_t *sc; 3522 ieee80211com_t *ic; 3523 3524 if (NULL == arg) { 3525 return; 3526 } 3527 sc = (iwp_sc_t *)arg; 3528 ic = &sc->sc_ic; 3529 3530 iwp_stop(sc); 3531 3532 /* 3533 * release buffer for calibration 3534 */ 3535 iwp_release_calib_buffer(sc); 3536 3537 ieee80211_new_state(ic, IEEE80211_S_INIT, -1); 3538 3539 atomic_and_32(&sc->sc_flags, ~IWP_F_HW_ERR_RECOVER); 3540 atomic_and_32(&sc->sc_flags, ~IWP_F_RATE_AUTO_CTL); 3541 3542 atomic_and_32(&sc->sc_flags, ~IWP_F_RUNNING); 3543 atomic_and_32(&sc->sc_flags, ~IWP_F_SCANNING); 3544 } 3545 3546 /* 3547 * invoked by GLD to configure NIC 3548 */ 3549 static int 3550 iwp_m_unicst(void *arg, const uint8_t *macaddr) 3551 { 3552 iwp_sc_t *sc; 3553 ieee80211com_t *ic; 3554 int err = IWP_SUCCESS; 3555 3556 if (NULL == arg) { 3557 return (EINVAL); 3558 } 3559 sc = (iwp_sc_t *)arg; 3560 ic = &sc->sc_ic; 3561 3562 if (!IEEE80211_ADDR_EQ(ic->ic_macaddr, macaddr)) { 3563 IEEE80211_ADDR_COPY(ic->ic_macaddr, macaddr); 3564 mutex_enter(&sc->sc_glock); 3565 err = iwp_config(sc); 3566 mutex_exit(&sc->sc_glock); 3567 if (err != IWP_SUCCESS) { 3568 cmn_err(CE_WARN, "iwp_m_unicst(): " 3569 "failed to configure device\n"); 3570 goto fail; 3571 } 3572 } 3573 3574 return (err); 3575 3576 fail: 3577 return (err); 3578 } 3579 3580 /* ARGSUSED */ 3581 static int 3582 iwp_m_multicst(void *arg, boolean_t add, const uint8_t *m) 3583 { 3584 return (IWP_SUCCESS); 3585 } 3586 3587 /* ARGSUSED */ 3588 static int 3589 iwp_m_promisc(void *arg, boolean_t on) 3590 { 3591 return (IWP_SUCCESS); 3592 } 3593 3594 /* 3595 * kernel thread to deal with exceptional situation 3596 */ 3597 static void 3598 iwp_thread(iwp_sc_t *sc) 3599 { 3600 ieee80211com_t *ic = &sc->sc_ic; 3601 clock_t clk; 3602 int err, n = 0, timeout = 0; 3603 uint32_t tmp; 3604 #ifdef DEBUG 3605 int times = 0; 3606 #endif 3607 3608 while (sc->sc_mf_thread_switch) { 3609 tmp = IWP_READ(sc, CSR_GP_CNTRL); 3610 if (tmp & CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW) { 3611 atomic_and_32(&sc->sc_flags, ~IWP_F_RADIO_OFF); 3612 } else { 3613 atomic_or_32(&sc->sc_flags, IWP_F_RADIO_OFF); 3614 } 3615 3616 /* 3617 * If in SUSPEND or the RF is OFF, do nothing. 3618 */ 3619 if (sc->sc_flags & IWP_F_RADIO_OFF) { 3620 delay(drv_usectohz(100000)); 3621 continue; 3622 } 3623 3624 /* 3625 * recovery fatal error 3626 */ 3627 if (ic->ic_mach && 3628 (sc->sc_flags & IWP_F_HW_ERR_RECOVER)) { 3629 3630 IWP_DBG((IWP_DEBUG_FW, "iwp_thread(): " 3631 "try to recover fatal hw error: %d\n", times++)); 3632 3633 iwp_stop(sc); 3634 3635 if (IWP_CHK_FAST_RECOVER(sc)) { 3636 /* save runtime configuration */ 3637 bcopy(&sc->sc_config, &sc->sc_config_save, 3638 sizeof (sc->sc_config)); 3639 } else { 3640 ieee80211_new_state(ic, IEEE80211_S_INIT, -1); 3641 delay(drv_usectohz(2000000 + n*500000)); 3642 } 3643 3644 err = iwp_init(sc); 3645 if (err != IWP_SUCCESS) { 3646 n++; 3647 if (n < 20) { 3648 continue; 3649 } 3650 } 3651 3652 n = 0; 3653 if (!err) { 3654 atomic_or_32(&sc->sc_flags, IWP_F_RUNNING); 3655 } 3656 3657 3658 if (!IWP_CHK_FAST_RECOVER(sc) || 3659 iwp_fast_recover(sc) != IWP_SUCCESS) { 3660 atomic_and_32(&sc->sc_flags, 3661 ~IWP_F_HW_ERR_RECOVER); 3662 3663 delay(drv_usectohz(2000000)); 3664 if (sc->sc_ostate != IEEE80211_S_INIT) { 3665 ieee80211_new_state(ic, 3666 IEEE80211_S_SCAN, 0); 3667 } 3668 } 3669 } 3670 3671 if (ic->ic_mach && 3672 (sc->sc_flags & IWP_F_SCANNING) && sc->sc_scan_pending) { 3673 IWP_DBG((IWP_DEBUG_SCAN, "iwp_thread(): " 3674 "wait for probe response\n")); 3675 3676 sc->sc_scan_pending--; 3677 delay(drv_usectohz(200000)); 3678 ieee80211_next_scan(ic); 3679 } 3680 3681 /* 3682 * rate ctl 3683 */ 3684 if (ic->ic_mach && 3685 (sc->sc_flags & IWP_F_RATE_AUTO_CTL)) { 3686 clk = ddi_get_lbolt(); 3687 if (clk > sc->sc_clk + drv_usectohz(1000000)) { 3688 iwp_amrr_timeout(sc); 3689 } 3690 } 3691 3692 delay(drv_usectohz(100000)); 3693 3694 mutex_enter(&sc->sc_mt_lock); 3695 if (sc->sc_tx_timer) { 3696 timeout++; 3697 if (10 == timeout) { 3698 sc->sc_tx_timer--; 3699 if (0 == sc->sc_tx_timer) { 3700 atomic_or_32(&sc->sc_flags, 3701 IWP_F_HW_ERR_RECOVER); 3702 sc->sc_ostate = IEEE80211_S_RUN; 3703 IWP_DBG((IWP_DEBUG_FW, "iwp_thread(): " 3704 "try to recover from " 3705 "send fail\n")); 3706 } 3707 timeout = 0; 3708 } 3709 } 3710 mutex_exit(&sc->sc_mt_lock); 3711 } 3712 3713 mutex_enter(&sc->sc_mt_lock); 3714 sc->sc_mf_thread = NULL; 3715 cv_signal(&sc->sc_mt_cv); 3716 mutex_exit(&sc->sc_mt_lock); 3717 } 3718 3719 3720 /* 3721 * Send a command to the ucode. 3722 */ 3723 static int 3724 iwp_cmd(iwp_sc_t *sc, int code, const void *buf, int size, int async) 3725 { 3726 iwp_tx_ring_t *ring = &sc->sc_txq[IWP_CMD_QUEUE_NUM]; 3727 iwp_tx_desc_t *desc; 3728 iwp_cmd_t *cmd; 3729 3730 ASSERT(size <= sizeof (cmd->data)); 3731 ASSERT(mutex_owned(&sc->sc_glock)); 3732 3733 IWP_DBG((IWP_DEBUG_CMD, "iwp_cmd() " 3734 "code[%d]", code)); 3735 desc = ring->data[ring->cur].desc; 3736 cmd = ring->data[ring->cur].cmd; 3737 3738 cmd->hdr.type = (uint8_t)code; 3739 cmd->hdr.flags = 0; 3740 cmd->hdr.qid = ring->qid; 3741 cmd->hdr.idx = ring->cur; 3742 (void) memcpy(cmd->data, buf, size); 3743 (void) memset(desc, 0, sizeof (*desc)); 3744 3745 desc->val0 = 1 << 24; 3746 desc->pa[0].tb1_addr = 3747 (uint32_t)(ring->data[ring->cur].paddr_cmd & 0xffffffff); 3748 desc->pa[0].val1 = ((4 + size) << 4) & 0xfff0; 3749 3750 if (async) { 3751 sc->sc_cmd_accum++; 3752 } 3753 3754 /* 3755 * kick cmd ring XXX 3756 */ 3757 sc->sc_shared->queues_byte_cnt_tbls[ring->qid]. 3758 tfd_offset[ring->cur].val = 8; 3759 if (ring->cur < IWP_MAX_WIN_SIZE) { 3760 sc->sc_shared->queues_byte_cnt_tbls[ring->qid]. 3761 tfd_offset[IWP_QUEUE_SIZE + ring->cur].val = 8; 3762 } 3763 ring->cur = (ring->cur + 1) % ring->count; 3764 IWP_WRITE(sc, HBUS_TARG_WRPTR, ring->qid << 8 | ring->cur); 3765 3766 if (async) { 3767 return (IWP_SUCCESS); 3768 } else { 3769 clock_t clk; 3770 3771 clk = ddi_get_lbolt() + drv_usectohz(2000000); 3772 while (sc->sc_cmd_flag != SC_CMD_FLG_DONE) { 3773 if (cv_timedwait(&sc->sc_cmd_cv, 3774 &sc->sc_glock, clk) < 0) { 3775 break; 3776 } 3777 } 3778 3779 if (SC_CMD_FLG_DONE == sc->sc_cmd_flag) { 3780 sc->sc_cmd_flag = SC_CMD_FLG_NONE; 3781 return (IWP_SUCCESS); 3782 } else { 3783 sc->sc_cmd_flag = SC_CMD_FLG_NONE; 3784 return (IWP_FAIL); 3785 } 3786 } 3787 } 3788 3789 /* 3790 * require ucode seting led of NIC 3791 */ 3792 static void 3793 iwp_set_led(iwp_sc_t *sc, uint8_t id, uint8_t off, uint8_t on) 3794 { 3795 iwp_led_cmd_t led; 3796 3797 led.interval = LE_32(100000); /* unit: 100ms */ 3798 led.id = id; 3799 led.off = off; 3800 led.on = on; 3801 3802 (void) iwp_cmd(sc, REPLY_LEDS_CMD, &led, sizeof (led), 1); 3803 } 3804 3805 /* 3806 * necessary setting to NIC before authentication 3807 */ 3808 static int 3809 iwp_hw_set_before_auth(iwp_sc_t *sc) 3810 { 3811 ieee80211com_t *ic = &sc->sc_ic; 3812 ieee80211_node_t *in = ic->ic_bss; 3813 int err = IWP_FAIL; 3814 3815 /* 3816 * update adapter's configuration according 3817 * the info of target AP 3818 */ 3819 IEEE80211_ADDR_COPY(sc->sc_config.bssid, in->in_bssid); 3820 sc->sc_config.chan = LE_16(ieee80211_chan2ieee(ic, in->in_chan)); 3821 3822 sc->sc_config.ofdm_ht_triple_stream_basic_rates = 0; 3823 sc->sc_config.ofdm_ht_dual_stream_basic_rates = 0; 3824 sc->sc_config.ofdm_ht_single_stream_basic_rates = 0; 3825 3826 if (IEEE80211_MODE_11B == ic->ic_curmode) { 3827 sc->sc_config.cck_basic_rates = 0x03; 3828 sc->sc_config.ofdm_basic_rates = 0; 3829 } else if ((in->in_chan != IEEE80211_CHAN_ANYC) && 3830 (IEEE80211_IS_CHAN_5GHZ(in->in_chan))) { 3831 sc->sc_config.cck_basic_rates = 0; 3832 sc->sc_config.ofdm_basic_rates = 0x15; 3833 } else { /* assume 802.11b/g */ 3834 sc->sc_config.cck_basic_rates = 0x0f; 3835 sc->sc_config.ofdm_basic_rates = 0xff; 3836 } 3837 3838 sc->sc_config.flags &= ~LE_32(RXON_FLG_SHORT_PREAMBLE_MSK | 3839 RXON_FLG_SHORT_SLOT_MSK); 3840 3841 if (ic->ic_flags & IEEE80211_F_SHSLOT) { 3842 sc->sc_config.flags |= LE_32(RXON_FLG_SHORT_SLOT_MSK); 3843 } else { 3844 sc->sc_config.flags &= LE_32(~RXON_FLG_SHORT_SLOT_MSK); 3845 } 3846 3847 if (ic->ic_flags & IEEE80211_F_SHPREAMBLE) { 3848 sc->sc_config.flags |= LE_32(RXON_FLG_SHORT_PREAMBLE_MSK); 3849 } else { 3850 sc->sc_config.flags &= LE_32(~RXON_FLG_SHORT_PREAMBLE_MSK); 3851 } 3852 3853 IWP_DBG((IWP_DEBUG_80211, "iwp_hw_set_before_auth(): " 3854 "config chan %d flags %x " 3855 "filter_flags %x cck %x ofdm %x" 3856 " bssid:%02x:%02x:%02x:%02x:%02x:%2x\n", 3857 LE_16(sc->sc_config.chan), LE_32(sc->sc_config.flags), 3858 LE_32(sc->sc_config.filter_flags), 3859 sc->sc_config.cck_basic_rates, sc->sc_config.ofdm_basic_rates, 3860 sc->sc_config.bssid[0], sc->sc_config.bssid[1], 3861 sc->sc_config.bssid[2], sc->sc_config.bssid[3], 3862 sc->sc_config.bssid[4], sc->sc_config.bssid[5])); 3863 3864 err = iwp_cmd(sc, REPLY_RXON, &sc->sc_config, 3865 sizeof (iwp_rxon_cmd_t), 1); 3866 if (err != IWP_SUCCESS) { 3867 cmn_err(CE_WARN, "iwp_hw_set_before_auth(): " 3868 "failed to config chan%d\n", sc->sc_config.chan); 3869 return (err); 3870 } 3871 3872 /* 3873 * add default AP node 3874 */ 3875 err = iwp_add_ap_sta(sc); 3876 if (err != IWP_SUCCESS) { 3877 return (err); 3878 } 3879 3880 3881 return (err); 3882 } 3883 3884 /* 3885 * Send a scan request(assembly scan cmd) to the firmware. 3886 */ 3887 static int 3888 iwp_scan(iwp_sc_t *sc) 3889 { 3890 ieee80211com_t *ic = &sc->sc_ic; 3891 iwp_tx_ring_t *ring = &sc->sc_txq[IWP_CMD_QUEUE_NUM]; 3892 iwp_tx_desc_t *desc; 3893 iwp_tx_data_t *data; 3894 iwp_cmd_t *cmd; 3895 iwp_scan_hdr_t *hdr; 3896 iwp_scan_chan_t chan; 3897 struct ieee80211_frame *wh; 3898 ieee80211_node_t *in = ic->ic_bss; 3899 uint8_t essid[IEEE80211_NWID_LEN+1]; 3900 struct ieee80211_rateset *rs; 3901 enum ieee80211_phymode mode; 3902 uint8_t *frm; 3903 int i, pktlen, nrates; 3904 3905 data = &ring->data[ring->cur]; 3906 desc = data->desc; 3907 cmd = (iwp_cmd_t *)data->dma_data.mem_va; 3908 3909 cmd->hdr.type = REPLY_SCAN_CMD; 3910 cmd->hdr.flags = 0; 3911 cmd->hdr.qid = ring->qid; 3912 cmd->hdr.idx = ring->cur | 0x40; 3913 3914 hdr = (iwp_scan_hdr_t *)cmd->data; 3915 (void) memset(hdr, 0, sizeof (iwp_scan_hdr_t)); 3916 hdr->nchan = 1; 3917 hdr->quiet_time = LE_16(50); 3918 hdr->quiet_plcp_th = LE_16(1); 3919 3920 hdr->flags = LE_32(RXON_FLG_BAND_24G_MSK); 3921 hdr->rx_chain = LE_16(RXON_RX_CHAIN_DRIVER_FORCE_MSK | 3922 (0x7 << RXON_RX_CHAIN_VALID_POS) | 3923 (0x2 << RXON_RX_CHAIN_FORCE_SEL_POS) | 3924 (0x2 << RXON_RX_CHAIN_FORCE_MIMO_SEL_POS)); 3925 3926 hdr->tx_cmd.tx_flags = LE_32(TX_CMD_FLG_SEQ_CTL_MSK); 3927 hdr->tx_cmd.sta_id = IWP_BROADCAST_ID; 3928 hdr->tx_cmd.stop_time.life_time = LE_32(0xffffffff); 3929 hdr->tx_cmd.rate.r.rate_n_flags = LE_32(iwp_rate_to_plcp(2)); 3930 hdr->tx_cmd.rate.r.rate_n_flags |= 3931 LE_32(RATE_MCS_ANT_B_MSK |RATE_MCS_CCK_MSK); 3932 hdr->direct_scan[0].len = ic->ic_des_esslen; 3933 hdr->direct_scan[0].id = IEEE80211_ELEMID_SSID; 3934 3935 hdr->filter_flags = LE_32(RXON_FILTER_ACCEPT_GRP_MSK | 3936 RXON_FILTER_BCON_AWARE_MSK); 3937 3938 if (ic->ic_des_esslen) { 3939 bcopy(ic->ic_des_essid, essid, ic->ic_des_esslen); 3940 essid[ic->ic_des_esslen] = '\0'; 3941 IWP_DBG((IWP_DEBUG_SCAN, "iwp_scan(): " 3942 "directed scan %s\n", essid)); 3943 3944 bcopy(ic->ic_des_essid, hdr->direct_scan[0].ssid, 3945 ic->ic_des_esslen); 3946 } else { 3947 bzero(hdr->direct_scan[0].ssid, 3948 sizeof (hdr->direct_scan[0].ssid)); 3949 } 3950 3951 /* 3952 * a probe request frame is required after the REPLY_SCAN_CMD 3953 */ 3954 wh = (struct ieee80211_frame *)(hdr + 1); 3955 wh->i_fc[0] = IEEE80211_FC0_VERSION_0 | IEEE80211_FC0_TYPE_MGT | 3956 IEEE80211_FC0_SUBTYPE_PROBE_REQ; 3957 wh->i_fc[1] = IEEE80211_FC1_DIR_NODS; 3958 (void) memset(wh->i_addr1, 0xff, 6); 3959 IEEE80211_ADDR_COPY(wh->i_addr2, ic->ic_macaddr); 3960 (void) memset(wh->i_addr3, 0xff, 6); 3961 *(uint16_t *)&wh->i_dur[0] = 0; 3962 *(uint16_t *)&wh->i_seq[0] = 0; 3963 3964 frm = (uint8_t *)(wh + 1); 3965 3966 /* 3967 * essid IE 3968 */ 3969 if (in->in_esslen) { 3970 bcopy(in->in_essid, essid, in->in_esslen); 3971 essid[in->in_esslen] = '\0'; 3972 IWP_DBG((IWP_DEBUG_SCAN, "iwp_scan(): " 3973 "probe with ESSID %s\n", 3974 essid)); 3975 } 3976 *frm++ = IEEE80211_ELEMID_SSID; 3977 *frm++ = in->in_esslen; 3978 (void) memcpy(frm, in->in_essid, in->in_esslen); 3979 frm += in->in_esslen; 3980 3981 mode = ieee80211_chan2mode(ic, ic->ic_curchan); 3982 rs = &ic->ic_sup_rates[mode]; 3983 3984 /* 3985 * supported rates IE 3986 */ 3987 *frm++ = IEEE80211_ELEMID_RATES; 3988 nrates = rs->ir_nrates; 3989 if (nrates > IEEE80211_RATE_SIZE) { 3990 nrates = IEEE80211_RATE_SIZE; 3991 } 3992 3993 *frm++ = (uint8_t)nrates; 3994 (void) memcpy(frm, rs->ir_rates, nrates); 3995 frm += nrates; 3996 3997 /* 3998 * supported xrates IE 3999 */ 4000 if (rs->ir_nrates > IEEE80211_RATE_SIZE) { 4001 nrates = rs->ir_nrates - IEEE80211_RATE_SIZE; 4002 *frm++ = IEEE80211_ELEMID_XRATES; 4003 *frm++ = (uint8_t)nrates; 4004 (void) memcpy(frm, rs->ir_rates + IEEE80211_RATE_SIZE, nrates); 4005 frm += nrates; 4006 } 4007 4008 /* 4009 * optionnal IE (usually for wpa) 4010 */ 4011 if (ic->ic_opt_ie != NULL) { 4012 (void) memcpy(frm, ic->ic_opt_ie, ic->ic_opt_ie_len); 4013 frm += ic->ic_opt_ie_len; 4014 } 4015 4016 /* setup length of probe request */ 4017 hdr->tx_cmd.len = LE_16(_PTRDIFF(frm, wh)); 4018 hdr->len = LE_16(hdr->nchan * sizeof (iwp_scan_chan_t) + 4019 LE_16(hdr->tx_cmd.len) + sizeof (iwp_scan_hdr_t)); 4020 4021 /* 4022 * the attribute of the scan channels are required after the probe 4023 * request frame. 4024 */ 4025 for (i = 1; i <= hdr->nchan; i++) { 4026 if (ic->ic_des_esslen) { 4027 chan.type = LE_32(3); 4028 } else { 4029 chan.type = LE_32(1); 4030 } 4031 4032 chan.chan = LE_16(ieee80211_chan2ieee(ic, ic->ic_curchan)); 4033 chan.tpc.tx_gain = 0x28; 4034 chan.tpc.dsp_atten = 110; 4035 chan.active_dwell = LE_16(50); 4036 chan.passive_dwell = LE_16(120); 4037 4038 bcopy(&chan, frm, sizeof (iwp_scan_chan_t)); 4039 frm += sizeof (iwp_scan_chan_t); 4040 } 4041 4042 pktlen = _PTRDIFF(frm, cmd); 4043 4044 (void) memset(desc, 0, sizeof (*desc)); 4045 desc->val0 = 1 << 24; 4046 desc->pa[0].tb1_addr = 4047 (uint32_t)(data->dma_data.cookie.dmac_address & 0xffffffff); 4048 desc->pa[0].val1 = (pktlen << 4) & 0xfff0; 4049 4050 /* 4051 * maybe for cmd, filling the byte cnt table is not necessary. 4052 * anyway, we fill it here. 4053 */ 4054 sc->sc_shared->queues_byte_cnt_tbls[ring->qid] 4055 .tfd_offset[ring->cur].val = 8; 4056 if (ring->cur < IWP_MAX_WIN_SIZE) { 4057 sc->sc_shared->queues_byte_cnt_tbls[ring->qid]. 4058 tfd_offset[IWP_QUEUE_SIZE + ring->cur].val = 8; 4059 } 4060 4061 /* 4062 * kick cmd ring 4063 */ 4064 ring->cur = (ring->cur + 1) % ring->count; 4065 IWP_WRITE(sc, HBUS_TARG_WRPTR, ring->qid << 8 | ring->cur); 4066 4067 return (IWP_SUCCESS); 4068 } 4069 4070 /* 4071 * configure NIC by using ucode commands after loading ucode. 4072 */ 4073 static int 4074 iwp_config(iwp_sc_t *sc) 4075 { 4076 ieee80211com_t *ic = &sc->sc_ic; 4077 iwp_powertable_cmd_t powertable; 4078 iwp_bt_cmd_t bt; 4079 iwp_add_sta_t node; 4080 iwp_rem_sta_t rm_sta; 4081 const uint8_t bcast[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; 4082 int err = IWP_FAIL; 4083 4084 /* 4085 * set power mode. Disable power management at present, do it later 4086 */ 4087 (void) memset(&powertable, 0, sizeof (powertable)); 4088 powertable.flags = LE_16(0x8); 4089 err = iwp_cmd(sc, POWER_TABLE_CMD, &powertable, 4090 sizeof (powertable), 0); 4091 if (err != IWP_SUCCESS) { 4092 cmn_err(CE_WARN, "iwp_config(): " 4093 "failed to set power mode\n"); 4094 return (err); 4095 } 4096 4097 /* 4098 * configure bt coexistence 4099 */ 4100 (void) memset(&bt, 0, sizeof (bt)); 4101 bt.flags = 3; 4102 bt.lead_time = 0xaa; 4103 bt.max_kill = 1; 4104 err = iwp_cmd(sc, REPLY_BT_CONFIG, &bt, 4105 sizeof (bt), 0); 4106 if (err != IWP_SUCCESS) { 4107 cmn_err(CE_WARN, "iwp_config(): " 4108 "failed to configurate bt coexistence\n"); 4109 return (err); 4110 } 4111 4112 /* 4113 * configure rxon 4114 */ 4115 (void) memset(&sc->sc_config, 0, sizeof (iwp_rxon_cmd_t)); 4116 IEEE80211_ADDR_COPY(sc->sc_config.node_addr, ic->ic_macaddr); 4117 IEEE80211_ADDR_COPY(sc->sc_config.wlap_bssid, ic->ic_macaddr); 4118 sc->sc_config.chan = LE_16(ieee80211_chan2ieee(ic, ic->ic_curchan)); 4119 sc->sc_config.flags = LE_32(RXON_FLG_BAND_24G_MSK); 4120 sc->sc_config.flags &= LE_32(~(RXON_FLG_CHANNEL_MODE_MIXED_MSK | 4121 RXON_FLG_CHANNEL_MODE_PURE_40_MSK)); 4122 4123 switch (ic->ic_opmode) { 4124 case IEEE80211_M_STA: 4125 sc->sc_config.dev_type = RXON_DEV_TYPE_ESS; 4126 sc->sc_config.filter_flags |= LE_32(RXON_FILTER_ACCEPT_GRP_MSK | 4127 RXON_FILTER_DIS_DECRYPT_MSK | 4128 RXON_FILTER_DIS_GRP_DECRYPT_MSK); 4129 break; 4130 case IEEE80211_M_IBSS: 4131 case IEEE80211_M_AHDEMO: 4132 sc->sc_config.dev_type = RXON_DEV_TYPE_IBSS; 4133 4134 sc->sc_config.flags |= LE_32(RXON_FLG_SHORT_PREAMBLE_MSK); 4135 sc->sc_config.filter_flags = LE_32(RXON_FILTER_ACCEPT_GRP_MSK | 4136 RXON_FILTER_DIS_DECRYPT_MSK | 4137 RXON_FILTER_DIS_GRP_DECRYPT_MSK); 4138 break; 4139 case IEEE80211_M_HOSTAP: 4140 sc->sc_config.dev_type = RXON_DEV_TYPE_AP; 4141 break; 4142 case IEEE80211_M_MONITOR: 4143 sc->sc_config.dev_type = RXON_DEV_TYPE_SNIFFER; 4144 sc->sc_config.filter_flags |= LE_32(RXON_FILTER_ACCEPT_GRP_MSK | 4145 RXON_FILTER_CTL2HOST_MSK | RXON_FILTER_PROMISC_MSK); 4146 break; 4147 } 4148 4149 /* 4150 * Support all CCK rates. 4151 */ 4152 sc->sc_config.cck_basic_rates = 0x0f; 4153 4154 /* 4155 * Support all OFDM rates. 4156 */ 4157 sc->sc_config.ofdm_basic_rates = 0xff; 4158 4159 sc->sc_config.rx_chain = LE_16(RXON_RX_CHAIN_DRIVER_FORCE_MSK | 4160 (0x7 << RXON_RX_CHAIN_VALID_POS) | 4161 (0x2 << RXON_RX_CHAIN_FORCE_SEL_POS) | 4162 (0x2 << RXON_RX_CHAIN_FORCE_MIMO_SEL_POS)); 4163 4164 err = iwp_cmd(sc, REPLY_RXON, &sc->sc_config, 4165 sizeof (iwp_rxon_cmd_t), 0); 4166 if (err != IWP_SUCCESS) { 4167 cmn_err(CE_WARN, "iwp_config(): " 4168 "failed to set configure command\n"); 4169 return (err); 4170 } 4171 4172 /* 4173 * remove all nodes in NIC 4174 */ 4175 (void) memset(&rm_sta, 0, sizeof (rm_sta)); 4176 rm_sta.num_sta = 1; 4177 (void) memcpy(rm_sta.addr, bcast, 6); 4178 4179 err = iwp_cmd(sc, REPLY_REMOVE_STA, &rm_sta, sizeof (iwp_rem_sta_t), 0); 4180 if (err != IWP_SUCCESS) { 4181 cmn_err(CE_WARN, "iwp_config(): " 4182 "failed to remove broadcast node in hardware.\n"); 4183 return (err); 4184 } 4185 4186 /* 4187 * add broadcast node so that we can send broadcast frame 4188 */ 4189 (void) memset(&node, 0, sizeof (node)); 4190 (void) memset(node.sta.addr, 0xff, 6); 4191 node.mode = 0; 4192 node.sta.sta_id = IWP_BROADCAST_ID; 4193 node.station_flags = 0; 4194 4195 err = iwp_cmd(sc, REPLY_ADD_STA, &node, sizeof (node), 0); 4196 if (err != IWP_SUCCESS) { 4197 cmn_err(CE_WARN, "iwp_config(): " 4198 "failed to add broadcast node\n"); 4199 return (err); 4200 } 4201 4202 return (err); 4203 } 4204 4205 /* 4206 * quiesce(9E) entry point. 4207 * This function is called when the system is single-threaded at high 4208 * PIL with preemption disabled. Therefore, this function must not be 4209 * blocked. 4210 * This function returns DDI_SUCCESS on success, or DDI_FAILURE on failure. 4211 * DDI_FAILURE indicates an error condition and should almost never happen. 4212 */ 4213 static int 4214 iwp_quiesce(dev_info_t *dip) 4215 { 4216 iwp_sc_t *sc; 4217 4218 sc = ddi_get_soft_state(iwp_soft_state_p, ddi_get_instance(dip)); 4219 if (NULL == sc) { 4220 return (DDI_FAILURE); 4221 } 4222 4223 #ifdef DEBUG 4224 /* by pass any messages, if it's quiesce */ 4225 iwp_dbg_flags = 0; 4226 #endif 4227 4228 /* 4229 * No more blocking is allowed while we are in the 4230 * quiesce(9E) entry point. 4231 */ 4232 atomic_or_32(&sc->sc_flags, IWP_F_QUIESCED); 4233 4234 /* 4235 * Disable and mask all interrupts. 4236 */ 4237 iwp_stop(sc); 4238 4239 return (DDI_SUCCESS); 4240 } 4241 4242 static void 4243 iwp_stop_master(iwp_sc_t *sc) 4244 { 4245 uint32_t tmp; 4246 int n; 4247 4248 tmp = IWP_READ(sc, CSR_RESET); 4249 IWP_WRITE(sc, CSR_RESET, tmp | CSR_RESET_REG_FLAG_STOP_MASTER); 4250 4251 tmp = IWP_READ(sc, CSR_GP_CNTRL); 4252 if ((tmp & CSR_GP_CNTRL_REG_MSK_POWER_SAVE_TYPE) == 4253 CSR_GP_CNTRL_REG_FLAG_MAC_POWER_SAVE) { 4254 return; 4255 } 4256 4257 for (n = 0; n < 2000; n++) { 4258 if (IWP_READ(sc, CSR_RESET) & 4259 CSR_RESET_REG_FLAG_MASTER_DISABLED) { 4260 break; 4261 } 4262 DELAY(1000); 4263 } 4264 4265 #ifdef DEBUG 4266 if (2000 == n) { 4267 IWP_DBG((IWP_DEBUG_HW, "iwp_stop_master(): " 4268 "timeout waiting for master stop\n")); 4269 } 4270 #endif 4271 } 4272 4273 static int 4274 iwp_power_up(iwp_sc_t *sc) 4275 { 4276 uint32_t tmp; 4277 4278 iwp_mac_access_enter(sc); 4279 tmp = iwp_reg_read(sc, ALM_APMG_PS_CTL); 4280 tmp &= ~APMG_PS_CTRL_REG_MSK_POWER_SRC; 4281 tmp |= APMG_PS_CTRL_REG_VAL_POWER_SRC_VMAIN; 4282 iwp_reg_write(sc, ALM_APMG_PS_CTL, tmp); 4283 iwp_mac_access_exit(sc); 4284 4285 DELAY(5000); 4286 return (IWP_SUCCESS); 4287 } 4288 4289 /* 4290 * hardware initialization 4291 */ 4292 static int 4293 iwp_preinit(iwp_sc_t *sc) 4294 { 4295 int n; 4296 uint8_t vlink; 4297 uint16_t radio_cfg; 4298 uint32_t tmp; 4299 4300 /* 4301 * clear any pending interrupts 4302 */ 4303 IWP_WRITE(sc, CSR_INT, 0xffffffff); 4304 4305 tmp = IWP_READ(sc, CSR_GIO_CHICKEN_BITS); 4306 IWP_WRITE(sc, CSR_GIO_CHICKEN_BITS, 4307 tmp | CSR_GIO_CHICKEN_BITS_REG_BIT_DIS_L0S_EXIT_TIMER); 4308 4309 tmp = IWP_READ(sc, CSR_GP_CNTRL); 4310 IWP_WRITE(sc, CSR_GP_CNTRL, tmp | CSR_GP_CNTRL_REG_FLAG_INIT_DONE); 4311 4312 /* 4313 * wait for clock ready 4314 */ 4315 for (n = 0; n < 1000; n++) { 4316 if (IWP_READ(sc, CSR_GP_CNTRL) & 4317 CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY) { 4318 break; 4319 } 4320 DELAY(10); 4321 } 4322 4323 if (1000 == n) { 4324 return (ETIMEDOUT); 4325 } 4326 4327 iwp_mac_access_enter(sc); 4328 4329 iwp_reg_write(sc, ALM_APMG_CLK_EN, APMG_CLK_REG_VAL_DMA_CLK_RQT); 4330 4331 DELAY(20); 4332 tmp = iwp_reg_read(sc, ALM_APMG_PCIDEV_STT); 4333 iwp_reg_write(sc, ALM_APMG_PCIDEV_STT, tmp | 4334 APMG_DEV_STATE_REG_VAL_L1_ACTIVE_DISABLE); 4335 iwp_mac_access_exit(sc); 4336 4337 radio_cfg = IWP_READ_EEP_SHORT(sc, EEP_SP_RADIO_CONFIGURATION); 4338 if (SP_RADIO_TYPE_MSK(radio_cfg) < SP_RADIO_TYPE_MAX) { 4339 tmp = IWP_READ(sc, CSR_HW_IF_CONFIG_REG); 4340 IWP_WRITE(sc, CSR_HW_IF_CONFIG_REG, 4341 tmp | SP_RADIO_TYPE_MSK(radio_cfg) | 4342 SP_RADIO_STEP_MSK(radio_cfg) | 4343 SP_RADIO_DASH_MSK(radio_cfg)); 4344 } else { 4345 cmn_err(CE_WARN, "iwp_preinit(): " 4346 "radio configuration information in eeprom is wrong\n"); 4347 return (IWP_FAIL); 4348 } 4349 4350 4351 IWP_WRITE(sc, CSR_INT_COALESCING, 512 / 32); 4352 4353 (void) iwp_power_up(sc); 4354 4355 if ((sc->sc_rev & 0x80) == 0x80 && (sc->sc_rev & 0x7f) < 8) { 4356 tmp = ddi_get32(sc->sc_cfg_handle, 4357 (uint32_t *)(sc->sc_cfg_base + 0xe8)); 4358 ddi_put32(sc->sc_cfg_handle, 4359 (uint32_t *)(sc->sc_cfg_base + 0xe8), 4360 tmp & ~(1 << 11)); 4361 } 4362 4363 vlink = ddi_get8(sc->sc_cfg_handle, 4364 (uint8_t *)(sc->sc_cfg_base + 0xf0)); 4365 ddi_put8(sc->sc_cfg_handle, (uint8_t *)(sc->sc_cfg_base + 0xf0), 4366 vlink & ~2); 4367 4368 tmp = IWP_READ(sc, CSR_HW_IF_CONFIG_REG); 4369 tmp |= CSR_HW_IF_CONFIG_REG_BIT_RADIO_SI | 4370 CSR_HW_IF_CONFIG_REG_BIT_MAC_SI; 4371 IWP_WRITE(sc, CSR_HW_IF_CONFIG_REG, tmp); 4372 4373 /* 4374 * make sure power supply on each part of the hardware 4375 */ 4376 iwp_mac_access_enter(sc); 4377 tmp = iwp_reg_read(sc, ALM_APMG_PS_CTL); 4378 tmp |= APMG_PS_CTRL_REG_VAL_ALM_R_RESET_REQ; 4379 iwp_reg_write(sc, ALM_APMG_PS_CTL, tmp); 4380 DELAY(5); 4381 4382 tmp = iwp_reg_read(sc, ALM_APMG_PS_CTL); 4383 tmp &= ~APMG_PS_CTRL_REG_VAL_ALM_R_RESET_REQ; 4384 iwp_reg_write(sc, ALM_APMG_PS_CTL, tmp); 4385 iwp_mac_access_exit(sc); 4386 4387 if (PA_TYPE_MIX == sc->sc_chip_param.pa_type) { 4388 IWP_WRITE(sc, CSR_GP_DRIVER_REG, 4389 CSR_GP_DRIVER_REG_BIT_RADIO_SKU_2x2_MIX); 4390 } 4391 4392 if (PA_TYPE_INTER == sc->sc_chip_param.pa_type) { 4393 4394 IWP_WRITE(sc, CSR_GP_DRIVER_REG, 4395 CSR_GP_DRIVER_REG_BIT_RADIO_SKU_2x2_IPA); 4396 } 4397 4398 return (IWP_SUCCESS); 4399 } 4400 4401 /* 4402 * set up semphore flag to own EEPROM 4403 */ 4404 static int 4405 iwp_eep_sem_down(iwp_sc_t *sc) 4406 { 4407 int count1, count2; 4408 uint32_t tmp; 4409 4410 for (count1 = 0; count1 < 1000; count1++) { 4411 tmp = IWP_READ(sc, CSR_HW_IF_CONFIG_REG); 4412 IWP_WRITE(sc, CSR_HW_IF_CONFIG_REG, 4413 tmp | CSR_HW_IF_CONFIG_REG_EEP_SEM); 4414 4415 for (count2 = 0; count2 < 2; count2++) { 4416 if (IWP_READ(sc, CSR_HW_IF_CONFIG_REG) & 4417 CSR_HW_IF_CONFIG_REG_EEP_SEM) { 4418 return (IWP_SUCCESS); 4419 } 4420 DELAY(10000); 4421 } 4422 } 4423 return (IWP_FAIL); 4424 } 4425 4426 /* 4427 * reset semphore flag to release EEPROM 4428 */ 4429 static void 4430 iwp_eep_sem_up(iwp_sc_t *sc) 4431 { 4432 uint32_t tmp; 4433 4434 tmp = IWP_READ(sc, CSR_HW_IF_CONFIG_REG); 4435 IWP_WRITE(sc, CSR_HW_IF_CONFIG_REG, 4436 tmp & (~CSR_HW_IF_CONFIG_REG_EEP_SEM)); 4437 } 4438 4439 /* 4440 * This function read all infomation from eeprom 4441 */ 4442 static int 4443 iwp_eep_load(iwp_sc_t *sc) 4444 { 4445 int i, rr; 4446 uint32_t rv, tmp, eep_gp; 4447 uint16_t addr, eep_sz = sizeof (sc->sc_eep_map); 4448 uint16_t *eep_p = (uint16_t *)&sc->sc_eep_map; 4449 4450 /* 4451 * read eeprom gp register in CSR 4452 */ 4453 eep_gp = IWP_READ(sc, CSR_EEPROM_GP); 4454 if ((eep_gp & CSR_EEPROM_GP_VALID_MSK) == 4455 CSR_EEPROM_GP_BAD_SIGNATURE) { 4456 IWP_DBG((IWP_DEBUG_EEPROM, "iwp_eep_load(): " 4457 "not find eeprom\n")); 4458 return (IWP_FAIL); 4459 } 4460 4461 rr = iwp_eep_sem_down(sc); 4462 if (rr != 0) { 4463 IWP_DBG((IWP_DEBUG_EEPROM, "iwp_eep_load(): " 4464 "driver failed to own EEPROM\n")); 4465 return (IWP_FAIL); 4466 } 4467 4468 for (addr = 0; addr < eep_sz; addr += 2) { 4469 IWP_WRITE(sc, CSR_EEPROM_REG, addr<<1); 4470 tmp = IWP_READ(sc, CSR_EEPROM_REG); 4471 IWP_WRITE(sc, CSR_EEPROM_REG, tmp & ~(0x2)); 4472 4473 for (i = 0; i < 10; i++) { 4474 rv = IWP_READ(sc, CSR_EEPROM_REG); 4475 if (rv & 1) { 4476 break; 4477 } 4478 DELAY(10); 4479 } 4480 4481 if (!(rv & 1)) { 4482 IWP_DBG((IWP_DEBUG_EEPROM, "iwp_eep_load(): " 4483 "time out when read eeprome\n")); 4484 iwp_eep_sem_up(sc); 4485 return (IWP_FAIL); 4486 } 4487 4488 eep_p[addr/2] = LE_16(rv >> 16); 4489 } 4490 4491 iwp_eep_sem_up(sc); 4492 return (IWP_SUCCESS); 4493 } 4494 4495 /* 4496 * initialize mac address in ieee80211com_t struct 4497 */ 4498 static void 4499 iwp_get_mac_from_eep(iwp_sc_t *sc) 4500 { 4501 ieee80211com_t *ic = &sc->sc_ic; 4502 4503 IEEE80211_ADDR_COPY(ic->ic_macaddr, &sc->sc_eep_map[EEP_MAC_ADDRESS]); 4504 4505 IWP_DBG((IWP_DEBUG_EEPROM, "iwp_get_mac_from_eep(): " 4506 "mac:%2x:%2x:%2x:%2x:%2x:%2x\n", 4507 ic->ic_macaddr[0], ic->ic_macaddr[1], ic->ic_macaddr[2], 4508 ic->ic_macaddr[3], ic->ic_macaddr[4], ic->ic_macaddr[5])); 4509 } 4510 4511 /* 4512 * main initialization function 4513 */ 4514 static int 4515 iwp_init(iwp_sc_t *sc) 4516 { 4517 int err = IWP_FAIL; 4518 clock_t clk; 4519 4520 /* 4521 * release buffer for calibration 4522 */ 4523 iwp_release_calib_buffer(sc); 4524 4525 mutex_enter(&sc->sc_glock); 4526 atomic_and_32(&sc->sc_flags, ~IWP_F_FW_INIT); 4527 4528 err = iwp_init_common(sc); 4529 if (err != IWP_SUCCESS) { 4530 mutex_exit(&sc->sc_glock); 4531 return (IWP_FAIL); 4532 } 4533 4534 /* 4535 * backup ucode data part for future use. 4536 */ 4537 (void) memcpy(sc->sc_dma_fw_data_bak.mem_va, 4538 sc->sc_dma_fw_data.mem_va, 4539 sc->sc_dma_fw_data.alength); 4540 4541 /* load firmware init segment into NIC */ 4542 err = iwp_load_init_firmware(sc); 4543 if (err != IWP_SUCCESS) { 4544 cmn_err(CE_WARN, "iwp_init(): " 4545 "failed to setup init firmware\n"); 4546 mutex_exit(&sc->sc_glock); 4547 return (IWP_FAIL); 4548 } 4549 4550 /* 4551 * now press "execute" start running 4552 */ 4553 IWP_WRITE(sc, CSR_RESET, 0); 4554 4555 clk = ddi_get_lbolt() + drv_usectohz(1000000); 4556 while (!(sc->sc_flags & IWP_F_FW_INIT)) { 4557 if (cv_timedwait(&sc->sc_ucode_cv, 4558 &sc->sc_glock, clk) < 0) { 4559 break; 4560 } 4561 } 4562 4563 if (!(sc->sc_flags & IWP_F_FW_INIT)) { 4564 cmn_err(CE_WARN, "iwp_init(): " 4565 "failed to process init alive.\n"); 4566 mutex_exit(&sc->sc_glock); 4567 return (IWP_FAIL); 4568 } 4569 4570 mutex_exit(&sc->sc_glock); 4571 4572 /* 4573 * stop chipset for initializing chipset again 4574 */ 4575 iwp_stop(sc); 4576 4577 mutex_enter(&sc->sc_glock); 4578 atomic_and_32(&sc->sc_flags, ~IWP_F_FW_INIT); 4579 4580 err = iwp_init_common(sc); 4581 if (err != IWP_SUCCESS) { 4582 mutex_exit(&sc->sc_glock); 4583 return (IWP_FAIL); 4584 } 4585 4586 /* 4587 * load firmware run segment into NIC 4588 */ 4589 err = iwp_load_run_firmware(sc); 4590 if (err != IWP_SUCCESS) { 4591 cmn_err(CE_WARN, "iwp_init(): " 4592 "failed to setup run firmware\n"); 4593 mutex_exit(&sc->sc_glock); 4594 return (IWP_FAIL); 4595 } 4596 4597 /* 4598 * now press "execute" start running 4599 */ 4600 IWP_WRITE(sc, CSR_RESET, 0); 4601 4602 clk = ddi_get_lbolt() + drv_usectohz(1000000); 4603 while (!(sc->sc_flags & IWP_F_FW_INIT)) { 4604 if (cv_timedwait(&sc->sc_ucode_cv, 4605 &sc->sc_glock, clk) < 0) { 4606 break; 4607 } 4608 } 4609 4610 if (!(sc->sc_flags & IWP_F_FW_INIT)) { 4611 cmn_err(CE_WARN, "iwp_init(): " 4612 "failed to process runtime alive.\n"); 4613 mutex_exit(&sc->sc_glock); 4614 return (IWP_FAIL); 4615 } 4616 4617 mutex_exit(&sc->sc_glock); 4618 4619 DELAY(1000); 4620 4621 mutex_enter(&sc->sc_glock); 4622 atomic_and_32(&sc->sc_flags, ~IWP_F_FW_INIT); 4623 4624 /* 4625 * at this point, the firmware is loaded OK, then config the hardware 4626 * with the ucode API, including rxon, txpower, etc. 4627 */ 4628 err = iwp_config(sc); 4629 if (err) { 4630 cmn_err(CE_WARN, "iwp_init(): " 4631 "failed to configure device\n"); 4632 mutex_exit(&sc->sc_glock); 4633 return (IWP_FAIL); 4634 } 4635 4636 /* 4637 * at this point, hardware may receive beacons :) 4638 */ 4639 mutex_exit(&sc->sc_glock); 4640 return (IWP_SUCCESS); 4641 } 4642 4643 /* 4644 * stop or disable NIC 4645 */ 4646 static void 4647 iwp_stop(iwp_sc_t *sc) 4648 { 4649 uint32_t tmp; 4650 int i; 4651 4652 /* by pass if it's quiesced */ 4653 if (!(sc->sc_flags & IWP_F_QUIESCED)) { 4654 mutex_enter(&sc->sc_glock); 4655 } 4656 4657 IWP_WRITE(sc, CSR_RESET, CSR_RESET_REG_FLAG_NEVO_RESET); 4658 /* 4659 * disable interrupts 4660 */ 4661 IWP_WRITE(sc, CSR_INT_MASK, 0); 4662 IWP_WRITE(sc, CSR_INT, CSR_INI_SET_MASK); 4663 IWP_WRITE(sc, CSR_FH_INT_STATUS, 0xffffffff); 4664 4665 /* 4666 * reset all Tx rings 4667 */ 4668 for (i = 0; i < IWP_NUM_QUEUES; i++) { 4669 iwp_reset_tx_ring(sc, &sc->sc_txq[i]); 4670 } 4671 4672 /* 4673 * reset Rx ring 4674 */ 4675 iwp_reset_rx_ring(sc); 4676 4677 iwp_mac_access_enter(sc); 4678 iwp_reg_write(sc, ALM_APMG_CLK_DIS, APMG_CLK_REG_VAL_DMA_CLK_RQT); 4679 iwp_mac_access_exit(sc); 4680 4681 DELAY(5); 4682 4683 iwp_stop_master(sc); 4684 4685 mutex_enter(&sc->sc_mt_lock); 4686 sc->sc_tx_timer = 0; 4687 mutex_exit(&sc->sc_mt_lock); 4688 4689 tmp = IWP_READ(sc, CSR_RESET); 4690 IWP_WRITE(sc, CSR_RESET, tmp | CSR_RESET_REG_FLAG_SW_RESET); 4691 4692 /* by pass if it's quiesced */ 4693 if (!(sc->sc_flags & IWP_F_QUIESCED)) { 4694 mutex_exit(&sc->sc_glock); 4695 } 4696 } 4697 4698 /* 4699 * Naive implementation of the Adaptive Multi Rate Retry algorithm: 4700 * "IEEE 802.11 Rate Adaptation: A Practical Approach" 4701 * Mathieu Lacage, Hossein Manshaei, Thierry Turletti 4702 * INRIA Sophia - Projet Planete 4703 * http://www-sop.inria.fr/rapports/sophia/RR-5208.html 4704 */ 4705 #define is_success(amrr) \ 4706 ((amrr)->retrycnt < (amrr)->txcnt / 10) 4707 #define is_failure(amrr) \ 4708 ((amrr)->retrycnt > (amrr)->txcnt / 3) 4709 #define is_enough(amrr) \ 4710 ((amrr)->txcnt > 200) 4711 #define not_very_few(amrr) \ 4712 ((amrr)->txcnt > 40) 4713 #define is_min_rate(in) \ 4714 (0 == (in)->in_txrate) 4715 #define is_max_rate(in) \ 4716 ((in)->in_rates.ir_nrates - 1 == (in)->in_txrate) 4717 #define increase_rate(in) \ 4718 ((in)->in_txrate++) 4719 #define decrease_rate(in) \ 4720 ((in)->in_txrate--) 4721 #define reset_cnt(amrr) \ 4722 { (amrr)->txcnt = (amrr)->retrycnt = 0; } 4723 4724 #define IWP_AMRR_MIN_SUCCESS_THRESHOLD 1 4725 #define IWP_AMRR_MAX_SUCCESS_THRESHOLD 15 4726 4727 static void 4728 iwp_amrr_init(iwp_amrr_t *amrr) 4729 { 4730 amrr->success = 0; 4731 amrr->recovery = 0; 4732 amrr->txcnt = amrr->retrycnt = 0; 4733 amrr->success_threshold = IWP_AMRR_MIN_SUCCESS_THRESHOLD; 4734 } 4735 4736 static void 4737 iwp_amrr_timeout(iwp_sc_t *sc) 4738 { 4739 ieee80211com_t *ic = &sc->sc_ic; 4740 4741 IWP_DBG((IWP_DEBUG_RATECTL, "iwp_amrr_timeout(): " 4742 "enter\n")); 4743 4744 if (IEEE80211_M_STA == ic->ic_opmode) { 4745 iwp_amrr_ratectl(NULL, ic->ic_bss); 4746 } else { 4747 ieee80211_iterate_nodes(&ic->ic_sta, iwp_amrr_ratectl, NULL); 4748 } 4749 4750 sc->sc_clk = ddi_get_lbolt(); 4751 } 4752 4753 /* ARGSUSED */ 4754 static void 4755 iwp_amrr_ratectl(void *arg, ieee80211_node_t *in) 4756 { 4757 iwp_amrr_t *amrr = (iwp_amrr_t *)in; 4758 int need_change = 0; 4759 4760 if (is_success(amrr) && is_enough(amrr)) { 4761 amrr->success++; 4762 if (amrr->success >= amrr->success_threshold && 4763 !is_max_rate(in)) { 4764 amrr->recovery = 1; 4765 amrr->success = 0; 4766 increase_rate(in); 4767 IWP_DBG((IWP_DEBUG_RATECTL, "iwp_amrr_ratectl(): " 4768 "AMRR increasing rate %d " 4769 "(txcnt=%d retrycnt=%d)\n", 4770 in->in_txrate, amrr->txcnt, 4771 amrr->retrycnt)); 4772 need_change = 1; 4773 } else { 4774 amrr->recovery = 0; 4775 } 4776 } else if (not_very_few(amrr) && is_failure(amrr)) { 4777 amrr->success = 0; 4778 if (!is_min_rate(in)) { 4779 if (amrr->recovery) { 4780 amrr->success_threshold++; 4781 if (amrr->success_threshold > 4782 IWP_AMRR_MAX_SUCCESS_THRESHOLD) { 4783 amrr->success_threshold = 4784 IWP_AMRR_MAX_SUCCESS_THRESHOLD; 4785 } 4786 } else { 4787 amrr->success_threshold = 4788 IWP_AMRR_MIN_SUCCESS_THRESHOLD; 4789 } 4790 decrease_rate(in); 4791 IWP_DBG((IWP_DEBUG_RATECTL, "iwp_amrr_ratectl(): " 4792 "AMRR decreasing rate %d " 4793 "(txcnt=%d retrycnt=%d)\n", 4794 in->in_txrate, amrr->txcnt, 4795 amrr->retrycnt)); 4796 need_change = 1; 4797 } 4798 amrr->recovery = 0; /* paper is incorrect */ 4799 } 4800 4801 if (is_enough(amrr) || need_change) { 4802 reset_cnt(amrr); 4803 } 4804 } 4805 4806 /* 4807 * translate indirect address in eeprom to direct address 4808 * in eeprom and return address of entry whos indirect address 4809 * is indi_addr 4810 */ 4811 static uint8_t * 4812 iwp_eep_addr_trans(iwp_sc_t *sc, uint32_t indi_addr) 4813 { 4814 uint32_t di_addr; 4815 uint16_t temp; 4816 4817 if (!(indi_addr & INDIRECT_ADDRESS)) { 4818 di_addr = indi_addr; 4819 return (&sc->sc_eep_map[di_addr]); 4820 } 4821 4822 switch (indi_addr & INDIRECT_TYPE_MSK) { 4823 case INDIRECT_GENERAL: 4824 temp = IWP_READ_EEP_SHORT(sc, EEP_LINK_GENERAL); 4825 break; 4826 case INDIRECT_HOST: 4827 temp = IWP_READ_EEP_SHORT(sc, EEP_LINK_HOST); 4828 break; 4829 case INDIRECT_REGULATORY: 4830 temp = IWP_READ_EEP_SHORT(sc, EEP_LINK_REGULATORY); 4831 break; 4832 case INDIRECT_CALIBRATION: 4833 temp = IWP_READ_EEP_SHORT(sc, EEP_LINK_CALIBRATION); 4834 break; 4835 case INDIRECT_PROCESS_ADJST: 4836 temp = IWP_READ_EEP_SHORT(sc, EEP_LINK_PROCESS_ADJST); 4837 break; 4838 case INDIRECT_OTHERS: 4839 temp = IWP_READ_EEP_SHORT(sc, EEP_LINK_OTHERS); 4840 break; 4841 default: 4842 temp = 0; 4843 cmn_err(CE_WARN, "iwp_eep_addr_trans(): " 4844 "incorrect indirect eeprom address.\n"); 4845 break; 4846 } 4847 4848 di_addr = (indi_addr & ADDRESS_MSK) + (temp << 1); 4849 4850 return (&sc->sc_eep_map[di_addr]); 4851 } 4852 4853 /* 4854 * loade a section of ucode into NIC 4855 */ 4856 static int 4857 iwp_put_seg_fw(iwp_sc_t *sc, uint32_t addr_s, uint32_t addr_d, uint32_t len) 4858 { 4859 4860 iwp_mac_access_enter(sc); 4861 4862 IWP_WRITE(sc, IWP_FH_TCSR_CHNL_TX_CONFIG_REG(IWP_FH_SRVC_CHNL), 4863 IWP_FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_PAUSE); 4864 4865 IWP_WRITE(sc, IWP_FH_SRVC_CHNL_SRAM_ADDR_REG(IWP_FH_SRVC_CHNL), addr_d); 4866 4867 IWP_WRITE(sc, IWP_FH_TFDIB_CTRL0_REG(IWP_FH_SRVC_CHNL), 4868 (addr_s & FH_MEM_TFDIB_DRAM_ADDR_LSB_MASK)); 4869 4870 IWP_WRITE(sc, IWP_FH_TFDIB_CTRL1_REG(IWP_FH_SRVC_CHNL), len); 4871 4872 IWP_WRITE(sc, IWP_FH_TCSR_CHNL_TX_BUF_STS_REG(IWP_FH_SRVC_CHNL), 4873 (1 << IWP_FH_TCSR_CHNL_TX_BUF_STS_REG_POS_TB_NUM) | 4874 (1 << IWP_FH_TCSR_CHNL_TX_BUF_STS_REG_POS_TB_IDX) | 4875 IWP_FH_TCSR_CHNL_TX_BUF_STS_REG_VAL_TFDB_VALID); 4876 4877 IWP_WRITE(sc, IWP_FH_TCSR_CHNL_TX_CONFIG_REG(IWP_FH_SRVC_CHNL), 4878 IWP_FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_ENABLE | 4879 IWP_FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_DISABLE_VAL | 4880 IWP_FH_TCSR_TX_CONFIG_REG_VAL_CIRQ_HOST_ENDTFD); 4881 4882 iwp_mac_access_exit(sc); 4883 4884 return (IWP_SUCCESS); 4885 } 4886 4887 /* 4888 * necessary setting during alive notification 4889 */ 4890 static int 4891 iwp_alive_common(iwp_sc_t *sc) 4892 { 4893 uint32_t base; 4894 uint32_t i; 4895 iwp_wimax_coex_cmd_t w_cmd; 4896 iwp_calibration_crystal_cmd_t c_cmd; 4897 uint32_t rv = IWP_FAIL; 4898 4899 /* 4900 * initialize SCD related registers to make TX work. 4901 */ 4902 iwp_mac_access_enter(sc); 4903 4904 /* 4905 * read sram address of data base. 4906 */ 4907 sc->sc_scd_base = iwp_reg_read(sc, IWP_SCD_SRAM_BASE_ADDR); 4908 4909 for (base = sc->sc_scd_base + IWP_SCD_CONTEXT_DATA_OFFSET; 4910 base < sc->sc_scd_base + IWP_SCD_TX_STTS_BITMAP_OFFSET; 4911 base += 4) { 4912 iwp_mem_write(sc, base, 0); 4913 } 4914 4915 for (; base < sc->sc_scd_base + IWP_SCD_TRANSLATE_TBL_OFFSET; 4916 base += 4) { 4917 iwp_mem_write(sc, base, 0); 4918 } 4919 4920 for (i = 0; i < sizeof (uint16_t) * IWP_NUM_QUEUES; i += 4) { 4921 iwp_mem_write(sc, base + i, 0); 4922 } 4923 4924 iwp_reg_write(sc, IWP_SCD_DRAM_BASE_ADDR, 4925 sc->sc_dma_sh.cookie.dmac_address >> 10); 4926 4927 iwp_reg_write(sc, IWP_SCD_QUEUECHAIN_SEL, 4928 IWP_SCD_QUEUECHAIN_SEL_ALL(IWP_NUM_QUEUES)); 4929 4930 iwp_reg_write(sc, IWP_SCD_AGGR_SEL, 0); 4931 4932 for (i = 0; i < IWP_NUM_QUEUES; i++) { 4933 iwp_reg_write(sc, IWP_SCD_QUEUE_RDPTR(i), 0); 4934 IWP_WRITE(sc, HBUS_TARG_WRPTR, 0 | (i << 8)); 4935 iwp_mem_write(sc, sc->sc_scd_base + 4936 IWP_SCD_CONTEXT_QUEUE_OFFSET(i), 0); 4937 iwp_mem_write(sc, sc->sc_scd_base + 4938 IWP_SCD_CONTEXT_QUEUE_OFFSET(i) + 4939 sizeof (uint32_t), 4940 ((SCD_WIN_SIZE << IWP_SCD_QUEUE_CTX_REG2_WIN_SIZE_POS) & 4941 IWP_SCD_QUEUE_CTX_REG2_WIN_SIZE_MSK) | 4942 ((SCD_FRAME_LIMIT << 4943 IWP_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_POS) & 4944 IWP_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_MSK)); 4945 } 4946 4947 iwp_reg_write(sc, IWP_SCD_INTERRUPT_MASK, (1 << IWP_NUM_QUEUES) - 1); 4948 4949 iwp_reg_write(sc, (IWP_SCD_BASE + 0x10), 4950 SCD_TXFACT_REG_TXFIFO_MASK(0, 7)); 4951 4952 IWP_WRITE(sc, HBUS_TARG_WRPTR, (IWP_CMD_QUEUE_NUM << 8)); 4953 iwp_reg_write(sc, IWP_SCD_QUEUE_RDPTR(IWP_CMD_QUEUE_NUM), 0); 4954 4955 /* 4956 * queue 0-7 map to FIFO 0-7 and 4957 * all queues work under FIFO mode(none-scheduler_ack) 4958 */ 4959 for (i = 0; i < 4; i++) { 4960 iwp_reg_write(sc, IWP_SCD_QUEUE_STATUS_BITS(i), 4961 (1 << IWP_SCD_QUEUE_STTS_REG_POS_ACTIVE) | 4962 ((3-i) << IWP_SCD_QUEUE_STTS_REG_POS_TXF) | 4963 (1 << IWP_SCD_QUEUE_STTS_REG_POS_WSL) | 4964 IWP_SCD_QUEUE_STTS_REG_MSK); 4965 } 4966 4967 iwp_reg_write(sc, IWP_SCD_QUEUE_STATUS_BITS(IWP_CMD_QUEUE_NUM), 4968 (1 << IWP_SCD_QUEUE_STTS_REG_POS_ACTIVE) | 4969 (IWP_CMD_FIFO_NUM << IWP_SCD_QUEUE_STTS_REG_POS_TXF) | 4970 (1 << IWP_SCD_QUEUE_STTS_REG_POS_WSL) | 4971 IWP_SCD_QUEUE_STTS_REG_MSK); 4972 4973 for (i = 5; i < 7; i++) { 4974 iwp_reg_write(sc, IWP_SCD_QUEUE_STATUS_BITS(i), 4975 (1 << IWP_SCD_QUEUE_STTS_REG_POS_ACTIVE) | 4976 (i << IWP_SCD_QUEUE_STTS_REG_POS_TXF) | 4977 (1 << IWP_SCD_QUEUE_STTS_REG_POS_WSL) | 4978 IWP_SCD_QUEUE_STTS_REG_MSK); 4979 } 4980 4981 iwp_mac_access_exit(sc); 4982 4983 (void) memset(&w_cmd, 0, sizeof (w_cmd)); 4984 4985 rv = iwp_cmd(sc, COEX_PRIORITY_TABLE_CMD, &w_cmd, sizeof (w_cmd), 1); 4986 if (rv != IWP_SUCCESS) { 4987 cmn_err(CE_WARN, "iwp_alive_common(): " 4988 "failed to send wimax coexist command.\n"); 4989 return (rv); 4990 } 4991 4992 (void) memset(&c_cmd, 0, sizeof (c_cmd)); 4993 4994 c_cmd.opCode = PHY_CALIBRATE_CRYSTAL_FRQ_CMD; 4995 c_cmd.data.cap_pin1 = LE_16(sc->sc_eep_calib->xtal_calib[0]); 4996 c_cmd.data.cap_pin2 = LE_16(sc->sc_eep_calib->xtal_calib[1]); 4997 4998 rv = iwp_cmd(sc, REPLY_PHY_CALIBRATION_CMD, &c_cmd, sizeof (c_cmd), 1); 4999 if (rv != IWP_SUCCESS) { 5000 cmn_err(CE_WARN, "iwp_alive_common(): " 5001 "failed to send crystal frq calibration command.\n"); 5002 return (rv); 5003 } 5004 5005 /* 5006 * make sure crystal frequency calibration ready 5007 * before next operations. 5008 */ 5009 DELAY(1000); 5010 5011 return (IWP_SUCCESS); 5012 } 5013 5014 /* 5015 * save results of calibration from ucode 5016 */ 5017 static void 5018 iwp_save_calib_result(iwp_sc_t *sc, iwp_rx_desc_t *desc) 5019 { 5020 struct iwp_calib_results *res_p = &sc->sc_calib_results; 5021 struct iwp_calib_hdr *calib_hdr = (struct iwp_calib_hdr *)(desc + 1); 5022 int len = LE_32(desc->len); 5023 5024 /* 5025 * ensure the size of buffer is not too big 5026 */ 5027 len = (len & FH_RSCSR_FRAME_SIZE_MASK) - 4; 5028 5029 switch (calib_hdr->op_code) { 5030 case PHY_CALIBRATE_LO_CMD: 5031 if (NULL == res_p->lo_res) { 5032 res_p->lo_res = kmem_alloc(len, KM_NOSLEEP); 5033 } 5034 5035 if (NULL == res_p->lo_res) { 5036 cmn_err(CE_WARN, "iwp_save_calib_result(): " 5037 "failed to allocate memory.\n"); 5038 return; 5039 } 5040 5041 res_p->lo_res_len = len; 5042 (void) memcpy(res_p->lo_res, calib_hdr, len); 5043 break; 5044 case PHY_CALIBRATE_TX_IQ_CMD: 5045 if (NULL == res_p->tx_iq_res) { 5046 res_p->tx_iq_res = kmem_alloc(len, KM_NOSLEEP); 5047 } 5048 5049 if (NULL == res_p->tx_iq_res) { 5050 cmn_err(CE_WARN, "iwp_save_calib_result(): " 5051 "failed to allocate memory.\n"); 5052 return; 5053 } 5054 5055 res_p->tx_iq_res_len = len; 5056 (void) memcpy(res_p->tx_iq_res, calib_hdr, len); 5057 break; 5058 case PHY_CALIBRATE_TX_IQ_PERD_CMD: 5059 if (NULL == res_p->tx_iq_perd_res) { 5060 res_p->tx_iq_perd_res = kmem_alloc(len, KM_NOSLEEP); 5061 } 5062 5063 if (NULL == res_p->tx_iq_perd_res) { 5064 cmn_err(CE_WARN, "iwp_save_calib_result(): " 5065 "failed to allocate memory.\n"); 5066 } 5067 5068 res_p->tx_iq_perd_res_len = len; 5069 (void) memcpy(res_p->tx_iq_perd_res, calib_hdr, len); 5070 break; 5071 case PHY_CALIBRATE_BASE_BAND_CMD: 5072 if (NULL == res_p->base_band_res) { 5073 res_p->base_band_res = kmem_alloc(len, KM_NOSLEEP); 5074 } 5075 5076 if (NULL == res_p->base_band_res) { 5077 cmn_err(CE_WARN, "iwp_save_calib_result(): " 5078 "failed to allocate memory.\n"); 5079 } 5080 5081 res_p->base_band_res_len = len; 5082 (void) memcpy(res_p->base_band_res, calib_hdr, len); 5083 break; 5084 default: 5085 cmn_err(CE_WARN, "iwp_save_calib_result(): " 5086 "incorrect calibration type(%d).\n", calib_hdr->op_code); 5087 break; 5088 } 5089 5090 } 5091 5092 static void 5093 iwp_release_calib_buffer(iwp_sc_t *sc) 5094 { 5095 if (sc->sc_calib_results.lo_res != NULL) { 5096 kmem_free(sc->sc_calib_results.lo_res, 5097 sc->sc_calib_results.lo_res_len); 5098 sc->sc_calib_results.lo_res = NULL; 5099 } 5100 5101 if (sc->sc_calib_results.tx_iq_res != NULL) { 5102 kmem_free(sc->sc_calib_results.tx_iq_res, 5103 sc->sc_calib_results.tx_iq_res_len); 5104 sc->sc_calib_results.tx_iq_res = NULL; 5105 } 5106 5107 if (sc->sc_calib_results.tx_iq_perd_res != NULL) { 5108 kmem_free(sc->sc_calib_results.tx_iq_perd_res, 5109 sc->sc_calib_results.tx_iq_perd_res_len); 5110 sc->sc_calib_results.tx_iq_perd_res = NULL; 5111 } 5112 5113 if (sc->sc_calib_results.base_band_res != NULL) { 5114 kmem_free(sc->sc_calib_results.base_band_res, 5115 sc->sc_calib_results.base_band_res_len); 5116 sc->sc_calib_results.base_band_res = NULL; 5117 } 5118 5119 } 5120 5121 /* 5122 * common section of intialization 5123 */ 5124 static int 5125 iwp_init_common(iwp_sc_t *sc) 5126 { 5127 int32_t qid; 5128 uint32_t tmp; 5129 5130 (void) iwp_preinit(sc); 5131 5132 tmp = IWP_READ(sc, CSR_GP_CNTRL); 5133 if (!(tmp & CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW)) { 5134 cmn_err(CE_NOTE, "iwp_init_common(): " 5135 "radio transmitter is off\n"); 5136 return (IWP_FAIL); 5137 } 5138 5139 /* 5140 * init Rx ring 5141 */ 5142 iwp_mac_access_enter(sc); 5143 IWP_WRITE(sc, FH_MEM_RCSR_CHNL0_CONFIG_REG, 0); 5144 5145 IWP_WRITE(sc, FH_RSCSR_CHNL0_RBDCB_WPTR_REG, 0); 5146 IWP_WRITE(sc, FH_RSCSR_CHNL0_RBDCB_BASE_REG, 5147 sc->sc_rxq.dma_desc.cookie.dmac_address >> 8); 5148 5149 IWP_WRITE(sc, FH_RSCSR_CHNL0_STTS_WPTR_REG, 5150 ((uint32_t)(sc->sc_dma_sh.cookie.dmac_address + 5151 offsetof(struct iwp_shared, val0)) >> 4)); 5152 5153 IWP_WRITE(sc, FH_MEM_RCSR_CHNL0_CONFIG_REG, 5154 FH_RCSR_RX_CONFIG_CHNL_EN_ENABLE_VAL | 5155 FH_RCSR_CHNL0_RX_CONFIG_IRQ_DEST_INT_HOST_VAL | 5156 IWP_FH_RCSR_RX_CONFIG_REG_VAL_RB_SIZE_4K | 5157 (RX_QUEUE_SIZE_LOG << 5158 FH_RCSR_RX_CONFIG_RBDCB_SIZE_BITSHIFT)); 5159 iwp_mac_access_exit(sc); 5160 IWP_WRITE(sc, FH_RSCSR_CHNL0_RBDCB_WPTR_REG, 5161 (RX_QUEUE_SIZE - 1) & ~0x7); 5162 5163 /* 5164 * init Tx rings 5165 */ 5166 iwp_mac_access_enter(sc); 5167 iwp_reg_write(sc, IWP_SCD_TXFACT, 0); 5168 5169 /* 5170 * keep warm page 5171 */ 5172 IWP_WRITE(sc, IWP_FH_KW_MEM_ADDR_REG, 5173 sc->sc_dma_kw.cookie.dmac_address >> 4); 5174 5175 for (qid = 0; qid < IWP_NUM_QUEUES; qid++) { 5176 IWP_WRITE(sc, FH_MEM_CBBC_QUEUE(qid), 5177 sc->sc_txq[qid].dma_desc.cookie.dmac_address >> 8); 5178 IWP_WRITE(sc, IWP_FH_TCSR_CHNL_TX_CONFIG_REG(qid), 5179 IWP_FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_ENABLE | 5180 IWP_FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_ENABLE_VAL); 5181 } 5182 5183 iwp_mac_access_exit(sc); 5184 5185 /* 5186 * clear "radio off" and "disable command" bits 5187 */ 5188 IWP_WRITE(sc, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL); 5189 IWP_WRITE(sc, CSR_UCODE_DRV_GP1_CLR, 5190 CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED); 5191 5192 /* 5193 * clear any pending interrupts 5194 */ 5195 IWP_WRITE(sc, CSR_INT, 0xffffffff); 5196 5197 /* 5198 * enable interrupts 5199 */ 5200 IWP_WRITE(sc, CSR_INT_MASK, CSR_INI_SET_MASK); 5201 5202 IWP_WRITE(sc, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL); 5203 IWP_WRITE(sc, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL); 5204 5205 return (IWP_SUCCESS); 5206 } 5207 5208 static int 5209 iwp_fast_recover(iwp_sc_t *sc) 5210 { 5211 ieee80211com_t *ic = &sc->sc_ic; 5212 int err = IWP_FAIL; 5213 5214 mutex_enter(&sc->sc_glock); 5215 5216 /* restore runtime configuration */ 5217 bcopy(&sc->sc_config_save, &sc->sc_config, 5218 sizeof (sc->sc_config)); 5219 5220 sc->sc_config.assoc_id = 0; 5221 sc->sc_config.filter_flags &= ~LE_32(RXON_FILTER_ASSOC_MSK); 5222 5223 if ((err = iwp_hw_set_before_auth(sc)) != IWP_SUCCESS) { 5224 cmn_err(CE_WARN, "iwp_fast_recover(): " 5225 "could not setup authentication\n"); 5226 mutex_exit(&sc->sc_glock); 5227 return (err); 5228 } 5229 5230 bcopy(&sc->sc_config_save, &sc->sc_config, 5231 sizeof (sc->sc_config)); 5232 5233 /* update adapter's configuration */ 5234 err = iwp_run_state_config(sc); 5235 if (err != IWP_SUCCESS) { 5236 cmn_err(CE_WARN, "iwp_fast_recover(): " 5237 "failed to setup association\n"); 5238 mutex_exit(&sc->sc_glock); 5239 return (err); 5240 } 5241 /* set LED on */ 5242 iwp_set_led(sc, 2, 0, 1); 5243 5244 mutex_exit(&sc->sc_glock); 5245 5246 atomic_and_32(&sc->sc_flags, ~IWP_F_HW_ERR_RECOVER); 5247 5248 /* start queue */ 5249 IWP_DBG((IWP_DEBUG_FW, "iwp_fast_recover(): " 5250 "resume xmit\n")); 5251 mac_tx_update(ic->ic_mach); 5252 5253 return (IWP_SUCCESS); 5254 } 5255 5256 static int 5257 iwp_run_state_config(iwp_sc_t *sc) 5258 { 5259 struct ieee80211com *ic = &sc->sc_ic; 5260 ieee80211_node_t *in = ic->ic_bss; 5261 int err = IWP_FAIL; 5262 5263 /* 5264 * update adapter's configuration 5265 */ 5266 sc->sc_config.assoc_id = in->in_associd & 0x3fff; 5267 5268 /* 5269 * short preamble/slot time are 5270 * negotiated when associating 5271 */ 5272 sc->sc_config.flags &= 5273 ~LE_32(RXON_FLG_SHORT_PREAMBLE_MSK | 5274 RXON_FLG_SHORT_SLOT_MSK); 5275 5276 if (ic->ic_flags & IEEE80211_F_SHSLOT) { 5277 sc->sc_config.flags |= 5278 LE_32(RXON_FLG_SHORT_SLOT_MSK); 5279 } 5280 5281 if (ic->ic_flags & IEEE80211_F_SHPREAMBLE) { 5282 sc->sc_config.flags |= 5283 LE_32(RXON_FLG_SHORT_PREAMBLE_MSK); 5284 } 5285 5286 sc->sc_config.filter_flags |= 5287 LE_32(RXON_FILTER_ASSOC_MSK); 5288 5289 if (ic->ic_opmode != IEEE80211_M_STA) { 5290 sc->sc_config.filter_flags |= 5291 LE_32(RXON_FILTER_BCON_AWARE_MSK); 5292 } 5293 5294 IWP_DBG((IWP_DEBUG_80211, "iwp_run_state_config(): " 5295 "config chan %d flags %x" 5296 " filter_flags %x\n", 5297 sc->sc_config.chan, sc->sc_config.flags, 5298 sc->sc_config.filter_flags)); 5299 5300 err = iwp_cmd(sc, REPLY_RXON, &sc->sc_config, 5301 sizeof (iwp_rxon_cmd_t), 1); 5302 if (err != IWP_SUCCESS) { 5303 cmn_err(CE_WARN, "iwp_run_state_config(): " 5304 "could not update configuration\n"); 5305 return (err); 5306 } 5307 5308 return (err); 5309 } 5310 5311 /* 5312 * This function overwrites default configurations of 5313 * ieee80211com structure in Net80211 module. 5314 */ 5315 static void 5316 iwp_overwrite_ic_default(iwp_sc_t *sc) 5317 { 5318 ieee80211com_t *ic = &sc->sc_ic; 5319 5320 sc->sc_newstate = ic->ic_newstate; 5321 ic->ic_newstate = iwp_newstate; 5322 ic->ic_node_alloc = iwp_node_alloc; 5323 ic->ic_node_free = iwp_node_free; 5324 } 5325 5326 5327 /* 5328 * This function adds AP station into hardware. 5329 */ 5330 static int 5331 iwp_add_ap_sta(iwp_sc_t *sc) 5332 { 5333 ieee80211com_t *ic = &sc->sc_ic; 5334 ieee80211_node_t *in = ic->ic_bss; 5335 iwp_add_sta_t node; 5336 int err = IWP_FAIL; 5337 5338 /* 5339 * Add AP node into hardware. 5340 */ 5341 (void) memset(&node, 0, sizeof (node)); 5342 IEEE80211_ADDR_COPY(node.sta.addr, in->in_bssid); 5343 node.mode = STA_MODE_ADD_MSK; 5344 node.sta.sta_id = IWP_AP_ID; 5345 5346 err = iwp_cmd(sc, REPLY_ADD_STA, &node, sizeof (node), 1); 5347 if (err != IWP_SUCCESS) { 5348 cmn_err(CE_WARN, "iwp_add_ap_sta(): " 5349 "failed to add AP node\n"); 5350 return (err); 5351 } 5352 5353 return (err); 5354 } 5355 5356 /* 5357 * Check EEPROM version and Calibration version. 5358 */ 5359 static int 5360 iwp_eep_ver_chk(iwp_sc_t *sc) 5361 { 5362 if ((IWP_READ_EEP_SHORT(sc, EEP_VERSION) < 0x011a) || 5363 (sc->sc_eep_calib->tx_pow_calib_hdr.calib_version < 4)) { 5364 cmn_err(CE_WARN, "iwp_eep_ver_chk(): " 5365 "unsupported eeprom detected\n"); 5366 return (IWP_FAIL); 5367 } 5368 5369 return (IWP_SUCCESS); 5370 } 5371 5372 /* 5373 * Determine parameters for all supported chips. 5374 */ 5375 static void 5376 iwp_set_chip_param(iwp_sc_t *sc) 5377 { 5378 if ((0x008d == sc->sc_dev_id) || 5379 (0x008e == sc->sc_dev_id)) { 5380 sc->sc_chip_param.phy_mode = PHY_MODE_G | 5381 PHY_MODE_A | PHY_MODE_N; 5382 5383 sc->sc_chip_param.tx_ant = ANT_A | ANT_B; 5384 sc->sc_chip_param.rx_ant = ANT_A | ANT_B; 5385 5386 sc->sc_chip_param.pa_type = PA_TYPE_MIX; 5387 } 5388 5389 if ((0x422c == sc->sc_dev_id) || 5390 (0x4239 == sc->sc_dev_id)) { 5391 sc->sc_chip_param.phy_mode = PHY_MODE_G | 5392 PHY_MODE_A | PHY_MODE_N; 5393 5394 sc->sc_chip_param.tx_ant = ANT_B | ANT_C; 5395 sc->sc_chip_param.rx_ant = ANT_B | ANT_C; 5396 5397 sc->sc_chip_param.pa_type = PA_TYPE_INTER; 5398 } 5399 5400 if ((0x422b == sc->sc_dev_id) || 5401 (0x4238 == sc->sc_dev_id)) { 5402 sc->sc_chip_param.phy_mode = PHY_MODE_G | 5403 PHY_MODE_A | PHY_MODE_N; 5404 5405 sc->sc_chip_param.tx_ant = ANT_A | ANT_B | ANT_C; 5406 sc->sc_chip_param.rx_ant = ANT_A | ANT_B | ANT_C; 5407 5408 sc->sc_chip_param.pa_type = PA_TYPE_SYSTEM; 5409 } 5410 } 5411