Lines Matching +full:thermal +full:- +full:sensors
82 #include "fw-wpi/ipw3945.ucode.hex"
294 /* OFDM: IEEE Std 802.11a-1999, pp. 14 Table 80 */
295 /* R1-R4 (ral/ural is R4-R1) */
297 /* CCK: device-dependent */
422 mutex_enter(&sc->sc_glock); in wpi_attach()
423 sc->sc_flags &= ~WPI_F_SUSPEND; in wpi_attach()
424 mutex_exit(&sc->sc_glock); in wpi_attach()
426 if (sc->sc_flags & WPI_F_RUNNING) in wpi_attach()
429 mutex_enter(&sc->sc_glock); in wpi_attach()
430 sc->sc_flags |= WPI_F_LAZY_RESUME; in wpi_attach()
431 mutex_exit(&sc->sc_glock); in wpi_attach()
448 sc->sc_dip = dip; in wpi_attach()
457 sc->sc_rev = ddi_get8(cfg_handle, in wpi_attach()
460 sc->sc_clsz = ddi_get16(cfg_handle, in wpi_attach()
463 if (!sc->sc_clsz) in wpi_attach()
464 sc->sc_clsz = 16; in wpi_attach()
465 sc->sc_clsz = (sc->sc_clsz << 2); in wpi_attach()
466 sc->sc_dmabuf_sz = roundup(0x1000 + sizeof (struct ieee80211_frame) + in wpi_attach()
469 IEEE80211_WEP_CRCLEN), sc->sc_clsz); in wpi_attach()
473 err = ddi_regs_map_setup(dip, 1, &sc->sc_base, in wpi_attach()
474 0, 0, &wpi_reg_accattr, &sc->sc_handle); in wpi_attach()
501 sc->sc_hdr = (const wpi_firmware_hdr_t *)wpi_fw_bin; in wpi_attach()
503 /* firmware image layout: |HDR|<--TEXT-->|<--DATA-->|<--BOOT-->| */ in wpi_attach()
504 sc->sc_text = (const char *)(sc->sc_hdr + 1); in wpi_attach()
505 sc->sc_data = sc->sc_text + LE_32(sc->sc_hdr->textsz); in wpi_attach()
506 sc->sc_boot = sc->sc_data + LE_32(sc->sc_hdr->datasz); in wpi_attach()
517 err = ddi_get_iblock_cookie(dip, 0, &sc->sc_iblk); in wpi_attach()
523 mutex_init(&sc->sc_glock, NULL, MUTEX_DRIVER, sc->sc_iblk); in wpi_attach()
524 mutex_init(&sc->sc_tx_lock, NULL, MUTEX_DRIVER, sc->sc_iblk); in wpi_attach()
525 cv_init(&sc->sc_fw_cv, NULL, CV_DRIVER, NULL); in wpi_attach()
526 cv_init(&sc->sc_cmd_cv, NULL, CV_DRIVER, NULL); in wpi_attach()
531 mutex_init(&sc->sc_mt_lock, NULL, MUTEX_DRIVER, in wpi_attach()
532 (void *) sc->sc_iblk); in wpi_attach()
533 cv_init(&sc->sc_mt_cv, NULL, CV_DRIVER, NULL); in wpi_attach()
534 sc->sc_mf_thread = NULL; in wpi_attach()
535 sc->sc_mf_thread_switch = 0; in wpi_attach()
540 ic = &sc->sc_ic; in wpi_attach()
541 ic->ic_phytype = IEEE80211_T_OFDM; in wpi_attach()
542 ic->ic_opmode = IEEE80211_M_STA; /* default to BSS mode */ in wpi_attach()
543 ic->ic_state = IEEE80211_S_INIT; in wpi_attach()
544 ic->ic_maxrssi = 70; /* experimental number */ in wpi_attach()
545 ic->ic_caps = IEEE80211_C_SHPREAMBLE | IEEE80211_C_TXPMGT | in wpi_attach()
551 ic->ic_caps |= IEEE80211_C_AES_CCM; in wpi_attach()
552 ic->ic_caps |= IEEE80211_C_WPA; /* Support WPA/WPA2 */ in wpi_attach()
555 ic->ic_sup_rates[IEEE80211_MODE_11B] = wpi_rateset_11b; in wpi_attach()
556 ic->ic_sup_rates[IEEE80211_MODE_11G] = wpi_rateset_11g; in wpi_attach()
560 ic->ic_sup_channels[i].ich_freq = in wpi_attach()
562 ic->ic_sup_channels[i].ich_flags = in wpi_attach()
567 ic->ic_ibss_chan = &ic->ic_sup_channels[0]; in wpi_attach()
568 ic->ic_xmit = wpi_send; in wpi_attach()
581 sc->sc_newstate = ic->ic_newstate; in wpi_attach()
582 ic->ic_newstate = wpi_newstate; in wpi_attach()
583 ic->ic_node_alloc = wpi_node_alloc; in wpi_attach()
584 ic->ic_node_free = wpi_node_free; in wpi_attach()
585 ic->ic_crypto.cs_key_set = wpi_key_set; in wpi_attach()
590 ic->ic_def_txkey = 0; in wpi_attach()
593 &sc->sc_notif_softint_id, &sc->sc_iblk, NULL, wpi_notif_softintr, in wpi_attach()
604 err = ddi_add_intr(dip, 0, &sc->sc_iblk, NULL, in wpi_attach()
616 wd.wd_opmode = ic->ic_opmode; in wpi_attach()
617 IEEE80211_ADDR_COPY(wd.wd_bssid, ic->ic_macaddr); in wpi_attach()
626 macp->m_type_ident = MAC_PLUGIN_IDENT_WIFI; in wpi_attach()
627 macp->m_driver = sc; in wpi_attach()
628 macp->m_dip = dip; in wpi_attach()
629 macp->m_src_addr = ic->ic_macaddr; in wpi_attach()
630 macp->m_callbacks = &wpi_m_callbacks; in wpi_attach()
631 macp->m_min_sdu = 0; in wpi_attach()
632 macp->m_max_sdu = IEEE80211_MTU; in wpi_attach()
633 macp->m_pdata = &wd; in wpi_attach()
634 macp->m_pdata_size = sizeof (wd); in wpi_attach()
639 err = mac_register(macp, &ic->ic_mach); in wpi_attach()
660 mac_link_update(ic->ic_mach, LINK_STATE_DOWN); in wpi_attach()
667 sc->sc_mf_thread_switch = 1; in wpi_attach()
668 if (sc->sc_mf_thread == NULL) in wpi_attach()
669 sc->sc_mf_thread = thread_create((caddr_t)NULL, 0, in wpi_attach()
672 sc->sc_flags |= WPI_F_ATTACHED; in wpi_attach()
676 ddi_remove_intr(dip, 0, sc->sc_iblk); in wpi_attach()
678 ddi_remove_softintr(sc->sc_notif_softint_id); in wpi_attach()
679 sc->sc_notif_softint_id = NULL; in wpi_attach()
690 ddi_regs_map_free(&sc->sc_handle); in wpi_attach()
710 mutex_enter(&sc->sc_glock); in wpi_detach()
711 sc->sc_flags |= WPI_F_SUSPEND; in wpi_detach()
712 mutex_exit(&sc->sc_glock); in wpi_detach()
714 if (sc->sc_flags & WPI_F_RUNNING) { in wpi_detach()
723 if (!(sc->sc_flags & WPI_F_ATTACHED)) in wpi_detach()
726 err = mac_disable(sc->sc_ic.ic_mach); in wpi_detach()
733 mutex_enter(&sc->sc_mt_lock); in wpi_detach()
734 sc->sc_mf_thread_switch = 0; in wpi_detach()
735 while (sc->sc_mf_thread != NULL) { in wpi_detach()
736 if (cv_wait_sig(&sc->sc_mt_cv, &sc->sc_mt_lock) == 0) in wpi_detach()
739 mutex_exit(&sc->sc_mt_lock); in wpi_detach()
746 (void) mac_unregister(sc->sc_ic.ic_mach); in wpi_detach()
748 mutex_enter(&sc->sc_glock); in wpi_detach()
752 mutex_exit(&sc->sc_glock); in wpi_detach()
754 ddi_remove_intr(dip, 0, sc->sc_iblk); in wpi_detach()
755 ddi_remove_softintr(sc->sc_notif_softint_id); in wpi_detach()
756 sc->sc_notif_softint_id = NULL; in wpi_detach()
761 ieee80211_detach(&sc->sc_ic); in wpi_detach()
765 ddi_regs_map_free(&sc->sc_handle); in wpi_detach()
775 cv_destroy(&sc->sc_mt_cv); in wpi_destroy_locks()
776 mutex_destroy(&sc->sc_mt_lock); in wpi_destroy_locks()
777 cv_destroy(&sc->sc_cmd_cv); in wpi_destroy_locks()
778 cv_destroy(&sc->sc_fw_cv); in wpi_destroy_locks()
779 mutex_destroy(&sc->sc_tx_lock); in wpi_destroy_locks()
780 mutex_destroy(&sc->sc_glock); in wpi_destroy_locks()
796 err = ddi_dma_alloc_handle(sc->sc_dip, dma_attr_p, in wpi_alloc_dma_mem()
797 DDI_DMA_SLEEP, NULL, &dma_p->dma_hdl); in wpi_alloc_dma_mem()
799 dma_p->dma_hdl = NULL; in wpi_alloc_dma_mem()
806 err = ddi_dma_mem_alloc(dma_p->dma_hdl, memsize, acc_attr_p, in wpi_alloc_dma_mem()
808 DDI_DMA_SLEEP, NULL, &vaddr, &dma_p->alength, &dma_p->acc_hdl); in wpi_alloc_dma_mem()
810 ddi_dma_free_handle(&dma_p->dma_hdl); in wpi_alloc_dma_mem()
811 dma_p->dma_hdl = NULL; in wpi_alloc_dma_mem()
812 dma_p->acc_hdl = NULL; in wpi_alloc_dma_mem()
819 dma_p->mem_va = vaddr; in wpi_alloc_dma_mem()
820 err = ddi_dma_addr_bind_handle(dma_p->dma_hdl, NULL, in wpi_alloc_dma_mem()
821 vaddr, dma_p->alength, dma_flags, DDI_DMA_SLEEP, NULL, in wpi_alloc_dma_mem()
822 &dma_p->cookie, &dma_p->ncookies); in wpi_alloc_dma_mem()
824 ddi_dma_mem_free(&dma_p->acc_hdl); in wpi_alloc_dma_mem()
825 ddi_dma_free_handle(&dma_p->dma_hdl); in wpi_alloc_dma_mem()
826 dma_p->acc_hdl = NULL; in wpi_alloc_dma_mem()
827 dma_p->dma_hdl = NULL; in wpi_alloc_dma_mem()
831 dma_p->nslots = ~0U; in wpi_alloc_dma_mem()
832 dma_p->size = ~0U; in wpi_alloc_dma_mem()
833 dma_p->token = ~0U; in wpi_alloc_dma_mem()
834 dma_p->offset = 0; in wpi_alloc_dma_mem()
844 if (dma_p->dma_hdl != NULL) { in wpi_free_dma_mem()
845 if (dma_p->ncookies) { in wpi_free_dma_mem()
846 (void) ddi_dma_unbind_handle(dma_p->dma_hdl); in wpi_free_dma_mem()
847 dma_p->ncookies = 0; in wpi_free_dma_mem()
849 ddi_dma_free_handle(&dma_p->dma_hdl); in wpi_free_dma_mem()
850 dma_p->dma_hdl = NULL; in wpi_free_dma_mem()
853 if (dma_p->acc_hdl != NULL) { in wpi_free_dma_mem()
854 ddi_dma_mem_free(&dma_p->acc_hdl); in wpi_free_dma_mem()
855 dma_p->acc_hdl = NULL; in wpi_free_dma_mem()
864 * reload the firmware, and re-allocate dma at run time may be failed,
874 err = wpi_alloc_dma_mem(sc, LE_32(sc->sc_hdr->textsz), in wpi_alloc_fw_dma()
877 &sc->sc_dma_fw_text); in wpi_alloc_fw_dma()
878 dma_p = &sc->sc_dma_fw_text; in wpi_alloc_fw_dma()
880 dma_p->ncookies, dma_p->cookie.dmac_address, in wpi_alloc_fw_dma()
881 dma_p->cookie.dmac_size)); in wpi_alloc_fw_dma()
887 for (i = 0; i < dma_p->ncookies; i++) { in wpi_alloc_fw_dma()
889 c = ddi_dma_cookie_get(dma_p->dma_hdl, i); in wpi_alloc_fw_dma()
890 sc->sc_fw_text_cookie[i] = *c; in wpi_alloc_fw_dma()
892 err = wpi_alloc_dma_mem(sc, LE_32(sc->sc_hdr->datasz), in wpi_alloc_fw_dma()
895 &sc->sc_dma_fw_data); in wpi_alloc_fw_dma()
896 dma_p = &sc->sc_dma_fw_data; in wpi_alloc_fw_dma()
898 dma_p->ncookies, dma_p->cookie.dmac_address, in wpi_alloc_fw_dma()
899 dma_p->cookie.dmac_size)); in wpi_alloc_fw_dma()
905 for (i = 0; i < dma_p->ncookies; i++) { in wpi_alloc_fw_dma()
907 c = ddi_dma_cookie_get(dma_p->dma_hdl, i); in wpi_alloc_fw_dma()
908 sc->sc_fw_data_cookie[i] = *c; in wpi_alloc_fw_dma()
917 wpi_free_dma_mem(&sc->sc_dma_fw_text); in wpi_free_fw_dma()
918 wpi_free_dma_mem(&sc->sc_dma_fw_data); in wpi_free_fw_dma()
929 /* must be aligned on a 4K-page boundary */ in wpi_alloc_shared()
933 &sc->sc_dma_sh); in wpi_alloc_shared()
936 sc->sc_shared = (wpi_shared_t *)sc->sc_dma_sh.mem_va; in wpi_alloc_shared()
947 wpi_free_dma_mem(&sc->sc_dma_sh); in wpi_free_shared()
957 ring = &sc->sc_rxq; in wpi_alloc_rx_ring()
958 ring->cur = 0; in wpi_alloc_rx_ring()
963 &ring->dma_desc); in wpi_alloc_rx_ring()
968 ring->desc = (uint32_t *)ring->dma_desc.mem_va; in wpi_alloc_rx_ring()
974 data = &ring->data[i]; in wpi_alloc_rx_ring()
975 err = wpi_alloc_dma_mem(sc, sc->sc_dmabuf_sz, in wpi_alloc_rx_ring()
978 &data->dma_data); in wpi_alloc_rx_ring()
985 ring->desc[i] = LE_32(data->dma_data.cookie.dmac_address); in wpi_alloc_rx_ring()
988 WPI_DMA_SYNC(ring->dma_desc, DDI_DMA_SYNC_FORDEV); in wpi_alloc_rx_ring()
1015 sc->sc_rxq.cur = 0; in wpi_reset_rx_ring()
1024 if (sc->sc_rxq.data[i].dma_data.dma_hdl) in wpi_free_rx_ring()
1025 WPI_DMA_SYNC(sc->sc_rxq.data[i].dma_data, in wpi_free_rx_ring()
1027 wpi_free_dma_mem(&sc->sc_rxq.data[i].dma_data); in wpi_free_rx_ring()
1030 if (sc->sc_rxq.dma_desc.dma_hdl) in wpi_free_rx_ring()
1031 WPI_DMA_SYNC(sc->sc_rxq.dma_desc, DDI_DMA_SYNC_FORDEV); in wpi_free_rx_ring()
1032 wpi_free_dma_mem(&sc->sc_rxq.dma_desc); in wpi_free_rx_ring()
1045 ring->qid = qid; in wpi_alloc_tx_ring()
1046 ring->count = count; in wpi_alloc_tx_ring()
1047 ring->queued = 0; in wpi_alloc_tx_ring()
1048 ring->cur = 0; in wpi_alloc_tx_ring()
1053 &ring->dma_desc); in wpi_alloc_tx_ring()
1061 sc->sc_shared->txbase[qid] = ring->dma_desc.cookie.dmac_address; in wpi_alloc_tx_ring()
1063 desc_h = (wpi_tx_desc_t *)ring->dma_desc.mem_va; in wpi_alloc_tx_ring()
1064 paddr_desc_h = ring->dma_desc.cookie.dmac_address; in wpi_alloc_tx_ring()
1069 &ring->dma_cmd); in wpi_alloc_tx_ring()
1076 cmd_h = (wpi_tx_cmd_t *)ring->dma_cmd.mem_va; in wpi_alloc_tx_ring()
1077 paddr_cmd_h = ring->dma_cmd.cookie.dmac_address; in wpi_alloc_tx_ring()
1082 ring->data = kmem_zalloc(sizeof (wpi_tx_data_t) * count, KM_NOSLEEP); in wpi_alloc_tx_ring()
1083 if (ring->data == NULL) { in wpi_alloc_tx_ring()
1089 data = &ring->data[i]; in wpi_alloc_tx_ring()
1090 err = wpi_alloc_dma_mem(sc, sc->sc_dmabuf_sz, in wpi_alloc_tx_ring()
1093 &data->dma_data); in wpi_alloc_tx_ring()
1100 data->desc = desc_h + i; in wpi_alloc_tx_ring()
1101 data->paddr_desc = paddr_desc_h + in wpi_alloc_tx_ring()
1102 ((uintptr_t)data->desc - (uintptr_t)desc_h); in wpi_alloc_tx_ring()
1103 data->cmd = cmd_h + i; in wpi_alloc_tx_ring()
1104 data->paddr_cmd = paddr_cmd_h + in wpi_alloc_tx_ring()
1105 ((uintptr_t)data->cmd - (uintptr_t)cmd_h); in wpi_alloc_tx_ring()
1123 WPI_WRITE(sc, WPI_TX_CONFIG(ring->qid), 0); in wpi_reset_tx_ring()
1125 if (WPI_READ(sc, WPI_TX_STATUS) & WPI_TX_IDLE(ring->qid)) in wpi_reset_tx_ring()
1132 ring->qid)); in wpi_reset_tx_ring()
1137 if (!(sc->sc_flags & WPI_F_QUIESCED)) { in wpi_reset_tx_ring()
1138 for (i = 0; i < ring->count; i++) { in wpi_reset_tx_ring()
1139 data = &ring->data[i]; in wpi_reset_tx_ring()
1140 WPI_DMA_SYNC(data->dma_data, DDI_DMA_SYNC_FORDEV); in wpi_reset_tx_ring()
1144 ring->queued = 0; in wpi_reset_tx_ring()
1145 ring->cur = 0; in wpi_reset_tx_ring()
1154 if (ring->dma_desc.dma_hdl != NULL) in wpi_free_tx_ring()
1155 WPI_DMA_SYNC(ring->dma_desc, DDI_DMA_SYNC_FORDEV); in wpi_free_tx_ring()
1156 wpi_free_dma_mem(&ring->dma_desc); in wpi_free_tx_ring()
1158 if (ring->dma_cmd.dma_hdl != NULL) in wpi_free_tx_ring()
1159 WPI_DMA_SYNC(ring->dma_cmd, DDI_DMA_SYNC_FORDEV); in wpi_free_tx_ring()
1160 wpi_free_dma_mem(&ring->dma_cmd); in wpi_free_tx_ring()
1162 if (ring->data != NULL) { in wpi_free_tx_ring()
1163 for (i = 0; i < ring->count; i++) { in wpi_free_tx_ring()
1164 if (ring->data[i].dma_data.dma_hdl) in wpi_free_tx_ring()
1165 WPI_DMA_SYNC(ring->data[i].dma_data, in wpi_free_tx_ring()
1167 wpi_free_dma_mem(&ring->data[i].dma_data); in wpi_free_tx_ring()
1169 kmem_free(ring->data, ring->count * sizeof (wpi_tx_data_t)); in wpi_free_tx_ring()
1170 ring->data = NULL; in wpi_free_tx_ring()
1180 err = wpi_alloc_tx_ring(sc, &sc->sc_txq[i], WPI_TX_RING_COUNT, in wpi_ring_init()
1185 err = wpi_alloc_tx_ring(sc, &sc->sc_cmdq, WPI_CMD_RING_COUNT, 4); in wpi_ring_init()
1188 err = wpi_alloc_tx_ring(sc, &sc->sc_svcq, WPI_SVC_RING_COUNT, 5); in wpi_ring_init()
1206 wpi_free_tx_ring(sc, &sc->sc_svcq); in wpi_ring_free()
1207 wpi_free_tx_ring(sc, &sc->sc_cmdq); in wpi_ring_free()
1208 while (--i >= 0) { in wpi_ring_free()
1209 wpi_free_tx_ring(sc, &sc->sc_txq[i]); in wpi_ring_free()
1222 return (&amrr->in); in wpi_node_alloc()
1228 ieee80211com_t *ic = in->in_ic; in wpi_node_free()
1230 ic->ic_node_cleanup(in); in wpi_node_free()
1231 if (in->in_wpa_ie != NULL) in wpi_node_free()
1232 ieee80211_free(in->in_wpa_ie); in wpi_node_free()
1241 ieee80211_node_t *in = ic->ic_bss; in wpi_newstate()
1245 mutex_enter(&sc->sc_glock); in wpi_newstate()
1246 ostate = ic->ic_state; in wpi_newstate()
1254 sc->sc_flags |= WPI_F_SCANNING; in wpi_newstate()
1255 sc->sc_scan_next = 0; in wpi_newstate()
1264 sc->sc_config.state = 0; in wpi_newstate()
1265 sc->sc_config.filter &= ~LE_32(WPI_FILTER_BSS); in wpi_newstate()
1269 sc->sc_config.chan, sc->sc_config.flags, in wpi_newstate()
1270 sc->sc_config.filter)); in wpi_newstate()
1272 err = wpi_cmd(sc, WPI_CMD_CONFIGURE, &sc->sc_config, in wpi_newstate()
1277 sc->sc_flags &= ~WPI_F_SCANNING; in wpi_newstate()
1278 mutex_exit(&sc->sc_glock); in wpi_newstate()
1292 sc->sc_flags &= ~WPI_F_SCANNING; in wpi_newstate()
1293 mutex_exit(&sc->sc_glock); in wpi_newstate()
1299 mutex_exit(&sc->sc_glock); in wpi_newstate()
1301 err = sc->sc_newstate(ic, nstate, arg); in wpi_newstate()
1302 mutex_enter(&sc->sc_glock); in wpi_newstate()
1306 sc->sc_flags &= ~WPI_F_SCANNING; in wpi_newstate()
1309 mutex_exit(&sc->sc_glock); in wpi_newstate()
1314 sc->sc_clk = 0; in wpi_newstate()
1319 sc->sc_flags &= ~WPI_F_SCANNING; in wpi_newstate()
1323 sc->sc_config.state = 0; in wpi_newstate()
1324 sc->sc_config.filter &= ~LE_32(WPI_FILTER_BSS); in wpi_newstate()
1329 mutex_exit(&sc->sc_glock); in wpi_newstate()
1336 sc->sc_flags &= ~WPI_F_SCANNING; in wpi_newstate()
1339 if (ic->ic_opmode == IEEE80211_M_MONITOR) { in wpi_newstate()
1345 if (ic->ic_opmode != IEEE80211_M_STA) { in wpi_newstate()
1352 sc->sc_config.state = LE_16(WPI_CONFIG_ASSOCIATED); in wpi_newstate()
1354 sc->sc_config.flags &= ~LE_32(WPI_CONFIG_SHPREAMBLE | in wpi_newstate()
1356 if (ic->ic_flags & IEEE80211_F_SHSLOT) in wpi_newstate()
1357 sc->sc_config.flags |= LE_32(WPI_CONFIG_SHSLOT); in wpi_newstate()
1358 if (ic->ic_flags & IEEE80211_F_SHPREAMBLE) in wpi_newstate()
1359 sc->sc_config.flags |= LE_32(WPI_CONFIG_SHPREAMBLE); in wpi_newstate()
1360 sc->sc_config.filter |= LE_32(WPI_FILTER_BSS); in wpi_newstate()
1361 if (ic->ic_opmode != IEEE80211_M_STA) in wpi_newstate()
1362 sc->sc_config.filter |= LE_32(WPI_FILTER_BEACON); in wpi_newstate()
1365 sc->sc_config.chan, sc->sc_config.flags)); in wpi_newstate()
1366 err = wpi_cmd(sc, WPI_CMD_CONFIGURE, &sc->sc_config, in wpi_newstate()
1371 mutex_exit(&sc->sc_glock); in wpi_newstate()
1376 mutex_enter(&sc->sc_mt_lock); in wpi_newstate()
1377 if (ic->ic_fixed_rate == IEEE80211_FIXED_RATE_NONE) { in wpi_newstate()
1378 sc->sc_flags |= WPI_F_RATE_AUTO_CTL; in wpi_newstate()
1380 i = in->in_rates.ir_nrates - 1; in wpi_newstate()
1382 i--; in wpi_newstate()
1383 in->in_txrate = i; in wpi_newstate()
1385 sc->sc_flags &= ~WPI_F_RATE_AUTO_CTL; in wpi_newstate()
1387 mutex_exit(&sc->sc_mt_lock); in wpi_newstate()
1394 sc->sc_flags &= ~WPI_F_SCANNING; in wpi_newstate()
1398 sc->sc_flags &= ~WPI_F_SCANNING; in wpi_newstate()
1402 mutex_exit(&sc->sc_glock); in wpi_newstate()
1403 return (sc->sc_newstate(ic, nstate, arg)); in wpi_newstate()
1414 switch (k->wk_cipher->ic_cipher) { in wpi_key_set()
1423 sc->sc_config.filter &= ~(WPI_FILTER_NODECRYPTUNI | in wpi_key_set()
1426 mutex_enter(&sc->sc_glock); in wpi_key_set()
1434 IEEE80211_ADDR_COPY(node.bssid, ic->ic_bss->in_bssid); in wpi_key_set()
1437 if (k->wk_flags & IEEE80211_KEY_XMIT) { in wpi_key_set()
1439 node.keyp = k->wk_keyix; in wpi_key_set()
1442 node.keyp = k->wk_keyix + 4; in wpi_key_set()
1444 (void) memcpy(node.key, k->wk_key, k->wk_keylen); in wpi_key_set()
1445 node.key_flags |= (2 | (1 << 3) | (k->wk_keyix << 8)); in wpi_key_set()
1452 mutex_exit(&sc->sc_glock); in wpi_key_set()
1455 mutex_exit(&sc->sc_glock); in wpi_key_set()
1510 for (; wlen > 0; wlen--, data++, addr += 4) in wpi_mem_write_region_4()
1516 * using the traditional bit-bang method.
1551 ucode = sc->sc_boot; in wpi_load_microcode()
1552 size = LE_32(sc->sc_hdr->bootsz); in wpi_load_microcode()
1579 * The driver just copies the firmware into DMA-safe memory and tells the NIC
1595 fw = sc->sc_text; in wpi_load_firmware()
1596 size = LE_32(sc->sc_hdr->textsz); in wpi_load_firmware()
1597 dma_p = &sc->sc_dma_fw_text; in wpi_load_firmware()
1598 cookie = sc->sc_fw_text_cookie; in wpi_load_firmware()
1600 fw = sc->sc_data; in wpi_load_firmware()
1601 size = LE_32(sc->sc_hdr->datasz); in wpi_load_firmware()
1602 dma_p = &sc->sc_dma_fw_data; in wpi_load_firmware()
1603 cookie = sc->sc_fw_data_cookie; in wpi_load_firmware()
1606 /* copy firmware image to DMA-safe memory */ in wpi_load_firmware()
1607 (void) memcpy(dma_p->mem_va, fw, size); in wpi_load_firmware()
1609 /* make sure the adapter will get up-to-date values */ in wpi_load_firmware()
1610 (void) ddi_dma_sync(dma_p->dma_hdl, 0, size, DDI_DMA_SYNC_FORDEV); in wpi_load_firmware()
1613 desc.flags = LE_32(WPI_PAD32(size) << 28 | dma_p->ncookies << 24); in wpi_load_firmware()
1614 for (i = 0; i < dma_p->ncookies; i++) { in wpi_load_firmware()
1658 ieee80211com_t *ic = &sc->sc_ic;
1659 wpi_rx_ring_t *ring = &sc->sc_rxq;
1670 if (stat->len > WPI_STAT_MAXLEN) {
1675 head = (wpi_rx_head_t *)((caddr_t)(stat + 1) + stat->len);
1676 tail = (wpi_rx_tail_t *)((caddr_t)(head + 1) + LE_16(head->len));
1678 len = LE_16(head->len);
1681 "rate=%x chan=%d tstamp=%llu", ring->cur, LE_32(desc->len),
1682 len, (int8_t)stat->rssi, head->rate, head->chan,
1683 LE_64(tail->tstamp)));
1685 if ((len < 20) || (len > sc->sc_dmabuf_sz)) {
1686 sc->sc_rx_err++;
1693 if ((LE_32(tail->flags) & WPI_RX_NOERROR) != WPI_RX_NOERROR) {
1695 LE_32(tail->flags)));
1696 sc->sc_rx_err++;
1701 /* ring->desc[ring->cur] = LE_32(data->dma_data.cookie.dmac_address); */
1705 if (sc->sc_drvbpf != NULL) {
1707 if (bpf_peers_present(sc->sc_drvbpf)) {
1709 struct wpi_rx_radiotap_header *tap = &sc->sc_rxtap;
1711 tap->wr_flags = 0;
1712 tap->wr_rate = head->rate;
1713 tap->wr_chan_freq =
1714 LE_16(ic->ic_channels[head->chan].ic_freq);
1715 tap->wr_chan_flags =
1716 LE_16(ic->ic_channels[head->chan].ic_flags);
1717 tap->wr_dbm_antsignal = (int8_t)(stat->rssi - WPI_RSSI_OFFSET);
1718 tap->wr_dbm_antnoise = (int8_t)LE_16(stat->noise);
1719 tap->wr_tsft = tail->tstamp;
1720 tap->wr_antenna = (LE_16(head->flags) >> 4) & 0xf;
1721 switch (head->rate) {
1723 case 10: tap->wr_rate = 2; break;
1724 case 20: tap->wr_rate = 4; break;
1725 case 55: tap->wr_rate = 11; break;
1726 case 110: tap->wr_rate = 22; break;
1728 case 0xd: tap->wr_rate = 12; break;
1729 case 0xf: tap->wr_rate = 18; break;
1730 case 0x5: tap->wr_rate = 24; break;
1731 case 0x7: tap->wr_rate = 36; break;
1732 case 0x9: tap->wr_rate = 48; break;
1733 case 0xb: tap->wr_rate = 72; break;
1734 case 0x1: tap->wr_rate = 96; break;
1735 case 0x3: tap->wr_rate = 108; break;
1737 default: tap->wr_rate = 0;
1739 if (LE_16(head->flags) & 0x4)
1740 tap->wr_flags |= IEEE80211_RADIOTAP_F_SHORTPRE;
1742 bpf_mtap2(sc->sc_drvbpf, tap, sc->sc_rxtap_len, m);
1756 (void) memcpy(mp->b_wptr, wh, len);
1757 mp->b_wptr += len;
1760 (void) ieee80211_input(ic, mp, in, stat->rssi, 0);
1762 sc->sc_rx_nobuf++;
1774 ieee80211com_t *ic = &sc->sc_ic;
1775 wpi_tx_ring_t *ring = &sc->sc_txq[desc->qid & 0x3];
1776 /* wpi_tx_data_t *txdata = &ring->data[desc->idx]; */
1778 wpi_amrr_t *amrr = (wpi_amrr_t *)ic->ic_bss;
1782 desc->qid, desc->idx, stat->ntries, stat->nkill, stat->rate,
1783 LE_32(stat->duration), LE_32(stat->status)));
1785 amrr->txcnt++;
1786 WPI_DBG((WPI_DEBUG_RATECTL, "tx: %d cnt\n", amrr->txcnt));
1787 if (stat->ntries > 0) {
1788 amrr->retrycnt++;
1789 sc->sc_tx_retries++;
1791 amrr->retrycnt));
1794 sc->sc_tx_timer = 0;
1796 mutex_enter(&sc->sc_tx_lock);
1797 ring->queued--;
1798 if (ring->queued < 0)
1799 ring->queued = 0;
1800 if ((sc->sc_need_reschedule) && (ring->queued <= (ring->count << 3))) {
1801 sc->sc_need_reschedule = 0;
1802 mutex_exit(&sc->sc_tx_lock);
1803 mac_tx_update(ic->ic_mach);
1804 mutex_enter(&sc->sc_tx_lock);
1806 mutex_exit(&sc->sc_tx_lock);
1812 if ((desc->qid & 7) != 4) {
1815 mutex_enter(&sc->sc_glock);
1816 sc->sc_flags |= WPI_F_CMD_DONE;
1817 cv_signal(&sc->sc_cmd_cv);
1818 mutex_exit(&sc->sc_glock);
1829 mutex_enter(&sc->sc_glock);
1830 if (sc->sc_notif_softint_pending != 1) {
1831 mutex_exit(&sc->sc_glock);
1834 mutex_exit(&sc->sc_glock);
1836 hw = LE_32(sc->sc_shared->next);
1838 while (sc->sc_rxq.cur != hw) {
1839 data = &sc->sc_rxq.data[sc->sc_rxq.cur];
1840 desc = (wpi_rx_desc_t *)data->dma_data.mem_va;
1844 hw, sc->sc_rxq.cur, desc->qid, desc->idx, desc->flags,
1845 desc->type, LE_32(desc->len)));
1847 if (!(desc->qid & 0x80)) /* reply to a command */
1850 switch (desc->type) {
1869 "alive %x\n", LE_32(uc->version),
1870 LE_32(uc->valid)));
1872 if (LE_32(uc->valid) != 1) {
1895 sc->sc_ostate = sc->sc_ic.ic_state;
1896 ieee80211_new_state(&sc->sc_ic,
1897 IEEE80211_S_INIT, -1);
1898 sc->sc_flags |=
1910 scan->chan, LE_32(scan->status)));
1921 scan->chan, scan->nchan, scan->status));
1923 sc->sc_scan_pending = 0;
1924 sc->sc_scan_next++;
1931 sc->sc_rxq.cur = (sc->sc_rxq.cur + 1) % WPI_RX_RING_COUNT;
1935 hw = (hw == 0) ? WPI_RX_RING_COUNT - 1 : hw - 1;
1937 mutex_enter(&sc->sc_glock);
1938 sc->sc_notif_softint_pending = 0;
1939 mutex_exit(&sc->sc_glock);
1950 mutex_enter(&sc->sc_glock);
1951 if (sc->sc_flags & WPI_F_SUSPEND) {
1952 mutex_exit(&sc->sc_glock);
1958 mutex_exit(&sc->sc_glock);
1971 if (sc->sc_notif_softint_id == NULL) {
1972 mutex_exit(&sc->sc_glock);
1978 mutex_exit(&sc->sc_glock);
1980 if (!(sc->sc_flags & WPI_F_HW_ERR_RECOVER)) {
1981 sc->sc_ostate = sc->sc_ic.ic_state;
1986 ieee80211_new_state(&sc->sc_ic, IEEE80211_S_INIT, -1);
1988 sc->sc_flags |= WPI_F_HW_ERR_RECOVER;
1994 sc->sc_notif_softint_pending = 1;
1995 ddi_trigger_softintr(sc->sc_notif_softint_id);
1999 sc->sc_flags |= WPI_F_FW_INIT;
2000 cv_signal(&sc->sc_fw_cv);
2003 /* re-enable interrupts */
2005 mutex_exit(&sc->sc_glock);
2014 /* CCK rates (returned values are device-dependent) */
2020 /* OFDM rates (cf IEEE Std 802.11a-1999, pp. 14 Table 80) */
2021 /* R1-R4 (ral/ural is R4-R1) */
2040 ieee80211com_t *ic = &sc->sc_ic;
2043 if (sc->sc_flags & WPI_F_SUSPEND) {
2048 if (ic->ic_state != IEEE80211_S_RUN) {
2053 if ((sc->sc_flags & WPI_F_HW_ERR_RECOVER) &&
2060 next = mp->b_next;
2061 mp->b_next = NULL;
2063 mp->b_next = next;
2088 (&sc->sc_txq[0]) : (&sc->sc_txq[1]);
2089 data = &ring->data[ring->cur];
2090 desc = data->desc;
2091 cmd = data->cmd;
2095 mutex_enter(&sc->sc_tx_lock);
2096 if (sc->sc_flags & WPI_F_SUSPEND) {
2097 mutex_exit(&sc->sc_tx_lock);
2106 if (ring->queued > ring->count - 64) {
2108 sc->sc_need_reschedule = 1;
2109 mutex_exit(&sc->sc_tx_lock);
2114 sc->sc_tx_nobuf++;
2118 mutex_exit(&sc->sc_tx_lock);
2130 for (off = 0, m0 = mp; m0 != NULL; m0 = m0->b_cont) {
2132 (void) memcpy(m->b_rptr + off, m0->b_rptr, mblen);
2135 m->b_wptr += off;
2138 wh = (struct ieee80211_frame *)m->b_rptr;
2140 in = ieee80211_find_txnode(ic, wh->i_addr1);
2144 sc->sc_tx_err++;
2151 cmd->code = WPI_CMD_TX_DATA;
2152 cmd->flags = 0;
2153 cmd->qid = ring->qid;
2154 cmd->idx = ring->cur;
2156 tx = (wpi_cmd_data_t *)cmd->data;
2157 tx->flags = 0;
2158 if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) {
2159 tx->flags |= LE_32(WPI_TX_NEED_ACK);
2161 tx->flags &= ~(LE_32(WPI_TX_NEED_ACK));
2164 if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
2168 sc->sc_tx_err++;
2173 if (k->wk_cipher->ic_cipher == IEEE80211_CIPHER_AES_CCM) {
2174 tx->security = 2; /* for CCMP */
2175 tx->flags |= LE_32(WPI_TX_NEED_ACK);
2176 (void) memcpy(&tx->key, k->wk_key, k->wk_keylen);
2180 wh = (struct ieee80211_frame *)m->b_rptr;
2191 if ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) ==
2193 /* mgmt frames are sent at the lowest available bit-rate */
2196 if (ic->ic_fixed_rate != IEEE80211_FIXED_RATE_NONE) {
2197 rate = ic->ic_fixed_rate;
2199 rate = in->in_rates.ir_rates[in->in_txrate];
2203 in->in_txrate, in->in_rates.ir_nrates, rate));
2206 if (sc->sc_drvbpf != NULL) {
2208 if (bpf_peers_present(sc->sc_drvbpf)) {
2210 struct wpi_tx_radiotap_header *tap = &sc->sc_txtap;
2212 tap->wt_flags = 0;
2213 tap->wt_chan_freq = LE_16(ic->ic_curchan->ic_freq);
2214 tap->wt_chan_flags = LE_16(ic->ic_curchan->ic_flags);
2215 tap->wt_rate = rate;
2216 if (wh->i_fc[1] & IEEE80211_FC1_WEP)
2217 tap->wt_flags |= IEEE80211_RADIOTAP_F_WEP;
2219 bpf_mtap2(sc->sc_drvbpf, tap, sc->sc_txtap_len, m0);
2223 tx->flags |= (LE_32(WPI_TX_AUTO_SEQ));
2224 tx->flags |= LE_32(WPI_TX_BT_DISABLE | WPI_TX_CALIBRATION);
2227 tx->id = IEEE80211_IS_MULTICAST(wh->i_addr1) ? WPI_ID_BROADCAST :
2230 if ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) ==
2233 if ((wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK) ==
2235 tx->flags |= LE_32(WPI_TX_INSERT_TSTAMP);
2237 if (((wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK) ==
2239 ((wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK) ==
2241 tx->timeout = 3;
2243 tx->timeout = 2;
2245 tx->timeout = 0;
2247 tx->rate = wpi_plcp_signal(rate);
2250 tx->rts_ntries = 7;
2251 tx->data_ntries = 15;
2253 tx->cck_mask = 0x0f;
2254 tx->ofdm_mask = 0xff;
2255 tx->lifetime = LE_32(0xffffffff);
2257 tx->len = LE_16(len);
2260 (void) memcpy(tx + 1, m->b_rptr, hdrlen);
2261 m->b_rptr += hdrlen;
2262 (void) memcpy(data->dma_data.mem_va, m->b_rptr, len - hdrlen);
2264 WPI_DBG((WPI_DEBUG_TX, "sending data: qid=%d idx=%d len=%d", ring->qid,
2265 ring->cur, len));
2268 desc->flags = LE_32(WPI_PAD32(len) << 28 | (2) << 24);
2269 desc->segs[0].addr = LE_32(data->paddr_cmd);
2270 desc->segs[0].len = LE_32(
2272 desc->segs[1].addr = LE_32(data->dma_data.cookie.dmac_address);
2273 desc->segs[1].len = LE_32(len - hdrlen);
2275 WPI_DMA_SYNC(data->dma_data, DDI_DMA_SYNC_FORDEV);
2276 WPI_DMA_SYNC(ring->dma_desc, DDI_DMA_SYNC_FORDEV);
2278 mutex_enter(&sc->sc_tx_lock);
2279 ring->queued++;
2280 mutex_exit(&sc->sc_tx_lock);
2283 ring->cur = (ring->cur + 1) % WPI_TX_RING_COUNT;
2284 WPI_WRITE(sc, WPI_TX_WIDX, ring->qid << 8 | ring->cur);
2289 ic->ic_stats.is_tx_bytes += len;
2290 ic->ic_stats.is_tx_frags++;
2292 if (sc->sc_tx_timer == 0)
2293 sc->sc_tx_timer = 5;
2302 ieee80211com_t *ic = &sc->sc_ic;
2315 if (ic->ic_des_esslen) {
2316 if (sc->sc_flags & WPI_F_RUNNING) {
2320 IEEE80211_S_SCAN, -1);
2337 err = ieee80211_getprop(&sc->sc_ic, pr_name, wldp_pr_name,
2349 ieee80211_propinfo(&sc->sc_ic, pr_name, wldp_pr_num, mph);
2358 ieee80211com_t *ic = &sc->sc_ic;
2364 if (ic->ic_des_esslen) {
2365 if (sc->sc_flags & WPI_F_RUNNING) {
2369 IEEE80211_S_SCAN, -1);
2384 ieee80211com_t *ic = &sc->sc_ic;
2387 mutex_enter(&sc->sc_glock);
2390 in = ic->ic_bss;
2391 *val = ((ic->ic_fixed_rate == IEEE80211_FIXED_RATE_NONE) ?
2392 IEEE80211_RATE(in->in_txrate) :
2393 ic->ic_fixed_rate) / 2 * 1000000;
2396 *val = sc->sc_tx_nobuf;
2399 *val = sc->sc_rx_nobuf;
2402 *val = sc->sc_rx_err;
2405 *val = ic->ic_stats.is_rx_bytes;
2408 *val = ic->ic_stats.is_rx_frags;
2411 *val = ic->ic_stats.is_tx_bytes;
2414 *val = ic->ic_stats.is_tx_frags;
2418 *val = sc->sc_tx_err;
2421 *val = sc->sc_tx_retries;
2433 mutex_exit(&sc->sc_glock);
2436 mutex_exit(&sc->sc_glock);
2439 mutex_exit(&sc->sc_glock);
2449 ieee80211com_t *ic = &sc->sc_ic;
2462 * the 'plumb' succeed. The wpi_thread() tries to re-init
2465 mutex_enter(&sc->sc_glock);
2466 sc->sc_flags |= WPI_F_HW_ERR_RECOVER;
2467 mutex_exit(&sc->sc_glock);
2470 ieee80211_new_state(ic, IEEE80211_S_INIT, -1);
2471 mutex_enter(&sc->sc_glock);
2472 sc->sc_flags |= WPI_F_RUNNING;
2473 mutex_exit(&sc->sc_glock);
2482 ieee80211com_t *ic = &sc->sc_ic;
2485 ieee80211_new_state(ic, IEEE80211_S_INIT, -1);
2486 mutex_enter(&sc->sc_mt_lock);
2487 sc->sc_flags &= ~WPI_F_HW_ERR_RECOVER;
2488 sc->sc_flags &= ~WPI_F_RATE_AUTO_CTL;
2489 mutex_exit(&sc->sc_mt_lock);
2490 mutex_enter(&sc->sc_glock);
2491 sc->sc_flags &= ~WPI_F_RUNNING;
2492 mutex_exit(&sc->sc_glock);
2500 ieee80211com_t *ic = &sc->sc_ic;
2503 if (!IEEE80211_ADDR_EQ(ic->ic_macaddr, macaddr)) {
2504 IEEE80211_ADDR_COPY(ic->ic_macaddr, macaddr);
2505 mutex_enter(&sc->sc_glock);
2507 mutex_exit(&sc->sc_glock);
2537 ieee80211com_t *ic = &sc->sc_ic;
2542 mutex_enter(&sc->sc_mt_lock);
2543 while (sc->sc_mf_thread_switch) {
2546 sc->sc_flags &= ~WPI_F_RADIO_OFF;
2548 sc->sc_flags |= WPI_F_RADIO_OFF;
2553 if ((sc->sc_flags & WPI_F_SUSPEND) ||
2554 (sc->sc_flags & WPI_F_RADIO_OFF)) {
2555 mutex_exit(&sc->sc_mt_lock);
2557 mutex_enter(&sc->sc_mt_lock);
2564 if (ic->ic_mach &&
2565 (sc->sc_flags & WPI_F_HW_ERR_RECOVER)) {
2575 bcopy(&sc->sc_config, &sc->sc_config_save,
2576 sizeof (sc->sc_config));
2578 mutex_exit(&sc->sc_mt_lock);
2579 ieee80211_new_state(ic, IEEE80211_S_INIT, -1);
2581 mutex_enter(&sc->sc_mt_lock);
2592 sc->sc_flags |= WPI_F_RUNNING;
2596 sc->sc_flags &= ~WPI_F_HW_ERR_RECOVER;
2598 mutex_exit(&sc->sc_mt_lock);
2600 if (sc->sc_ostate != IEEE80211_S_INIT)
2603 mutex_enter(&sc->sc_mt_lock);
2607 if (ic->ic_mach && (sc->sc_flags & WPI_F_LAZY_RESUME)) {
2611 sc->sc_flags &= ~WPI_F_LAZY_RESUME;
2612 mutex_exit(&sc->sc_mt_lock);
2619 ieee80211_new_state(&sc->sc_ic, IEEE80211_S_INIT, -1);
2620 mutex_enter(&sc->sc_mt_lock);
2626 if (ic->ic_mach &&
2627 (sc->sc_flags & WPI_F_SCANNING) && sc->sc_scan_next) {
2633 sc->sc_scan_next--;
2634 mutex_exit(&sc->sc_mt_lock);
2636 if (sc->sc_flags & WPI_F_SCANNING)
2638 mutex_enter(&sc->sc_mt_lock);
2644 if (ic->ic_mach &&
2645 (sc->sc_flags & WPI_F_RATE_AUTO_CTL)) {
2647 if (clk > sc->sc_clk + drv_usectohz(500000)) {
2651 mutex_exit(&sc->sc_mt_lock);
2653 mutex_enter(&sc->sc_mt_lock);
2654 if (sc->sc_tx_timer) {
2657 sc->sc_tx_timer--;
2658 if (sc->sc_tx_timer == 0) {
2659 sc->sc_flags |= WPI_F_HW_ERR_RECOVER;
2660 sc->sc_ostate = IEEE80211_S_RUN;
2668 sc->sc_mf_thread = NULL;
2669 cv_signal(&sc->sc_mt_cv);
2670 mutex_exit(&sc->sc_mt_lock);
2679 ieee80211com_t *ic = &sc->sc_ic;
2685 ic->ic_macaddr[0] = val & 0xff;
2686 ic->ic_macaddr[1] = val >> 8;
2688 ic->ic_macaddr[2] = val & 0xff;
2689 ic->ic_macaddr[3] = val >> 8;
2691 ic->ic_macaddr[4] = val & 0xff;
2692 ic->ic_macaddr[5] = val >> 8;
2696 ic->ic_macaddr[0], ic->ic_macaddr[1],
2697 ic->ic_macaddr[2], ic->ic_macaddr[3],
2698 ic->ic_macaddr[4], ic->ic_macaddr[5]));
2701 sc->sc_pwr1[i] = wpi_read_prom_word(sc, WPI_EEPROM_PWR1 + i);
2702 sc->sc_pwr2[i] = wpi_read_prom_word(sc, WPI_EEPROM_PWR2 + i);
2705 sc->sc_pwr1[i], sc->sc_pwr2[i]));
2715 wpi_tx_ring_t *ring = &sc->sc_cmdq;
2719 ASSERT(size <= sizeof (cmd->data));
2720 ASSERT(mutex_owned(&sc->sc_glock));
2723 desc = ring->data[ring->cur].desc;
2724 cmd = ring->data[ring->cur].cmd;
2726 cmd->code = (uint8_t)code;
2727 cmd->flags = 0;
2728 cmd->qid = ring->qid;
2729 cmd->idx = ring->cur;
2730 (void) memcpy(cmd->data, buf, size);
2732 desc->flags = LE_32(WPI_PAD32(size) << 28 | 1 << 24);
2733 desc->segs[0].addr = ring->data[ring->cur].paddr_cmd;
2734 desc->segs[0].len = 4 + size;
2737 ring->cur = (ring->cur + 1) % WPI_CMD_RING_COUNT;
2738 WPI_WRITE(sc, WPI_TX_WIDX, ring->qid << 8 | ring->cur);
2744 sc->sc_flags &= ~WPI_F_CMD_DONE;
2746 while (!(sc->sc_flags & WPI_F_CMD_DONE)) {
2747 if (cv_timedwait(&sc->sc_cmd_cv, &sc->sc_glock, clk)
2751 if (sc->sc_flags & WPI_F_CMD_DONE)
2759 * Configure h/w multi-rate retries.
2772 mrr.rates[i].next = (i == WPI_CCK1) ? WPI_CCK1 : i - 1;
2782 mrr.rates[i].next = (i == WPI_OFDM6) ? WPI_OFDM6 : i - 1;
2824 ieee80211com_t *ic = &sc->sc_ic;
2825 ieee80211_node_t *in = ic->ic_bss;
2830 IEEE80211_ADDR_COPY(sc->sc_config.bssid, in->in_bssid);
2831 sc->sc_config.chan = ieee80211_chan2ieee(ic, in->in_chan);
2832 if (ic->ic_curmode == IEEE80211_MODE_11B) {
2833 sc->sc_config.cck_mask = 0x03;
2834 sc->sc_config.ofdm_mask = 0;
2835 } else if ((in->in_chan != IEEE80211_CHAN_ANYC) &&
2836 (IEEE80211_IS_CHAN_5GHZ(in->in_chan))) {
2837 sc->sc_config.cck_mask = 0;
2838 sc->sc_config.ofdm_mask = 0x15;
2840 sc->sc_config.cck_mask = 0x0f;
2841 sc->sc_config.ofdm_mask = 0xff;
2846 sc->sc_config.chan, sc->sc_config.flags,
2847 sc->sc_config.cck_mask, sc->sc_config.ofdm_mask,
2848 sc->sc_config.bssid[0], sc->sc_config.bssid[1],
2849 sc->sc_config.bssid[2], sc->sc_config.bssid[3],
2850 sc->sc_config.bssid[4], sc->sc_config.bssid[5]));
2851 err = wpi_cmd(sc, WPI_CMD_CONFIGURE, &sc->sc_config,
2855 sc->sc_config.chan);
2861 IEEE80211_ADDR_COPY(node.bssid, in->in_bssid);
2885 ieee80211com_t *ic = &sc->sc_ic;
2886 wpi_tx_ring_t *ring = &sc->sc_cmdq;
2893 ieee80211_node_t *in = ic->ic_bss;
2901 if (sc->sc_scan_pending) {
2906 data = &ring->data[ring->cur];
2907 desc = data->desc;
2908 cmd = (wpi_tx_cmd_t *)data->dma_data.mem_va;
2910 cmd->code = WPI_CMD_SCAN;
2911 cmd->flags = 0;
2912 cmd->qid = ring->qid;
2913 cmd->idx = ring->cur;
2915 hdr = (wpi_scan_hdr_t *)cmd->data;
2917 hdr->first = 1;
2918 hdr->nchan = 1;
2919 hdr->len = hdr->nchan * sizeof (wpi_scan_chan_t);
2920 hdr->quiet = LE_16(50);
2921 hdr->threshold = LE_16(1);
2922 hdr->filter = LE_32(5);
2923 hdr->rate = wpi_plcp_signal(2);
2924 hdr->id = WPI_ID_BROADCAST;
2925 hdr->mask = LE_32(0xffffffff);
2926 hdr->esslen = ic->ic_des_esslen;
2928 if (ic->ic_des_esslen) {
2929 bcopy(ic->ic_des_essid, essid, ic->ic_des_esslen);
2930 essid[ic->ic_des_esslen] = '\0';
2933 bcopy(ic->ic_des_essid, hdr->essid, ic->ic_des_esslen);
2935 bzero(hdr->essid, sizeof (hdr->essid));
2944 wh->i_fc[0] = IEEE80211_FC0_VERSION_0 | IEEE80211_FC0_TYPE_MGT |
2946 wh->i_fc[1] = IEEE80211_FC1_DIR_NODS;
2947 (void) memset(wh->i_addr1, 0xff, 6);
2948 IEEE80211_ADDR_COPY(wh->i_addr2, ic->ic_macaddr);
2949 (void) memset(wh->i_addr3, 0xff, 6);
2950 *(uint16_t *)&wh->i_dur[0] = 0; /* filled by h/w */
2951 *(uint16_t *)&wh->i_seq[0] = 0; /* filled by h/w */
2956 if (in->in_esslen) {
2957 bcopy(in->in_essid, essid, in->in_esslen);
2958 essid[in->in_esslen] = '\0';
2963 *frm++ = in->in_esslen;
2964 (void) memcpy(frm, in->in_essid, in->in_esslen);
2965 frm += in->in_esslen;
2967 mode = ieee80211_chan2mode(ic, ic->ic_curchan);
2968 rs = &ic->ic_sup_rates[mode];
2972 nrates = rs->ir_nrates;
2976 (void) memcpy(frm, rs->ir_rates, nrates);
2980 if (rs->ir_nrates > IEEE80211_RATE_SIZE) {
2981 nrates = rs->ir_nrates - IEEE80211_RATE_SIZE;
2984 (void) memcpy(frm, rs->ir_rates + IEEE80211_RATE_SIZE, nrates);
2989 if (ic->ic_opt_ie != NULL) {
2990 (void) memcpy(frm, ic->ic_opt_ie, ic->ic_opt_ie_len);
2991 frm += ic->ic_opt_ie_len;
2995 hdr->pbrlen = LE_16((uintptr_t)frm - (uintptr_t)wh);
2997 /* align on a 4-byte boundary */
2999 for (i = 1; i <= hdr->nchan; i++, chan++) {
3000 if (ic->ic_des_esslen) {
3001 chan->flags = 0x3;
3003 chan->flags = 0x1;
3005 chan->chan = ieee80211_chan2ieee(ic, ic->ic_curchan);
3006 chan->magic = LE_16(0x62ab);
3007 chan->active = LE_16(50);
3008 chan->passive = LE_16(120);
3013 pktlen = (uintptr_t)frm - (uintptr_t)cmd;
3015 desc->flags = LE_32(WPI_PAD32(pktlen) << 28 | 1 << 24);
3016 desc->segs[0].addr = LE_32(data->dma_data.cookie.dmac_address);
3017 desc->segs[0].len = LE_32(pktlen);
3019 WPI_DMA_SYNC(data->dma_data, DDI_DMA_SYNC_FORDEV);
3020 WPI_DMA_SYNC(ring->dma_desc, DDI_DMA_SYNC_FORDEV);
3023 ring->cur = (ring->cur + 1) % WPI_CMD_RING_COUNT;
3024 WPI_WRITE(sc, WPI_TX_WIDX, ring->qid << 8 | ring->cur);
3026 sc->sc_scan_pending = 1;
3034 ieee80211com_t *ic = &sc->sc_ic;
3047 (void) memcpy(txpower.pwr1, sc->sc_pwr1, 14 * sizeof (uint16_t));
3048 (void) memcpy(txpower.pwr2, sc->sc_pwr2, 14 * sizeof (uint16_t));
3079 (void) memset(&sc->sc_config, 0, sizeof (wpi_config_t));
3080 IEEE80211_ADDR_COPY(sc->sc_config.myaddr, ic->ic_macaddr);
3081 sc->sc_config.chan = ieee80211_chan2ieee(ic, ic->ic_curchan);
3082 sc->sc_config.flags = LE_32(WPI_CONFIG_TSF | WPI_CONFIG_AUTO |
3084 sc->sc_config.filter = 0;
3085 switch (ic->ic_opmode) {
3087 sc->sc_config.mode = WPI_MODE_STA;
3088 sc->sc_config.filter |= LE_32(WPI_FILTER_MULTICAST);
3092 sc->sc_config.mode = WPI_MODE_IBSS;
3095 sc->sc_config.mode = WPI_MODE_HOSTAP;
3098 sc->sc_config.mode = WPI_MODE_MONITOR;
3099 sc->sc_config.filter |= LE_32(WPI_FILTER_MULTICAST |
3103 sc->sc_config.cck_mask = 0x0f; /* not yet negotiated */
3104 sc->sc_config.ofdm_mask = 0xff; /* not yet negotiated */
3105 err = wpi_cmd(sc, WPI_CMD_CONFIGURE, &sc->sc_config,
3224 if ((sc->sc_rev & 0xc0) == 0x40)
3226 else if (!(sc->sc_rev & 0x80))
3253 mutex_enter(&sc->sc_glock);
3254 sc->sc_flags &= ~WPI_F_FW_INIT;
3276 WPI_WRITE(sc, WPI_RX_BASE, sc->sc_rxq.dma_desc.cookie.dmac_address);
3278 (uint32_t)(sc->sc_dma_sh.cookie.dmac_address +
3280 WPI_WRITE(sc, WPI_RX_WIDX, (WPI_RX_RING_COUNT - 1) & (~7));
3294 WPI_WRITE(sc, WPI_TX_BASE_PTR, sc->sc_dma_sh.cookie.dmac_address);
3337 /* now press "execute" ;-) */
3344 while (!(sc->sc_flags & WPI_F_FW_INIT)) {
3345 if (cv_timedwait(&sc->sc_fw_cv, &sc->sc_glock, clk) < 0)
3348 if (!(sc->sc_flags & WPI_F_FW_INIT)) {
3354 /* wait for thermal sensors to calibrate */
3363 "wpi_init(): timeout waiting for thermal sensors "
3376 mutex_exit(&sc->sc_glock);
3381 mutex_exit(&sc->sc_glock);
3388 ieee80211com_t *ic = &sc->sc_ic;
3391 mutex_enter(&sc->sc_glock);
3394 bcopy(&sc->sc_config_save, &sc->sc_config,
3395 sizeof (sc->sc_config));
3397 sc->sc_config.state = 0;
3398 sc->sc_config.filter &= ~LE_32(WPI_FILTER_BSS);
3403 mutex_exit(&sc->sc_glock);
3407 sc->sc_config.state = LE_16(WPI_CONFIG_ASSOCIATED);
3408 sc->sc_config.flags &= ~LE_32(WPI_CONFIG_SHPREAMBLE |
3410 if (ic->ic_flags & IEEE80211_F_SHSLOT)
3411 sc->sc_config.flags |= LE_32(WPI_CONFIG_SHSLOT);
3412 if (ic->ic_flags & IEEE80211_F_SHPREAMBLE)
3413 sc->sc_config.flags |= LE_32(WPI_CONFIG_SHPREAMBLE);
3414 sc->sc_config.filter |= LE_32(WPI_FILTER_BSS);
3415 if (ic->ic_opmode != IEEE80211_M_STA)
3416 sc->sc_config.filter |= LE_32(WPI_FILTER_BEACON);
3419 sc->sc_config.chan, sc->sc_config.flags));
3420 err = wpi_cmd(sc, WPI_CMD_CONFIGURE, &sc->sc_config,
3424 mutex_exit(&sc->sc_glock);
3430 mutex_exit(&sc->sc_glock);
3433 if (ic->ic_flags & IEEE80211_F_PRIVACY) {
3435 if (ic->ic_nw_keys[i].wk_keyix == IEEE80211_KEYIX_NONE)
3437 err = wpi_key_set(ic, &ic->ic_nw_keys[i],
3438 ic->ic_bss->in_macaddr);
3448 sc->sc_flags &= ~WPI_F_HW_ERR_RECOVER;
3452 mac_tx_update(ic->ic_mach);
3459 * This function is called when the system is single-threaded at high
3483 sc->sc_flags |= WPI_F_QUIESCED;
3499 if (!(sc->sc_flags & WPI_F_QUIESCED))
3500 mutex_enter(&sc->sc_glock);
3514 wpi_reset_tx_ring(sc, &sc->sc_txq[ac]);
3515 wpi_reset_tx_ring(sc, &sc->sc_cmdq);
3516 wpi_reset_tx_ring(sc, &sc->sc_svcq);
3529 sc->sc_tx_timer = 0;
3530 sc->sc_flags &= ~WPI_F_SCANNING;
3531 sc->sc_scan_pending = 0;
3532 sc->sc_scan_next = 0;
3538 if (!(sc->sc_flags & WPI_F_QUIESCED))
3539 mutex_exit(&sc->sc_glock);
3546 * INRIA Sophia - Projet Planete
3547 * http://www-sop.inria.fr/rapports/sophia/RR-5208.html
3550 ((amrr)->retrycnt < (amrr)->txcnt / 10)
3552 ((amrr)->retrycnt > (amrr)->txcnt / 3)
3554 ((amrr)->txcnt > 100)
3556 ((in)->in_txrate == 0)
3558 ((in)->in_txrate == (in)->in_rates.ir_nrates - 1)
3560 ((in)->in_txrate++)
3562 ((in)->in_txrate--)
3564 { (amrr)->txcnt = (amrr)->retrycnt = 0; }
3572 amrr->success = 0;
3573 amrr->recovery = 0;
3574 amrr->txcnt = amrr->retrycnt = 0;
3575 amrr->success_threshold = WPI_AMRR_MIN_SUCCESS_THRESHOLD;
3581 ieee80211com_t *ic = &sc->sc_ic;
3584 if (ic->ic_opmode == IEEE80211_M_STA)
3585 wpi_amrr_ratectl(NULL, ic->ic_bss);
3587 ieee80211_iterate_nodes(&ic->ic_sta, wpi_amrr_ratectl, NULL);
3588 sc->sc_clk = ddi_get_lbolt();
3599 amrr->success++;
3600 if (amrr->success >= amrr->success_threshold &&
3602 amrr->recovery = 1;
3603 amrr->success = 0;
3607 in->in_txrate, amrr->txcnt, amrr->retrycnt));
3610 amrr->recovery = 0;
3613 amrr->success = 0;
3615 if (amrr->recovery) {
3616 amrr->success_threshold++;
3617 if (amrr->success_threshold >
3619 amrr->success_threshold =
3622 amrr->success_threshold =
3628 in->in_txrate, amrr->txcnt, amrr->retrycnt));
3631 amrr->recovery = 0; /* paper is incorrect */