Lines Matching +full:mac +full:-

1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause
4 * Copyright (c) 2009-2010 Weongyo Jeong <weongyo@freebsd.org>
537 struct bwn_mac *mac;
544 sc->sc_dev = dev;
546 sc->sc_debug = bwn_debug;
549 mac = NULL;
553 sc->sc_quirks = bhnd_device_quirks(dev, bwn_devices,
558 sc->sc_quirks |= bhnd_device_quirks(hostb, bridge_devices,
564 sc->sc_quirks |= BWN_QUIRK_NODMA;
567 sc->sc_cid = *bhnd_get_chipid(dev);
568 if ((error = bhnd_read_board_info(dev, &sc->sc_board_info))) {
569 device_printf(sc->sc_dev, "couldn't read board info\n");
574 sc->sc_mem_rid = 0;
575 sc->sc_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
576 &sc->sc_mem_rid, RF_ACTIVE);
577 if (sc->sc_mem_res == NULL) {
578 device_printf(sc->sc_dev, "couldn't allocate registers\n");
582 if ((error = bhnd_alloc_pmu(sc->sc_dev))) {
583 bus_release_resource(sc->sc_dev, SYS_RES_MEMORY,
584 sc->sc_mem_rid, sc->sc_mem_res);
593 error = bhnd_nvram_getvar_uint8(sc->sc_dev, BHND_NVAR_AA2G,
594 &sc->sc_ant2g);
596 device_printf(sc->sc_dev, "error determining 2GHz antenna "
601 error = bhnd_nvram_getvar_uint8(sc->sc_dev, BHND_NVAR_AA5G,
602 &sc->sc_ant5g);
604 device_printf(sc->sc_dev, "error determining 5GHz antenna "
609 if ((sc->sc_flags & BWN_FLAG_ATTACHED) == 0) {
612 sc->sc_flags |= BWN_FLAG_ATTACHED;
615 mac = malloc(sizeof(*mac), M_DEVBUF, M_WAITOK | M_ZERO);
616 mac->mac_sc = sc;
617 mac->mac_status = BWN_MAC_STATUS_UNINIT;
619 mac->mac_flags |= BWN_MAC_FLAG_BADFRAME_PREEMP;
621 TASK_INIT(&mac->mac_hwreset, 0, bwn_hwreset, mac);
622 NET_TASK_INIT(&mac->mac_intrtask, 0, bwn_intrtask, mac);
623 TASK_INIT(&mac->mac_txpower, 0, bwn_txpwr, mac);
625 error = bwn_attach_core(mac);
628 error = bwn_led_attach(mac);
632 bhnd_format_chip_id(chip_name, sizeof(chip_name), sc->sc_cid.chip_id);
633 device_printf(sc->sc_dev, "WLAN (%s rev %u sromrev %u) "
635 chip_name, bhnd_get_hwrev(sc->sc_dev),
636 sc->sc_board_info.board_srom_rev, mac->mac_phy.analog,
637 mac->mac_phy.type, mac->mac_phy.rev, mac->mac_phy.rf_manuf,
638 mac->mac_phy.rf_ver, mac->mac_phy.rf_rev);
639 if (mac->mac_flags & BWN_MAC_FLAG_DMA)
640 device_printf(sc->sc_dev, "DMA (%d bits)\n", mac->mac_dmatype);
642 device_printf(sc->sc_dev, "PIO\n");
645 device_printf(sc->sc_dev,
649 mac->mac_rid_irq = 0;
650 mac->mac_res_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ,
651 &mac->mac_rid_irq, RF_ACTIVE | RF_SHAREABLE);
653 if (mac->mac_res_irq == NULL) {
654 device_printf(sc->sc_dev, "couldn't allocate IRQ resource\n");
659 error = bus_setup_intr(dev, mac->mac_res_irq,
660 INTR_TYPE_NET | INTR_MPSAFE, bwn_intr, NULL, mac,
661 &mac->mac_intrhand);
663 device_printf(sc->sc_dev, "couldn't setup interrupt (%d)\n",
668 TAILQ_INSERT_TAIL(&sc->sc_maclist, mac, mac_list);
671 * calls attach-post routine
673 if ((sc->sc_flags & BWN_FLAG_ATTACHED) != 0)
678 if (mac != NULL && mac->mac_res_irq != NULL) {
679 bus_release_resource(dev, SYS_RES_IRQ, mac->mac_rid_irq,
680 mac->mac_res_irq);
683 free(mac, M_DEVBUF);
687 if (sc->sc_mem_res != NULL) {
688 bus_release_resource(sc->sc_dev, SYS_RES_MEMORY,
689 sc->sc_mem_rid, sc->sc_mem_res);
700 sc->sc_chipc = bhnd_retain_provider(sc->sc_dev, BHND_SERVICE_CHIPC);
701 if (sc->sc_chipc == NULL) {
702 device_printf(sc->sc_dev, "ChipCommon device not found\n");
706 ccaps = BHND_CHIPC_GET_CAPS(sc->sc_chipc);
708 sc->sc_gpio = bhnd_retain_provider(sc->sc_dev, BHND_SERVICE_GPIO);
709 if (sc->sc_gpio == NULL) {
710 device_printf(sc->sc_dev, "GPIO device not found\n");
714 if (ccaps->pmu) {
715 sc->sc_pmu = bhnd_retain_provider(sc->sc_dev, BHND_SERVICE_PMU);
716 if (sc->sc_pmu == NULL) {
717 device_printf(sc->sc_dev, "PMU device not found\n");
733 if ((_sc)-> _prov != NULL) { \
734 bhnd_release_provider((_sc)->sc_dev, (_sc)-> _prov, \
736 (_sc)-> _prov = NULL; \
755 ic = &sc->sc_ic;
757 ic->ic_softc = sc;
758 ic->ic_name = device_get_nameunit(sc->sc_dev);
760 ic->ic_phytype = IEEE80211_T_OFDM;
761 ic->ic_opmode = IEEE80211_M_STA;
762 ic->ic_caps =
776 ic->ic_flags_ext |= IEEE80211_FEXT_SWBMISS; /* s/w bmiss */
778 /* Determine the NVRAM variable containing our MAC address */
779 core_unit = bhnd_get_core_unit(sc->sc_dev);
781 if (sc->sc_board_info.board_srom_rev <= 2) {
794 device_printf(sc->sc_dev, "missing MAC address variable for "
799 /* Read the MAC address from NVRAM */
800 error = bhnd_nvram_getvar_array(sc->sc_dev, mac_varname, ic->ic_macaddr,
801 sizeof(ic->ic_macaddr), BHND_NVRAM_TYPE_UINT8_ARRAY);
803 device_printf(sc->sc_dev, "error reading %s: %d\n", mac_varname,
812 ic->ic_raw_xmit = bwn_raw_xmit;
813 ic->ic_updateslot = bwn_updateslot;
814 ic->ic_update_promisc = bwn_update_promisc;
815 ic->ic_wme.wme_update = bwn_wme_update;
816 ic->ic_scan_start = bwn_scan_start;
817 ic->ic_scan_end = bwn_scan_end;
818 ic->ic_set_channel = bwn_set_channel;
819 ic->ic_vap_create = bwn_vap_create;
820 ic->ic_vap_delete = bwn_vap_delete;
821 ic->ic_transmit = bwn_transmit;
822 ic->ic_parent = bwn_parent;
825 &sc->sc_tx_th.wt_ihdr, sizeof(sc->sc_tx_th),
827 &sc->sc_rx_th.wr_ihdr, sizeof(sc->sc_rx_th),
838 bwn_phy_detach(struct bwn_mac *mac)
841 if (mac->mac_phy.detach != NULL)
842 mac->mac_phy.detach(mac);
849 struct bwn_mac *mac = sc->sc_curmac;
850 struct ieee80211com *ic = &sc->sc_ic;
852 sc->sc_flags |= BWN_FLAG_INVALID;
854 if (device_is_attached(sc->sc_dev)) {
858 bwn_dma_free(mac);
859 callout_drain(&sc->sc_led_blink_ch);
860 callout_drain(&sc->sc_rfswitch_ch);
861 callout_drain(&sc->sc_task_ch);
862 callout_drain(&sc->sc_watchdog_ch);
863 bwn_phy_detach(mac);
864 ieee80211_draintask(ic, &mac->mac_hwreset);
865 ieee80211_draintask(ic, &mac->mac_txpower);
868 taskqueue_drain(sc->sc_tq, &mac->mac_intrtask);
869 taskqueue_free(sc->sc_tq);
871 if (mac->mac_intrhand != NULL) {
872 bus_teardown_intr(dev, mac->mac_res_irq, mac->mac_intrhand);
873 mac->mac_intrhand = NULL;
877 bus_release_resource(dev, SYS_RES_MEMORY, sc->sc_mem_rid,
878 sc->sc_mem_res);
879 bus_release_resource(dev, SYS_RES_IRQ, mac->mac_rid_irq,
880 mac->mac_res_irq);
881 mbufq_drain(&sc->sc_snd);
882 bwn_release_firmware(mac);
895 TAILQ_INIT(&sc->sc_maclist);
896 callout_init_mtx(&sc->sc_rfswitch_ch, &sc->sc_mtx, 0);
897 callout_init_mtx(&sc->sc_task_ch, &sc->sc_mtx, 0);
898 callout_init_mtx(&sc->sc_watchdog_ch, &sc->sc_mtx, 0);
899 mbufq_init(&sc->sc_snd, ifqmaxlen);
900 sc->sc_tq = taskqueue_create_fast("bwn_taskq", M_NOWAIT,
901 taskqueue_thread_enqueue, &sc->sc_tq);
902 taskqueue_start_threads(&sc->sc_tq, 1, PI_NET,
903 "%s taskq", device_get_nameunit(sc->sc_dev));
912 ((sc->sc_board_info.board_devid == PCI_DEVID_##_device) && \
913 (sc->sc_board_info.board_vendor == PCI_VENDOR_##_subvendor) && \
914 (sc->sc_board_info.board_type == _subdevice))
918 if (sc->sc_board_info.board_vendor == PCI_VENDOR_APPLE &&
919 sc->sc_board_info.board_type == 0x4e &&
920 sc->sc_board_info.board_rev > 0x40)
921 sc->sc_board_info.board_flags |= BHND_BFL_PACTRL;
930 sc->sc_board_info.board_flags &= ~BHND_BFL_BTCOEX;
937 struct bwn_softc *sc = ic->ic_softc;
941 if (ic->ic_nrunning > 0) {
942 if ((sc->sc_flags & BWN_FLAG_RUNNING) == 0) {
947 } else if (sc->sc_flags & BWN_FLAG_RUNNING)
958 struct bwn_softc *sc = ic->ic_softc;
962 if ((sc->sc_flags & BWN_FLAG_RUNNING) == 0) {
966 error = mbufq_enqueue(&sc->sc_snd, m);
979 struct bwn_mac *mac = sc->sc_curmac;
987 if ((sc->sc_flags & BWN_FLAG_RUNNING) == 0 || mac == NULL ||
988 mac->mac_status < BWN_MAC_STATUS_STARTED)
991 while ((m = mbufq_dequeue(&sc->sc_snd)) != NULL) {
994 ni = (struct ieee80211_node *) m->m_pkthdr.rcvif;
996 device_printf(sc->sc_dev, "unexpected NULL ni\n");
998 counter_u64_add(sc->sc_ic.ic_oerrors, 1);
1002 if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) {
1005 if_inc_counter(ni->ni_vap->iv_ifp,
1015 if_inc_counter(ni->ni_vap->iv_ifp,
1021 sc->sc_watchdog_timer = 5;
1029 struct bwn_mac *mac = sc->sc_curmac;
1031 int pktlen = roundup(m->m_pkthdr.len + BWN_HDRSIZE(mac), 4);
1035 if (mac->mac_flags & BWN_MAC_FLAG_DMA) {
1036 dr = bwn_dma_select(mac, M_WME_GETAC(m));
1037 if (dr->dr_stop == 1 ||
1039 dr->dr_stop = 1;
1043 tq = bwn_pio_select(mac, M_WME_GETAC(m));
1044 if (tq->tq_free == 0 || pktlen > tq->tq_size ||
1045 pktlen > (tq->tq_size - tq->tq_used))
1050 mbufq_prepend(&sc->sc_snd, m);
1057 struct bwn_mac *mac = sc->sc_curmac;
1062 if (m->m_pkthdr.len < IEEE80211_MIN_LEN || mac == NULL) {
1067 error = (mac->mac_flags & BWN_MAC_FLAG_DMA) ?
1068 bwn_dma_tx_start(mac, ni, &m) : bwn_pio_tx_start(mac, ni, &m);
1077 bwn_pio_tx_start(struct bwn_mac *mac, struct ieee80211_node *ni,
1082 struct bwn_softc *sc = mac->mac_sc;
1094 tq = bwn_pio_select(mac, M_WME_GETAC(m));
1095 KASSERT(!TAILQ_EMPTY(&tq->tq_pktlist), ("%s: fail", __func__));
1096 tp = TAILQ_FIRST(&tq->tq_pktlist);
1097 tp->tp_ni = ni;
1098 tp->tp_m = m;
1100 error = bwn_set_txhdr(mac, ni, m, &txhdr, BWN_PIO_COOKIE(tq, tp));
1102 device_printf(sc->sc_dev, "tx fail\n");
1106 TAILQ_REMOVE(&tq->tq_pktlist, tp, tp_list);
1107 tq->tq_used += roundup(m->m_pkthdr.len + BWN_HDRSIZE(mac), 4);
1108 tq->tq_free--;
1110 if (bhnd_get_hwrev(sc->sc_dev) >= 8) {
1116 device_printf(sc->sc_dev,
1122 if (m_new->m_next != NULL)
1123 device_printf(sc->sc_dev,
1125 tp->tp_m = m_new;
1128 ctl32 = bwn_pio_write_multi_4(mac, tq,
1129 (BWN_PIO_READ_4(mac, tq, BWN_PIO8_TXCTL) |
1131 (const uint8_t *)&txhdr, BWN_HDRSIZE(mac));
1133 ctl32 = bwn_pio_write_multi_4(mac, tq, ctl32,
1134 mtod(m_new, const void *), m_new->m_pkthdr.len);
1135 bwn_pio_write_4(mac, tq, BWN_PIO_TXCTL,
1138 ctl16 = bwn_pio_write_multi_2(mac, tq,
1139 (bwn_pio_read_2(mac, tq, BWN_PIO_TXCTL) |
1141 (const uint8_t *)&txhdr, BWN_HDRSIZE(mac));
1142 ctl16 = bwn_pio_write_mbuf_2(mac, tq, ctl16, m);
1143 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL,
1151 bwn_pio_select(struct bwn_mac *mac, uint8_t prio)
1154 if ((mac->mac_flags & BWN_MAC_FLAG_WME) == 0)
1155 return (&mac->mac_method.pio.wme[WME_AC_BE]);
1159 return (&mac->mac_method.pio.wme[WME_AC_BE]);
1161 return (&mac->mac_method.pio.wme[WME_AC_BK]);
1163 return (&mac->mac_method.pio.wme[WME_AC_VI]);
1165 return (&mac->mac_method.pio.wme[WME_AC_VO]);
1172 bwn_dma_tx_start(struct bwn_mac *mac, struct ieee80211_node *ni,
1176 &(txhdr_cache[(slot / BWN_TX_SLOTS_PER_FRAME) * BWN_HDRSIZE(mac)])
1177 struct bwn_dma *dma = &mac->mac_method.dma;
1178 struct bwn_dma_ring *dr = bwn_dma_select(mac, M_WME_GETAC(*mp));
1181 struct bwn_softc *sc = mac->mac_sc;
1183 uint8_t *txhdr_cache = (uint8_t *)dr->dr_txhdr_cache;
1184 int error, slot, backup[2] = { dr->dr_curslot, dr->dr_usedslot };
1187 KASSERT(!dr->dr_stop, ("%s:%d: fail", __func__, __LINE__));
1193 dr->getdesc(dr, slot, &desc, &mt);
1194 KASSERT(mt->mt_txtype == BWN_DMADESC_METATYPE_HEADER,
1197 error = bwn_set_txhdr(dr->dr_mac, ni, m,
1202 error = bus_dmamap_load(dr->dr_txring_dtag, mt->mt_dmap,
1203 BWN_GET_TXHDRCACHE(slot), BWN_HDRSIZE(mac), bwn_dma_ring_addr,
1204 &mt->mt_paddr, BUS_DMA_NOWAIT);
1206 device_printf(sc->sc_dev, "%s: can't load TX buffer (1) %d\n",
1210 bus_dmamap_sync(dr->dr_txring_dtag, mt->mt_dmap,
1212 dr->setdesc(dr, desc, mt->mt_paddr, BWN_HDRSIZE(mac), 1, 0, 0);
1213 bus_dmamap_sync(dr->dr_ring_dtag, dr->dr_ring_dmap,
1217 dr->getdesc(dr, slot, &desc, &mt);
1218 KASSERT(mt->mt_txtype == BWN_DMADESC_METATYPE_BODY &&
1219 mt->mt_islast == 1, ("%s:%d: fail", __func__, __LINE__));
1220 mt->mt_m = m;
1221 mt->mt_ni = ni;
1223 error = bus_dmamap_load_mbuf(dma->txbuf_dtag, mt->mt_dmap, m,
1224 bwn_dma_buf_addr, &mt->mt_paddr, BUS_DMA_NOWAIT);
1226 device_printf(sc->sc_dev, "%s: can't load TX buffer (1) %d\n",
1235 device_printf(sc->sc_dev,
1243 mt->mt_m = m;
1244 error = bus_dmamap_load_mbuf(dma->txbuf_dtag, mt->mt_dmap,
1245 m, bwn_dma_buf_addr, &mt->mt_paddr, BUS_DMA_NOWAIT);
1247 device_printf(sc->sc_dev,
1253 bus_dmamap_sync(dma->txbuf_dtag, mt->mt_dmap, BUS_DMASYNC_PREWRITE);
1254 dr->setdesc(dr, desc, mt->mt_paddr, m->m_pkthdr.len, 0, 1, 1);
1255 bus_dmamap_sync(dr->dr_ring_dtag, dr->dr_ring_dmap,
1260 dr->start_transfer(dr, bwn_dma_nextslot(dr, slot));
1263 dr->dr_curslot = backup[0];
1264 dr->dr_usedslot = backup[1];
1274 if (sc->sc_watchdog_timer != 0 && --sc->sc_watchdog_timer == 0) {
1275 device_printf(sc->sc_dev, "device timeout\n");
1276 counter_u64_add(sc->sc_ic.ic_oerrors, 1);
1278 callout_schedule(&sc->sc_watchdog_ch, hz);
1282 bwn_attach_core(struct bwn_mac *mac)
1284 struct bwn_softc *sc = mac->mac_sc;
1288 KASSERT(bhnd_get_hwrev(sc->sc_dev) >= 5,
1289 ("unsupported revision %d", bhnd_get_hwrev(sc->sc_dev)));
1291 if ((error = bwn_core_forceclk(mac, true)))
1294 if ((error = bhnd_read_iost(sc->sc_dev, &iost))) {
1295 device_printf(sc->sc_dev, "error reading I/O status flags: "
1308 device_printf(sc->sc_dev, "%s: iost=0x%04hx, have_a=%d, have_bg=%d,"
1314 sc->sc_board_info.board_devid,
1315 sc->sc_cid.chip_id);
1319 * Guess at whether it has A-PHY or G-PHY.
1321 * we will re-guess once it's all up and working.
1323 error = bwn_reset_core(mac, have_bg);
1331 mac->mac_dmatype = BHND_DMA_ADDR_64BIT;
1337 BWN_WRITE_4(mac, base + BWN_DMA32_TXCTL,
1339 tmp = BWN_READ_4(mac, base + BWN_DMA32_TXCTL);
1341 mac->mac_dmatype = BHND_DMA_ADDR_32BIT;
1343 mac->mac_dmatype = BHND_DMA_ADDR_30BIT;
1350 error = bwn_phy_getinfo(mac, have_bg);
1358 if (sc->sc_board_info.board_devid != PCI_DEVID_BCM4311_D11DUAL &&
1359 sc->sc_board_info.board_devid != PCI_DEVID_BCM4328_D11G &&
1360 sc->sc_board_info.board_devid != PCI_DEVID_BCM4318_D11DUAL &&
1361 sc->sc_board_info.board_devid != PCI_DEVID_BCM4306_D11DUAL &&
1362 sc->sc_board_info.board_devid != PCI_DEVID_BCM4321_D11N &&
1363 sc->sc_board_info.board_devid != PCI_DEVID_BCM4322_D11N) {
1365 if (mac->mac_phy.type == BWN_PHYTYPE_A)
1367 else if (mac->mac_phy.type == BWN_PHYTYPE_G ||
1368 mac->mac_phy.type == BWN_PHYTYPE_N ||
1369 mac->mac_phy.type == BWN_PHYTYPE_LP)
1373 mac->mac_phy.type));
1377 * XXX The PHY-G support doesn't do 5GHz operation.
1379 if (mac->mac_phy.type != BWN_PHYTYPE_LP &&
1380 mac->mac_phy.type != BWN_PHYTYPE_N) {
1381 device_printf(sc->sc_dev,
1382 "%s: forcing 2GHz only; no dual-band support for PHY\n",
1388 mac->mac_phy.phy_n = NULL;
1390 if (mac->mac_phy.type == BWN_PHYTYPE_G) {
1391 mac->mac_phy.attach = bwn_phy_g_attach;
1392 mac->mac_phy.detach = bwn_phy_g_detach;
1393 mac->mac_phy.prepare_hw = bwn_phy_g_prepare_hw;
1394 mac->mac_phy.init_pre = bwn_phy_g_init_pre;
1395 mac->mac_phy.init = bwn_phy_g_init;
1396 mac->mac_phy.exit = bwn_phy_g_exit;
1397 mac->mac_phy.phy_read = bwn_phy_g_read;
1398 mac->mac_phy.phy_write = bwn_phy_g_write;
1399 mac->mac_phy.rf_read = bwn_phy_g_rf_read;
1400 mac->mac_phy.rf_write = bwn_phy_g_rf_write;
1401 mac->mac_phy.use_hwpctl = bwn_phy_g_hwpctl;
1402 mac->mac_phy.rf_onoff = bwn_phy_g_rf_onoff;
1403 mac->mac_phy.switch_analog = bwn_phy_switch_analog;
1404 mac->mac_phy.switch_channel = bwn_phy_g_switch_channel;
1405 mac->mac_phy.get_default_chan = bwn_phy_g_get_default_chan;
1406 mac->mac_phy.set_antenna = bwn_phy_g_set_antenna;
1407 mac->mac_phy.set_im = bwn_phy_g_im;
1408 mac->mac_phy.recalc_txpwr = bwn_phy_g_recalc_txpwr;
1409 mac->mac_phy.set_txpwr = bwn_phy_g_set_txpwr;
1410 mac->mac_phy.task_15s = bwn_phy_g_task_15s;
1411 mac->mac_phy.task_60s = bwn_phy_g_task_60s;
1412 } else if (mac->mac_phy.type == BWN_PHYTYPE_LP) {
1413 mac->mac_phy.init_pre = bwn_phy_lp_init_pre;
1414 mac->mac_phy.init = bwn_phy_lp_init;
1415 mac->mac_phy.phy_read = bwn_phy_lp_read;
1416 mac->mac_phy.phy_write = bwn_phy_lp_write;
1417 mac->mac_phy.phy_maskset = bwn_phy_lp_maskset;
1418 mac->mac_phy.rf_read = bwn_phy_lp_rf_read;
1419 mac->mac_phy.rf_write = bwn_phy_lp_rf_write;
1420 mac->mac_phy.rf_onoff = bwn_phy_lp_rf_onoff;
1421 mac->mac_phy.switch_analog = bwn_phy_lp_switch_analog;
1422 mac->mac_phy.switch_channel = bwn_phy_lp_switch_channel;
1423 mac->mac_phy.get_default_chan = bwn_phy_lp_get_default_chan;
1424 mac->mac_phy.set_antenna = bwn_phy_lp_set_antenna;
1425 mac->mac_phy.task_60s = bwn_phy_lp_task_60s;
1426 } else if (mac->mac_phy.type == BWN_PHYTYPE_N) {
1427 mac->mac_phy.attach = bwn_phy_n_attach;
1428 mac->mac_phy.detach = bwn_phy_n_detach;
1429 mac->mac_phy.prepare_hw = bwn_phy_n_prepare_hw;
1430 mac->mac_phy.init_pre = bwn_phy_n_init_pre;
1431 mac->mac_phy.init = bwn_phy_n_init;
1432 mac->mac_phy.exit = bwn_phy_n_exit;
1433 mac->mac_phy.phy_read = bwn_phy_n_read;
1434 mac->mac_phy.phy_write = bwn_phy_n_write;
1435 mac->mac_phy.rf_read = bwn_phy_n_rf_read;
1436 mac->mac_phy.rf_write = bwn_phy_n_rf_write;
1437 mac->mac_phy.use_hwpctl = bwn_phy_n_hwpctl;
1438 mac->mac_phy.rf_onoff = bwn_phy_n_rf_onoff;
1439 mac->mac_phy.switch_analog = bwn_phy_n_switch_analog;
1440 mac->mac_phy.switch_channel = bwn_phy_n_switch_channel;
1441 mac->mac_phy.get_default_chan = bwn_phy_n_get_default_chan;
1442 mac->mac_phy.set_antenna = bwn_phy_n_set_antenna;
1443 mac->mac_phy.set_im = bwn_phy_n_im;
1444 mac->mac_phy.recalc_txpwr = bwn_phy_n_recalc_txpwr;
1445 mac->mac_phy.set_txpwr = bwn_phy_n_set_txpwr;
1446 mac->mac_phy.task_15s = bwn_phy_n_task_15s;
1447 mac->mac_phy.task_60s = bwn_phy_n_task_60s;
1449 device_printf(sc->sc_dev, "unsupported PHY type (%d)\n",
1450 mac->mac_phy.type);
1455 mac->mac_phy.gmode = have_bg;
1456 if (mac->mac_phy.attach != NULL) {
1457 error = mac->mac_phy.attach(mac);
1459 device_printf(sc->sc_dev, "failed\n");
1464 error = bwn_reset_core(mac, have_bg);
1468 error = bwn_chiptest(mac);
1471 error = bwn_setup_channels(mac, have_bg, have_a);
1473 device_printf(sc->sc_dev, "failed to setup channels\n");
1477 if (sc->sc_curmac == NULL)
1478 sc->sc_curmac = mac;
1480 error = bwn_dma_attach(mac);
1482 device_printf(sc->sc_dev, "failed to initialize DMA\n");
1486 mac->mac_phy.switch_analog(mac, 0);
1489 bhnd_suspend_hw(sc->sc_dev, 0);
1490 bwn_release_firmware(mac);
1498 bwn_reset_core(struct bwn_mac *mac, int g_mode)
1505 sc = mac->mac_sc;
1514 /* XXX N-PHY only; and hard-code to 20MHz for now */
1515 if (mac->mac_phy.type == BWN_PHYTYPE_N)
1518 if ((error = bhnd_reset_hw(sc->sc_dev, ioctl, ioctl))) {
1519 device_printf(sc->sc_dev, "core reset failed: %d", error);
1531 if ((error = bhnd_write_ioctl(sc->sc_dev, ioctl, ioctl_mask))) {
1532 device_printf(sc->sc_dev, "failed to set core ioctl flags: "
1540 if ((error = bhnd_write_ioctl(sc->sc_dev, ioctl, ioctl_mask))) {
1541 device_printf(sc->sc_dev, "failed to set core ioctl flags: "
1548 if (mac->mac_phy.switch_analog != NULL)
1549 mac->mac_phy.switch_analog(mac, 1);
1551 ctl = BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_GMODE;
1554 BWN_WRITE_4(mac, BWN_MACCTL, ctl | BWN_MACCTL_IHR_ON);
1560 bwn_phy_getinfo(struct bwn_mac *mac, int gmode)
1562 struct bwn_phy *phy = &mac->mac_phy;
1563 struct bwn_softc *sc = mac->mac_sc;
1567 tmp = BWN_READ_2(mac, BWN_PHYVER);
1568 phy->gmode = gmode;
1569 phy->rf_on = 1;
1570 phy->analog = (tmp & BWN_PHYVER_ANALOG) >> 12;
1571 phy->type = (tmp & BWN_PHYVER_TYPE) >> 8;
1572 phy->rev = (tmp & BWN_PHYVER_VERSION);
1573 if ((phy->type == BWN_PHYTYPE_A && phy->rev >= 4) ||
1574 (phy->type == BWN_PHYTYPE_B && phy->rev != 2 &&
1575 phy->rev != 4 && phy->rev != 6 && phy->rev != 7) ||
1576 (phy->type == BWN_PHYTYPE_G && phy->rev > 9) ||
1577 (phy->type == BWN_PHYTYPE_N && phy->rev > 6) ||
1578 (phy->type == BWN_PHYTYPE_LP && phy->rev > 2))
1582 BWN_WRITE_2(mac, BWN_RFCTL, BWN_RFCTL_ID);
1583 tmp = BWN_READ_2(mac, BWN_RFDATALO);
1584 BWN_WRITE_2(mac, BWN_RFCTL, BWN_RFCTL_ID);
1585 tmp |= (uint32_t)BWN_READ_2(mac, BWN_RFDATAHI) << 16;
1587 phy->rf_rev = (tmp & 0xf0000000) >> 28;
1588 phy->rf_ver = (tmp & 0x0ffff000) >> 12;
1589 phy->rf_manuf = (tmp & 0x00000fff);
1595 phy->phy_do_full_init = 1;
1597 if (phy->rf_manuf != 0x17f) /* 0x17f is broadcom */
1599 if ((phy->type == BWN_PHYTYPE_A && (phy->rf_ver != 0x2060 ||
1600 phy->rf_rev != 1 || phy->rf_manuf != 0x17f)) ||
1601 (phy->type == BWN_PHYTYPE_B && (phy->rf_ver & 0xfff0) != 0x2050) ||
1602 (phy->type == BWN_PHYTYPE_G && phy->rf_ver != 0x2050) ||
1603 (phy->type == BWN_PHYTYPE_N &&
1604 phy->rf_ver != 0x2055 && phy->rf_ver != 0x2056) ||
1605 (phy->type == BWN_PHYTYPE_LP &&
1606 phy->rf_ver != 0x2062 && phy->rf_ver != 0x2063))
1611 device_printf(sc->sc_dev, "unsupported PHY (type %#x, rev %#x, "
1613 phy->type, phy->rev, phy->analog);
1616 device_printf(sc->sc_dev, "unsupported radio (manuf %#x, ver %#x, "
1618 phy->rf_manuf, phy->rf_ver, phy->rf_rev);
1623 bwn_chiptest(struct bwn_mac *mac)
1627 struct bwn_softc *sc = mac->mac_sc;
1632 backup = bwn_shm_read_4(mac, BWN_SHARED, 0);
1634 bwn_shm_write_4(mac, BWN_SHARED, 0, TESTVAL0);
1635 if (bwn_shm_read_4(mac, BWN_SHARED, 0) != TESTVAL0)
1637 bwn_shm_write_4(mac, BWN_SHARED, 0, TESTVAL1);
1638 if (bwn_shm_read_4(mac, BWN_SHARED, 0) != TESTVAL1)
1641 bwn_shm_write_4(mac, BWN_SHARED, 0, backup);
1643 if ((bhnd_get_hwrev(sc->sc_dev) >= 3) &&
1644 (bhnd_get_hwrev(sc->sc_dev) <= 10)) {
1645 BWN_WRITE_2(mac, BWN_TSF_CFP_START, 0xaaaa);
1646 BWN_WRITE_4(mac, BWN_TSF_CFP_START, 0xccccbbbb);
1647 if (BWN_READ_2(mac, BWN_TSF_CFP_START_LOW) != 0xbbbb)
1649 if (BWN_READ_2(mac, BWN_TSF_CFP_START_HIGH) != 0xcccc)
1652 BWN_WRITE_4(mac, BWN_TSF_CFP_START, 0);
1654 v = BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_GMODE;
1662 device_printf(sc->sc_dev, "failed to validate the chipaccess\n");
1667 bwn_setup_channels(struct bwn_mac *mac, int have_bg, int have_a)
1669 struct bwn_softc *sc = mac->mac_sc;
1670 struct ieee80211com *ic = &sc->sc_ic;
1673 memset(ic->ic_channels, 0, sizeof(ic->ic_channels));
1674 ic->ic_nchans = 0;
1685 bwn_addchannels(ic->ic_channels, IEEE80211_CHAN_MAX,
1686 &ic->ic_nchans, &bwn_chantable_bg, bands);
1692 bwn_addchannels(ic->ic_channels, IEEE80211_CHAN_MAX,
1693 &ic->ic_nchans, &bwn_chantable_a, bands);
1696 mac->mac_phy.supports_2ghz = have_bg;
1697 mac->mac_phy.supports_5ghz = have_a;
1699 return (ic->ic_nchans == 0 ? ENXIO : 0);
1703 bwn_shm_read_4(struct bwn_mac *mac, uint16_t way, uint16_t offset)
1707 BWN_ASSERT_LOCKED(mac->mac_sc);
1713 bwn_shm_ctlword(mac, way, offset >> 2);
1714 ret = BWN_READ_2(mac, BWN_SHM_DATA_UNALIGNED);
1716 bwn_shm_ctlword(mac, way, (offset >> 2) + 1);
1717 ret |= BWN_READ_2(mac, BWN_SHM_DATA);
1722 bwn_shm_ctlword(mac, way, offset);
1723 ret = BWN_READ_4(mac, BWN_SHM_DATA);
1729 bwn_shm_read_2(struct bwn_mac *mac, uint16_t way, uint16_t offset)
1733 BWN_ASSERT_LOCKED(mac->mac_sc);
1739 bwn_shm_ctlword(mac, way, offset >> 2);
1740 ret = BWN_READ_2(mac, BWN_SHM_DATA_UNALIGNED);
1745 bwn_shm_ctlword(mac, way, offset);
1746 ret = BWN_READ_2(mac, BWN_SHM_DATA);
1753 bwn_shm_ctlword(struct bwn_mac *mac, uint16_t way,
1761 BWN_WRITE_4(mac, BWN_SHM_CONTROL, control);
1765 bwn_shm_write_4(struct bwn_mac *mac, uint16_t way, uint16_t offset,
1768 BWN_ASSERT_LOCKED(mac->mac_sc);
1774 bwn_shm_ctlword(mac, way, offset >> 2);
1775 BWN_WRITE_2(mac, BWN_SHM_DATA_UNALIGNED,
1777 bwn_shm_ctlword(mac, way, (offset >> 2) + 1);
1778 BWN_WRITE_2(mac, BWN_SHM_DATA, value & 0xffff);
1783 bwn_shm_ctlword(mac, way, offset);
1784 BWN_WRITE_4(mac, BWN_SHM_DATA, value);
1788 bwn_shm_write_2(struct bwn_mac *mac, uint16_t way, uint16_t offset,
1791 BWN_ASSERT_LOCKED(mac->mac_sc);
1797 bwn_shm_ctlword(mac, way, offset >> 2);
1798 BWN_WRITE_2(mac, BWN_SHM_DATA_UNALIGNED, value);
1803 bwn_shm_ctlword(mac, way, offset);
1804 BWN_WRITE_2(mac, BWN_SHM_DATA, value);
1813 for (i = 0, error = 0; i < ci->nchannels && error == 0; i++) {
1814 const struct bwn_channel *hc = &ci->channels[i];
1817 hc->ieee, hc->freq, hc->maxTxPow, 0, bands);
1825 struct ieee80211com *ic = ni->ni_ic;
1826 struct bwn_softc *sc = ic->ic_softc;
1827 struct bwn_mac *mac = sc->sc_curmac;
1830 if ((sc->sc_flags & BWN_FLAG_RUNNING) == 0 ||
1831 mac->mac_status < BWN_MAC_STATUS_STARTED) {
1845 sc->sc_watchdog_timer = 5;
1859 struct bwn_softc *sc = ic->ic_softc;
1860 struct bwn_mac *mac;
1863 if (sc->sc_flags & BWN_FLAG_RUNNING) {
1864 mac = (struct bwn_mac *)sc->sc_curmac;
1865 bwn_set_slot_time(mac, IEEE80211_GET_SLOTTIME(ic));
1880 struct bwn_softc *sc = ic->ic_softc;
1881 struct bwn_mac *mac = sc->sc_curmac;
1884 mac = sc->sc_curmac;
1885 if (mac != NULL && mac->mac_status >= BWN_MAC_STATUS_INITED) {
1886 if (ic->ic_promisc > 0)
1887 sc->sc_filters |= BWN_MACCTL_PROMISC;
1889 sc->sc_filters &= ~BWN_MACCTL_PROMISC;
1890 bwn_set_opmode(mac);
1901 struct bwn_softc *sc = ic->ic_softc;
1902 struct bwn_mac *mac = sc->sc_curmac;
1910 mac = sc->sc_curmac;
1911 if (mac != NULL && mac->mac_status >= BWN_MAC_STATUS_INITED) {
1912 bwn_mac_suspend(mac);
1913 for (i = 0; i < N(sc->sc_wmeParams); i++) {
1915 bwn_wme_loadparams(mac, wmep, bwn_wme_shm_offsets[i]);
1917 bwn_mac_enable(mac);
1926 struct bwn_softc *sc = ic->ic_softc;
1927 struct bwn_mac *mac;
1930 mac = sc->sc_curmac;
1931 if (mac != NULL && mac->mac_status >= BWN_MAC_STATUS_INITED) {
1932 sc->sc_filters |= BWN_MACCTL_BEACON_PROMISC;
1933 bwn_set_opmode(mac);
1935 bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_SKIP_CFP_UPDATE);
1943 struct bwn_softc *sc = ic->ic_softc;
1944 struct bwn_mac *mac;
1947 mac = sc->sc_curmac;
1948 if (mac != NULL && mac->mac_status >= BWN_MAC_STATUS_INITED) {
1949 sc->sc_filters &= ~BWN_MACCTL_BEACON_PROMISC;
1950 bwn_set_opmode(mac);
1951 bwn_hf_write(mac, bwn_hf_read(mac) & ~BWN_HF_SKIP_CFP_UPDATE);
1959 struct bwn_softc *sc = ic->ic_softc;
1960 struct bwn_mac *mac = sc->sc_curmac;
1961 struct bwn_phy *phy = &mac->mac_phy;
1966 error = bwn_switch_band(sc, ic->ic_curchan);
1969 bwn_mac_suspend(mac);
1970 bwn_set_txretry(mac, BWN_RETRY_SHORT, BWN_RETRY_LONG);
1971 chan = ieee80211_chan2ieee(ic, ic->ic_curchan);
1972 if (chan != phy->chan)
1973 bwn_switch_channel(mac, chan);
1976 if (ic->ic_curchan->ic_maxpower != 0 &&
1977 ic->ic_curchan->ic_maxpower != phy->txpower) {
1978 phy->txpower = ic->ic_curchan->ic_maxpower / 2;
1979 bwn_phy_txpower_check(mac, BWN_TXPWR_IGNORE_TIME |
1983 bwn_set_txantenna(mac, BWN_ANT_DEFAULT);
1984 if (phy->set_antenna)
1985 phy->set_antenna(mac, BWN_ANT_DEFAULT);
1987 if (sc->sc_rf_enabled != phy->rf_on) {
1988 if (sc->sc_rf_enabled) {
1989 bwn_rf_turnon(mac);
1990 if (!(mac->mac_flags & BWN_MAC_FLAG_RADIO_ON))
1991 device_printf(sc->sc_dev,
1994 bwn_rf_turnoff(mac);
1997 bwn_mac_enable(mac);
2007 const uint8_t mac[IEEE80211_ADDR_LEN])
2026 vap = &bvp->bv_vap;
2029 bvp->bv_newstate = vap->iv_newstate;
2030 vap->iv_newstate = bwn_newstate;
2033 vap->iv_max_aid = BWN_STAID_MAX;
2039 ieee80211_media_status, mac);
2056 struct bwn_mac *mac;
2063 bzero(sc->sc_bssid, IEEE80211_ADDR_LEN);
2064 sc->sc_flags |= BWN_FLAG_NEED_BEACON_TP;
2065 sc->sc_filters = 0;
2067 sc->sc_beacons[0] = sc->sc_beacons[1] = 0;
2068 sc->sc_rf_enabled = 1;
2070 mac = sc->sc_curmac;
2071 if (mac->mac_status == BWN_MAC_STATUS_UNINIT) {
2072 error = bwn_core_init(mac);
2076 if (mac->mac_status == BWN_MAC_STATUS_INITED)
2077 bwn_core_start(mac);
2079 bwn_set_opmode(mac);
2080 bwn_set_pretbtt(mac);
2081 bwn_spu_setdelay(mac, 0);
2082 bwn_set_macaddr(mac);
2084 sc->sc_flags |= BWN_FLAG_RUNNING;
2085 callout_reset(&sc->sc_rfswitch_ch, hz, bwn_rfswitch, sc);
2086 callout_reset(&sc->sc_watchdog_ch, hz, bwn_watchdog, sc);
2094 struct bwn_mac *mac = sc->sc_curmac;
2100 if (mac->mac_status >= BWN_MAC_STATUS_INITED) {
2102 bwn_set_opmode(mac);
2103 bwn_set_macaddr(mac);
2106 if (mac->mac_status >= BWN_MAC_STATUS_STARTED)
2107 bwn_core_stop(mac);
2109 callout_stop(&sc->sc_led_blink_ch);
2110 sc->sc_led_blinking = 0;
2112 bwn_core_exit(mac);
2113 sc->sc_rf_enabled = 0;
2115 sc->sc_flags &= ~BWN_FLAG_RUNNING;
2124 KASSERT(N(bwn_wme_shm_offsets) == N(sc->sc_wmeParams),
2127 for (i = 0; i < N(sc->sc_wmeParams); i++) {
2128 p = &(sc->sc_wmeParams[i]);
2132 p->wmep_txopLimit = 0;
2133 p->wmep_aifsn = 2;
2135 p->wmep_logcwmin =
2137 p->wmep_logcwmax =
2141 p->wmep_txopLimit = 0;
2142 p->wmep_aifsn = 2;
2144 p->wmep_logcwmin =
2146 p->wmep_logcwmax =
2150 p->wmep_txopLimit = 0;
2151 p->wmep_aifsn = 3;
2153 p->wmep_logcwmin =
2155 p->wmep_logcwmax =
2159 p->wmep_txopLimit = 0;
2160 p->wmep_aifsn = 7;
2162 p->wmep_logcwmin =
2164 p->wmep_logcwmax =
2174 bwn_core_forceclk(struct bwn_mac *mac, bool force)
2180 sc = mac->mac_sc;
2183 if (sc->sc_pmu != NULL)
2192 if ((error = bhnd_request_clock(sc->sc_dev, clock))) {
2193 device_printf(sc->sc_dev, "%d clock request failed: %d\n",
2202 bwn_core_init(struct bwn_mac *mac)
2204 struct bwn_softc *sc = mac->mac_sc;
2208 KASSERT(mac->mac_status == BWN_MAC_STATUS_UNINIT,
2211 DPRINTF(mac->mac_sc, BWN_DEBUG_RESET, "%s: called\n", __func__);
2213 if ((error = bwn_core_forceclk(mac, true)))
2216 if (bhnd_is_hw_suspended(sc->sc_dev)) {
2217 if ((error = bwn_reset_core(mac, mac->mac_phy.gmode)))
2221 mac->mac_flags &= ~BWN_MAC_FLAG_DFQVALID;
2222 mac->mac_flags |= BWN_MAC_FLAG_RADIO_ON;
2223 mac->mac_phy.hwpctl = (bwn_hwpctl) ? 1 : 0;
2224 BWN_GETTIME(mac->mac_phy.nexttime);
2225 mac->mac_phy.txerrors = BWN_TXERROR_MAX;
2226 bzero(&mac->mac_stats, sizeof(mac->mac_stats));
2227 mac->mac_stats.link_noise = -95;
2228 mac->mac_reason_intr = 0;
2229 bzero(mac->mac_reason, sizeof(mac->mac_reason));
2230 mac->mac_intr_mask = BWN_INTR_MASKTEMPLATE;
2232 if (sc->sc_debug & BWN_DEBUG_XMIT)
2233 mac->mac_intr_mask &= ~BWN_INTR_PHY_TXERR;
2235 mac->mac_suspended = 1;
2236 mac->mac_task_state = 0;
2237 memset(&mac->mac_noise, 0, sizeof(mac->mac_noise));
2239 mac->mac_phy.init_pre(mac);
2241 bwn_bt_disable(mac);
2242 if (mac->mac_phy.prepare_hw) {
2243 error = mac->mac_phy.prepare_hw(mac);
2247 DPRINTF(mac->mac_sc, BWN_DEBUG_RESET, "%s: chip_init\n", __func__);
2248 error = bwn_chip_init(mac);
2251 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_COREREV,
2252 bhnd_get_hwrev(sc->sc_dev));
2253 hf = bwn_hf_read(mac);
2254 if (mac->mac_phy.type == BWN_PHYTYPE_G) {
2256 if (sc->sc_board_info.board_flags & BHND_BFL_PACTRL)
2258 if (mac->mac_phy.rev == 1)
2261 if (mac->mac_phy.rf_ver == 0x2050) {
2262 if (mac->mac_phy.rf_rev < 6)
2264 if (mac->mac_phy.rf_rev == 6)
2267 if (sc->sc_board_info.board_flags & BHND_BFL_NOPLLDOWN)
2269 if (sc->sc_quirks & BWN_QUIRK_UCODE_SLOWCLOCK_WAR)
2272 bwn_hf_write(mac, hf);
2274 /* Tell the firmware about the MAC capabilities */
2275 if (bhnd_get_hwrev(sc->sc_dev) >= 13) {
2277 cap = BWN_READ_4(mac, BWN_MAC_HW_CAP);
2281 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_MACHW_L,
2283 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_MACHW_H,
2287 bwn_set_txretry(mac, BWN_RETRY_SHORT, BWN_RETRY_LONG);
2288 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_SHORT_RETRY_FALLBACK, 3);
2289 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_LONG_RETRY_FALLBACK, 2);
2290 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_PROBE_RESP_MAXTIME, 1);
2292 bwn_rate_init(mac);
2293 bwn_set_phytxctl(mac);
2295 bwn_shm_write_2(mac, BWN_SCRATCH, BWN_SCRATCH_CONT_MIN,
2296 (mac->mac_phy.type == BWN_PHYTYPE_B) ? 0x1f : 0xf);
2297 bwn_shm_write_2(mac, BWN_SCRATCH, BWN_SCRATCH_CONT_MAX, 0x3ff);
2299 if (sc->sc_quirks & BWN_QUIRK_NODMA)
2300 bwn_pio_init(mac);
2302 bwn_dma_init(mac);
2303 bwn_wme_init(mac);
2304 bwn_spu_setdelay(mac, 1);
2305 bwn_bt_enable(mac);
2307 DPRINTF(mac->mac_sc, BWN_DEBUG_RESET, "%s: powerup\n", __func__);
2308 if (sc->sc_board_info.board_flags & BHND_BFL_NOPLLDOWN)
2309 bwn_core_forceclk(mac, true);
2311 bwn_core_forceclk(mac, false);
2313 bwn_set_macaddr(mac);
2314 bwn_crypt_init(mac);
2318 mac->mac_status = BWN_MAC_STATUS_INITED;
2320 DPRINTF(mac->mac_sc, BWN_DEBUG_RESET, "%s: done\n", __func__);
2324 bhnd_suspend_hw(sc->sc_dev, 0);
2325 KASSERT(mac->mac_status == BWN_MAC_STATUS_UNINIT,
2327 DPRINTF(mac->mac_sc, BWN_DEBUG_RESET, "%s: fail\n", __func__);
2332 bwn_core_start(struct bwn_mac *mac)
2334 struct bwn_softc *sc = mac->mac_sc;
2337 KASSERT(mac->mac_status == BWN_MAC_STATUS_INITED,
2340 if (bhnd_get_hwrev(sc->sc_dev) < 5)
2344 tmp = BWN_READ_4(mac, BWN_XMITSTAT_0);
2347 tmp = BWN_READ_4(mac, BWN_XMITSTAT_1);
2350 bwn_mac_enable(mac);
2351 BWN_WRITE_4(mac, BWN_INTR_MASK, mac->mac_intr_mask);
2352 callout_reset(&sc->sc_task_ch, hz * 15, bwn_tasks, mac);
2354 mac->mac_status = BWN_MAC_STATUS_STARTED;
2358 bwn_core_exit(struct bwn_mac *mac)
2360 struct bwn_softc *sc = mac->mac_sc;
2363 BWN_ASSERT_LOCKED(mac->mac_sc);
2365 KASSERT(mac->mac_status <= BWN_MAC_STATUS_INITED,
2368 if (mac->mac_status != BWN_MAC_STATUS_INITED)
2370 mac->mac_status = BWN_MAC_STATUS_UNINIT;
2372 macctl = BWN_READ_4(mac, BWN_MACCTL);
2375 BWN_WRITE_4(mac, BWN_MACCTL, macctl);
2377 bwn_dma_stop(mac);
2378 bwn_pio_stop(mac);
2379 bwn_chip_exit(mac);
2380 mac->mac_phy.switch_analog(mac, 0);
2381 bhnd_suspend_hw(sc->sc_dev, 0);
2385 bwn_bt_disable(struct bwn_mac *mac)
2387 struct bwn_softc *sc = mac->mac_sc;
2394 bwn_chip_init(struct bwn_mac *mac)
2396 struct bwn_softc *sc = mac->mac_sc;
2397 struct bwn_phy *phy = &mac->mac_phy;
2403 if (phy->gmode)
2405 BWN_WRITE_4(mac, BWN_MACCTL, macctl);
2407 error = bwn_fw_fillinfo(mac);
2410 error = bwn_fw_loaducode(mac);
2414 error = bwn_gpio_init(mac);
2418 error = bwn_fw_loadinitvals(mac);
2422 phy->switch_analog(mac, 1);
2423 error = bwn_phy_init(mac);
2427 if (phy->set_im)
2428 phy->set_im(mac, BWN_IMMODE_NONE);
2429 if (phy->set_antenna)
2430 phy->set_antenna(mac, BWN_ANT_DEFAULT);
2431 bwn_set_txantenna(mac, BWN_ANT_DEFAULT);
2433 if (phy->type == BWN_PHYTYPE_B)
2434 BWN_WRITE_2(mac, 0x005e, BWN_READ_2(mac, 0x005e) | 0x0004);
2435 BWN_WRITE_4(mac, 0x0100, 0x01000000);
2436 if (bhnd_get_hwrev(sc->sc_dev) < 5)
2437 BWN_WRITE_4(mac, 0x010c, 0x01000000);
2439 BWN_WRITE_4(mac, BWN_MACCTL,
2440 BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_STA);
2441 BWN_WRITE_4(mac, BWN_MACCTL,
2442 BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_STA);
2443 bwn_shm_write_2(mac, BWN_SHARED, 0x0074, 0x0000);
2445 bwn_set_opmode(mac);
2446 if (bhnd_get_hwrev(sc->sc_dev) < 3) {
2447 BWN_WRITE_2(mac, 0x060e, 0x0000);
2448 BWN_WRITE_2(mac, 0x0610, 0x8000);
2449 BWN_WRITE_2(mac, 0x0604, 0x0000);
2450 BWN_WRITE_2(mac, 0x0606, 0x0200);
2452 BWN_WRITE_4(mac, 0x0188, 0x80000000);
2453 BWN_WRITE_4(mac, 0x018c, 0x02000000);
2455 BWN_WRITE_4(mac, BWN_INTR_REASON, 0x00004000);
2456 BWN_WRITE_4(mac, BWN_DMA0_INTR_MASK, 0x0001dc00);
2457 BWN_WRITE_4(mac, BWN_DMA1_INTR_MASK, 0x0000dc00);
2458 BWN_WRITE_4(mac, BWN_DMA2_INTR_MASK, 0x0000dc00);
2459 BWN_WRITE_4(mac, BWN_DMA3_INTR_MASK, 0x0001dc00);
2460 BWN_WRITE_4(mac, BWN_DMA4_INTR_MASK, 0x0000dc00);
2461 BWN_WRITE_4(mac, BWN_DMA5_INTR_MASK, 0x0000dc00);
2463 bwn_mac_phy_clock_set(mac, true);
2465 /* Provide the HT clock transition latency to the MAC core */
2466 error = bhnd_get_clock_latency(sc->sc_dev, BHND_CLOCK_HT, &delay);
2468 device_printf(sc->sc_dev, "failed to fetch HT clock latency: "
2474 device_printf(sc->sc_dev, "invalid HT clock latency: %u\n",
2479 BWN_WRITE_2(mac, BWN_POWERUP_DELAY, delay);
2485 bwn_hf_read(struct bwn_mac *mac)
2489 ret = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_HFHI);
2491 ret |= bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_HFMI);
2493 ret |= bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_HFLO);
2498 bwn_hf_write(struct bwn_mac *mac, uint64_t value)
2501 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_HFLO,
2503 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_HFMI,
2505 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_HFHI,
2510 bwn_set_txretry(struct bwn_mac *mac, int s, int l)
2513 bwn_shm_write_2(mac, BWN_SCRATCH, BWN_SCRATCH_SHORT_RETRY, MIN(s, 0xf));
2514 bwn_shm_write_2(mac, BWN_SCRATCH, BWN_SCRATCH_LONG_RETRY, MIN(l, 0xf));
2518 bwn_rate_init(struct bwn_mac *mac)
2521 switch (mac->mac_phy.type) {
2526 bwn_rate_write(mac, BWN_OFDM_RATE_6MB, 1);
2527 bwn_rate_write(mac, BWN_OFDM_RATE_12MB, 1);
2528 bwn_rate_write(mac, BWN_OFDM_RATE_18MB, 1);
2529 bwn_rate_write(mac, BWN_OFDM_RATE_24MB, 1);
2530 bwn_rate_write(mac, BWN_OFDM_RATE_36MB, 1);
2531 bwn_rate_write(mac, BWN_OFDM_RATE_48MB, 1);
2532 bwn_rate_write(mac, BWN_OFDM_RATE_54MB, 1);
2533 if (mac->mac_phy.type == BWN_PHYTYPE_A)
2537 bwn_rate_write(mac, BWN_CCK_RATE_1MB, 0);
2538 bwn_rate_write(mac, BWN_CCK_RATE_2MB, 0);
2539 bwn_rate_write(mac, BWN_CCK_RATE_5MB, 0);
2540 bwn_rate_write(mac, BWN_CCK_RATE_11MB, 0);
2548 bwn_rate_write(struct bwn_mac *mac, uint16_t rate, int ofdm)
2559 bwn_shm_write_2(mac, BWN_SHARED, offset + 0x20,
2560 bwn_shm_read_2(mac, BWN_SHARED, offset));
2608 bwn_set_phytxctl(struct bwn_mac *mac)
2614 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_BEACON_PHYCTL, ctl);
2615 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_ACKCTS_PHYCTL, ctl);
2616 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_PROBE_RESP_PHYCTL, ctl);
2620 bwn_pio_init(struct bwn_mac *mac)
2622 struct bwn_pio *pio = &mac->mac_method.pio;
2624 BWN_WRITE_4(mac, BWN_MACCTL, BWN_READ_4(mac, BWN_MACCTL)
2626 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_RX_PADOFFSET, 0);
2628 bwn_pio_set_txqueue(mac, &pio->wme[WME_AC_BK], 0);
2629 bwn_pio_set_txqueue(mac, &pio->wme[WME_AC_BE], 1);
2630 bwn_pio_set_txqueue(mac, &pio->wme[WME_AC_VI], 2);
2631 bwn_pio_set_txqueue(mac, &pio->wme[WME_AC_VO], 3);
2632 bwn_pio_set_txqueue(mac, &pio->mcast, 4);
2633 bwn_pio_setupqueue_rx(mac, &pio->rx, 0);
2637 bwn_pio_set_txqueue(struct bwn_mac *mac, struct bwn_pio_txqueue *tq,
2641 struct bwn_softc *sc = mac->mac_sc;
2644 tq->tq_base = bwn_pio_idx2base(mac, index) + BWN_PIO_TXQOFFSET(mac);
2645 tq->tq_index = index;
2647 tq->tq_free = BWN_PIO_MAX_TXPACKETS;
2648 if (bhnd_get_hwrev(sc->sc_dev) >= 8)
2649 tq->tq_size = 1920;
2651 tq->tq_size = bwn_pio_read_2(mac, tq, BWN_PIO_TXQBUFSIZE);
2652 tq->tq_size -= 80;
2655 TAILQ_INIT(&tq->tq_pktlist);
2656 for (i = 0; i < N(tq->tq_pkts); i++) {
2657 tp = &(tq->tq_pkts[i]);
2658 tp->tp_index = i;
2659 tp->tp_queue = tq;
2660 TAILQ_INSERT_TAIL(&tq->tq_pktlist, tp, tp_list);
2665 bwn_pio_idx2base(struct bwn_mac *mac, int index)
2667 struct bwn_softc *sc = mac->mac_sc;
2687 if (bhnd_get_hwrev(sc->sc_dev) >= 11) {
2689 device_printf(sc->sc_dev, "%s: warning\n", __func__);
2693 device_printf(sc->sc_dev, "%s: warning\n", __func__);
2698 bwn_pio_setupqueue_rx(struct bwn_mac *mac, struct bwn_pio_rxqueue *prq,
2701 struct bwn_softc *sc = mac->mac_sc;
2703 prq->prq_mac = mac;
2704 prq->prq_rev = bhnd_get_hwrev(sc->sc_dev);
2705 prq->prq_base = bwn_pio_idx2base(mac, index) + BWN_PIO_RXQOFFSET(mac);
2706 bwn_dma_rxdirectfifo(mac, index, 1);
2725 bwn_pio_read_2(struct bwn_mac *mac, struct bwn_pio_txqueue *tq,
2729 return (BWN_READ_2(mac, tq->tq_base + offset));
2733 bwn_dma_rxdirectfifo(struct bwn_mac *mac, int idx, uint8_t enable)
2738 base = bwn_dma_base(mac->mac_dmatype, idx);
2739 if (mac->mac_dmatype == BHND_DMA_ADDR_64BIT) {
2740 ctl = BWN_READ_4(mac, base + BWN_DMA64_RXCTL);
2744 BWN_WRITE_4(mac, base + BWN_DMA64_RXCTL, ctl);
2746 ctl = BWN_READ_4(mac, base + BWN_DMA32_RXCTL);
2750 BWN_WRITE_4(mac, base + BWN_DMA32_RXCTL, ctl);
2760 for (i = 0; i < N(tq->tq_pkts); i++) {
2761 tp = &(tq->tq_pkts[i]);
2762 if (tp->tp_m) {
2763 m_freem(tp->tp_m);
2764 tp->tp_m = NULL;
2800 bwn_dma_init(struct bwn_mac *mac)
2802 struct bwn_dma *dma = &mac->mac_method.dma;
2805 bwn_dma_setup(dma->wme[WME_AC_BK]);
2806 bwn_dma_setup(dma->wme[WME_AC_BE]);
2807 bwn_dma_setup(dma->wme[WME_AC_VI]);
2808 bwn_dma_setup(dma->wme[WME_AC_VO]);
2809 bwn_dma_setup(dma->mcast);
2811 bwn_dma_setup(dma->rx);
2815 bwn_dma_ringsetup(struct bwn_mac *mac, int controller_index,
2818 struct bwn_dma *dma = &mac->mac_method.dma;
2822 struct bwn_softc *sc = mac->mac_sc;
2828 dr->dr_numslots = BWN_RXRING_SLOTS;
2830 dr->dr_numslots = BWN_TXRING_SLOTS;
2832 dr->dr_meta = malloc(dr->dr_numslots * sizeof(struct bwn_dmadesc_meta),
2834 if (dr->dr_meta == NULL)
2837 dr->dr_type = mac->mac_dmatype;
2838 dr->dr_mac = mac;
2839 dr->dr_base = bwn_dma_base(dr->dr_type, controller_index);
2840 dr->dr_index = controller_index;
2841 if (dr->dr_type == BHND_DMA_ADDR_64BIT) {
2842 dr->getdesc = bwn_dma_64_getdesc;
2843 dr->setdesc = bwn_dma_64_setdesc;
2844 dr->start_transfer = bwn_dma_64_start_transfer;
2845 dr->suspend = bwn_dma_64_suspend;
2846 dr->resume = bwn_dma_64_resume;
2847 dr->get_curslot = bwn_dma_64_get_curslot;
2848 dr->set_curslot = bwn_dma_64_set_curslot;
2850 dr->getdesc = bwn_dma_32_getdesc;
2851 dr->setdesc = bwn_dma_32_setdesc;
2852 dr->start_transfer = bwn_dma_32_start_transfer;
2853 dr->suspend = bwn_dma_32_suspend;
2854 dr->resume = bwn_dma_32_resume;
2855 dr->get_curslot = bwn_dma_32_get_curslot;
2856 dr->set_curslot = bwn_dma_32_set_curslot;
2859 dr->dr_tx = 1;
2860 dr->dr_curslot = -1;
2862 if (dr->dr_index == 0) {
2863 switch (mac->mac_fw.fw_hdr_format) {
2866 dr->dr_rx_bufsize =
2868 dr->dr_frameoffset =
2872 dr->dr_rx_bufsize =
2874 dr->dr_frameoffset =
2894 dr->dr_txhdr_cache = contigmalloc(
2895 (dr->dr_numslots / BWN_TX_SLOTS_PER_FRAME) *
2898 if (dr->dr_txhdr_cache == NULL) {
2899 device_printf(sc->sc_dev,
2907 error = bus_dma_tag_create(dma->parent_dtag,
2912 BWN_HDRSIZE(mac),
2917 &dr->dr_txring_dtag);
2919 device_printf(sc->sc_dev,
2924 for (i = 0; i < dr->dr_numslots; i += 2) {
2925 dr->getdesc(dr, i, &desc, &mt);
2927 mt->mt_txtype = BWN_DMADESC_METATYPE_HEADER;
2928 mt->mt_m = NULL;
2929 mt->mt_ni = NULL;
2930 mt->mt_islast = 0;
2931 error = bus_dmamap_create(dr->dr_txring_dtag, 0,
2932 &mt->mt_dmap);
2934 device_printf(sc->sc_dev,
2939 dr->getdesc(dr, i + 1, &desc, &mt);
2941 mt->mt_txtype = BWN_DMADESC_METATYPE_BODY;
2942 mt->mt_m = NULL;
2943 mt->mt_ni = NULL;
2944 mt->mt_islast = 1;
2945 error = bus_dmamap_create(dma->txbuf_dtag, 0,
2946 &mt->mt_dmap);
2948 device_printf(sc->sc_dev,
2954 error = bus_dmamap_create(dma->rxbuf_dtag, 0,
2955 &dr->dr_spare_dmap);
2957 device_printf(sc->sc_dev,
2962 for (i = 0; i < dr->dr_numslots; i++) {
2963 dr->getdesc(dr, i, &desc, &mt);
2965 error = bus_dmamap_create(dma->rxbuf_dtag, 0,
2966 &mt->mt_dmap);
2968 device_printf(sc->sc_dev,
2974 device_printf(sc->sc_dev,
2980 bus_dmamap_sync(dr->dr_ring_dtag, dr->dr_ring_dmap,
2983 dr->dr_usedslot = dr->dr_numslots;
2990 free(dr->dr_txhdr_cache, M_DEVBUF);
2992 free(dr->dr_meta, M_DEVBUF);
3008 free((*dr)->dr_txhdr_cache, M_DEVBUF);
3009 free((*dr)->dr_meta, M_DEVBUF);
3021 *meta = &(dr->dr_meta[slot]);
3022 desc = dr->dr_ring_descbase;
3039 descbase = dr->dr_ring_descbase;
3040 dma = &dr->dr_mac->mac_method.dma;
3041 dt = &dma->translation;
3043 slot = (int)(&(desc->dma.dma32) - descbase);
3044 KASSERT(slot >= 0 && slot < dr->dr_numslots,
3047 addr = (dmaaddr & dt->addr_mask) | dt->base_addr;
3048 addrext = ((dmaaddr & dt->addrext_mask) >> dma->addrext_shift);
3050 if (slot == dr->dr_numslots - 1)
3061 desc->dma.dma32.control = htole32(ctl);
3062 desc->dma.dma32.address = htole32(addr);
3114 *meta = &(dr->dr_meta[slot]);
3115 desc = dr->dr_ring_descbase;
3135 descbase = dr->dr_ring_descbase;
3136 dma = &dr->dr_mac->mac_method.dma;
3137 dt = &dma->translation;
3139 slot = (int)(&(desc->dma.dma64) - descbase);
3140 KASSERT(slot >= 0 && slot < dr->dr_numslots,
3143 addr = (dmaaddr & dt->addr_mask) | dt->base_addr;
3146 addrext = ((dmaaddr & dt->addrext_mask) >> dma->addrext_shift);
3149 if (slot == dr->dr_numslots - 1)
3163 desc->dma.dma64.control0 = htole32(ctl0);
3164 desc->dma.dma64.control1 = htole32(ctl1);
3165 desc->dma.dma64.address_low = htole32(addrlo);
3166 desc->dma.dma64.address_high = htole32(addrhi);
3215 struct bwn_mac *mac = dr->dr_mac;
3216 struct bwn_dma *dma = &mac->mac_method.dma;
3217 struct bwn_softc *sc = mac->mac_sc;
3220 error = bus_dma_tag_create(dma->parent_dtag,
3230 &dr->dr_ring_dtag);
3232 device_printf(sc->sc_dev,
3234 return (-1);
3237 error = bus_dmamem_alloc(dr->dr_ring_dtag,
3238 &dr->dr_ring_descbase, BUS_DMA_WAITOK | BUS_DMA_ZERO,
3239 &dr->dr_ring_dmap);
3241 device_printf(sc->sc_dev,
3243 return (-1);
3245 error = bus_dmamap_load(dr->dr_ring_dtag, dr->dr_ring_dmap,
3246 dr->dr_ring_descbase, BWN_DMA_RINGMEMSIZE,
3247 bwn_dma_ring_addr, &dr->dr_ring_dmabase, BUS_DMA_NOWAIT);
3249 device_printf(sc->sc_dev,
3251 return (-1);
3260 struct bwn_mac *mac;
3266 mac = dr->dr_mac;
3267 dma = &mac->mac_method.dma;
3268 dt = &dma->translation;
3270 paddr = dr->dr_ring_dmabase;
3271 addr = (paddr & dt->addr_mask) | dt->base_addr;
3274 addrext = ((paddr & dt->addrext_mask) >> dma->addrext_shift);
3276 if (dr->dr_tx) {
3277 dr->dr_curslot = -1;
3279 if (dr->dr_type == BHND_DMA_ADDR_64BIT) {
3301 dr->dr_usedslot = dr->dr_numslots;
3303 if (dr->dr_type == BHND_DMA_ADDR_64BIT) {
3304 value = (dr->dr_frameoffset << BWN_DMA64_RXFROFF_SHIFT);
3312 BWN_DMA_WRITE(dr, BWN_DMA64_RXINDEX, dr->dr_numslots *
3315 value = (dr->dr_frameoffset << BWN_DMA32_RXFROFF_SHIFT);
3322 BWN_DMA_WRITE(dr, BWN_DMA32_RXINDEX, dr->dr_numslots *
3331 bus_dmamap_unload(dr->dr_ring_dtag, dr->dr_ring_dmap);
3332 bus_dmamem_free(dr->dr_ring_dtag, dr->dr_ring_descbase,
3333 dr->dr_ring_dmap);
3340 if (dr->dr_tx) {
3341 bwn_dma_tx_reset(dr->dr_mac, dr->dr_base, dr->dr_type);
3342 if (dr->dr_type == BHND_DMA_ADDR_64BIT) {
3348 bwn_dma_rx_reset(dr->dr_mac, dr->dr_base, dr->dr_type);
3349 if (dr->dr_type == BHND_DMA_ADDR_64BIT) {
3362 struct bwn_mac *mac = dr->dr_mac;
3363 struct bwn_dma *dma = &mac->mac_method.dma;
3364 struct bwn_softc *sc = mac->mac_sc;
3367 if (!dr->dr_usedslot)
3369 for (i = 0; i < dr->dr_numslots; i++) {
3370 dr->getdesc(dr, i, &desc, &meta);
3372 if (meta->mt_m == NULL) {
3373 if (!dr->dr_tx)
3374 device_printf(sc->sc_dev, "%s: not TX?\n",
3378 if (dr->dr_tx) {
3379 if (meta->mt_txtype == BWN_DMADESC_METATYPE_HEADER)
3380 bus_dmamap_unload(dr->dr_txring_dtag,
3381 meta->mt_dmap);
3382 else if (meta->mt_txtype == BWN_DMADESC_METATYPE_BODY)
3383 bus_dmamap_unload(dma->txbuf_dtag,
3384 meta->mt_dmap);
3386 bus_dmamap_unload(dma->rxbuf_dtag, meta->mt_dmap);
3392 bwn_dma_tx_reset(struct bwn_mac *mac, uint16_t base,
3395 struct bwn_softc *sc = mac->mac_sc;
3403 value = BWN_READ_4(mac, base + offset);
3421 BWN_WRITE_4(mac, base + offset, 0);
3425 value = BWN_READ_4(mac, base + offset);
3429 i = -1;
3435 i = -1;
3441 if (i != -1) {
3442 device_printf(sc->sc_dev, "%s: timed out\n", __func__);
3451 bwn_dma_rx_reset(struct bwn_mac *mac, uint16_t base,
3454 struct bwn_softc *sc = mac->mac_sc;
3461 BWN_WRITE_4(mac, base + offset, 0);
3465 value = BWN_READ_4(mac, base + offset);
3469 i = -1;
3475 i = -1;
3481 if (i != -1) {
3482 device_printf(sc->sc_dev, "%s: timed out\n", __func__);
3494 if (meta->mt_m != NULL) {
3495 m_freem(meta->mt_m);
3496 meta->mt_m = NULL;
3498 if (meta->mt_ni != NULL) {
3499 ieee80211_free_node(meta->mt_ni);
3500 meta->mt_ni = NULL;
3511 rxhdr->frame_len = 0;
3513 KASSERT(dr->dr_rx_bufsize >= dr->dr_frameoffset +
3516 frame = mtod(m, char *) + dr->dr_frameoffset;
3523 unsigned char *f = mtod(m, char *) + dr->dr_frameoffset;
3530 bwn_wme_init(struct bwn_mac *mac)
3533 bwn_wme_load(mac);
3536 bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_EDCF);
3537 BWN_WRITE_2(mac, BWN_IFSCTL, BWN_READ_2(mac, BWN_IFSCTL) |
3542 bwn_spu_setdelay(struct bwn_mac *mac, int idle)
3544 struct bwn_softc *sc = mac->mac_sc;
3545 struct ieee80211com *ic = &sc->sc_ic;
3548 delay = (mac->mac_phy.type == BWN_PHYTYPE_A) ? 3700 : 1050;
3549 if (ic->ic_opmode == IEEE80211_M_IBSS || idle)
3551 if ((mac->mac_phy.rf_ver == 0x2050) && (mac->mac_phy.rf_rev == 8))
3554 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_SPU_WAKEUP, delay);
3558 bwn_bt_enable(struct bwn_mac *mac)
3560 struct bwn_softc *sc = mac->mac_sc;
3565 if ((sc->sc_board_info.board_flags & BHND_BFL_BTCOEX) == 0)
3567 if (mac->mac_phy.type != BWN_PHYTYPE_B && !mac->mac_phy.gmode)
3570 hf = bwn_hf_read(mac);
3571 if (sc->sc_board_info.board_flags & BHND_BFL_BTC2WIRE_ALTGPIO)
3575 bwn_hf_write(mac, hf);
3579 bwn_set_macaddr(struct bwn_mac *mac)
3582 bwn_mac_write_bssid(mac);
3583 bwn_mac_setfilter(mac, BWN_MACFILTER_SELF,
3584 mac->mac_sc->sc_ic.ic_macaddr);
3588 bwn_clear_keys(struct bwn_mac *mac)
3592 for (i = 0; i < mac->mac_max_nr_keys; i++) {
3593 KASSERT(i >= 0 && i < mac->mac_max_nr_keys,
3596 bwn_key_dowrite(mac, i, BWN_SEC_ALGO_NONE,
3598 if ((i <= 3) && !BWN_SEC_NEWAPI(mac)) {
3599 bwn_key_dowrite(mac, i + 4, BWN_SEC_ALGO_NONE,
3602 mac->mac_key[i].keyconf = NULL;
3607 bwn_crypt_init(struct bwn_mac *mac)
3609 struct bwn_softc *sc = mac->mac_sc;
3611 mac->mac_max_nr_keys = (bhnd_get_hwrev(sc->sc_dev) >= 5) ? 58 : 20;
3612 KASSERT(mac->mac_max_nr_keys <= N(mac->mac_key),
3614 mac->mac_ktp = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_KEY_TABLEP);
3615 mac->mac_ktp *= 2;
3616 if (bhnd_get_hwrev(sc->sc_dev) >= 5)
3617 BWN_WRITE_2(mac, BWN_RCMTA_COUNT, mac->mac_max_nr_keys - 8);
3618 bwn_clear_keys(mac);
3622 bwn_chip_exit(struct bwn_mac *mac)
3624 bwn_phy_exit(mac);
3628 bwn_fw_fillinfo(struct bwn_mac *mac)
3632 error = bwn_fw_gets(mac, BWN_FWTYPE_DEFAULT);
3635 error = bwn_fw_gets(mac, BWN_FWTYPE_OPENSOURCE);
3643 * the MAC core control over the pins.
3645 * @param mac bwn MAC state.
3650 bwn_gpio_control(struct bwn_mac *mac, uint32_t pins)
3656 sc = mac->mac_sc;
3672 error = GPIO_PIN_CONFIG_32(sc->sc_gpio, 0, nitems(flags), flags);
3674 device_printf(sc->sc_dev, "error configuring %s pin flags: "
3675 "%d\n", device_get_nameunit(sc->sc_gpio), error);
3683 bwn_gpio_init(struct bwn_mac *mac)
3688 sc = mac->mac_sc;
3692 BWN_WRITE_4(mac, BWN_MACCTL,
3693 BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_GPOUT_MASK);
3694 BWN_WRITE_2(mac, BWN_GPIO_MASK,
3695 BWN_READ_2(mac, BWN_GPIO_MASK) | pins);
3697 if (sc->sc_board_info.board_flags & BHND_BFL_PACTRL) {
3698 /* MAC core is responsible for toggling PAREF via gpio9 */
3699 BWN_WRITE_2(mac, BWN_GPIO_MASK,
3700 BWN_READ_2(mac, BWN_GPIO_MASK) | BHND_GPIO_BOARD_PACTRL);
3705 return (bwn_gpio_control(mac, pins));
3709 bwn_fw_loadinitvals(struct bwn_mac *mac)
3712 ((const struct bwn_fwinitvals *)((const char *)fwp.fw->data + offset))
3715 struct bwn_fw *fw = &mac->mac_fw;
3718 hdr = (const struct bwn_fwhdr *)(fw->initvals.fw->data);
3719 error = bwn_fwinitvals_write(mac, GETFWOFFSET(fw->initvals, hdr_len),
3720 be32toh(hdr->size), fw->initvals.fw->datasize - hdr_len);
3723 if (fw->initvals_band.fw) {
3724 hdr = (const struct bwn_fwhdr *)(fw->initvals_band.fw->data);
3725 error = bwn_fwinitvals_write(mac,
3726 GETFWOFFSET(fw->initvals_band, hdr_len),
3727 be32toh(hdr->size),
3728 fw->initvals_band.fw->datasize - hdr_len);
3735 bwn_phy_init(struct bwn_mac *mac)
3737 struct bwn_softc *sc = mac->mac_sc;
3740 mac->mac_phy.chan = mac->mac_phy.get_default_chan(mac);
3741 mac->mac_phy.rf_onoff(mac, 1);
3742 error = mac->mac_phy.init(mac);
3744 device_printf(sc->sc_dev, "PHY init failed\n");
3747 error = bwn_switch_channel(mac,
3748 mac->mac_phy.get_default_chan(mac));
3750 device_printf(sc->sc_dev,
3756 if (mac->mac_phy.exit)
3757 mac->mac_phy.exit(mac);
3759 mac->mac_phy.rf_onoff(mac, 0);
3765 bwn_set_txantenna(struct bwn_mac *mac, int antenna)
3773 tmp = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_ACKCTS_PHYCTL);
3775 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_ACKCTS_PHYCTL, tmp);
3777 tmp = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_PROBE_RESP_PHYCTL);
3779 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_PROBE_RESP_PHYCTL, tmp);
3783 bwn_set_opmode(struct bwn_mac *mac)
3785 struct bwn_softc *sc = mac->mac_sc;
3786 struct ieee80211com *ic = &sc->sc_ic;
3790 ctl = BWN_READ_4(mac, BWN_MACCTL);
3796 if (ic->ic_opmode == IEEE80211_M_HOSTAP ||
3797 ic->ic_opmode == IEEE80211_M_MBSS)
3799 else if (ic->ic_opmode == IEEE80211_M_IBSS)
3801 ctl |= sc->sc_filters;
3803 if (bhnd_get_hwrev(sc->sc_dev) <= 4)
3806 BWN_WRITE_4(mac, BWN_MACCTL, ctl);
3810 if (sc->sc_cid.chip_id == BHND_CHIPID_BCM4306 &&
3811 sc->sc_cid.chip_rev == 3)
3816 BWN_WRITE_2(mac, 0x612, cfp_pretbtt);
3824 *((bus_addr_t *)arg) = seg->ds_addr;
3829 bwn_dummy_transmission(struct bwn_mac *mac, int ofdm, int paon)
3831 struct bwn_phy *phy = &mac->mac_phy;
3832 struct bwn_softc *sc = mac->mac_sc;
3847 BWN_ASSERT_LOCKED(mac->mac_sc);
3850 bwn_ram_write(mac, i * 4, buffer[i]);
3852 BWN_WRITE_2(mac, 0x0568, 0x0000);
3853 BWN_WRITE_2(mac, 0x07c0,
3854 (bhnd_get_hwrev(sc->sc_dev) < 11) ? 0x0000 : 0x0100);
3857 BWN_WRITE_2(mac, 0x050c, value);
3859 if (phy->type == BWN_PHYTYPE_N || phy->type == BWN_PHYTYPE_LP ||
3860 phy->type == BWN_PHYTYPE_LCN)
3861 BWN_WRITE_2(mac, 0x0514, 0x1a02);
3862 BWN_WRITE_2(mac, 0x0508, 0x0000);
3863 BWN_WRITE_2(mac, 0x050a, 0x0000);
3864 BWN_WRITE_2(mac, 0x054c, 0x0000);
3865 BWN_WRITE_2(mac, 0x056a, 0x0014);
3866 BWN_WRITE_2(mac, 0x0568, 0x0826);
3867 BWN_WRITE_2(mac, 0x0500, 0x0000);
3871 switch (phy->type) {
3874 BWN_WRITE_2(mac, 0x0502, 0x00d0);
3877 BWN_WRITE_2(mac, 0x0502, 0x0050);
3880 BWN_WRITE_2(mac, 0x0502, 0x0030);
3885 BWN_READ_2(mac, 0x0502);
3887 if (phy->rf_ver == 0x2050 && phy->rf_rev <= 0x5)
3888 BWN_RF_WRITE(mac, 0x0051, 0x0017);
3890 value = BWN_READ_2(mac, 0x050e);
3896 value = BWN_READ_2(mac, 0x050e);
3902 value = BWN_READ_2(mac, 0x0690);
3907 if (phy->rf_ver == 0x2050 && phy->rf_rev <= 0x5)
3908 BWN_RF_WRITE(mac, 0x0051, 0x0037);
3912 bwn_ram_write(struct bwn_mac *mac, uint16_t offset, uint32_t val)
3918 macctl = BWN_READ_4(mac, BWN_MACCTL);
3922 BWN_WRITE_4(mac, BWN_RAM_CONTROL, offset);
3923 BWN_BARRIER(mac, BWN_RAM_CONTROL, 4, BUS_SPACE_BARRIER_WRITE);
3924 BWN_WRITE_4(mac, BWN_RAM_DATA, val);
3928 bwn_mac_suspend(struct bwn_mac *mac)
3930 struct bwn_softc *sc = mac->mac_sc;
3934 KASSERT(mac->mac_suspended >= 0,
3937 DPRINTF(mac->mac_sc, BWN_DEBUG_RESET, "%s: suspended=%d\n",
3938 __func__, mac->mac_suspended);
3940 if (mac->mac_suspended == 0) {
3941 bwn_psctl(mac, BWN_PS_AWAKE);
3942 BWN_WRITE_4(mac, BWN_MACCTL,
3943 BWN_READ_4(mac, BWN_MACCTL)
3945 BWN_READ_4(mac, BWN_MACCTL);
3946 for (i = 35; i; i--) {
3947 tmp = BWN_READ_4(mac, BWN_INTR_REASON);
3952 for (i = 40; i; i--) {
3953 tmp = BWN_READ_4(mac, BWN_INTR_REASON);
3958 device_printf(sc->sc_dev, "MAC suspend failed\n");
3961 mac->mac_suspended++;
3965 bwn_mac_enable(struct bwn_mac *mac)
3967 struct bwn_softc *sc = mac->mac_sc;
3970 DPRINTF(mac->mac_sc, BWN_DEBUG_RESET, "%s: suspended=%d\n",
3971 __func__, mac->mac_suspended);
3973 state = bwn_shm_read_2(mac, BWN_SHARED,
3982 mac->mac_suspended--;
3983 KASSERT(mac->mac_suspended >= 0,
3985 if (mac->mac_suspended == 0) {
3986 BWN_WRITE_4(mac, BWN_MACCTL,
3987 BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_ON);
3988 BWN_WRITE_4(mac, BWN_INTR_REASON, BWN_INTR_MAC_SUSPENDED);
3989 BWN_READ_4(mac, BWN_MACCTL);
3990 BWN_READ_4(mac, BWN_INTR_REASON);
3991 bwn_psctl(mac, 0);
3996 bwn_psctl(struct bwn_mac *mac, uint32_t flags)
3998 struct bwn_softc *sc = mac->mac_sc;
4007 /* XXX forcibly awake and hwps-off */
4009 BWN_WRITE_4(mac, BWN_MACCTL,
4010 (BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_AWAKE) &
4012 BWN_READ_4(mac, BWN_MACCTL);
4013 if (bhnd_get_hwrev(sc->sc_dev) >= 5) {
4015 ucstat = bwn_shm_read_2(mac, BWN_SHARED,
4022 DPRINTF(mac->mac_sc, BWN_DEBUG_RESET, "%s: ucstat=%d\n", __func__,
4027 bwn_fw_gets(struct bwn_mac *mac, enum bwn_fwtype type)
4029 struct bwn_softc *sc = mac->mac_sc;
4030 struct bwn_fw *fw = &mac->mac_fw;
4031 const uint8_t rev = bhnd_get_hwrev(sc->sc_dev);
4040 if (mac->mac_phy.type == BWN_PHYTYPE_AC)
4044 if (mac->mac_phy.type == BWN_PHYTYPE_AC)
4048 if (mac->mac_phy.type == BWN_PHYTYPE_LCN40)
4052 if (mac->mac_phy.type == BWN_PHYTYPE_N)
4056 if (mac->mac_phy.type == BWN_PHYTYPE_HT)
4060 if (mac->mac_phy.type == BWN_PHYTYPE_HT)
4065 if (mac->mac_phy.type == BWN_PHYTYPE_N)
4067 else if (mac->mac_phy.type == BWN_PHYTYPE_LCN)
4071 if (mac->mac_phy.type == BWN_PHYTYPE_LCN)
4075 if (mac->mac_phy.type == BWN_PHYTYPE_N)
4082 if (mac->mac_phy.type == BWN_PHYTYPE_N)
4084 else if (mac->mac_phy.type == BWN_PHYTYPE_LP)
4109 device_printf(sc->sc_dev, "no ucode for rev %d\n", rev);
4110 bwn_release_firmware(mac);
4114 device_printf(sc->sc_dev, "ucode fw: %s\n", filename);
4115 error = bwn_fw_get(mac, type, filename, &fw->ucode);
4117 bwn_release_firmware(mac);
4122 KASSERT(fw->no_pcmfile == 0, ("%s:%d fail", __func__, __LINE__));
4124 error = bwn_fw_get(mac, type, "pcm5", &fw->pcm);
4126 fw->no_pcmfile = 1;
4128 bwn_release_firmware(mac);
4132 device_printf(sc->sc_dev, "no PCM for rev %d\n", rev);
4133 bwn_release_firmware(mac);
4138 error = bhnd_read_iost(sc->sc_dev, &iost);
4142 switch (mac->mac_phy.type) {
4188 error = bwn_fw_get(mac, type, filename, &fw->initvals);
4190 bwn_release_firmware(mac);
4195 switch (mac->mac_phy.type) {
4242 device_printf(sc->sc_dev, "unknown phy (%d)\n",
4243 mac->mac_phy.type);
4246 error = bwn_fw_get(mac, type, filename, &fw->initvals_band);
4248 bwn_release_firmware(mac);
4253 device_printf(sc->sc_dev, "no INITVALS for rev %d, phy.type %d\n",
4254 rev, mac->mac_phy.type);
4255 bwn_release_firmware(mac);
4260 bwn_fw_get(struct bwn_mac *mac, enum bwn_fwtype type,
4264 struct bwn_softc *sc = mac->mac_sc;
4272 if (bfw->filename != NULL) {
4273 if (bfw->type == type && (strcmp(bfw->filename, name) == 0))
4279 (type == BWN_FWTYPE_OPENSOURCE) ? "-open" : "",
4280 (mac->mac_phy.type == BWN_PHYTYPE_LP) ? "lp_" : "", name);
4281 /* XXX Sleeping on "fwload" with the non-sleepable locks held */
4284 device_printf(sc->sc_dev, "the fw file(%s) not found\n",
4288 if (fw->datasize < sizeof(struct bwn_fwhdr))
4290 hdr = (const struct bwn_fwhdr *)(fw->data);
4291 switch (hdr->type) {
4294 if (be32toh(hdr->size) !=
4295 (fw->datasize - sizeof(struct bwn_fwhdr)))
4299 if (hdr->ver != 1)
4305 bfw->filename = name;
4306 bfw->fw = fw;
4307 bfw->type = type;
4310 device_printf(sc->sc_dev, "the fw file(%s) format error\n", namebuf);
4317 bwn_release_firmware(struct bwn_mac *mac)
4320 bwn_do_release_fw(&mac->mac_fw.ucode);
4321 bwn_do_release_fw(&mac->mac_fw.pcm);
4322 bwn_do_release_fw(&mac->mac_fw.initvals);
4323 bwn_do_release_fw(&mac->mac_fw.initvals_band);
4330 if (bfw->fw != NULL)
4331 firmware_put(bfw->fw, FIRMWARE_UNLOAD);
4332 bfw->fw = NULL;
4333 bfw->filename = NULL;
4337 bwn_fw_loaducode(struct bwn_mac *mac)
4340 ((const uint32_t *)((const char *)fwp.fw->data + offset))
4342 ((fwp.fw->datasize - offset) / sizeof(uint32_t))
4343 struct bwn_softc *sc = mac->mac_sc;
4350 ctl = BWN_READ_4(mac, BWN_MACCTL);
4354 BWN_WRITE_4(mac, BWN_MACCTL, ctl);
4356 bwn_shm_write_2(mac, BWN_SCRATCH, i, 0);
4358 bwn_shm_write_2(mac, BWN_SHARED, i, 0);
4360 data = GETFWOFFSET(mac->mac_fw.ucode, sizeof(struct bwn_fwhdr));
4361 bwn_shm_ctlword(mac, BWN_UCODE | BWN_SHARED_AUTOINC, 0x0000);
4362 for (i = 0; i < GETFWSIZE(mac->mac_fw.ucode, sizeof(struct bwn_fwhdr));
4364 BWN_WRITE_4(mac, BWN_SHM_DATA, be32toh(data[i]));
4368 if (mac->mac_fw.pcm.fw) {
4369 data = GETFWOFFSET(mac->mac_fw.pcm, sizeof(struct bwn_fwhdr));
4370 bwn_shm_ctlword(mac, BWN_HW, 0x01ea);
4371 BWN_WRITE_4(mac, BWN_SHM_DATA, 0x00004000);
4372 bwn_shm_ctlword(mac, BWN_HW, 0x01eb);
4373 for (i = 0; i < GETFWSIZE(mac->mac_fw.pcm,
4375 BWN_WRITE_4(mac, BWN_SHM_DATA, be32toh(data[i]));
4380 BWN_WRITE_4(mac, BWN_INTR_REASON, BWN_INTR_ALL);
4381 BWN_WRITE_4(mac, BWN_MACCTL,
4382 (BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_MCODE_JMP0) |
4386 if (BWN_READ_4(mac, BWN_INTR_REASON) == BWN_INTR_MAC_SUSPENDED)
4389 device_printf(sc->sc_dev, "ucode timeout\n");
4395 BWN_READ_4(mac, BWN_INTR_REASON);
4397 mac->mac_fw.rev = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_UCODE_REV);
4398 if (mac->mac_fw.rev <= 0x128) {
4399 device_printf(sc->sc_dev, "the firmware is too old\n");
4408 if (mac->mac_fw.rev >= 598)
4409 mac->mac_fw.fw_hdr_format = BWN_FW_HDR_598;
4410 else if (mac->mac_fw.rev >= 410)
4411 mac->mac_fw.fw_hdr_format = BWN_FW_HDR_410;
4413 mac->mac_fw.fw_hdr_format = BWN_FW_HDR_351;
4424 if (mac->mac_fw.fw_hdr_format == BWN_FW_HDR_598) {
4425 device_printf(sc->sc_dev,
4432 mac->mac_fw.patch = bwn_shm_read_2(mac, BWN_SHARED,
4434 date = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_UCODE_DATE);
4435 mac->mac_fw.opensource = (date == 0xffff);
4437 mac->mac_flags |= BWN_MAC_FLAG_WME;
4438 mac->mac_flags |= BWN_MAC_FLAG_HWCRYPTO;
4440 time = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_UCODE_TIME);
4441 if (mac->mac_fw.opensource == 0) {
4442 device_printf(sc->sc_dev,
4444 mac->mac_fw.rev, mac->mac_fw.patch, date, time);
4445 if (mac->mac_fw.no_pcmfile)
4446 device_printf(sc->sc_dev,
4449 mac->mac_fw.patch = time;
4450 fwcaps = bwn_fwcaps_read(mac);
4451 if (!(fwcaps & BWN_FWCAPS_HWCRYPTO) || mac->mac_fw.no_pcmfile) {
4452 device_printf(sc->sc_dev,
4454 mac->mac_flags &= ~BWN_MAC_FLAG_HWCRYPTO;
4457 device_printf(sc->sc_dev, "disabling WME support\n");
4458 mac->mac_flags &= ~BWN_MAC_FLAG_WME;
4462 if (BWN_ISOLDFMT(mac))
4463 device_printf(sc->sc_dev, "using old firmware image\n");
4468 BWN_WRITE_4(mac, BWN_MACCTL,
4469 (BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_MCODE_RUN) |
4479 bwn_fwcaps_read(struct bwn_mac *mac)
4482 KASSERT(mac->mac_fw.opensource == 1,
4484 return (bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_FWCAPS));
4488 bwn_fwinitvals_write(struct bwn_mac *mac, const struct bwn_fwinitvals *ivals,
4497 struct bwn_softc *sc = mac->mac_sc;
4507 if (array_size < sizeof(iv->offset_size))
4509 array_size -= sizeof(iv->offset_size);
4510 offset = be16toh(iv->offset_size);
4516 if (array_size < sizeof(iv->data.d32))
4518 array_size -= sizeof(iv->data.d32);
4519 BWN_WRITE_4(mac, offset, be32toh(iv->data.d32));
4522 if (array_size < sizeof(iv->data.d16))
4524 array_size -= sizeof(iv->data.d16);
4525 BWN_WRITE_2(mac, offset, be16toh(iv->data.d16));
4534 device_printf(sc->sc_dev, "initvals: invalid format\n");
4541 bwn_switch_channel(struct bwn_mac *mac, int chan)
4543 struct bwn_phy *phy = &(mac->mac_phy);
4544 struct bwn_softc *sc = mac->mac_sc;
4545 struct ieee80211com *ic = &sc->sc_ic;
4550 chan = phy->get_default_chan(mac);
4553 if (IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan))
4555 savedcookie = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_CHAN);
4556 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_CHAN, channelcookie);
4557 error = phy->switch_channel(mac, chan);
4561 mac->mac_phy.chan = chan;
4565 device_printf(sc->sc_dev, "failed to switch channel\n");
4566 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_CHAN, savedcookie);
4591 bwn_wme_load(struct bwn_mac *mac)
4593 struct bwn_softc *sc = mac->mac_sc;
4596 KASSERT(N(bwn_wme_shm_offsets) == N(sc->sc_wmeParams),
4599 bwn_mac_suspend(mac);
4600 for (i = 0; i < N(sc->sc_wmeParams); i++)
4601 bwn_wme_loadparams(mac, &(sc->sc_wmeParams[i]),
4603 bwn_mac_enable(mac);
4607 bwn_wme_loadparams(struct bwn_mac *mac,
4610 struct bwn_softc *sc = mac->mac_sc;
4615 slot = BWN_READ_2(mac, BWN_RNG) &
4616 _IEEE80211_SHIFTMASK(p->wmep_logcwmin, WME_PARAM_LOGCWMIN);
4621 "wmep_logcwmax %d wmep_aifsn %d\n", p->wmep_txopLimit,
4622 p->wmep_logcwmin, p->wmep_logcwmax, p->wmep_aifsn);
4624 params[BWN_WMEPARAM_TXOP] = p->wmep_txopLimit * 32;
4626 _IEEE80211_SHIFTMASK(p->wmep_logcwmin, WME_PARAM_LOGCWMIN);
4628 _IEEE80211_SHIFTMASK(p->wmep_logcwmax, WME_PARAM_LOGCWMAX);
4630 _IEEE80211_SHIFTMASK(p->wmep_logcwmin, WME_PARAM_LOGCWMIN);
4631 params[BWN_WMEPARAM_AIFS] = p->wmep_aifsn;
4633 params[BWN_WMEPARAM_REGGAP] = slot + p->wmep_aifsn;
4637 tmp = bwn_shm_read_2(mac, BWN_SHARED,
4640 bwn_shm_write_2(mac, BWN_SHARED, shm_offset + (i * 2),
4643 bwn_shm_write_2(mac, BWN_SHARED, shm_offset + (i * 2),
4650 bwn_mac_write_bssid(struct bwn_mac *mac)
4652 struct bwn_softc *sc = mac->mac_sc;
4657 bwn_mac_setfilter(mac, BWN_MACFILTER_BSSID, sc->sc_bssid);
4658 memcpy(mac_bssid, sc->sc_ic.ic_macaddr, IEEE80211_ADDR_LEN);
4659 memcpy(mac_bssid + IEEE80211_ADDR_LEN, sc->sc_bssid,
4667 bwn_ram_write(mac, 0x20 + i, tmp);
4672 bwn_mac_setfilter(struct bwn_mac *mac, uint16_t offset,
4678 if (!mac)
4682 BWN_WRITE_2(mac, BWN_MACFILTER_CONTROL, offset);
4686 BWN_WRITE_2(mac, BWN_MACFILTER_DATA, data);
4689 BWN_WRITE_2(mac, BWN_MACFILTER_DATA, data);
4692 BWN_WRITE_2(mac, BWN_MACFILTER_DATA, data);
4696 bwn_key_dowrite(struct bwn_mac *mac, uint8_t index, uint8_t algorithm,
4702 if (BWN_SEC_NEWAPI(mac))
4705 KASSERT(index < mac->mac_max_nr_keys,
4711 bwn_key_macwrite(mac, index, NULL);
4714 bwn_key_write(mac, index, algorithm, buf);
4716 bwn_key_macwrite(mac, index, mac_addr);
4718 mac->mac_key[index].algorithm = algorithm;
4722 bwn_key_macwrite(struct bwn_mac *mac, uint8_t index, const uint8_t *addr)
4724 struct bwn_softc *sc = mac->mac_sc;
4728 if (BWN_SEC_NEWAPI(mac))
4733 index -= start;
4744 if (bhnd_get_hwrev(sc->sc_dev) >= 5) {
4745 bwn_shm_write_4(mac, BWN_RCMTA, (index * 2) + 0, addrtmp[0]);
4746 bwn_shm_write_2(mac, BWN_RCMTA, (index * 2) + 1, addrtmp[1]);
4749 bwn_shm_write_4(mac, BWN_SHARED,
4751 bwn_shm_write_2(mac, BWN_SHARED,
4758 bwn_key_write(struct bwn_mac *mac, uint8_t index, uint8_t algorithm,
4765 kidx = BWN_SEC_KEY2FW(mac, index);
4766 bwn_shm_write_2(mac, BWN_SHARED,
4769 offset = mac->mac_ktp + (index * BWN_SEC_KEYSIZE);
4773 bwn_shm_write_2(mac, BWN_SHARED, offset + i, value);
4778 bwn_phy_exit(struct bwn_mac *mac)
4781 mac->mac_phy.rf_onoff(mac, 0);
4782 if (mac->mac_phy.exit != NULL)
4783 mac->mac_phy.exit(mac);
4787 bwn_dma_free(struct bwn_mac *mac)
4791 if ((mac->mac_flags & BWN_MAC_FLAG_DMA) == 0)
4793 dma = &mac->mac_method.dma;
4795 bwn_dma_ringfree(&dma->rx);
4796 bwn_dma_ringfree(&dma->wme[WME_AC_BK]);
4797 bwn_dma_ringfree(&dma->wme[WME_AC_BE]);
4798 bwn_dma_ringfree(&dma->wme[WME_AC_VI]);
4799 bwn_dma_ringfree(&dma->wme[WME_AC_VO]);
4800 bwn_dma_ringfree(&dma->mcast);
4804 bwn_core_stop(struct bwn_mac *mac)
4806 struct bwn_softc *sc = mac->mac_sc;
4810 if (mac->mac_status < BWN_MAC_STATUS_STARTED)
4813 callout_stop(&sc->sc_rfswitch_ch);
4814 callout_stop(&sc->sc_task_ch);
4815 callout_stop(&sc->sc_watchdog_ch);
4816 sc->sc_watchdog_timer = 0;
4817 BWN_WRITE_4(mac, BWN_INTR_MASK, 0);
4818 BWN_READ_4(mac, BWN_INTR_MASK);
4819 bwn_mac_suspend(mac);
4821 mac->mac_status = BWN_MAC_STATUS_INITED;
4829 struct bwn_mac *mac;
4835 TAILQ_FOREACH(mac, &sc->sc_maclist, mac_list) {
4837 mac->mac_phy.supports_2ghz) {
4838 up_dev = mac;
4841 mac->mac_phy.supports_5ghz) {
4842 up_dev = mac;
4852 device_printf(sc->sc_dev, "Could not find a device\n");
4855 if (up_dev == sc->sc_curmac && sc->sc_curmac->mac_phy.gmode == gmode)
4859 "switching to %s-GHz band\n",
4862 down_dev = sc->sc_curmac;
4863 status = down_dev->mac_status;
4875 up_dev->mac_phy.gmode = gmode;
4879 device_printf(sc->sc_dev,
4880 "fatal: failed to initialize for %s-GHz\n",
4887 KASSERT(up_dev->mac_status == status, ("%s: fail", __func__));
4888 sc->sc_curmac = up_dev;
4892 sc->sc_curmac = NULL;
4897 bwn_rf_turnon(struct bwn_mac *mac)
4900 DPRINTF(mac->mac_sc, BWN_DEBUG_RESET, "%s: called\n", __func__);
4902 bwn_mac_suspend(mac);
4903 mac->mac_phy.rf_onoff(mac, 1);
4904 mac->mac_phy.rf_on = 1;
4905 bwn_mac_enable(mac);
4909 bwn_rf_turnoff(struct bwn_mac *mac)
4912 DPRINTF(mac->mac_sc, BWN_DEBUG_RESET, "%s: called\n", __func__);
4914 bwn_mac_suspend(mac);
4915 mac->mac_phy.rf_onoff(mac, 0);
4916 mac->mac_phy.rf_on = 0;
4917 bwn_mac_enable(mac);
4924 bwn_phy_reset(struct bwn_mac *mac)
4930 sc = mac->mac_sc;
4935 if ((error = bhnd_write_ioctl(sc->sc_dev, iost, mask)))
4942 if ((error = bhnd_write_ioctl(sc->sc_dev, iost, mask)))
4954 struct ieee80211com *ic= vap->iv_ic;
4955 enum ieee80211_state ostate = vap->iv_state;
4956 struct bwn_softc *sc = ic->ic_softc;
4957 struct bwn_mac *mac = sc->sc_curmac;
4960 DPRINTF(sc, BWN_DEBUG_STATE, "%s: %s -> %s\n", __func__,
4961 ieee80211_state_name[vap->iv_state],
4964 error = bvp->bv_newstate(vap, nstate, arg);
4970 bwn_led_newstate(mac, nstate);
4975 if (vap->iv_opmode == IEEE80211_M_STA) {
4982 if (ic->ic_opmode == IEEE80211_M_STA &&
4983 (sc->sc_flags & BWN_FLAG_INVALID) == 0) {
4984 memset(sc->sc_bssid, 0, IEEE80211_ADDR_LEN);
4985 bwn_set_macaddr(mac);
4990 if (vap->iv_opmode == IEEE80211_M_MONITOR ||
4991 vap->iv_opmode == IEEE80211_M_AHDEMO) {
4994 memcpy(sc->sc_bssid, vap->iv_bss->ni_bssid, IEEE80211_ADDR_LEN);
4995 bwn_set_opmode(mac);
4996 bwn_set_pretbtt(mac);
4997 bwn_spu_setdelay(mac, 0);
4998 bwn_set_macaddr(mac);
5007 bwn_set_pretbtt(struct bwn_mac *mac)
5009 struct bwn_softc *sc = mac->mac_sc;
5010 struct ieee80211com *ic = &sc->sc_ic;
5013 if (ic->ic_opmode == IEEE80211_M_IBSS)
5016 pretbtt = (mac->mac_phy.type == BWN_PHYTYPE_A) ? 120 : 250;
5017 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_PRETBTT, pretbtt);
5018 BWN_WRITE_2(mac, BWN_TSF_CFP_PRETBTT, pretbtt);
5024 struct bwn_mac *mac = arg;
5025 struct bwn_softc *sc = mac->mac_sc;
5028 if (mac->mac_status < BWN_MAC_STATUS_STARTED ||
5029 (sc->sc_flags & BWN_FLAG_INVALID))
5034 reason = BWN_READ_4(mac, BWN_INTR_REASON);
5037 reason &= mac->mac_intr_mask;
5042 mac->mac_reason[0] = BWN_READ_4(mac, BWN_DMA0_REASON) & 0x0001dc00;
5043 mac->mac_reason[1] = BWN_READ_4(mac, BWN_DMA1_REASON) & 0x0000dc00;
5044 mac->mac_reason[2] = BWN_READ_4(mac, BWN_DMA2_REASON) & 0x0000dc00;
5045 mac->mac_reason[3] = BWN_READ_4(mac, BWN_DMA3_REASON) & 0x0001dc00;
5046 mac->mac_reason[4] = BWN_READ_4(mac, BWN_DMA4_REASON) & 0x0000dc00;
5047 BWN_WRITE_4(mac, BWN_INTR_REASON, reason);
5048 BWN_WRITE_4(mac, BWN_DMA0_REASON, mac->mac_reason[0]);
5049 BWN_WRITE_4(mac, BWN_DMA1_REASON, mac->mac_reason[1]);
5050 BWN_WRITE_4(mac, BWN_DMA2_REASON, mac->mac_reason[2]);
5051 BWN_WRITE_4(mac, BWN_DMA3_REASON, mac->mac_reason[3]);
5052 BWN_WRITE_4(mac, BWN_DMA4_REASON, mac->mac_reason[4]);
5055 BWN_WRITE_4(mac, BWN_INTR_MASK, 0);
5057 mac->mac_reason_intr = reason;
5059 BWN_BARRIER(mac, 0, 0, BUS_SPACE_BARRIER_READ|BUS_SPACE_BARRIER_WRITE);
5061 taskqueue_enqueue(sc->sc_tq, &mac->mac_intrtask);
5068 struct bwn_mac *mac = arg;
5069 struct bwn_softc *sc = mac->mac_sc;
5074 if (mac->mac_status < BWN_MAC_STATUS_STARTED ||
5075 (sc->sc_flags & BWN_FLAG_INVALID)) {
5080 for (i = 0; i < N(mac->mac_reason); i++)
5081 merged |= mac->mac_reason[i];
5083 if (mac->mac_reason_intr & BWN_INTR_MAC_TXERR)
5084 device_printf(sc->sc_dev, "MAC trans error\n");
5086 if (mac->mac_reason_intr & BWN_INTR_PHY_TXERR) {
5088 mac->mac_phy.txerrors--;
5089 if (mac->mac_phy.txerrors == 0) {
5090 mac->mac_phy.txerrors = BWN_TXERROR_MAX;
5091 bwn_restart(mac, "PHY TX errors");
5097 device_printf(sc->sc_dev,
5099 mac->mac_reason[0], mac->mac_reason[1],
5100 mac->mac_reason[2], mac->mac_reason[3],
5101 mac->mac_reason[4], mac->mac_reason[5]);
5102 bwn_restart(mac, "DMA error");
5107 device_printf(sc->sc_dev,
5109 mac->mac_reason[0], mac->mac_reason[1],
5110 mac->mac_reason[2], mac->mac_reason[3],
5111 mac->mac_reason[4], mac->mac_reason[5]);
5115 if (mac->mac_reason_intr & BWN_INTR_UCODE_DEBUG)
5116 bwn_intr_ucode_debug(mac);
5117 if (mac->mac_reason_intr & BWN_INTR_TBTT_INDI)
5118 bwn_intr_tbtt_indication(mac);
5119 if (mac->mac_reason_intr & BWN_INTR_ATIM_END)
5120 bwn_intr_atim_end(mac);
5121 if (mac->mac_reason_intr & BWN_INTR_BEACON)
5122 bwn_intr_beacon(mac);
5123 if (mac->mac_reason_intr & BWN_INTR_PMQ)
5124 bwn_intr_pmq(mac);
5125 if (mac->mac_reason_intr & BWN_INTR_NOISESAMPLE_OK)
5126 bwn_intr_noise(mac);
5128 if (mac->mac_flags & BWN_MAC_FLAG_DMA) {
5129 if (mac->mac_reason[0] & BWN_DMAINTR_RX_DONE) {
5130 bwn_dma_rx(mac->mac_method.dma.rx);
5134 rx = bwn_pio_rx(&mac->mac_method.pio.rx);
5136 KASSERT(!(mac->mac_reason[1] & BWN_DMAINTR_RX_DONE), ("%s", __func__));
5137 KASSERT(!(mac->mac_reason[2] & BWN_DMAINTR_RX_DONE), ("%s", __func__));
5138 KASSERT(!(mac->mac_reason[3] & BWN_DMAINTR_RX_DONE), ("%s", __func__));
5139 KASSERT(!(mac->mac_reason[4] & BWN_DMAINTR_RX_DONE), ("%s", __func__));
5140 KASSERT(!(mac->mac_reason[5] & BWN_DMAINTR_RX_DONE), ("%s", __func__));
5142 if (mac->mac_reason_intr & BWN_INTR_TX_OK) {
5143 bwn_intr_txeof(mac);
5147 BWN_WRITE_4(mac, BWN_INTR_MASK, mac->mac_intr_mask);
5149 if (sc->sc_blink_led != NULL && sc->sc_led_blink) {
5153 if (sc->sc_rx_rate > sc->sc_tx_rate)
5166 bwn_led_event(mac, evt);
5169 if (mbufq_first(&sc->sc_snd) != NULL)
5172 BWN_BARRIER(mac, 0, 0, BUS_SPACE_BARRIER_READ|BUS_SPACE_BARRIER_WRITE);
5178 bwn_restart(struct bwn_mac *mac, const char *msg)
5180 struct bwn_softc *sc = mac->mac_sc;
5181 struct ieee80211com *ic = &sc->sc_ic;
5183 if (mac->mac_status < BWN_MAC_STATUS_INITED)
5186 device_printf(sc->sc_dev, "HW reset: %s\n", msg);
5187 ieee80211_runtask(ic, &mac->mac_hwreset);
5191 bwn_intr_ucode_debug(struct bwn_mac *mac)
5193 struct bwn_softc *sc = mac->mac_sc;
5196 if (mac->mac_fw.opensource == 0)
5199 reason = bwn_shm_read_2(mac, BWN_SCRATCH, BWN_DEBUGINTR_REASON_REG);
5202 bwn_handle_fwpanic(mac);
5205 device_printf(sc->sc_dev, "BWN_DEBUGINTR_DUMP_SHM\n");
5208 device_printf(sc->sc_dev, "BWN_DEBUGINTR_DUMP_REGS\n");
5211 device_printf(sc->sc_dev, "BWN_DEBUGINTR_MARKER\n");
5214 device_printf(sc->sc_dev,
5218 bwn_shm_write_2(mac, BWN_SCRATCH, BWN_DEBUGINTR_REASON_REG,
5223 bwn_intr_tbtt_indication(struct bwn_mac *mac)
5225 struct bwn_softc *sc = mac->mac_sc;
5226 struct ieee80211com *ic = &sc->sc_ic;
5228 if (ic->ic_opmode != IEEE80211_M_HOSTAP)
5229 bwn_psctl(mac, 0);
5230 if (ic->ic_opmode == IEEE80211_M_IBSS)
5231 mac->mac_flags |= BWN_MAC_FLAG_DFQVALID;
5235 bwn_intr_atim_end(struct bwn_mac *mac)
5238 if (mac->mac_flags & BWN_MAC_FLAG_DFQVALID) {
5239 BWN_WRITE_4(mac, BWN_MACCMD,
5240 BWN_READ_4(mac, BWN_MACCMD) | BWN_MACCMD_DFQ_VALID);
5241 mac->mac_flags &= ~BWN_MAC_FLAG_DFQVALID;
5246 bwn_intr_beacon(struct bwn_mac *mac)
5248 struct bwn_softc *sc = mac->mac_sc;
5249 struct ieee80211com *ic = &sc->sc_ic;
5252 if (ic->ic_opmode == IEEE80211_M_HOSTAP ||
5253 ic->ic_opmode == IEEE80211_M_MBSS)
5256 mac->mac_intr_mask &= ~BWN_INTR_BEACON;
5258 cmd = BWN_READ_4(mac, BWN_MACCMD);
5263 BWN_WRITE_4(mac, BWN_INTR_REASON, BWN_INTR_BEACON);
5264 mac->mac_intr_mask |= BWN_INTR_BEACON;
5268 if (sc->sc_flags & BWN_FLAG_NEED_BEACON_TP) {
5269 sc->sc_flags &= ~BWN_FLAG_NEED_BEACON_TP;
5270 bwn_load_beacon0(mac);
5271 bwn_load_beacon1(mac);
5272 cmd = BWN_READ_4(mac, BWN_MACCMD);
5274 BWN_WRITE_4(mac, BWN_MACCMD, cmd);
5277 bwn_load_beacon0(mac);
5278 cmd = BWN_READ_4(mac, BWN_MACCMD);
5280 BWN_WRITE_4(mac, BWN_MACCMD, cmd);
5282 bwn_load_beacon1(mac);
5283 cmd = BWN_READ_4(mac, BWN_MACCMD);
5285 BWN_WRITE_4(mac, BWN_MACCMD, cmd);
5291 bwn_intr_pmq(struct bwn_mac *mac)
5296 tmp = BWN_READ_4(mac, BWN_PS_STATUS);
5300 BWN_WRITE_2(mac, BWN_PS_STATUS, 0x0002);
5304 bwn_intr_noise(struct bwn_mac *mac)
5306 struct bwn_phy_g *pg = &mac->mac_phy.phy_g;
5312 if (mac->mac_phy.type != BWN_PHYTYPE_G)
5315 KASSERT(mac->mac_noise.noi_running, ("%s: fail", __func__));
5316 *((uint32_t *)noise) = htole32(bwn_jssi_read(mac));
5321 KASSERT(mac->mac_noise.noi_nsamples < 8,
5323 i = mac->mac_noise.noi_nsamples;
5324 noise[0] = MIN(MAX(noise[0], 0), N(pg->pg_nrssi_lt) - 1);
5325 noise[1] = MIN(MAX(noise[1], 0), N(pg->pg_nrssi_lt) - 1);
5326 noise[2] = MIN(MAX(noise[2], 0), N(pg->pg_nrssi_lt) - 1);
5327 noise[3] = MIN(MAX(noise[3], 0), N(pg->pg_nrssi_lt) - 1);
5328 mac->mac_noise.noi_samples[i][0] = pg->pg_nrssi_lt[noise[0]];
5329 mac->mac_noise.noi_samples[i][1] = pg->pg_nrssi_lt[noise[1]];
5330 mac->mac_noise.noi_samples[i][2] = pg->pg_nrssi_lt[noise[2]];
5331 mac->mac_noise.noi_samples[i][3] = pg->pg_nrssi_lt[noise[3]];
5332 mac->mac_noise.noi_nsamples++;
5333 if (mac->mac_noise.noi_nsamples == 8) {
5337 average += mac->mac_noise.noi_samples[i][j];
5340 tmp = (bwn_shm_read_2(mac, BWN_SHARED, 0x40c) / 128) & 0x1f;
5344 average -= 25;
5345 average -= (tmp == 8) ? 72 : 48;
5347 mac->mac_stats.link_noise = average;
5348 mac->mac_noise.noi_running = 0;
5352 bwn_noise_gensample(mac);
5358 struct bwn_mac *mac = prq->prq_mac;
5359 struct bwn_softc *sc = mac->mac_sc;
5364 if (mac->mac_status < BWN_MAC_STATUS_STARTED)
5372 device_printf(sc->sc_dev, "too many RX frames in PIO mode\n");
5381 KASSERT(!dr->dr_tx, ("%s:%d: fail", __func__, __LINE__));
5382 curslot = dr->get_curslot(dr);
5383 KASSERT(curslot >= 0 && curslot < dr->dr_numslots,
5386 slot = dr->dr_curslot;
5390 bus_dmamap_sync(dr->dr_ring_dtag, dr->dr_ring_dmap,
5393 dr->set_curslot(dr, slot);
5394 dr->dr_curslot = slot;
5398 bwn_intr_txeof(struct bwn_mac *mac)
5404 BWN_ASSERT_LOCKED(mac->mac_sc);
5407 stat0 = BWN_READ_4(mac, BWN_XMITSTAT_0);
5410 stat1 = BWN_READ_4(mac, BWN_XMITSTAT_1);
5412 DPRINTF(mac->mac_sc, BWN_DEBUG_XMIT,
5430 DPRINTF(mac->mac_sc, BWN_DEBUG_XMIT,
5445 bwn_handle_txeof(mac, &stat);
5452 struct bwn_mac *mac = arg;
5453 struct bwn_softc *sc = mac->mac_sc;
5459 prev_status = mac->mac_status;
5461 bwn_core_stop(mac);
5463 bwn_core_exit(mac);
5466 error = bwn_core_init(mac);
5471 bwn_core_start(mac);
5474 device_printf(sc->sc_dev, "%s: failed (%d)\n", __func__, error);
5475 sc->sc_curmac = NULL;
5481 bwn_handle_fwpanic(struct bwn_mac *mac)
5483 struct bwn_softc *sc = mac->mac_sc;
5486 reason = bwn_shm_read_2(mac, BWN_SCRATCH, BWN_FWPANIC_REASON_REG);
5487 device_printf(sc->sc_dev,"fw panic (%u)\n", reason);
5490 bwn_restart(mac, "ucode panic");
5494 bwn_load_beacon0(struct bwn_mac *mac)
5501 bwn_load_beacon1(struct bwn_mac *mac)
5508 bwn_jssi_read(struct bwn_mac *mac)
5512 val = bwn_shm_read_2(mac, BWN_SHARED, 0x08a);
5514 val |= bwn_shm_read_2(mac, BWN_SHARED, 0x088);
5520 bwn_noise_gensample(struct bwn_mac *mac)
5524 bwn_shm_write_2(mac, BWN_SHARED, 0x088, (jssi & 0x0000ffff));
5525 bwn_shm_write_2(mac, BWN_SHARED, 0x08a, (jssi & 0xffff0000) >> 16);
5526 BWN_WRITE_4(mac, BWN_MACCMD,
5527 BWN_READ_4(mac, BWN_MACCMD) | BWN_MACCMD_BGNOISE);
5533 BWN_ASSERT_LOCKED(dr->dr_mac->mac_sc);
5535 return (dr->dr_numslots - dr->dr_usedslot);
5541 BWN_ASSERT_LOCKED(dr->dr_mac->mac_sc);
5543 KASSERT(slot >= -1 && slot <= dr->dr_numslots - 1,
5545 if (slot == dr->dr_numslots - 1)
5553 struct bwn_mac *mac = dr->dr_mac;
5554 struct bwn_softc *sc = mac->mac_sc;
5555 struct bwn_dma *dma = &mac->mac_method.dma;
5565 dr->getdesc(dr, *slot, &desc, &meta);
5567 bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap, BUS_DMASYNC_POSTREAD);
5568 m = meta->mt_m;
5571 counter_u64_add(sc->sc_ic.ic_ierrors, 1);
5576 len = le16toh(rxhdr->frame_len);
5578 counter_u64_add(sc->sc_ic.ic_ierrors, 1);
5582 device_printf(sc->sc_dev, "redzone error.\n");
5584 bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap,
5588 if (len > dr->dr_rx_bufsize) {
5591 dr->getdesc(dr, *slot, &desc, &meta);
5592 bwn_dma_set_redzone(dr, meta->mt_m);
5593 bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap,
5597 tmp -= dr->dr_rx_bufsize;
5601 device_printf(sc->sc_dev, "too small buffer "
5603 len, dr->dr_rx_bufsize, cnt);
5607 switch (mac->mac_fw.fw_hdr_format) {
5610 macstat = le32toh(rxhdr->ps4.r351.mac_status);
5613 macstat = le32toh(rxhdr->ps4.r598.mac_status);
5618 if (!(mac->mac_sc->sc_filters & BWN_MACCTL_PASS_BADFCS)) {
5619 device_printf(sc->sc_dev, "RX drop\n");
5624 m->m_len = m->m_pkthdr.len = len + dr->dr_frameoffset;
5625 m_adj(m, dr->dr_frameoffset);
5627 bwn_rxeof(dr->dr_mac, m, rxhdr);
5631 bwn_handle_txeof(struct bwn_mac *mac, const struct bwn_txstatus *status)
5633 struct bwn_softc *sc = mac->mac_sc;
5634 struct bwn_stats *stats = &mac->mac_stats;
5636 BWN_ASSERT_LOCKED(mac->mac_sc);
5638 if (status->im)
5639 device_printf(sc->sc_dev, "TODO: STATUS IM\n");
5640 if (status->ampdu)
5641 device_printf(sc->sc_dev, "TODO: STATUS AMPDU\n");
5642 if (status->rtscnt) {
5643 if (status->rtscnt == 0xf)
5644 stats->rtsfail++;
5646 stats->rts++;
5649 if (mac->mac_flags & BWN_MAC_FLAG_DMA) {
5650 bwn_dma_handle_txeof(mac, status);
5652 bwn_pio_handle_txeof(mac, status);
5655 bwn_phy_txpower_check(mac, 0);
5661 struct bwn_mac *mac = prq->prq_mac;
5662 struct bwn_softc *sc = mac->mac_sc;
5673 if (prq->prq_rev >= 8) {
5698 device_printf(sc->sc_dev, "%s: timed out\n", __func__);
5701 if (prq->prq_rev >= 8) {
5702 bus_read_multi_4(sc->sc_mem_res,
5703 prq->prq_base + BWN_PIO8_RXDATA, (void *)&rxhdr,
5706 bus_read_multi_2(sc->sc_mem_res,
5707 prq->prq_base + BWN_PIO_RXDATA, (void *)&rxhdr,
5712 device_printf(sc->sc_dev, "%s: len is too big\n", __func__);
5716 device_printf(sc->sc_dev, "%s: len is 0\n", __func__);
5720 switch (mac->mac_fw.fw_hdr_format) {
5731 if (!(mac->mac_sc->sc_filters & BWN_MACCTL_PASS_BADFCS)) {
5732 device_printf(sc->sc_dev, "%s: FCS error", __func__);
5742 device_printf(sc->sc_dev, "%s: out of memory", __func__);
5746 if (prq->prq_rev >= 8) {
5747 bus_read_multi_4(sc->sc_mem_res,
5748 prq->prq_base + BWN_PIO8_RXDATA, (void *)mp, (totlen & ~3));
5751 data = &(mp[totlen - 1]);
5755 data--;
5758 data--;
5764 bus_read_multi_2(sc->sc_mem_res,
5765 prq->prq_base + BWN_PIO_RXDATA, (void *)mp, (totlen & ~1));
5768 mp[totlen - 1] = v16;
5772 m->m_len = m->m_pkthdr.len = totlen;
5774 bwn_rxeof(prq->prq_mac, m, &rxhdr);
5778 if (prq->prq_rev >= 8)
5790 struct bwn_mac *mac = dr->dr_mac;
5791 struct bwn_dma *dma = &mac->mac_method.dma;
5804 * - Clear RX buffer's header.
5805 * - Restore RX descriptor settings.
5812 m->m_len = m->m_pkthdr.len = MCLBYTES;
5819 error = bus_dmamap_load_mbuf(dma->rxbuf_dtag, dr->dr_spare_dmap, m,
5834 bus_dmamap_unload(dma->rxbuf_dtag, meta->mt_dmap);
5835 meta->mt_m = m;
5836 meta->mt_paddr = paddr;
5841 map = meta->mt_dmap;
5842 meta->mt_dmap = dr->dr_spare_dmap;
5843 dr->dr_spare_dmap = map;
5849 hdr = mtod(meta->mt_m, struct bwn_rxhdr4 *);
5851 bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap,
5857 dr->setdesc(dr, desc, meta->mt_paddr, meta->mt_m->m_len -
5869 *((bus_addr_t *)arg) = seg->ds_addr;
5914 bwn_rx_rssi_calc(struct bwn_mac *mac, uint8_t in_rssi,
5917 struct bwn_phy *phy = &mac->mac_phy;
5918 struct bwn_phy_g *gphy = &phy->phy_g;
5921 switch (phy->rf_ver) {
5926 tmp -= 256;
5931 tmp -= 3;
5933 if (mac->mac_sc->sc_board_info.board_flags
5937 tmp = gphy->pg_nrssi_lt[in_rssi];
5938 tmp = (31 - tmp) * -131 / 128 - 57;
5941 tmp = (31 - tmp) * -149 / 128 - 68;
5943 if (phy->type == BWN_PHYTYPE_G && adjust_2050)
5949 tmp = in_rssi - 256;
5955 tmp = (tmp - 11) * 103 / 64;
5957 tmp -= 109;
5959 tmp -= 83;
5966 bwn_rxeof(struct bwn_mac *mac, struct mbuf *m, const void *_rxhdr)
5970 struct bwn_softc *sc = mac->mac_sc;
5973 struct ieee80211com *ic = &sc->sc_ic;
5981 phystat0 = le16toh(rxhdr->phy_status0);
5984 * XXX Note: phy_status3 doesn't exist for HT-PHY; it's only
5985 * used for LP-PHY.
5987 phystat3 = le16toh(rxhdr->ps3.lp.phy_status3);
5989 switch (mac->mac_fw.fw_hdr_format) {
5992 macstat = le32toh(rxhdr->ps4.r351.mac_status);
5993 chanstat = le16toh(rxhdr->ps4.r351.channel);
5996 macstat = le32toh(rxhdr->ps4.r598.mac_status);
5997 chanstat = le16toh(rxhdr->ps4.r598.channel);
6004 device_printf(sc->sc_dev, "TODO RX: RX_FLAG_FAILED_FCS_CRC\n");
6006 device_printf(sc->sc_dev, "TODO RX: RX_FLAG_FAILED_PLCP_CRC\n");
6011 if (m->m_pkthdr.len < (sizeof(struct bwn_plcp6) + padding)) {
6012 device_printf(sc->sc_dev, "frame too short (length=%d)\n",
6013 m->m_pkthdr.len);
6018 if (m->m_pkthdr.len < IEEE80211_MIN_LEN) {
6019 device_printf(sc->sc_dev, "frame too short (length=%d)\n",
6020 m->m_pkthdr.len);
6028 BWN_ISOLDFMT(mac),
6033 rate = bwn_plcp_get_ofdmrate(mac, plcp,
6036 rate = bwn_plcp_get_cckrate(mac, plcp);
6037 if (rate == -1) {
6038 if (!(mac->mac_sc->sc_filters & BWN_MACCTL_PASS_BADPLCP))
6041 sc->sc_rx_rate = bwn_hwrate2ieeerate(rate);
6049 rssi = bwn_rx_rssi_calc(mac, rxhdr->phy.abg.rssi,
6056 if (rxhdr->phy.n.power0 == 16 || rxhdr->phy.n.power0 == 32)
6057 rssi = max(rxhdr->phy.n.power1, rxhdr->ps2.n.power2);
6059 rssi = max(rxhdr->phy.n.power0, rxhdr->phy.n.power1);
6061 DPRINTF(mac->mac_sc, BWN_DEBUG_RECV,
6064 rxhdr->phy.n.power0,
6065 rxhdr->phy.n.power1,
6066 rxhdr->ps2.n.power2);
6077 noise = mac->mac_stats.link_noise;
6078 rssi = rssi - noise;
6082 bwn_rx_radiotap(mac, m, rxhdr, plcp, rate, rssi, noise);
6083 m_adj(m, -IEEE80211_CRC_LEN);
6097 device_printf(sc->sc_dev, "%s: dropped\n", __func__);
6114 if (status->ack) {
6116 retrycnt = status->framecnt - 1;
6119 retrycnt = status->framecnt;
6128 bwn_dma_handle_txeof(struct bwn_mac *mac,
6131 struct bwn_dma *dma = &mac->mac_method.dma;
6135 struct bwn_softc *sc = mac->mac_sc;
6140 dr = bwn_dma_parse_cookie(mac, status, status->cookie, &slot);
6142 device_printf(sc->sc_dev, "failed to parse cookie\n");
6145 KASSERT(dr->dr_tx, ("%s:%d: fail", __func__, __LINE__));
6148 KASSERT(slot >= 0 && slot < dr->dr_numslots,
6150 dr->getdesc(dr, slot, &desc, &meta);
6152 if (meta->mt_txtype == BWN_DMADESC_METATYPE_HEADER)
6153 bus_dmamap_unload(dr->dr_txring_dtag, meta->mt_dmap);
6154 else if (meta->mt_txtype == BWN_DMADESC_METATYPE_BODY)
6155 bus_dmamap_unload(dma->txbuf_dtag, meta->mt_dmap);
6157 if (meta->mt_islast) {
6158 KASSERT(meta->mt_m != NULL,
6161 bwn_ratectl_tx_complete(meta->mt_ni, status);
6162 ieee80211_tx_complete(meta->mt_ni, meta->mt_m, 0);
6163 meta->mt_ni = NULL;
6164 meta->mt_m = NULL;
6166 KASSERT(meta->mt_m == NULL,
6169 dr->dr_usedslot--;
6170 if (meta->mt_islast)
6174 sc->sc_watchdog_timer = 0;
6175 if (dr->dr_stop) {
6178 dr->dr_stop = 0;
6183 bwn_pio_handle_txeof(struct bwn_mac *mac,
6188 struct bwn_softc *sc = mac->mac_sc;
6192 tq = bwn_pio_parse_cookie(mac, status->cookie, &tp);
6196 tq->tq_used -= roundup(tp->tp_m->m_pkthdr.len + BWN_HDRSIZE(mac), 4);
6197 tq->tq_free++;
6199 if (tp->tp_ni != NULL) {
6204 bwn_ratectl_tx_complete(tp->tp_ni, status);
6206 ieee80211_tx_complete(tp->tp_ni, tp->tp_m, 0);
6207 tp->tp_ni = NULL;
6208 tp->tp_m = NULL;
6209 TAILQ_INSERT_TAIL(&tq->tq_pktlist, tp, tp_list);
6211 sc->sc_watchdog_timer = 0;
6215 bwn_phy_txpower_check(struct bwn_mac *mac, uint32_t flags)
6217 struct bwn_softc *sc = mac->mac_sc;
6218 struct bwn_phy *phy = &mac->mac_phy;
6219 struct ieee80211com *ic = &sc->sc_ic;
6225 if (!(flags & BWN_TXPWR_IGNORE_TIME) && ieee80211_time_before(now, phy->nexttime))
6227 phy->nexttime = now + 2 * 1000;
6229 if (sc->sc_board_info.board_vendor == PCI_VENDOR_BROADCOM &&
6230 sc->sc_board_info.board_type == BHND_BOARD_BU4306)
6233 if (phy->recalc_txpwr != NULL) {
6234 result = phy->recalc_txpwr(mac,
6240 KASSERT(phy->set_txpwr != NULL, ("%s: fail", __func__));
6242 ieee80211_runtask(ic, &mac->mac_txpower);
6250 return (BWN_READ_2(prq->prq_mac, prq->prq_base + offset));
6257 return (BWN_READ_4(prq->prq_mac, prq->prq_base + offset));
6264 BWN_WRITE_2(prq->prq_mac, prq->prq_base + offset, value);
6271 BWN_WRITE_4(prq->prq_mac, prq->prq_base + offset, value);
6279 /* OFDM rates (cf IEEE Std 802.11a-1999, pp. 14 Table 80) */
6296 /* CCK rates (NB: not IEEE std, device-specific) */
6307 device_printf(sc->sc_dev, "unsupported rate %d\n", rate);
6312 bwn_set_txhdr_phyctl1(struct bwn_mac *mac, uint8_t bitrate)
6314 struct bwn_phy *phy = &mac->mac_phy;
6318 /* XXX TODO: this is for LP phy, what about N-PHY, etc? */
6321 if (BWN_ISCCKRATE(bitrate) && phy->type != BWN_PHYTYPE_LP) {
6326 /* XXX TODO: table-ize, for MCS transmit */
6383 bwn_set_txhdr(struct bwn_mac *mac, struct ieee80211_node *ni,
6386 const struct bwn_phy *phy = &mac->mac_phy;
6387 struct bwn_softc *sc = mac->mac_sc;
6390 const struct ieee80211_txparam *tp = ni->ni_txparms;
6391 struct ieee80211vap *vap = ni->ni_vap;
6392 struct ieee80211com *ic = &sc->sc_ic;
6405 type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
6406 ismcast = IEEE80211_IS_MULTICAST(wh->i_addr1);
6407 isshort = (ic->ic_flags & IEEE80211_F_SHPREAMBLE) != 0;
6409 if ((phy->type == BWN_PHYTYPE_N) || (phy->type == BWN_PHYTYPE_LP)
6410 || (phy->type == BWN_PHYTYPE_HT))
6416 if (type != IEEE80211_FC0_TYPE_DATA || (m->m_flags & M_EAPOL))
6417 rate = rate_fb = tp->mgmtrate;
6419 rate = rate_fb = tp->mcastrate;
6420 else if (tp->ucastrate != IEEE80211_FIXED_RATE_NONE)
6421 rate = rate_fb = tp->ucastrate;
6424 rate = ni->ni_txrate;
6427 rate_fb = ni->ni_rates.rs_rates[rix - 1] &
6433 sc->sc_tx_rate = rate;
6439 txhdr->phyrate = (BWN_ISOFDMRATE(rate)) ? bwn_plcp_getofdm(rate) :
6441 bcopy(wh->i_fc, txhdr->macfc, sizeof(txhdr->macfc));
6442 bcopy(wh->i_addr1, txhdr->addr1, IEEE80211_ADDR_LEN);
6446 (*(u_int16_t *)wh->i_dur & htole16(0x8000)) ||
6447 (*(u_int16_t *)wh->i_dur == htole16(0)))
6448 txhdr->dur_fb = *(u_int16_t *)wh->i_dur;
6450 txhdr->dur_fb = ieee80211_compute_duration(ic->ic_rt,
6451 m->m_pkthdr.len, rate, isshort);
6455 switch (mac->mac_fw.fw_hdr_format) {
6457 bwn_plcp_genhdr((struct bwn_plcp4 *)(&txhdr->body.r351.plcp),
6458 m->m_pkthdr.len + IEEE80211_CRC_LEN, rate);
6461 bwn_plcp_genhdr((struct bwn_plcp4 *)(&txhdr->body.r410.plcp),
6462 m->m_pkthdr.len + IEEE80211_CRC_LEN, rate);
6465 bwn_plcp_genhdr((struct bwn_plcp4 *)(&txhdr->body.r598.plcp),
6466 m->m_pkthdr.len + IEEE80211_CRC_LEN, rate);
6470 bwn_plcp_genhdr((struct bwn_plcp4 *)(&txhdr->plcp_fb),
6471 m->m_pkthdr.len + IEEE80211_CRC_LEN, rate_fb);
6473 txhdr->eftypes |= (BWN_ISOFDMRATE(rate_fb)) ? BWN_TX_EFT_FB_OFDM :
6475 txhdr->chan = phy->chan;
6483 if (! phy->gmode)
6488 switch (bwn_antenna_sanitize(mac, 0)) {
6512 if (!IEEE80211_IS_MULTICAST(wh->i_addr1) &&
6513 m->m_pkthdr.len + IEEE80211_CRC_LEN > vap->iv_rtsthreshold)
6516 if ((ic->ic_flags & IEEE80211_F_USEPROT) &&
6517 ic->ic_protmode != IEEE80211_PROT_NONE) {
6519 if (phy->gmode)
6526 mprot = ieee80211_alloc_prot(ni, m, rate, ic->ic_protmode);
6528 if_inc_counter(vap->iv_ifp, IFCOUNTER_OERRORS, 1);
6529 device_printf(sc->sc_dev,
6531 ic->ic_protmode);
6535 switch (mac->mac_fw.fw_hdr_format) {
6537 prot_ptr = txhdr->body.r351.rts_frame;
6540 prot_ptr = txhdr->body.r410.rts_frame;
6543 prot_ptr = txhdr->body.r598.rts_frame;
6547 bcopy(mtod(mprot, uint8_t *), prot_ptr, mprot->m_pkthdr.len);
6550 if (ic->ic_protmode == IEEE80211_PROT_CTSONLY) {
6559 switch (mac->mac_fw.fw_hdr_format) {
6562 &txhdr->body.r351.rts_plcp, len, rts_rate);
6566 &txhdr->body.r410.rts_plcp, len, rts_rate);
6570 &txhdr->body.r598.rts_plcp, len, rts_rate);
6574 bwn_plcp_genhdr((struct bwn_plcp4 *)&txhdr->rts_plcp_fb, len,
6577 switch (mac->mac_fw.fw_hdr_format) {
6580 &txhdr->body.r351.rts_frame;
6584 &txhdr->body.r410.rts_frame;
6588 &txhdr->body.r598.rts_frame;
6592 txhdr->rts_dur_fb = *(u_int16_t *)protwh->i_dur;
6595 txhdr->eftypes |= BWN_TX_EFT_RTS_OFDM;
6596 txhdr->phyrate_rts = bwn_plcp_getofdm(rts_rate);
6598 txhdr->eftypes |= BWN_TX_EFT_RTS_CCK;
6599 txhdr->phyrate_rts = bwn_plcp_getcck(rts_rate);
6601 txhdr->eftypes |= (BWN_ISOFDMRATE(rts_rate_fb)) ?
6605 txhdr->phyctl_1rts = htole16(bwn_set_txhdr_phyctl1(mac, rts_rate));
6606 txhdr->phyctl_1rtsfb = htole16(bwn_set_txhdr_phyctl1(mac, rts_rate_fb));
6611 txhdr->phyctl_1 = htole16(bwn_set_txhdr_phyctl1(mac, rate));
6612 txhdr->phyctl_1fb = htole16(bwn_set_txhdr_phyctl1(mac, rate_fb));
6615 switch (mac->mac_fw.fw_hdr_format) {
6617 txhdr->body.r351.cookie = htole16(cookie);
6620 txhdr->body.r410.cookie = htole16(cookie);
6623 txhdr->body.r598.cookie = htole16(cookie);
6627 txhdr->macctl = htole32(macctl);
6628 txhdr->phyctl = htole16(phyctl);
6634 sc->sc_tx_th.wt_flags = 0;
6635 if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED)
6636 sc->sc_tx_th.wt_flags |= IEEE80211_RADIOTAP_F_WEP;
6640 sc->sc_tx_th.wt_flags |= IEEE80211_RADIOTAP_F_SHORTPRE;
6641 sc->sc_tx_th.wt_rate = rate;
6654 uint8_t *raw = plcp->o.raw;
6661 plcp->o.data = htole32(d);
6673 plcp->o.data |= htole32(plen << 16);
6679 bwn_antenna_sanitize(struct bwn_mac *mac, uint8_t n)
6681 struct bwn_softc *sc = mac->mac_sc;
6686 if (mac->mac_phy.gmode)
6687 mask = sc->sc_ant2g;
6689 mask = sc->sc_ant5g;
6690 if (!(mask & (1 << (n - 1))))
6737 bwn_pio_write_multi_4(struct bwn_mac *mac, struct bwn_pio_txqueue *tq,
6740 struct bwn_softc *sc = mac->mac_sc;
6746 bwn_pio_write_4(mac, tq, BWN_PIO8_TXCTL, ctl);
6748 bus_write_multi_4(sc->sc_mem_res, tq->tq_base + BWN_PIO8_TXDATA,
6753 data = &(data[len - 1]);
6758 data--;
6762 data--;
6766 bwn_pio_write_4(mac, tq, BWN_PIO8_TXCTL, ctl);
6767 bwn_pio_write_4(mac, tq, BWN_PIO8_TXDATA, value);
6774 bwn_pio_write_4(struct bwn_mac *mac, struct bwn_pio_txqueue *tq,
6778 BWN_WRITE_4(mac, tq->tq_base + offset, value);
6782 bwn_pio_write_multi_2(struct bwn_mac *mac, struct bwn_pio_txqueue *tq,
6785 struct bwn_softc *sc = mac->mac_sc;
6789 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl);
6791 bus_write_multi_2(sc->sc_mem_res, tq->tq_base + BWN_PIO_TXDATA,
6795 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl);
6796 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXDATA, data[len - 1]);
6803 bwn_pio_write_mbuf_2(struct bwn_mac *mac, struct bwn_pio_txqueue *tq,
6812 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl);
6814 for (; m != NULL; m = m->m_next) {
6816 for (i = 0; i < m->m_len; i++) {
6821 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXDATA, data);
6826 if (m0->m_pkthdr.len % 2) {
6828 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl);
6829 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXDATA, data);
6836 bwn_set_slot_time(struct bwn_mac *mac, uint16_t time)
6840 if (mac->mac_phy.type != BWN_PHYTYPE_G)
6843 BWN_WRITE_2(mac, 0x684, 510 + time);
6846 bwn_shm_write_2(mac, BWN_SHARED, 0x0010, time);
6851 bwn_dma_select(struct bwn_mac *mac, uint8_t prio)
6854 if ((mac->mac_flags & BWN_MAC_FLAG_WME) == 0)
6855 return (mac->mac_method.dma.wme[WME_AC_BE]);
6859 return (mac->mac_method.dma.wme[WME_AC_VO]);
6861 return (mac->mac_method.dma.wme[WME_AC_VI]);
6863 return (mac->mac_method.dma.wme[WME_AC_BE]);
6865 return (mac->mac_method.dma.wme[WME_AC_BK]);
6876 BWN_ASSERT_LOCKED(dr->dr_mac->mac_sc);
6878 KASSERT(dr->dr_tx, ("%s:%d: fail", __func__, __LINE__));
6879 KASSERT(!(dr->dr_stop), ("%s:%d: fail", __func__, __LINE__));
6882 slot = bwn_dma_nextslot(dr, dr->dr_curslot);
6884 dr->dr_curslot = slot;
6885 dr->dr_usedslot++;
6891 bwn_pio_parse_cookie(struct bwn_mac *mac, uint16_t cookie,
6894 struct bwn_pio *pio = &mac->mac_method.pio;
6900 tq = &pio->wme[WME_AC_BK];
6903 tq = &pio->wme[WME_AC_BE];
6906 tq = &pio->wme[WME_AC_VI];
6909 tq = &pio->wme[WME_AC_VO];
6912 tq = &pio->mcast;
6919 KASSERT(index < N(tq->tq_pkts), ("%s:%d: fail", __func__, __LINE__));
6920 if (index >= N(tq->tq_pkts))
6922 *pack = &tq->tq_pkts[index];
6930 struct bwn_mac *mac = arg;
6933 if (mac == NULL)
6936 sc = mac->mac_sc;
6939 if (mac->mac_status >= BWN_MAC_STATUS_STARTED &&
6940 mac->mac_phy.set_txpwr != NULL)
6941 mac->mac_phy.set_txpwr(mac);
6946 bwn_task_15s(struct bwn_mac *mac)
6950 if (mac->mac_fw.opensource) {
6951 reg = bwn_shm_read_2(mac, BWN_SCRATCH, BWN_WATCHDOG_REG);
6953 bwn_restart(mac, "fw watchdog");
6956 bwn_shm_write_2(mac, BWN_SCRATCH, BWN_WATCHDOG_REG, 1);
6958 if (mac->mac_phy.task_15s)
6959 mac->mac_phy.task_15s(mac);
6961 mac->mac_phy.txerrors = BWN_TXERROR_MAX;
6965 bwn_task_30s(struct bwn_mac *mac)
6968 if (mac->mac_phy.type != BWN_PHYTYPE_G || mac->mac_noise.noi_running)
6970 mac->mac_noise.noi_running = 1;
6971 mac->mac_noise.noi_nsamples = 0;
6973 bwn_noise_gensample(mac);
6977 bwn_task_60s(struct bwn_mac *mac)
6980 if (mac->mac_phy.task_60s)
6981 mac->mac_phy.task_60s(mac);
6982 bwn_phy_txpower_check(mac, BWN_TXPWR_IGNORE_TIME);
6988 struct bwn_mac *mac = arg;
6989 struct bwn_softc *sc = mac->mac_sc;
6992 if (mac->mac_status != BWN_MAC_STATUS_STARTED)
6995 if (mac->mac_task_state % 4 == 0)
6996 bwn_task_60s(mac);
6997 if (mac->mac_task_state % 2 == 0)
6998 bwn_task_30s(mac);
6999 bwn_task_15s(mac);
7001 mac->mac_task_state++;
7002 callout_reset(&sc->sc_task_ch, hz * 15, bwn_tasks, mac);
7006 bwn_plcp_get_ofdmrate(struct bwn_mac *mac, struct bwn_plcp6 *plcp, uint8_t a)
7008 struct bwn_softc *sc = mac->mac_sc;
7012 switch (plcp->o.raw[0] & 0xf) {
7030 device_printf(sc->sc_dev, "incorrect OFDM rate %d\n",
7031 plcp->o.raw[0] & 0xf);
7032 return (-1);
7036 bwn_plcp_get_cckrate(struct bwn_mac *mac, struct bwn_plcp6 *plcp)
7038 struct bwn_softc *sc = mac->mac_sc;
7040 switch (plcp->o.raw[0]) {
7050 device_printf(sc->sc_dev, "incorrect CCK rate %d\n", plcp->o.raw[0]);
7051 return (-1);
7055 bwn_rx_radiotap(struct bwn_mac *mac, struct mbuf *m,
7059 struct bwn_softc *sc = mac->mac_sc;
7065 if (htole16(rxhdr->phy_status0) & BWN_RX_PHYST0_SHORTPRMBL)
7066 sc->sc_rx_th.wr_flags |= IEEE80211_RADIOTAP_F_SHORTPRE;
7069 if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED)
7070 sc->sc_rx_th.wr_flags |= IEEE80211_RADIOTAP_F_WEP;
7072 bwn_tsf_read(mac, &tsf);
7076 switch (mac->mac_fw.fw_hdr_format) {
7079 mt = le16toh(rxhdr->ps4.r351.mac_time);
7082 mt = le16toh(rxhdr->ps4.r598.mac_time);
7088 tsf -= 0x10000;
7090 sc->sc_rx_th.wr_tsf = tsf;
7091 sc->sc_rx_th.wr_rate = rate;
7092 sc->sc_rx_th.wr_antsignal = rssi;
7093 sc->sc_rx_th.wr_antnoise = noise;
7097 bwn_tsf_read(struct bwn_mac *mac, uint64_t *tsf)
7101 KASSERT(bhnd_get_hwrev(mac->mac_sc->sc_dev) >= 3,
7104 low = BWN_READ_4(mac, BWN_REV3PLUS_TSF_LOW);
7105 high = BWN_READ_4(mac, BWN_REV3PLUS_TSF_HIGH);
7112 bwn_dma_attach(struct bwn_mac *mac)
7123 dma = &mac->mac_method.dma;
7124 sc = mac->mac_sc;
7127 if (sc->sc_quirks & BWN_QUIRK_NODMA)
7130 KASSERT(bhnd_get_hwrev(sc->sc_dev) >= 5, ("%s: fail", __func__));
7134 switch (mac->mac_dmatype) {
7136 /* 32-bit engine without addrext support */
7140 /* We can address the full 32-bit device address space */
7145 /* 32-bit engine with addrext support */
7152 /* 64-bit engine with addrext support */
7159 device_printf(sc->sc_dev, "unsupported DMA address width: %d\n",
7160 mac->mac_dmatype);
7164 /* Fetch our device->host DMA translation and tag */
7165 error = bhnd_get_dma_translation(sc->sc_dev, addr_width, 0, &dmat,
7168 device_printf(sc->sc_dev, "error fetching DMA translation: "
7178 device_printf(sc->sc_dev, "bus addrext mask %#jx incompatible "
7191 mac->mac_flags |= BWN_MAC_FLAG_DMA;
7193 dma->addrext_shift = addrext_shift;
7194 dma->translation = dma_translation;
7196 dt = &dma->translation;
7199 lowaddr = MIN((dt->addr_mask | dt->addrext_mask), BUS_SPACE_MAXADDR);
7214 &dma->parent_dtag);
7216 device_printf(sc->sc_dev, "can't create parent DMA tag\n");
7223 error = bus_dma_tag_create(dma->parent_dtag,
7234 &dma->rxbuf_dtag);
7236 device_printf(sc->sc_dev, "can't create mbuf DMA tag\n");
7239 error = bus_dma_tag_create(dma->parent_dtag,
7250 &dma->txbuf_dtag);
7252 device_printf(sc->sc_dev, "can't create mbuf DMA tag\n");
7256 dma->wme[WME_AC_BK] = bwn_dma_ringsetup(mac, 0, 1);
7257 if (!dma->wme[WME_AC_BK])
7260 dma->wme[WME_AC_BE] = bwn_dma_ringsetup(mac, 1, 1);
7261 if (!dma->wme[WME_AC_BE])
7264 dma->wme[WME_AC_VI] = bwn_dma_ringsetup(mac, 2, 1);
7265 if (!dma->wme[WME_AC_VI])
7268 dma->wme[WME_AC_VO] = bwn_dma_ringsetup(mac, 3, 1);
7269 if (!dma->wme[WME_AC_VO])
7272 dma->mcast = bwn_dma_ringsetup(mac, 4, 1);
7273 if (!dma->mcast)
7275 dma->rx = bwn_dma_ringsetup(mac, 0, 0);
7276 if (!dma->rx)
7281 fail7: bwn_dma_ringfree(&dma->mcast);
7282 fail6: bwn_dma_ringfree(&dma->wme[WME_AC_VO]);
7283 fail5: bwn_dma_ringfree(&dma->wme[WME_AC_VI]);
7284 fail4: bwn_dma_ringfree(&dma->wme[WME_AC_BE]);
7285 fail3: bwn_dma_ringfree(&dma->wme[WME_AC_BK]);
7286 fail2: bus_dma_tag_destroy(dma->txbuf_dtag);
7287 fail1: bus_dma_tag_destroy(dma->rxbuf_dtag);
7288 fail0: bus_dma_tag_destroy(dma->parent_dtag);
7293 bwn_dma_parse_cookie(struct bwn_mac *mac, const struct bwn_txstatus *status,
7296 struct bwn_dma *dma = &mac->mac_method.dma;
7298 struct bwn_softc *sc = mac->mac_sc;
7300 BWN_ASSERT_LOCKED(mac->mac_sc);
7304 dr = dma->wme[WME_AC_BK];
7307 dr = dma->wme[WME_AC_BE];
7310 dr = dma->wme[WME_AC_VI];
7313 dr = dma->wme[WME_AC_VO];
7316 dr = dma->mcast;
7324 if (*slot < 0 || *slot >= dr->dr_numslots) {
7330 KASSERT(status->seq == dma->lastseq,
7332 device_printf(sc->sc_dev,
7334 dr->dr_numslots);
7337 dma->lastseq = status->seq;
7342 bwn_dma_stop(struct bwn_mac *mac)
7346 if ((mac->mac_flags & BWN_MAC_FLAG_DMA) == 0)
7348 dma = &mac->mac_method.dma;
7350 bwn_dma_ringstop(&dma->rx);
7351 bwn_dma_ringstop(&dma->wme[WME_AC_BK]);
7352 bwn_dma_ringstop(&dma->wme[WME_AC_BE]);
7353 bwn_dma_ringstop(&dma->wme[WME_AC_VI]);
7354 bwn_dma_ringstop(&dma->wme[WME_AC_VO]);
7355 bwn_dma_ringstop(&dma->mcast);
7369 bwn_pio_stop(struct bwn_mac *mac)
7373 if (mac->mac_flags & BWN_MAC_FLAG_DMA)
7375 pio = &mac->mac_method.pio;
7377 bwn_destroy_queue_tx(&pio->mcast);
7378 bwn_destroy_queue_tx(&pio->wme[WME_AC_VO]);
7379 bwn_destroy_queue_tx(&pio->wme[WME_AC_VI]);
7380 bwn_destroy_queue_tx(&pio->wme[WME_AC_BE]);
7381 bwn_destroy_queue_tx(&pio->wme[WME_AC_BK]);
7385 bwn_led_attach(struct bwn_mac *mac)
7387 struct bwn_softc *sc = mac->mac_sc;
7392 sc->sc_led_idle = (2350 * hz) / 1000;
7393 sc->sc_led_blink = 1;
7396 if (sc->sc_board_info.board_vendor ==
7412 led = &sc->sc_leds[i];
7415 error = bhnd_nvram_getvar_uint8(sc->sc_dev, bwn_led_vars[i],
7419 device_printf(sc->sc_dev, "NVRAM variable %s "
7425 led->led_act = led_act[i];
7428 led->led_flags |= BWN_LED_F_ACTLOW;
7429 led->led_act = val & BWN_LED_ACT_MASK;
7431 led->led_mask = (1 << i);
7433 if (led->led_act == BWN_LED_ACT_BLINK_SLOW ||
7434 led->led_act == BWN_LED_ACT_BLINK_POLL ||
7435 led->led_act == BWN_LED_ACT_BLINK) {
7436 led->led_flags |= BWN_LED_F_BLINK;
7437 if (led->led_act == BWN_LED_ACT_BLINK_POLL)
7438 led->led_flags |= BWN_LED_F_POLLABLE;
7439 else if (led->led_act == BWN_LED_ACT_BLINK_SLOW)
7440 led->led_flags |= BWN_LED_F_SLOW;
7442 if (sc->sc_blink_led == NULL) {
7443 sc->sc_blink_led = led;
7444 if (led->led_flags & BWN_LED_F_SLOW)
7445 BWN_LED_SLOWDOWN(sc->sc_led_idle);
7451 led->led_act, led->led_flags & BWN_LED_F_ACTLOW);
7453 callout_init_mtx(&sc->sc_led_blink_ch, &sc->sc_mtx, 0);
7462 if (led->led_flags & BWN_LED_F_ACTLOW)
7465 val |= led->led_mask;
7467 val &= ~led->led_mask;
7472 bwn_led_newstate(struct bwn_mac *mac, enum ieee80211_state nstate)
7474 struct bwn_softc *sc = mac->mac_sc;
7475 struct ieee80211com *ic = &sc->sc_ic;
7480 callout_stop(&sc->sc_led_blink_ch);
7481 sc->sc_led_blinking = 0;
7484 if ((sc->sc_flags & BWN_FLAG_RUNNING) == 0)
7487 val = BWN_READ_2(mac, BWN_GPIO_CONTROL);
7489 struct bwn_led *led = &sc->sc_leds[i];
7492 if (led->led_act == BWN_LED_ACT_UNKN ||
7493 led->led_act == BWN_LED_ACT_NULL)
7496 if ((led->led_flags & BWN_LED_F_BLINK) &&
7500 switch (led->led_act) {
7515 if (led->led_act == BWN_LED_ACT_11G &&
7516 ic->ic_curmode != IEEE80211_MODE_11G)
7520 if (led->led_act == BWN_LED_ACT_ASSOC)
7529 BWN_WRITE_2(mac, BWN_GPIO_CONTROL, val);
7533 bwn_led_event(struct bwn_mac *mac, int event)
7535 struct bwn_softc *sc = mac->mac_sc;
7536 struct bwn_led *led = sc->sc_blink_led;
7540 if ((led->led_flags & BWN_LED_F_POLLABLE) == 0)
7542 if (ticks - sc->sc_led_ticks < sc->sc_led_idle)
7546 sc->sc_led_ticks = ticks;
7547 if (sc->sc_led_blinking)
7552 rate = sc->sc_rx_rate;
7555 rate = sc->sc_tx_rate;
7564 bwn_led_blink_start(mac, bwn_led_duration[rate].on_dur,
7569 bwn_led_blink_start(struct bwn_mac *mac, int on_dur, int off_dur)
7571 struct bwn_softc *sc = mac->mac_sc;
7572 struct bwn_led *led = sc->sc_blink_led;
7575 val = BWN_READ_2(mac, BWN_GPIO_CONTROL);
7577 BWN_WRITE_2(mac, BWN_GPIO_CONTROL, val);
7579 if (led->led_flags & BWN_LED_F_SLOW) {
7584 sc->sc_led_blinking = 1;
7585 sc->sc_led_blink_offdur = off_dur;
7587 callout_reset(&sc->sc_led_blink_ch, on_dur, bwn_led_blink_next, mac);
7593 struct bwn_mac *mac = arg;
7594 struct bwn_softc *sc = mac->mac_sc;
7597 val = BWN_READ_2(mac, BWN_GPIO_CONTROL);
7598 val = bwn_led_onoff(sc->sc_blink_led, val, 0);
7599 BWN_WRITE_2(mac, BWN_GPIO_CONTROL, val);
7601 callout_reset(&sc->sc_led_blink_ch, sc->sc_led_blink_offdur,
7602 bwn_led_blink_end, mac);
7608 struct bwn_mac *mac = arg;
7609 struct bwn_softc *sc = mac->mac_sc;
7611 sc->sc_led_blinking = 0;
7632 if (sc->sc_ic.ic_nrunning > 0)
7636 ieee80211_start_all(&sc->sc_ic);
7644 struct bwn_mac *mac = sc->sc_curmac;
7647 KASSERT(mac->mac_status >= BWN_MAC_STATUS_STARTED,
7648 ("%s: invalid MAC status %d", __func__, mac->mac_status));
7650 if (mac->mac_phy.rev >= 3 || mac->mac_phy.type == BWN_PHYTYPE_LP
7651 || mac->mac_phy.type == BWN_PHYTYPE_N) {
7652 if (!(BWN_READ_4(mac, BWN_RF_HWENABLED_HI)
7656 if (BWN_READ_2(mac, BWN_RF_HWENABLED_LO)
7661 if (mac->mac_flags & BWN_MAC_FLAG_RADIO_ON)
7669 mac->mac_flags |= BWN_MAC_FLAG_RADIO_ON;
7671 mac->mac_flags &= ~BWN_MAC_FLAG_RADIO_ON;
7673 device_printf(sc->sc_dev,
7676 if (cur != mac->mac_phy.rf_on) {
7678 bwn_rf_turnon(mac);
7680 bwn_rf_turnoff(mac);
7684 callout_schedule(&sc->sc_rfswitch_ch, hz);
7690 device_t dev = sc->sc_dev;
7691 struct bwn_mac *mac;
7694 /* XXX assume that count of MAC is only 1. */
7696 if ((mac = sc->sc_curmac) == NULL)
7698 stats = &mac->mac_stats;
7702 "linknoise", CTLFLAG_RW, &stats->rts, 0, "Noise level");
7705 "rts", CTLFLAG_RW, &stats->rts, 0, "RTS");
7708 "rtsfail", CTLFLAG_RW, &stats->rtsfail, 0, "RTS failed to send");
7713 "debug", CTLFLAG_RW, &sc->sc_debug, 0, "Debug flags");