Lines Matching defs:sc

279 static void	wpi_destroy_locks(wpi_sc_t *sc);
281 static void wpi_thread(wpi_sc_t *sc);
282 static int wpi_fast_recover(wpi_sc_t *sc);
405 wpi_sc_t *sc;
418 sc = ddi_get_soft_state(wpi_soft_state_p,
420 ASSERT(sc != NULL);
422 mutex_enter(&sc->sc_glock);
423 sc->sc_flags &= ~WPI_F_SUSPEND;
424 mutex_exit(&sc->sc_glock);
426 if (sc->sc_flags & WPI_F_RUNNING)
427 (void) wpi_init(sc);
429 mutex_enter(&sc->sc_glock);
430 sc->sc_flags |= WPI_F_LAZY_RESUME;
431 mutex_exit(&sc->sc_glock);
447 sc = ddi_get_soft_state(wpi_soft_state_p, instance);
448 sc->sc_dip = dip;
457 sc->sc_rev = ddi_get8(cfg_handle,
460 sc->sc_clsz = ddi_get16(cfg_handle,
463 if (!sc->sc_clsz)
464 sc->sc_clsz = 16;
465 sc->sc_clsz = (sc->sc_clsz << 2);
466 sc->sc_dmabuf_sz = roundup(0x1000 + sizeof (struct ieee80211_frame) +
469 IEEE80211_WEP_CRCLEN), sc->sc_clsz);
473 err = ddi_regs_map_setup(dip, 1, &sc->sc_base,
474 0, 0, &wpi_reg_accattr, &sc->sc_handle);
484 err = wpi_alloc_shared(sc);
493 wpi_read_eeprom(sc);
494 err = wpi_ring_init(sc);
501 sc->sc_hdr = (const wpi_firmware_hdr_t *)wpi_fw_bin;
504 sc->sc_text = (const char *)(sc->sc_hdr + 1);
505 sc->sc_data = sc->sc_text + LE_32(sc->sc_hdr->textsz);
506 sc->sc_boot = sc->sc_data + LE_32(sc->sc_hdr->datasz);
507 err = wpi_alloc_fw_dma(sc);
517 err = ddi_get_iblock_cookie(dip, 0, &sc->sc_iblk);
523 mutex_init(&sc->sc_glock, NULL, MUTEX_DRIVER, sc->sc_iblk);
524 mutex_init(&sc->sc_tx_lock, NULL, MUTEX_DRIVER, sc->sc_iblk);
525 cv_init(&sc->sc_fw_cv, NULL, CV_DRIVER, NULL);
526 cv_init(&sc->sc_cmd_cv, NULL, CV_DRIVER, NULL);
531 mutex_init(&sc->sc_mt_lock, NULL, MUTEX_DRIVER,
532 (void *) sc->sc_iblk);
533 cv_init(&sc->sc_mt_cv, NULL, CV_DRIVER, NULL);
534 sc->sc_mf_thread = NULL;
535 sc->sc_mf_thread_switch = 0;
540 ic = &sc->sc_ic;
581 sc->sc_newstate = ic->ic_newstate;
593 &sc->sc_notif_softint_id, &sc->sc_iblk, NULL, wpi_notif_softintr,
594 (caddr_t)sc);
604 err = ddi_add_intr(dip, 0, &sc->sc_iblk, NULL,
605 wpi_intr, (caddr_t)sc);
627 macp->m_driver = sc;
667 sc->sc_mf_thread_switch = 1;
668 if (sc->sc_mf_thread == NULL)
669 sc->sc_mf_thread = thread_create((caddr_t)NULL, 0,
670 wpi_thread, sc, 0, &p0, TS_RUN, minclsyspri);
672 sc->sc_flags |= WPI_F_ATTACHED;
676 ddi_remove_intr(dip, 0, sc->sc_iblk);
678 ddi_remove_softintr(sc->sc_notif_softint_id);
679 sc->sc_notif_softint_id = NULL;
682 wpi_destroy_locks(sc);
684 wpi_free_fw_dma(sc);
686 wpi_ring_free(sc);
688 wpi_free_shared(sc);
690 ddi_regs_map_free(&sc->sc_handle);
700 wpi_sc_t *sc;
703 sc = ddi_get_soft_state(wpi_soft_state_p, ddi_get_instance(dip));
704 ASSERT(sc != NULL);
710 mutex_enter(&sc->sc_glock);
711 sc->sc_flags |= WPI_F_SUSPEND;
712 mutex_exit(&sc->sc_glock);
714 if (sc->sc_flags & WPI_F_RUNNING) {
715 wpi_stop(sc);
723 if (!(sc->sc_flags & WPI_F_ATTACHED))
726 err = mac_disable(sc->sc_ic.ic_mach);
733 mutex_enter(&sc->sc_mt_lock);
734 sc->sc_mf_thread_switch = 0;
735 while (sc->sc_mf_thread != NULL) {
736 if (cv_wait_sig(&sc->sc_mt_cv, &sc->sc_mt_lock) == 0)
739 mutex_exit(&sc->sc_mt_lock);
741 wpi_stop(sc);
746 (void) mac_unregister(sc->sc_ic.ic_mach);
748 mutex_enter(&sc->sc_glock);
749 wpi_free_fw_dma(sc);
750 wpi_ring_free(sc);
751 wpi_free_shared(sc);
752 mutex_exit(&sc->sc_glock);
754 ddi_remove_intr(dip, 0, sc->sc_iblk);
755 ddi_remove_softintr(sc->sc_notif_softint_id);
756 sc->sc_notif_softint_id = NULL;
761 ieee80211_detach(&sc->sc_ic);
763 wpi_destroy_locks(sc);
765 ddi_regs_map_free(&sc->sc_handle);
773 wpi_destroy_locks(wpi_sc_t *sc)
775 cv_destroy(&sc->sc_mt_cv);
776 mutex_destroy(&sc->sc_mt_lock);
777 cv_destroy(&sc->sc_cmd_cv);
778 cv_destroy(&sc->sc_fw_cv);
779 mutex_destroy(&sc->sc_tx_lock);
780 mutex_destroy(&sc->sc_glock);
787 wpi_alloc_dma_mem(wpi_sc_t *sc, size_t memsize, ddi_dma_attr_t *dma_attr_p,
796 err = ddi_dma_alloc_handle(sc->sc_dip, dma_attr_p,
869 wpi_alloc_fw_dma(wpi_sc_t *sc)
874 err = wpi_alloc_dma_mem(sc, LE_32(sc->sc_hdr->textsz),
877 &sc->sc_dma_fw_text);
878 dma_p = &sc->sc_dma_fw_text;
888 sc->sc_fw_text_cookie[i] = dma_p->cookie;
891 err = wpi_alloc_dma_mem(sc, LE_32(sc->sc_hdr->datasz),
894 &sc->sc_dma_fw_data);
895 dma_p = &sc->sc_dma_fw_data;
905 sc->sc_fw_data_cookie[i] = dma_p->cookie;
913 wpi_free_fw_dma(wpi_sc_t *sc)
915 wpi_free_dma_mem(&sc->sc_dma_fw_text);
916 wpi_free_dma_mem(&sc->sc_dma_fw_data);
923 wpi_alloc_shared(wpi_sc_t *sc)
928 err = wpi_alloc_dma_mem(sc, sizeof (wpi_shared_t),
931 &sc->sc_dma_sh);
934 sc->sc_shared = (wpi_shared_t *)sc->sc_dma_sh.mem_va;
938 wpi_free_shared(sc);
943 wpi_free_shared(wpi_sc_t *sc)
945 wpi_free_dma_mem(&sc->sc_dma_sh);
949 wpi_alloc_rx_ring(wpi_sc_t *sc)
955 ring = &sc->sc_rxq;
958 err = wpi_alloc_dma_mem(sc, WPI_RX_RING_COUNT * sizeof (uint32_t),
973 err = wpi_alloc_dma_mem(sc, sc->sc_dmabuf_sz,
991 wpi_free_rx_ring(sc);
996 wpi_reset_rx_ring(wpi_sc_t *sc)
1000 wpi_mem_lock(sc);
1002 WPI_WRITE(sc, WPI_RX_CONFIG, 0);
1004 if (WPI_READ(sc, WPI_RX_STATUS) & WPI_RX_IDLE)
1011 wpi_mem_unlock(sc);
1013 sc->sc_rxq.cur = 0;
1017 wpi_free_rx_ring(wpi_sc_t *sc)
1022 if (sc->sc_rxq.data[i].dma_data.dma_hdl)
1023 WPI_DMA_SYNC(sc->sc_rxq.data[i].dma_data,
1025 wpi_free_dma_mem(&sc->sc_rxq.data[i].dma_data);
1028 if (sc->sc_rxq.dma_desc.dma_hdl)
1029 WPI_DMA_SYNC(sc->sc_rxq.dma_desc, DDI_DMA_SYNC_FORDEV);
1030 wpi_free_dma_mem(&sc->sc_rxq.dma_desc);
1034 wpi_alloc_tx_ring(wpi_sc_t *sc, wpi_tx_ring_t *ring, int count, int qid)
1048 err = wpi_alloc_dma_mem(sc, count * sizeof (wpi_tx_desc_t),
1059 sc->sc_shared->txbase[qid] = ring->dma_desc.cookie.dmac_address;
1064 err = wpi_alloc_dma_mem(sc, count * sizeof (wpi_tx_cmd_t),
1088 err = wpi_alloc_dma_mem(sc, sc->sc_dmabuf_sz,
1109 wpi_free_tx_ring(sc, ring);
1114 wpi_reset_tx_ring(wpi_sc_t *sc, wpi_tx_ring_t *ring)
1119 wpi_mem_lock(sc);
1121 WPI_WRITE(sc, WPI_TX_CONFIG(ring->qid), 0);
1123 if (WPI_READ(sc, WPI_TX_STATUS) & WPI_TX_IDLE(ring->qid))
1133 wpi_mem_unlock(sc);
1135 if (!(sc->sc_flags & WPI_F_QUIESCED)) {
1148 wpi_free_tx_ring(wpi_sc_t *sc, wpi_tx_ring_t *ring)
1173 wpi_ring_init(wpi_sc_t *sc)
1178 err = wpi_alloc_tx_ring(sc, &sc->sc_txq[i], WPI_TX_RING_COUNT,
1183 err = wpi_alloc_tx_ring(sc, &sc->sc_cmdq, WPI_CMD_RING_COUNT, 4);
1186 err = wpi_alloc_tx_ring(sc, &sc->sc_svcq, WPI_SVC_RING_COUNT, 5);
1189 err = wpi_alloc_rx_ring(sc);
1199 wpi_ring_free(wpi_sc_t *sc)
1203 wpi_free_rx_ring(sc);
1204 wpi_free_tx_ring(sc, &sc->sc_svcq);
1205 wpi_free_tx_ring(sc, &sc->sc_cmdq);
1207 wpi_free_tx_ring(sc, &sc->sc_txq[i]);
1238 wpi_sc_t *sc = (wpi_sc_t *)ic;
1243 mutex_enter(&sc->sc_glock);
1252 sc->sc_flags |= WPI_F_SCANNING;
1253 sc->sc_scan_next = 0;
1256 wpi_set_led(sc, WPI_LED_LINK, 20, 2);
1262 sc->sc_config.state = 0;
1263 sc->sc_config.filter &= ~LE_32(WPI_FILTER_BSS);
1267 sc->sc_config.chan, sc->sc_config.flags,
1268 sc->sc_config.filter));
1270 err = wpi_cmd(sc, WPI_CMD_CONFIGURE, &sc->sc_config,
1275 sc->sc_flags &= ~WPI_F_SCANNING;
1276 mutex_exit(&sc->sc_glock);
1285 err = wpi_cmd(sc, WPI_CMD_ADD_NODE, &node,
1290 sc->sc_flags &= ~WPI_F_SCANNING;
1291 mutex_exit(&sc->sc_glock);
1297 mutex_exit(&sc->sc_glock);
1299 err = sc->sc_newstate(ic, nstate, arg);
1300 mutex_enter(&sc->sc_glock);
1301 if ((err != 0) || ((err = wpi_scan(sc)) != 0)) {
1304 sc->sc_flags &= ~WPI_F_SCANNING;
1307 mutex_exit(&sc->sc_glock);
1312 sc->sc_clk = 0;
1317 sc->sc_flags &= ~WPI_F_SCANNING;
1321 sc->sc_config.state = 0;
1322 sc->sc_config.filter &= ~LE_32(WPI_FILTER_BSS);
1324 if ((err = wpi_auth(sc)) != 0) {
1327 mutex_exit(&sc->sc_glock);
1334 sc->sc_flags &= ~WPI_F_SCANNING;
1339 wpi_set_led(sc, WPI_LED_LINK, 5, 5);
1344 (void) wpi_auth(sc);
1350 sc->sc_config.state = LE_16(WPI_CONFIG_ASSOCIATED);
1352 sc->sc_config.flags &= ~LE_32(WPI_CONFIG_SHPREAMBLE |
1355 sc->sc_config.flags |= LE_32(WPI_CONFIG_SHSLOT);
1357 sc->sc_config.flags |= LE_32(WPI_CONFIG_SHPREAMBLE);
1358 sc->sc_config.filter |= LE_32(WPI_FILTER_BSS);
1360 sc->sc_config.filter |= LE_32(WPI_FILTER_BEACON);
1363 sc->sc_config.chan, sc->sc_config.flags));
1364 err = wpi_cmd(sc, WPI_CMD_CONFIGURE, &sc->sc_config,
1369 mutex_exit(&sc->sc_glock);
1374 mutex_enter(&sc->sc_mt_lock);
1376 sc->sc_flags |= WPI_F_RATE_AUTO_CTL;
1383 sc->sc_flags &= ~WPI_F_RATE_AUTO_CTL;
1385 mutex_exit(&sc->sc_mt_lock);
1388 wpi_set_led(sc, WPI_LED_LINK, 0, 1);
1392 sc->sc_flags &= ~WPI_F_SCANNING;
1396 sc->sc_flags &= ~WPI_F_SCANNING;
1400 mutex_exit(&sc->sc_glock);
1401 return (sc->sc_newstate(ic, nstate, arg));
1408 wpi_sc_t *sc = (wpi_sc_t *)ic;
1421 sc->sc_config.filter &= ~(WPI_FILTER_NODECRYPTUNI |
1424 mutex_enter(&sc->sc_glock);
1446 err = wpi_cmd(sc, WPI_CMD_ADD_NODE, &node, sizeof (node), 1);
1450 mutex_exit(&sc->sc_glock);
1453 mutex_exit(&sc->sc_glock);
1461 wpi_mem_lock(wpi_sc_t *sc)
1466 tmp = WPI_READ(sc, WPI_GPIO_CTL);
1467 WPI_WRITE(sc, WPI_GPIO_CTL, tmp | WPI_GPIO_MAC);
1471 if ((WPI_READ(sc, WPI_GPIO_CTL) &
1484 wpi_mem_unlock(wpi_sc_t *sc)
1486 uint32_t tmp = WPI_READ(sc, WPI_GPIO_CTL);
1487 WPI_WRITE(sc, WPI_GPIO_CTL, tmp & ~WPI_GPIO_MAC);
1491 wpi_mem_read(wpi_sc_t *sc, uint16_t addr)
1493 WPI_WRITE(sc, WPI_READ_MEM_ADDR, WPI_MEM_4 | addr);
1494 return (WPI_READ(sc, WPI_READ_MEM_DATA));
1498 wpi_mem_write(wpi_sc_t *sc, uint16_t addr, uint32_t data)
1500 WPI_WRITE(sc, WPI_WRITE_MEM_ADDR, WPI_MEM_4 | addr);
1501 WPI_WRITE(sc, WPI_WRITE_MEM_DATA, data);
1505 wpi_mem_write_region_4(wpi_sc_t *sc, uint16_t addr,
1509 wpi_mem_write(sc, addr, *data);
1517 wpi_read_prom_word(wpi_sc_t *sc, uint32_t addr)
1522 WPI_WRITE(sc, WPI_EEPROM_CTL, addr << 2);
1524 wpi_mem_lock(sc);
1526 if ((val = WPI_READ(sc, WPI_EEPROM_CTL)) & WPI_EEPROM_READY)
1530 wpi_mem_unlock(sc);
1544 wpi_load_microcode(wpi_sc_t *sc)
1549 ucode = sc->sc_boot;
1550 size = LE_32(sc->sc_hdr->bootsz);
1557 wpi_mem_lock(sc);
1560 wpi_mem_write_region_4(sc, WPI_MEM_UCODE_BASE, (const uint32_t *)ucode,
1563 wpi_mem_write(sc, WPI_MEM_UCODE_SRC, 0);
1564 wpi_mem_write(sc, WPI_MEM_UCODE_DST, WPI_FW_TEXT);
1565 wpi_mem_write(sc, WPI_MEM_UCODE_SIZE, size);
1568 wpi_mem_write(sc, WPI_MEM_UCODE_CTL, WPI_UC_RUN);
1570 wpi_mem_unlock(sc);
1582 wpi_load_firmware(wpi_sc_t *sc, uint32_t target)
1593 fw = sc->sc_text;
1594 size = LE_32(sc->sc_hdr->textsz);
1595 dma_p = &sc->sc_dma_fw_text;
1596 cookie = sc->sc_fw_text_cookie;
1598 fw = sc->sc_data;
1599 size = LE_32(sc->sc_hdr->datasz);
1600 dma_p = &sc->sc_dma_fw_data;
1601 cookie = sc->sc_fw_data_cookie;
1619 wpi_mem_lock(sc);
1622 WPI_WRITE(sc, WPI_FW_TARGET, target);
1624 WPI_WRITE(sc, WPI_TX_CONFIG(6), 0);
1627 WPI_WRITE_REGION_4(sc, WPI_TX_DESC(6), (uint32_t *)&desc,
1630 WPI_WRITE(sc, WPI_TX_CREDIT(6), 0xfffff);
1631 WPI_WRITE(sc, WPI_TX_STATE(6), 0x4001);
1632 WPI_WRITE(sc, WPI_TX_CONFIG(6), 0x80000001);
1636 if (WPI_READ(sc, WPI_TX_STATUS) & WPI_TX_IDLE(6))
1645 WPI_WRITE(sc, WPI_TX_CREDIT(6), 0);
1647 wpi_mem_unlock(sc);
1654 wpi_rx_intr(wpi_sc_t *sc, wpi_rx_desc_t *desc, wpi_rx_data_t *data)
1656 ieee80211com_t *ic = &sc->sc_ic;
1657 wpi_rx_ring_t *ring = &sc->sc_rxq;
1683 if ((len < 20) || (len > sc->sc_dmabuf_sz)) {
1684 sc->sc_rx_err++;
1694 sc->sc_rx_err++;
1703 if (sc->sc_drvbpf != NULL) {
1705 if (bpf_peers_present(sc->sc_drvbpf)) {
1707 struct wpi_rx_radiotap_header *tap = &sc->sc_rxtap;
1740 bpf_mtap2(sc->sc_drvbpf, tap, sc->sc_rxtap_len, m);
1760 sc->sc_rx_nobuf++;
1770 wpi_tx_intr(wpi_sc_t *sc, wpi_rx_desc_t *desc, wpi_rx_data_t *data)
1772 ieee80211com_t *ic = &sc->sc_ic;
1773 wpi_tx_ring_t *ring = &sc->sc_txq[desc->qid & 0x3];
1787 sc->sc_tx_retries++;
1792 sc->sc_tx_timer = 0;
1794 mutex_enter(&sc->sc_tx_lock);
1798 if ((sc->sc_need_reschedule) && (ring->queued <= (ring->count << 3))) {
1799 sc->sc_need_reschedule = 0;
1800 mutex_exit(&sc->sc_tx_lock);
1802 mutex_enter(&sc->sc_tx_lock);
1804 mutex_exit(&sc->sc_tx_lock);
1808 wpi_cmd_intr(wpi_sc_t *sc, wpi_rx_desc_t *desc)
1813 mutex_enter(&sc->sc_glock);
1814 sc->sc_flags |= WPI_F_CMD_DONE;
1815 cv_signal(&sc->sc_cmd_cv);
1816 mutex_exit(&sc->sc_glock);
1822 wpi_sc_t *sc = (wpi_sc_t *)arg;
1827 mutex_enter(&sc->sc_glock);
1828 if (sc->sc_notif_softint_pending != 1) {
1829 mutex_exit(&sc->sc_glock);
1832 mutex_exit(&sc->sc_glock);
1834 hw = LE_32(sc->sc_shared->next);
1836 while (sc->sc_rxq.cur != hw) {
1837 data = &sc->sc_rxq.data[sc->sc_rxq.cur];
1842 hw, sc->sc_rxq.cur, desc->qid, desc->idx, desc->flags,
1846 wpi_cmd_intr(sc, desc);
1851 wpi_rx_intr(sc, desc, data);
1856 wpi_tx_intr(sc, desc, data);
1893 sc->sc_ostate = sc->sc_ic.ic_state;
1894 ieee80211_new_state(&sc->sc_ic,
1896 sc->sc_flags |=
1921 sc->sc_scan_pending = 0;
1922 sc->sc_scan_next++;
1929 sc->sc_rxq.cur = (sc->sc_rxq.cur + 1) % WPI_RX_RING_COUNT;
1934 WPI_WRITE(sc, WPI_RX_WIDX, hw & (~7));
1935 mutex_enter(&sc->sc_glock);
1936 sc->sc_notif_softint_pending = 0;
1937 mutex_exit(&sc->sc_glock);
1945 wpi_sc_t *sc = (wpi_sc_t *)arg;
1948 mutex_enter(&sc->sc_glock);
1949 if (sc->sc_flags & WPI_F_SUSPEND) {
1950 mutex_exit(&sc->sc_glock);
1954 r = WPI_READ(sc, WPI_INTR);
1956 mutex_exit(&sc->sc_glock);
1962 rfh = WPI_READ(sc, WPI_INTR_STATUS);
1964 WPI_WRITE(sc, WPI_MASK, 0);
1966 WPI_WRITE(sc, WPI_INTR, r);
1967 WPI_WRITE(sc, WPI_INTR_STATUS, rfh);
1969 if (sc->sc_notif_softint_id == NULL) {
1970 mutex_exit(&sc->sc_glock);
1976 mutex_exit(&sc->sc_glock);
1977 wpi_stop(sc);
1978 if (!(sc->sc_flags & WPI_F_HW_ERR_RECOVER)) {
1979 sc->sc_ostate = sc->sc_ic.ic_state;
1983 if (!WPI_CHK_FAST_RECOVER(sc))
1984 ieee80211_new_state(&sc->sc_ic, IEEE80211_S_INIT, -1);
1986 sc->sc_flags |= WPI_F_HW_ERR_RECOVER;
1992 sc->sc_notif_softint_pending = 1;
1993 ddi_trigger_softintr(sc->sc_notif_softint_id);
1997 sc->sc_flags |= WPI_F_FW_INIT;
1998 cv_signal(&sc->sc_fw_cv);
2002 WPI_WRITE(sc, WPI_MASK, WPI_INTR_MASK);
2003 mutex_exit(&sc->sc_glock);
2037 wpi_sc_t *sc = (wpi_sc_t *)arg;
2038 ieee80211com_t *ic = &sc->sc_ic;
2041 if (sc->sc_flags & WPI_F_SUSPEND) {
2051 if ((sc->sc_flags & WPI_F_HW_ERR_RECOVER) &&
2052 WPI_CHK_FAST_RECOVER(sc)) {
2073 wpi_sc_t *sc = (wpi_sc_t *)ic;
2086 (&sc->sc_txq[0]) : (&sc->sc_txq[1]);
2093 mutex_enter(&sc->sc_tx_lock);
2094 if (sc->sc_flags & WPI_F_SUSPEND) {
2095 mutex_exit(&sc->sc_tx_lock);
2106 sc->sc_need_reschedule = 1;
2107 mutex_exit(&sc->sc_tx_lock);
2112 sc->sc_tx_nobuf++;
2116 mutex_exit(&sc->sc_tx_lock);
2142 sc->sc_tx_err++;
2166 sc->sc_tx_err++;
2204 if (sc->sc_drvbpf != NULL) {
2206 if (bpf_peers_present(sc->sc_drvbpf)) {
2208 struct wpi_tx_radiotap_header *tap = &sc->sc_txtap;
2217 bpf_mtap2(sc->sc_drvbpf, tap, sc->sc_txtap_len, m0);
2276 mutex_enter(&sc->sc_tx_lock);
2278 mutex_exit(&sc->sc_tx_lock);
2282 WPI_WRITE(sc, WPI_TX_WIDX, ring->qid << 8 | ring->cur);
2290 if (sc->sc_tx_timer == 0)
2291 sc->sc_tx_timer = 5;
2299 wpi_sc_t *sc = (wpi_sc_t *)arg;
2300 ieee80211com_t *ic = &sc->sc_ic;
2314 if (sc->sc_flags & WPI_F_RUNNING) {
2315 wpi_m_stop(sc);
2316 (void) wpi_m_start(sc);
2333 wpi_sc_t *sc = (wpi_sc_t *)arg;
2335 err = ieee80211_getprop(&sc->sc_ic, pr_name, wldp_pr_name,
2345 wpi_sc_t *sc = (wpi_sc_t *)arg;
2347 ieee80211_propinfo(&sc->sc_ic, pr_name, wldp_pr_num, mph);
2355 wpi_sc_t *sc = (wpi_sc_t *)arg;
2356 ieee80211com_t *ic = &sc->sc_ic;
2363 if (sc->sc_flags & WPI_F_RUNNING) {
2364 wpi_m_stop(sc);
2365 (void) wpi_m_start(sc);
2381 wpi_sc_t *sc = (wpi_sc_t *)arg;
2382 ieee80211com_t *ic = &sc->sc_ic;
2385 mutex_enter(&sc->sc_glock);
2394 *val = sc->sc_tx_nobuf;
2397 *val = sc->sc_rx_nobuf;
2400 *val = sc->sc_rx_err;
2416 *val = sc->sc_tx_err;
2419 *val = sc->sc_tx_retries;
2431 mutex_exit(&sc->sc_glock);
2434 mutex_exit(&sc->sc_glock);
2437 mutex_exit(&sc->sc_glock);
2446 wpi_sc_t *sc = (wpi_sc_t *)arg;
2447 ieee80211com_t *ic = &sc->sc_ic;
2450 err = wpi_init(sc);
2452 wpi_stop(sc);
2454 err = wpi_init(sc);
2463 mutex_enter(&sc->sc_glock);
2464 sc->sc_flags |= WPI_F_HW_ERR_RECOVER;
2465 mutex_exit(&sc->sc_glock);
2469 mutex_enter(&sc->sc_glock);
2470 sc->sc_flags |= WPI_F_RUNNING;
2471 mutex_exit(&sc->sc_glock);
2479 wpi_sc_t *sc = (wpi_sc_t *)arg;
2480 ieee80211com_t *ic = &sc->sc_ic;
2482 wpi_stop(sc);
2484 mutex_enter(&sc->sc_mt_lock);
2485 sc->sc_flags &= ~WPI_F_HW_ERR_RECOVER;
2486 sc->sc_flags &= ~WPI_F_RATE_AUTO_CTL;
2487 mutex_exit(&sc->sc_mt_lock);
2488 mutex_enter(&sc->sc_glock);
2489 sc->sc_flags &= ~WPI_F_RUNNING;
2490 mutex_exit(&sc->sc_glock);
2497 wpi_sc_t *sc = (wpi_sc_t *)arg;
2498 ieee80211com_t *ic = &sc->sc_ic;
2503 mutex_enter(&sc->sc_glock);
2504 err = wpi_config(sc);
2505 mutex_exit(&sc->sc_glock);
2533 wpi_thread(wpi_sc_t *sc)
2535 ieee80211com_t *ic = &sc->sc_ic;
2540 mutex_enter(&sc->sc_mt_lock);
2541 while (sc->sc_mf_thread_switch) {
2542 tmp = WPI_READ(sc, WPI_GPIO_CTL);
2544 sc->sc_flags &= ~WPI_F_RADIO_OFF;
2546 sc->sc_flags |= WPI_F_RADIO_OFF;
2551 if ((sc->sc_flags & WPI_F_SUSPEND) ||
2552 (sc->sc_flags & WPI_F_RADIO_OFF)) {
2553 mutex_exit(&sc->sc_mt_lock);
2555 mutex_enter(&sc->sc_mt_lock);
2563 (sc->sc_flags & WPI_F_HW_ERR_RECOVER)) {
2569 wpi_stop(sc);
2571 if (WPI_CHK_FAST_RECOVER(sc)) {
2573 bcopy(&sc->sc_config, &sc->sc_config_save,
2574 sizeof (sc->sc_config));
2576 mutex_exit(&sc->sc_mt_lock);
2579 mutex_enter(&sc->sc_mt_lock);
2582 err = wpi_init(sc);
2590 sc->sc_flags |= WPI_F_RUNNING;
2592 if (!WPI_CHK_FAST_RECOVER(sc) ||
2593 wpi_fast_recover(sc) != WPI_SUCCESS) {
2594 sc->sc_flags &= ~WPI_F_HW_ERR_RECOVER;
2596 mutex_exit(&sc->sc_mt_lock);
2598 if (sc->sc_ostate != IEEE80211_S_INIT)
2601 mutex_enter(&sc->sc_mt_lock);
2605 if (ic->ic_mach && (sc->sc_flags & WPI_F_LAZY_RESUME)) {
2609 sc->sc_flags &= ~WPI_F_LAZY_RESUME;
2610 mutex_exit(&sc->sc_mt_lock);
2617 ieee80211_new_state(&sc->sc_ic, IEEE80211_S_INIT, -1);
2618 mutex_enter(&sc->sc_mt_lock);
2625 (sc->sc_flags & WPI_F_SCANNING) && sc->sc_scan_next) {
2631 sc->sc_scan_next--;
2632 mutex_exit(&sc->sc_mt_lock);
2634 if (sc->sc_flags & WPI_F_SCANNING)
2636 mutex_enter(&sc->sc_mt_lock);
2643 (sc->sc_flags & WPI_F_RATE_AUTO_CTL)) {
2645 if (clk > sc->sc_clk + drv_usectohz(500000)) {
2646 wpi_amrr_timeout(sc);
2649 mutex_exit(&sc->sc_mt_lock);
2651 mutex_enter(&sc->sc_mt_lock);
2652 if (sc->sc_tx_timer) {
2655 sc->sc_tx_timer--;
2656 if (sc->sc_tx_timer == 0) {
2657 sc->sc_flags |= WPI_F_HW_ERR_RECOVER;
2658 sc->sc_ostate = IEEE80211_S_RUN;
2666 sc->sc_mf_thread = NULL;
2667 cv_signal(&sc->sc_mt_cv);
2668 mutex_exit(&sc->sc_mt_lock);
2675 wpi_read_eeprom(wpi_sc_t *sc)
2677 ieee80211com_t *ic = &sc->sc_ic;
2682 val = wpi_read_prom_word(sc, WPI_EEPROM_MAC + 0);
2685 val = wpi_read_prom_word(sc, WPI_EEPROM_MAC + 1);
2688 val = wpi_read_prom_word(sc, WPI_EEPROM_MAC + 2);
2699 sc->sc_pwr1[i] = wpi_read_prom_word(sc, WPI_EEPROM_PWR1 + i);
2700 sc->sc_pwr2[i] = wpi_read_prom_word(sc, WPI_EEPROM_PWR2 + i);
2703 sc->sc_pwr1[i], sc->sc_pwr2[i]));
2711 wpi_cmd(wpi_sc_t *sc, int code, const void *buf, int size, int async)
2713 wpi_tx_ring_t *ring = &sc->sc_cmdq;
2718 ASSERT(mutex_owned(&sc->sc_glock));
2736 WPI_WRITE(sc, WPI_TX_WIDX, ring->qid << 8 | ring->cur);
2742 sc->sc_flags &= ~WPI_F_CMD_DONE;
2744 while (!(sc->sc_flags & WPI_F_CMD_DONE)) {
2745 if (cv_timedwait(&sc->sc_cmd_cv, &sc->sc_glock, clk)
2749 if (sc->sc_flags & WPI_F_CMD_DONE)
2760 wpi_mrr_setup(wpi_sc_t *sc)
2787 err = wpi_cmd(sc, WPI_CMD_MRR_SETUP, &mrr, sizeof (mrr), 1);
2796 err = wpi_cmd(sc, WPI_CMD_MRR_SETUP, &mrr, sizeof (mrr), 1);
2807 wpi_set_led(wpi_sc_t *sc, uint8_t which, uint8_t off, uint8_t on)
2816 (void) wpi_cmd(sc, WPI_CMD_SET_LED, &led, sizeof (led), 1);
2820 wpi_auth(wpi_sc_t *sc)
2822 ieee80211com_t *ic = &sc->sc_ic;
2828 IEEE80211_ADDR_COPY(sc->sc_config.bssid, in->in_bssid);
2829 sc->sc_config.chan = ieee80211_chan2ieee(ic, in->in_chan);
2831 sc->sc_config.cck_mask = 0x03;
2832 sc->sc_config.ofdm_mask = 0;
2835 sc->sc_config.cck_mask = 0;
2836 sc->sc_config.ofdm_mask = 0x15;
2838 sc->sc_config.cck_mask = 0x0f;
2839 sc->sc_config.ofdm_mask = 0xff;
2844 sc->sc_config.chan, sc->sc_config.flags,
2845 sc->sc_config.cck_mask, sc->sc_config.ofdm_mask,
2846 sc->sc_config.bssid[0], sc->sc_config.bssid[1],
2847 sc->sc_config.bssid[2], sc->sc_config.bssid[3],
2848 sc->sc_config.bssid[4], sc->sc_config.bssid[5]));
2849 err = wpi_cmd(sc, WPI_CMD_CONFIGURE, &sc->sc_config,
2853 sc->sc_config.chan);
2862 err = wpi_cmd(sc, WPI_CMD_ADD_NODE, &node, sizeof (node), 1);
2868 err = wpi_mrr_setup(sc);
2881 wpi_scan(wpi_sc_t *sc)
2883 ieee80211com_t *ic = &sc->sc_ic;
2884 wpi_tx_ring_t *ring = &sc->sc_cmdq;
2899 if (sc->sc_scan_pending) {
3022 WPI_WRITE(sc, WPI_TX_WIDX, ring->qid << 8 | ring->cur);
3024 sc->sc_scan_pending = 1;
3030 wpi_config(wpi_sc_t *sc)
3032 ieee80211com_t *ic = &sc->sc_ic;
3045 (void) memcpy(txpower.pwr1, sc->sc_pwr1, 14 * sizeof (uint16_t));
3046 (void) memcpy(txpower.pwr2, sc->sc_pwr2, 14 * sizeof (uint16_t));
3047 err = wpi_cmd(sc, WPI_CMD_TXPOWER, &txpower, sizeof (txpower), 0);
3056 err = wpi_cmd(sc, WPI_CMD_SET_POWER_MODE, &power, sizeof (power), 0);
3067 err = wpi_cmd(sc, WPI_CMD_BLUETOOTH, &bluetooth,
3077 (void) memset(&sc->sc_config, 0, sizeof (wpi_config_t));
3078 IEEE80211_ADDR_COPY(sc->sc_config.myaddr, ic->ic_macaddr);
3079 sc->sc_config.chan = ieee80211_chan2ieee(ic, ic->ic_curchan);
3080 sc->sc_config.flags = LE_32(WPI_CONFIG_TSF | WPI_CONFIG_AUTO |
3082 sc->sc_config.filter = 0;
3085 sc->sc_config.mode = WPI_MODE_STA;
3086 sc->sc_config.filter |= LE_32(WPI_FILTER_MULTICAST);
3090 sc->sc_config.mode = WPI_MODE_IBSS;
3093 sc->sc_config.mode = WPI_MODE_HOSTAP;
3096 sc->sc_config.mode = WPI_MODE_MONITOR;
3097 sc->sc_config.filter |= LE_32(WPI_FILTER_MULTICAST |
3101 sc->sc_config.cck_mask = 0x0f; /* not yet negotiated */
3102 sc->sc_config.ofdm_mask = 0xff; /* not yet negotiated */
3103 err = wpi_cmd(sc, WPI_CMD_CONFIGURE, &sc->sc_config,
3116 err = wpi_cmd(sc, WPI_CMD_ADD_NODE, &node, sizeof (node), 0);
3127 wpi_stop_master(wpi_sc_t *sc)
3132 tmp = WPI_READ(sc, WPI_RESET);
3133 WPI_WRITE(sc, WPI_RESET, tmp | WPI_STOP_MASTER);
3135 tmp = WPI_READ(sc, WPI_GPIO_CTL);
3140 if (WPI_READ(sc, WPI_RESET) & WPI_MASTER_DISABLED)
3149 wpi_power_up(wpi_sc_t *sc)
3154 wpi_mem_lock(sc);
3155 tmp = wpi_mem_read(sc, WPI_MEM_POWER);
3156 wpi_mem_write(sc, WPI_MEM_POWER, tmp & ~0x03000000);
3157 wpi_mem_unlock(sc);
3160 if (WPI_READ(sc, WPI_GPIO_STATUS) & WPI_POWERED)
3173 wpi_reset(wpi_sc_t *sc)
3179 WPI_WRITE(sc, WPI_INTR, 0xffffffff);
3181 tmp = WPI_READ(sc, WPI_PLL_CTL);
3182 WPI_WRITE(sc, WPI_PLL_CTL, tmp | WPI_PLL_INIT);
3184 tmp = WPI_READ(sc, WPI_CHICKEN);
3185 WPI_WRITE(sc, WPI_CHICKEN, tmp | WPI_CHICKEN_RXNOLOS);
3187 tmp = WPI_READ(sc, WPI_GPIO_CTL);
3188 WPI_WRITE(sc, WPI_GPIO_CTL, tmp | WPI_GPIO_INIT);
3192 if (WPI_READ(sc, WPI_GPIO_CTL) & WPI_GPIO_CLOCK)
3203 tmp = WPI_READ(sc, WPI_EEPROM_STATUS);
3208 WPI_WRITE(sc, WPI_EEPROM_STATUS, tmp & ~WPI_EEPROM_LOCKED);
3214 wpi_hw_config(wpi_sc_t *sc)
3220 hw = WPI_READ(sc, WPI_HWCONFIG);
3222 if ((sc->sc_rev & 0xc0) == 0x40)
3224 else if (!(sc->sc_rev & 0x80))
3227 val = wpi_read_prom_word(sc, WPI_EEPROM_CAPABILITIES);
3231 val = wpi_read_prom_word(sc, WPI_EEPROM_REVISION);
3236 val = wpi_read_prom_word(sc, WPI_EEPROM_TYPE);
3241 WPI_WRITE(sc, WPI_HWCONFIG, hw);
3245 wpi_init(wpi_sc_t *sc)
3251 mutex_enter(&sc->sc_glock);
3252 sc->sc_flags &= ~WPI_F_FW_INIT;
3254 (void) wpi_reset(sc);
3256 wpi_mem_lock(sc);
3257 wpi_mem_write(sc, WPI_MEM_CLOCK1, 0xa00);
3259 tmp = wpi_mem_read(sc, WPI_MEM_PCIDEV);
3260 wpi_mem_write(sc, WPI_MEM_PCIDEV, tmp | 0x800);
3261 wpi_mem_unlock(sc);
3263 (void) wpi_power_up(sc);
3264 wpi_hw_config(sc);
3266 tmp = WPI_READ(sc, WPI_GPIO_CTL);
3273 wpi_mem_lock(sc);
3274 WPI_WRITE(sc, WPI_RX_BASE, sc->sc_rxq.dma_desc.cookie.dmac_address);
3275 WPI_WRITE(sc, WPI_RX_RIDX_PTR,
3276 (uint32_t)(sc->sc_dma_sh.cookie.dmac_address +
3278 WPI_WRITE(sc, WPI_RX_WIDX, (WPI_RX_RING_COUNT - 1) & (~7));
3279 WPI_WRITE(sc, WPI_RX_CONFIG, 0xa9601010);
3280 wpi_mem_unlock(sc);
3283 wpi_mem_lock(sc);
3284 wpi_mem_write(sc, WPI_MEM_MODE, 2); /* bypass mode */
3285 wpi_mem_write(sc, WPI_MEM_RA, 1); /* enable RA0 */
3286 wpi_mem_write(sc, WPI_MEM_TXCFG, 0x3f); /* enable all 6 Tx rings */
3287 wpi_mem_write(sc, WPI_MEM_BYPASS1, 0x10000);
3288 wpi_mem_write(sc, WPI_MEM_BYPASS2, 0x30002);
3289 wpi_mem_write(sc, WPI_MEM_MAGIC4, 4);
3290 wpi_mem_write(sc, WPI_MEM_MAGIC5, 5);
3292 WPI_WRITE(sc, WPI_TX_BASE_PTR, sc->sc_dma_sh.cookie.dmac_address);
3293 WPI_WRITE(sc, WPI_MSG_CONFIG, 0xffff05a5);
3296 WPI_WRITE(sc, WPI_TX_CTL(qid), 0);
3297 WPI_WRITE(sc, WPI_TX_BASE(qid), 0);
3298 WPI_WRITE(sc, WPI_TX_CONFIG(qid), 0x80200008);
3300 wpi_mem_unlock(sc);
3303 WPI_WRITE(sc, WPI_UCODE_CLR, WPI_RADIO_OFF);
3304 WPI_WRITE(sc, WPI_UCODE_CLR, WPI_DISABLE_CMD);
3307 WPI_WRITE(sc, WPI_INTR, 0xffffffff);
3310 WPI_WRITE(sc, WPI_MASK, WPI_INTR_MASK);
3313 err = wpi_load_microcode(sc);
3320 err = wpi_load_firmware(sc, WPI_FW_TEXT);
3328 err = wpi_load_firmware(sc, WPI_FW_DATA);
3336 tmp = WPI_READ(sc, WPI_RESET);
3338 WPI_WRITE(sc, WPI_RESET, tmp);
3342 while (!(sc->sc_flags & WPI_F_FW_INIT)) {
3343 if (cv_timedwait(&sc->sc_fw_cv, &sc->sc_glock, clk) < 0)
3346 if (!(sc->sc_flags & WPI_F_FW_INIT)) {
3354 if (WPI_READ(sc, WPI_TEMPERATURE) != 0)
3366 (int)WPI_READ(sc, WPI_TEMPERATURE)));
3368 err = wpi_config(sc);
3374 mutex_exit(&sc->sc_glock);
3379 mutex_exit(&sc->sc_glock);
3384 wpi_fast_recover(wpi_sc_t *sc)
3386 ieee80211com_t *ic = &sc->sc_ic;
3389 mutex_enter(&sc->sc_glock);
3392 bcopy(&sc->sc_config_save, &sc->sc_config,
3393 sizeof (sc->sc_config));
3395 sc->sc_config.state = 0;
3396 sc->sc_config.filter &= ~LE_32(WPI_FILTER_BSS);
3398 if ((err = wpi_auth(sc)) != 0) {
3401 mutex_exit(&sc->sc_glock);
3405 sc->sc_config.state = LE_16(WPI_CONFIG_ASSOCIATED);
3406 sc->sc_config.flags &= ~LE_32(WPI_CONFIG_SHPREAMBLE |
3409 sc->sc_config.flags |= LE_32(WPI_CONFIG_SHSLOT);
3411 sc->sc_config.flags |= LE_32(WPI_CONFIG_SHPREAMBLE);
3412 sc->sc_config.filter |= LE_32(WPI_FILTER_BSS);
3414 sc->sc_config.filter |= LE_32(WPI_FILTER_BEACON);
3417 sc->sc_config.chan, sc->sc_config.flags));
3418 err = wpi_cmd(sc, WPI_CMD_CONFIGURE, &sc->sc_config,
3422 mutex_exit(&sc->sc_glock);
3426 wpi_set_led(sc, WPI_LED_LINK, 0, 1);
3428 mutex_exit(&sc->sc_glock);
3446 sc->sc_flags &= ~WPI_F_HW_ERR_RECOVER;
3466 wpi_sc_t *sc;
3468 sc = ddi_get_soft_state(wpi_soft_state_p, ddi_get_instance(dip));
3469 if (sc == NULL)
3481 sc->sc_flags |= WPI_F_QUIESCED;
3486 wpi_stop(sc);
3491 wpi_stop(wpi_sc_t *sc)
3497 if (!(sc->sc_flags & WPI_F_QUIESCED))
3498 mutex_enter(&sc->sc_glock);
3501 WPI_WRITE(sc, WPI_MASK, 0);
3502 WPI_WRITE(sc, WPI_INTR, WPI_INTR_MASK);
3503 WPI_WRITE(sc, WPI_INTR_STATUS, 0xff);
3504 WPI_WRITE(sc, WPI_INTR_STATUS, 0x00070000);
3506 wpi_mem_lock(sc);
3507 wpi_mem_write(sc, WPI_MEM_MODE, 0);
3508 wpi_mem_unlock(sc);
3512 wpi_reset_tx_ring(sc, &sc->sc_txq[ac]);
3513 wpi_reset_tx_ring(sc, &sc->sc_cmdq);
3514 wpi_reset_tx_ring(sc, &sc->sc_svcq);
3517 wpi_reset_rx_ring(sc);
3519 wpi_mem_lock(sc);
3520 wpi_mem_write(sc, WPI_MEM_CLOCK2, 0x200);
3521 wpi_mem_unlock(sc);
3525 wpi_stop_master(sc);
3527 sc->sc_tx_timer = 0;
3528 sc->sc_flags &= ~WPI_F_SCANNING;
3529 sc->sc_scan_pending = 0;
3530 sc->sc_scan_next = 0;
3532 tmp = WPI_READ(sc, WPI_RESET);
3533 WPI_WRITE(sc, WPI_RESET, tmp | WPI_SW_RESET);
3536 if (!(sc->sc_flags & WPI_F_QUIESCED))
3537 mutex_exit(&sc->sc_glock);
3577 wpi_amrr_timeout(wpi_sc_t *sc)
3579 ieee80211com_t *ic = &sc->sc_ic;
3586 sc->sc_clk = ddi_get_lbolt();