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