Lines Matching +full:umac +full:- +full:reset
1 /*-
2 * SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) AND ISC
28 /*-
64 /*-
65 * Based on BSD-licensed source modules in the Linux iwlwifi driver,
76 * Copyright(c) 2018 - 2019 Intel Corporation
90 * Copyright(c) 2018 - 2019 Intel Corporation
122 /*-
123 * Copyright (c) 2007-2010 Damien Bergamini <damien.bergamini@free.fr>
187 #define DEVNAME(_sc) (device_get_nameunit((_sc)->sc_dev))
188 #define IC2IFP(ic) (((struct ieee80211vap *)TAILQ_FIRST(&(ic)->ic_vaps))->iv_ifp)
201 #define PCI_PRODUCT_INTEL_WL_22500_1 0x2723 /* Wi-Fi 6 AX200 */
202 #define PCI_PRODUCT_INTEL_WL_22500_2 0x02f0 /* Wi-Fi 6 AX201 */
203 #define PCI_PRODUCT_INTEL_WL_22500_3 0xa0f0 /* Wi-Fi 6 AX201 */
204 #define PCI_PRODUCT_INTEL_WL_22500_4 0x34f0 /* Wi-Fi 6 AX201 */
205 #define PCI_PRODUCT_INTEL_WL_22500_5 0x06f0 /* Wi-Fi 6 AX201 */
206 #define PCI_PRODUCT_INTEL_WL_22500_6 0x43f0 /* Wi-Fi 6 AX201 */
207 #define PCI_PRODUCT_INTEL_WL_22500_7 0x3df0 /* Wi-Fi 6 AX201 */
208 #define PCI_PRODUCT_INTEL_WL_22500_8 0x4df0 /* Wi-Fi 6 AX201 */
209 #define PCI_PRODUCT_INTEL_WL_22500_9 0x2725 /* Wi-Fi 6 AX210 */
210 #define PCI_PRODUCT_INTEL_WL_22500_10 0x2726 /* Wi-Fi 6 AX211 */
211 #define PCI_PRODUCT_INTEL_WL_22500_11 0x51f0 /* Wi-Fi 6 AX211 */
212 #define PCI_PRODUCT_INTEL_WL_22500_12 0x7a70 /* Wi-Fi 6 AX211 */
213 #define PCI_PRODUCT_INTEL_WL_22500_13 0x7af0 /* Wi-Fi 6 AX211 */
214 #define PCI_PRODUCT_INTEL_WL_22500_14 0x7e40 /* Wi-Fi 6 AX210 */
215 #define PCI_PRODUCT_INTEL_WL_22500_15 0x7f70 /* Wi-Fi 6 AX211 */
216 #define PCI_PRODUCT_INTEL_WL_22500_16 0x54f0 /* Wi-Fi 6 AX211 */
217 #define PCI_PRODUCT_INTEL_WL_22500_17 0x51f1 /* Wi-Fi 6 AX211 */
223 { PCI_PRODUCT_INTEL_WL_22500_1, "Wi-Fi 6 AX200" },
224 { PCI_PRODUCT_INTEL_WL_22500_2, "Wi-Fi 6 AX201" },
225 { PCI_PRODUCT_INTEL_WL_22500_3, "Wi-Fi 6 AX201" },
226 { PCI_PRODUCT_INTEL_WL_22500_4, "Wi-Fi 6 AX201" },
227 { PCI_PRODUCT_INTEL_WL_22500_5, "Wi-Fi 6 AX201" },
228 { PCI_PRODUCT_INTEL_WL_22500_6, "Wi-Fi 6 AX201" },
229 { PCI_PRODUCT_INTEL_WL_22500_7, "Wi-Fi 6 AX201" },
230 { PCI_PRODUCT_INTEL_WL_22500_8, "Wi-Fi 6 AX201" },
231 { PCI_PRODUCT_INTEL_WL_22500_9, "Wi-Fi 6 AX210" },
232 { PCI_PRODUCT_INTEL_WL_22500_10, "Wi-Fi 6 AX211" },
233 { PCI_PRODUCT_INTEL_WL_22500_11, "Wi-Fi 6 AX211" },
234 { PCI_PRODUCT_INTEL_WL_22500_12, "Wi-Fi 6 AX211" },
235 { PCI_PRODUCT_INTEL_WL_22500_13, "Wi-Fi 6 AX211" },
236 { PCI_PRODUCT_INTEL_WL_22500_14, "Wi-Fi 6 AX210" },
237 { PCI_PRODUCT_INTEL_WL_22500_15, "Wi-Fi 6 AX211" },
238 { PCI_PRODUCT_INTEL_WL_22500_16, "Wi-Fi 6 AX211" },
239 { PCI_PRODUCT_INTEL_WL_22500_17, "Wi-Fi 6 AX211" },
258 /* 6-7 GHz */
298 #define IWX_RIDX_MAX (nitems(iwx_rates)-1)
573 /* XXX-THJ - I don't have hardware for this */
592 #define DPRINTF(x) do { if (sc->sc_debug == IWX_DEBUG_ANY) { printf x; } } while (0)
654 return (wh->i_fc[1] & IEEE80211_FC1_DIR_MASK) == in ieee80211_has_addr4()
664 for (i = 0; i < sc->n_cmd_versions; i++) { in iwx_lookup_cmd_ver()
665 entry = &sc->cmd_versions[i]; in iwx_lookup_cmd_ver()
666 if (entry->group == grp && entry->cmd == cmd) in iwx_lookup_cmd_ver()
667 return entry->cmd_ver; in iwx_lookup_cmd_ver()
679 for (i = 0; i < sc->n_cmd_versions; i++) { in iwx_lookup_notif_ver()
680 entry = &sc->cmd_versions[i]; in iwx_lookup_notif_ver()
681 if (entry->group == grp && entry->cmd == cmd) in iwx_lookup_notif_ver()
682 return entry->notif_ver; in iwx_lookup_notif_ver()
694 dlen < sizeof(l->size) + l->size * sizeof(*l->cs)) in iwx_store_cscheme()
706 int err = iwx_dma_contig_alloc(sc->sc_dmat, dram, sec->fws_len, 1); in iwx_ctxt_info_alloc_dma()
713 memcpy(dram->vaddr, sec->fws_data, sec->fws_len); in iwx_ctxt_info_alloc_dma()
721 struct iwx_self_init_dram *dram = &sc->init_dram; in iwx_ctxt_info_free_paging()
724 if (!dram->paging) in iwx_ctxt_info_free_paging()
728 for (i = 0; i < dram->paging_cnt; i++) in iwx_ctxt_info_free_paging()
729 iwx_dma_contig_free(&dram->paging[i]); in iwx_ctxt_info_free_paging()
731 free(dram->paging, M_DEVBUF); in iwx_ctxt_info_free_paging()
732 dram->paging_cnt = 0; in iwx_ctxt_info_free_paging()
733 dram->paging = NULL; in iwx_ctxt_info_free_paging()
741 while (start < fws->fw_count && in iwx_get_num_sections()
742 fws->fw_sect[start].fws_devoff != IWX_CPU1_CPU2_SEPARATOR_SECTION && in iwx_get_num_sections()
743 fws->fw_sect[start].fws_devoff != IWX_PAGING_SEPARATOR_SECTION) { in iwx_get_num_sections()
755 struct iwx_self_init_dram *dram = &sc->init_dram; in iwx_init_fw_sec()
758 KASSERT(dram->paging == NULL, ("iwx_init_fw_sec")); in iwx_init_fw_sec()
760 dram->lmac_cnt = iwx_get_num_sections(fws, 0); in iwx_init_fw_sec()
762 dram->umac_cnt = iwx_get_num_sections(fws, dram->lmac_cnt + 1); in iwx_init_fw_sec()
764 dram->paging_cnt = iwx_get_num_sections(fws, in iwx_init_fw_sec()
765 dram->lmac_cnt + dram->umac_cnt + 2); in iwx_init_fw_sec()
768 dram->fw = mallocarray(dram->umac_cnt + dram->lmac_cnt, in iwx_init_fw_sec()
769 sizeof(*dram->fw), M_DEVBUF, M_ZERO | M_NOWAIT); in iwx_init_fw_sec()
770 if (!dram->fw) { in iwx_init_fw_sec()
777 dram->paging = mallocarray(dram->paging_cnt, sizeof(*dram->paging), in iwx_init_fw_sec()
780 if (!dram->paging) { in iwx_init_fw_sec()
787 for (i = 0; i < dram->lmac_cnt; i++) { in iwx_init_fw_sec()
788 ret = iwx_ctxt_info_alloc_dma(sc, &fws->fw_sect[i], in iwx_init_fw_sec()
789 &dram->fw[fw_cnt]); in iwx_init_fw_sec()
792 ctxt_dram->lmac_img[i] = in iwx_init_fw_sec()
793 htole64(dram->fw[fw_cnt].paddr); in iwx_init_fw_sec()
797 (unsigned long long)dram->fw[fw_cnt].paddr, in iwx_init_fw_sec()
798 (unsigned long long)dram->fw[fw_cnt].size); in iwx_init_fw_sec()
802 /* initialize umac sections */ in iwx_init_fw_sec()
803 for (i = 0; i < dram->umac_cnt; i++) { in iwx_init_fw_sec()
806 &fws->fw_sect[fw_cnt + 1], &dram->fw[fw_cnt]); in iwx_init_fw_sec()
809 ctxt_dram->umac_img[i] = in iwx_init_fw_sec()
810 htole64(dram->fw[fw_cnt].paddr); in iwx_init_fw_sec()
812 "%s: firmware UMAC section %d at 0x%llx size %lld\n", in iwx_init_fw_sec()
814 (unsigned long long)dram->fw[fw_cnt].paddr, in iwx_init_fw_sec()
815 (unsigned long long)dram->fw[fw_cnt].size); in iwx_init_fw_sec()
821 * Paging memory isn't stored in dram->fw as the umac and lmac - it is in iwx_init_fw_sec()
823 * This is since the timing of its release is different - in iwx_init_fw_sec()
827 * different - fw_cnt isn't changing so loop counter is added to it. in iwx_init_fw_sec()
829 for (i = 0; i < dram->paging_cnt; i++) { in iwx_init_fw_sec()
830 /* access FW with +2 to make up for lmac & umac separators */ in iwx_init_fw_sec()
834 &fws->fw_sect[fw_idx], &dram->paging[i]); in iwx_init_fw_sec()
838 ctxt_dram->virtual_img[i] = htole64(dram->paging[i].paddr); in iwx_init_fw_sec()
842 (unsigned long long)dram->paging[i].paddr, in iwx_init_fw_sec()
843 (unsigned long long)dram->paging[i].size); in iwx_init_fw_sec()
867 struct iwx_dma_info *fw_mon = &sc->fw_mon;
872 if (fw_mon->size)
875 for (power = max_power; power >= min_power; power--) {
878 err = iwx_dma_contig_alloc(sc->sc_dmat, fw_mon, size, 0);
889 fw_mon->size = 0;
895 "%s: Sorry - debug buffer is only %luK while you requested %luK\n",
896 DEVNAME(sc), (unsigned long)(1 << (power - 10)),
897 (unsigned long)(1 << (max_power - 10)));
919 if (sc->fw_mon.size)
935 dest_v1 = sc->sc_fw.dbg_dest_tlv_v1; in iwx_apply_debug_destination()
936 mon_mode = dest_v1->monitor_mode; in iwx_apply_debug_destination()
937 size_power = dest_v1->size_power; in iwx_apply_debug_destination()
938 base_reg = le32toh(dest_v1->base_reg); in iwx_apply_debug_destination()
939 end_reg = le32toh(dest_v1->end_reg); in iwx_apply_debug_destination()
940 base_shift = dest_v1->base_shift; in iwx_apply_debug_destination()
941 end_shift = dest_v1->end_shift; in iwx_apply_debug_destination()
954 for (i = 0; i < sc->sc_fw.n_dest_reg; i++) { in iwx_apply_debug_destination()
958 addr = le32toh(dest_v1->reg_ops[i].addr); in iwx_apply_debug_destination()
959 val = le32toh(dest_v1->reg_ops[i].val); in iwx_apply_debug_destination()
960 op = dest_v1->reg_ops[i].op; in iwx_apply_debug_destination()
991 DPRINTF(("%s: FW debug - unknown OP %d\n", in iwx_apply_debug_destination()
998 if (mon_mode == EXTERNAL_MODE && sc->fw_mon.size) { in iwx_apply_debug_destination()
1000 sc->fw_mon.paddr >> base_shift); in iwx_apply_debug_destination()
1002 (sc->fw_mon.paddr + sc->fw_mon.size - 256) in iwx_apply_debug_destination()
1033 if (!sc->sc_integrated) { in iwx_set_ltr()
1035 } else if (sc->sc_integrated && in iwx_set_ltr()
1036 sc->sc_device_family == IWX_DEVICE_FAMILY_22000) { in iwx_set_ltr()
1052 ctxt_info = sc->ctxt_info_dma.vaddr; in iwx_ctxt_info_init()
1055 ctxt_info->version.version = 0; in iwx_ctxt_info_init()
1056 ctxt_info->version.mac_id = in iwx_ctxt_info_init()
1059 ctxt_info->version.size = htole16(sizeof(*ctxt_info) / 4); in iwx_ctxt_info_init()
1068 ctxt_info->control.control_flags = htole32(control_flags); in iwx_ctxt_info_init()
1071 rx_cfg = &ctxt_info->rbd_cfg; in iwx_ctxt_info_init()
1072 rx_cfg->free_rbd_addr = htole64(sc->rxq.free_desc_dma.paddr); in iwx_ctxt_info_init()
1073 rx_cfg->used_rbd_addr = htole64(sc->rxq.used_desc_dma.paddr); in iwx_ctxt_info_init()
1074 rx_cfg->status_wr_ptr = htole64(sc->rxq.stat_dma.paddr); in iwx_ctxt_info_init()
1077 ctxt_info->hcmd_cfg.cmd_queue_addr = in iwx_ctxt_info_init()
1078 htole64(sc->txq[IWX_DQA_CMD_QUEUE].desc_dma.paddr); in iwx_ctxt_info_init()
1079 ctxt_info->hcmd_cfg.cmd_queue_size = in iwx_ctxt_info_init()
1083 err = iwx_init_fw_sec(sc, fws, &ctxt_info->dram); in iwx_ctxt_info_init()
1090 if (sc->sc_fw.dbg_dest_tlv_v1) { in iwx_ctxt_info_init()
1102 * 64-bit address but a simple bus_space_write_8 to this register in iwx_ctxt_info_init()
1105 paddr = sc->ctxt_info_dma.paddr; in iwx_ctxt_info_init()
1135 if (sc->sc_fw.iml == NULL || sc->sc_fw.iml_len == 0) { in iwx_ctxt_info_gen3_init()
1142 err = iwx_dma_contig_alloc(sc->sc_dmat, &sc->iml_dma, in iwx_ctxt_info_gen3_init()
1143 sc->sc_fw.iml_len, 1); in iwx_ctxt_info_gen3_init()
1151 prph_scratch = sc->prph_scratch_dma.vaddr; in iwx_ctxt_info_gen3_init()
1153 prph_sc_ctrl = &prph_scratch->ctrl_cfg; in iwx_ctxt_info_gen3_init()
1154 prph_sc_ctrl->version.version = 0; in iwx_ctxt_info_gen3_init()
1155 prph_sc_ctrl->version.mac_id = htole16(IWX_READ(sc, IWX_CSR_HW_REV)); in iwx_ctxt_info_gen3_init()
1156 prph_sc_ctrl->version.size = htole16(sizeof(*prph_scratch) / 4); in iwx_ctxt_info_gen3_init()
1161 if (sc->sc_imr_enabled) in iwx_ctxt_info_gen3_init()
1163 prph_sc_ctrl->control.control_flags = htole32(control_flags); in iwx_ctxt_info_gen3_init()
1166 prph_sc_ctrl->rbd_cfg.free_rbd_addr = in iwx_ctxt_info_gen3_init()
1167 htole64(sc->rxq.free_desc_dma.paddr); in iwx_ctxt_info_gen3_init()
1170 err = iwx_init_fw_sec(sc, fws, &prph_scratch->dram); in iwx_ctxt_info_gen3_init()
1172 iwx_dma_contig_free(&sc->iml_dma); in iwx_ctxt_info_gen3_init()
1177 ctxt_info_gen3 = sc->ctxt_info_dma.vaddr; in iwx_ctxt_info_gen3_init()
1179 ctxt_info_gen3->prph_info_base_addr = htole64(sc->prph_info_dma.paddr); in iwx_ctxt_info_gen3_init()
1180 ctxt_info_gen3->prph_scratch_base_addr = in iwx_ctxt_info_gen3_init()
1181 htole64(sc->prph_scratch_dma.paddr); in iwx_ctxt_info_gen3_init()
1183 ctxt_info_gen3->prph_scratch_size = htole32(scratch_size); in iwx_ctxt_info_gen3_init()
1184 ctxt_info_gen3->cr_head_idx_arr_base_addr = in iwx_ctxt_info_gen3_init()
1185 htole64(sc->rxq.stat_dma.paddr); in iwx_ctxt_info_gen3_init()
1186 ctxt_info_gen3->tr_tail_idx_arr_base_addr = in iwx_ctxt_info_gen3_init()
1187 htole64(sc->prph_info_dma.paddr + PAGE_SIZE / 2); in iwx_ctxt_info_gen3_init()
1188 ctxt_info_gen3->cr_tail_idx_arr_base_addr = in iwx_ctxt_info_gen3_init()
1189 htole64(sc->prph_info_dma.paddr + 3 * PAGE_SIZE / 4); in iwx_ctxt_info_gen3_init()
1190 ctxt_info_gen3->mtr_base_addr = in iwx_ctxt_info_gen3_init()
1191 htole64(sc->txq[IWX_DQA_CMD_QUEUE].desc_dma.paddr); in iwx_ctxt_info_gen3_init()
1192 ctxt_info_gen3->mcr_base_addr = htole64(sc->rxq.used_desc_dma.paddr); in iwx_ctxt_info_gen3_init()
1194 ctxt_info_gen3->mtr_size = htole16(cb_size); in iwx_ctxt_info_gen3_init()
1196 ctxt_info_gen3->mcr_size = htole16(cb_size); in iwx_ctxt_info_gen3_init()
1198 memcpy(sc->iml_dma.vaddr, sc->sc_fw.iml, sc->sc_fw.iml_len); in iwx_ctxt_info_gen3_init()
1200 paddr = sc->ctxt_info_dma.paddr; in iwx_ctxt_info_gen3_init()
1204 paddr = sc->iml_dma.paddr; in iwx_ctxt_info_gen3_init()
1207 IWX_WRITE(sc, IWX_CSR_IML_SIZE_ADDR, sc->sc_fw.iml_len); in iwx_ctxt_info_gen3_init()
1217 iwx_dma_contig_free(&sc->iml_dma); in iwx_ctxt_info_gen3_init()
1232 struct iwx_self_init_dram *dram = &sc->init_dram; in iwx_ctxt_info_free_fw_img()
1235 if (!dram->fw) in iwx_ctxt_info_free_fw_img()
1238 for (i = 0; i < dram->lmac_cnt + dram->umac_cnt; i++) in iwx_ctxt_info_free_fw_img()
1239 iwx_dma_contig_free(&dram->fw[i]); in iwx_ctxt_info_free_fw_img()
1241 free(dram->fw, M_DEVBUF); in iwx_ctxt_info_free_fw_img()
1242 dram->lmac_cnt = 0; in iwx_ctxt_info_free_fw_img()
1243 dram->umac_cnt = 0; in iwx_ctxt_info_free_fw_img()
1244 dram->fw = NULL; in iwx_ctxt_info_free_fw_img()
1259 fws = &sc->sc_fw.fw_sects[type]; in iwx_firmware_store_section()
1261 "%s: ucode type %d section %d\n", DEVNAME(sc), type, fws->fw_count); in iwx_firmware_store_section()
1262 if (fws->fw_count >= IWX_UCODE_SECT_MAX) in iwx_firmware_store_section()
1265 fwone = &fws->fw_sect[fws->fw_count]; in iwx_firmware_store_section()
1268 memcpy(&fwone->fws_devoff, data, sizeof(uint32_t)); in iwx_firmware_store_section()
1271 fwone->fws_data = data + sizeof(uint32_t); in iwx_firmware_store_section()
1272 fwone->fws_len = dlen - sizeof(uint32_t); in iwx_firmware_store_section()
1274 fws->fw_count++; in iwx_firmware_store_section()
1275 fws->fw_totlen += fwone->fws_len; in iwx_firmware_store_section()
1282 #define IWX_MAX_SCAN_CHANNELS 67 /* as of iwx-cc-a0-62 firmware */
1293 uint32_t ucode_type = le32toh(def_calib->ucode_type); in iwx_set_default_calib()
1298 sc->sc_default_calib[ucode_type].flow_trigger = in iwx_set_default_calib()
1299 def_calib->calib.flow_trigger; in iwx_set_default_calib()
1300 sc->sc_default_calib[ucode_type].event_trigger = in iwx_set_default_calib()
1301 def_calib->calib.event_trigger; in iwx_set_default_calib()
1309 free(fw->fw_rawdata, M_DEVBUF); in iwx_fw_info_free()
1310 fw->fw_rawdata = NULL; in iwx_fw_info_free()
1311 fw->fw_rawsize = 0; in iwx_fw_info_free()
1312 /* don't touch fw->fw_status */ in iwx_fw_info_free()
1313 memset(fw->fw_sects, 0, sizeof(fw->fw_sects)); in iwx_fw_info_free()
1314 free(fw->iml, M_DEVBUF); in iwx_fw_info_free()
1315 fw->iml = NULL; in iwx_fw_info_free()
1316 fw->iml_len = 0; in iwx_fw_info_free()
1324 struct iwx_fw_info *fw = &sc->sc_fw; in iwx_read_firmware()
1333 if (fw->fw_status == IWX_FW_STATUS_DONE) in iwx_read_firmware()
1336 fw->fw_status = IWX_FW_STATUS_INPROGRESS; in iwx_read_firmware()
1337 fwp = firmware_get(sc->sc_fwname); in iwx_read_firmware()
1338 sc->sc_fwp = fwp; in iwx_read_firmware()
1342 DEVNAME(sc), sc->sc_fwname); in iwx_read_firmware()
1348 __func__, __LINE__, DEVNAME(sc), sc->sc_fwname); in iwx_read_firmware()
1351 sc->sc_capaflags = 0; in iwx_read_firmware()
1352 sc->sc_capa_n_scan_channels = IWX_DEFAULT_SCAN_CHANNELS; in iwx_read_firmware()
1353 memset(sc->sc_enabled_capa, 0, sizeof(sc->sc_enabled_capa)); in iwx_read_firmware()
1354 memset(sc->sc_ucode_api, 0, sizeof(sc->sc_ucode_api)); in iwx_read_firmware()
1355 sc->n_cmd_versions = 0; in iwx_read_firmware()
1357 uhdr = (const void *)(fwp->data); in iwx_read_firmware()
1358 if (*(const uint32_t *)fwp->data != 0 in iwx_read_firmware()
1359 || le32toh(uhdr->magic) != IWX_TLV_UCODE_MAGIC) { in iwx_read_firmware()
1361 DEVNAME(sc), sc->sc_fwname); in iwx_read_firmware()
1366 iwx_fw_version_str(sc->sc_fwver, sizeof(sc->sc_fwver), in iwx_read_firmware()
1367 IWX_UCODE_MAJOR(le32toh(uhdr->ver)), in iwx_read_firmware()
1368 IWX_UCODE_MINOR(le32toh(uhdr->ver)), in iwx_read_firmware()
1369 IWX_UCODE_API(le32toh(uhdr->ver))); in iwx_read_firmware()
1371 data = uhdr->data; in iwx_read_firmware()
1372 len = fwp->datasize - sizeof(*uhdr); in iwx_read_firmware()
1382 len -= sizeof(tlv); in iwx_read_firmware()
1399 sc->sc_capa_max_probe_len in iwx_read_firmware()
1401 if (sc->sc_capa_max_probe_len > in iwx_read_firmware()
1412 sc->sc_capaflags |= IWX_UCODE_TLV_FLAGS_PAN; in iwx_read_firmware()
1430 sc->sc_capaflags = le32toh(*(const uint32_t *)tlv_data); in iwx_read_firmware()
1482 sc->sc_fw_phy_config = le32toh(*(const uint32_t *)tlv_data); in iwx_read_firmware()
1493 idx = le32toh(api->api_index); in iwx_read_firmware()
1499 if ((le32toh(api->api_flags) & (1 << i)) == 0) in iwx_read_firmware()
1501 setbit(sc->sc_ucode_api, i + (32 * idx)); in iwx_read_firmware()
1514 idx = le32toh(capa->api_index); in iwx_read_firmware()
1519 if ((le32toh(capa->api_capa) & (1 << i)) == 0) in iwx_read_firmware()
1521 setbit(sc->sc_enabled_capa, i + (32 * idx)); in iwx_read_firmware()
1551 sc->sc_capa_n_scan_channels = in iwx_read_firmware()
1553 if (sc->sc_capa_n_scan_channels > IWX_MAX_SCAN_CHANNELS) { in iwx_read_firmware()
1565 iwx_fw_version_str(sc->sc_fwver, sizeof(sc->sc_fwver), in iwx_read_firmware()
1574 fw->dbg_dest_ver = (const uint8_t *)tlv_data; in iwx_read_firmware()
1575 if (*fw->dbg_dest_ver != 0) { in iwx_read_firmware()
1580 if (fw->dbg_dest_tlv_init) in iwx_read_firmware()
1582 fw->dbg_dest_tlv_init = true; in iwx_read_firmware()
1585 fw->dbg_dest_tlv_v1 = dest_v1; in iwx_read_firmware()
1586 fw->n_dest_reg = tlv_len - in iwx_read_firmware()
1588 fw->n_dest_reg /= sizeof(dest_v1->reg_ops[0]); in iwx_read_firmware()
1591 __func__, fw->n_dest_reg); in iwx_read_firmware()
1598 if (!fw->dbg_dest_tlv_init || in iwx_read_firmware()
1599 conf->id >= nitems(fw->dbg_conf_tlv) || in iwx_read_firmware()
1600 fw->dbg_conf_tlv[conf->id] != NULL) in iwx_read_firmware()
1604 "Found debug configuration: %d\n", conf->id); in iwx_read_firmware()
1605 fw->dbg_conf_tlv[conf->id] = conf; in iwx_read_firmware()
1606 fw->dbg_conf_tlv_len[conf->id] = tlv_len; in iwx_read_firmware()
1618 if (sc->sc_device_family < IWX_DEVICE_FAMILY_22000) in iwx_read_firmware()
1620 sc->sc_uc.uc_umac_error_event_table = in iwx_read_firmware()
1621 le32toh(dbg_ptrs->error_info_addr) & in iwx_read_firmware()
1623 sc->sc_uc.error_event_table_tlv_status |= in iwx_read_firmware()
1636 if (sc->sc_device_family < IWX_DEVICE_FAMILY_22000) in iwx_read_firmware()
1638 sc->sc_uc.uc_lmac_error_event_table[0] = in iwx_read_firmware()
1639 le32toh(dbg_ptrs->error_event_table_ptr) & in iwx_read_firmware()
1641 sc->sc_uc.error_event_table_tlv_status |= in iwx_read_firmware()
1650 if (sc->sc_fw.iml != NULL) { in iwx_read_firmware()
1651 free(fw->iml, M_DEVBUF); in iwx_read_firmware()
1652 fw->iml_len = 0; in iwx_read_firmware()
1654 sc->sc_fw.iml = malloc(tlv_len, M_DEVBUF, in iwx_read_firmware()
1656 if (sc->sc_fw.iml == NULL) { in iwx_read_firmware()
1660 memcpy(sc->sc_fw.iml, tlv_data, tlv_len); in iwx_read_firmware()
1661 sc->sc_fw.iml_len = tlv_len; in iwx_read_firmware()
1669 if (sc->n_cmd_versions != 0) { in iwx_read_firmware()
1673 if (tlv_len > sizeof(sc->cmd_versions)) { in iwx_read_firmware()
1677 memcpy(&sc->cmd_versions[0], tlv_data, tlv_len); in iwx_read_firmware()
1678 sc->n_cmd_versions = tlv_len / sizeof(struct iwx_fw_cmd_version); in iwx_read_firmware()
1690 /* undocumented TLVs found in iwx-cc-a0-46 image */ in iwx_read_firmware()
1696 /* undocumented TLVs found in iwx-cc-a0-48 image */ in iwx_read_firmware()
1712 /* undocumented TLV found in iwx-cc-a0-67 image */ in iwx_read_firmware()
1716 /* undocumented TLV found in iwx-ty-a0-gf-a0-73 image */ in iwx_read_firmware()
1720 /* undocumented TLV found in iwx-ty-a0-gf-a0-77 image */ in iwx_read_firmware()
1724 /* undocumented TLV found in iwx-ty-a0-gf-a0-89 image */ in iwx_read_firmware()
1740 len -= roundup(tlv_len, 4); in iwx_read_firmware()
1754 fw->fw_status = IWX_FW_STATUS_NONE; in iwx_read_firmware()
1755 if (fw->fw_rawdata != NULL) in iwx_read_firmware()
1758 fw->fw_status = IWX_FW_STATUS_DONE; in iwx_read_firmware()
1765 if (sc->sc_device_family >= IWX_DEVICE_FAMILY_AX210) in iwx_prph_addr_mask()
1806 return iwx_read_prph(sc, addr + sc->sc_umac_prph_offset); in iwx_read_umac_prph()
1812 iwx_write_prph(sc, addr + sc->sc_umac_prph_offset, val); in iwx_write_umac_prph()
1843 timo -= 10; in iwx_poll_bit()
1851 if (sc->sc_nic_locks > 0) { in iwx_nic_lock()
1853 sc->sc_nic_locks++; in iwx_nic_lock()
1866 sc->sc_nic_locks++; in iwx_nic_lock()
1877 if (sc->sc_nic_locks <= 0) in iwx_nic_assert_locked()
1878 panic("%s: nic locks counter %d", DEVNAME(sc), sc->sc_nic_locks); in iwx_nic_assert_locked()
1884 if (sc->sc_nic_locks > 0) { in iwx_nic_unlock()
1885 if (--sc->sc_nic_locks == 0) in iwx_nic_unlock()
1935 dma->tag = NULL; in iwx_dma_contig_alloc()
1936 dma->map = NULL; in iwx_dma_contig_alloc()
1937 dma->size = size; in iwx_dma_contig_alloc()
1938 dma->vaddr = NULL; in iwx_dma_contig_alloc()
1942 1, size, 0, NULL, NULL, &dma->tag); in iwx_dma_contig_alloc()
1946 error = bus_dmamem_alloc(dma->tag, (void **)&dma->vaddr, in iwx_dma_contig_alloc()
1947 BUS_DMA_NOWAIT | BUS_DMA_ZERO | BUS_DMA_COHERENT, &dma->map); in iwx_dma_contig_alloc()
1951 error = bus_dmamap_load(dma->tag, dma->map, dma->vaddr, size, in iwx_dma_contig_alloc()
1952 iwx_dma_map_addr, &dma->paddr, BUS_DMA_NOWAIT); in iwx_dma_contig_alloc()
1954 bus_dmamem_free(dma->tag, dma->vaddr, dma->map); in iwx_dma_contig_alloc()
1955 dma->vaddr = NULL; in iwx_dma_contig_alloc()
1959 bus_dmamap_sync(dma->tag, dma->map, BUS_DMASYNC_PREWRITE); in iwx_dma_contig_alloc()
1971 if (dma->vaddr != NULL) { in iwx_dma_contig_free()
1972 bus_dmamap_sync(dma->tag, dma->map, in iwx_dma_contig_free()
1974 bus_dmamap_unload(dma->tag, dma->map); in iwx_dma_contig_free()
1975 bus_dmamem_free(dma->tag, dma->vaddr, dma->map); in iwx_dma_contig_free()
1976 dma->vaddr = NULL; in iwx_dma_contig_free()
1978 if (dma->tag != NULL) { in iwx_dma_contig_free()
1979 bus_dma_tag_destroy(dma->tag); in iwx_dma_contig_free()
1980 dma->tag = NULL; in iwx_dma_contig_free()
1990 ring->cur = 0; in iwx_alloc_rx_ring()
1992 /* Allocate RX descriptors (256-byte aligned). */ in iwx_alloc_rx_ring()
1993 if (sc->sc_device_family >= IWX_DEVICE_FAMILY_AX210) in iwx_alloc_rx_ring()
1997 err = iwx_dma_contig_alloc(sc->sc_dmat, &ring->free_desc_dma, in iwx_alloc_rx_ring()
2000 device_printf(sc->sc_dev, in iwx_alloc_rx_ring()
2004 ring->desc = ring->free_desc_dma.vaddr; in iwx_alloc_rx_ring()
2006 /* Allocate RX status area (16-byte aligned). */ in iwx_alloc_rx_ring()
2007 if (sc->sc_device_family >= IWX_DEVICE_FAMILY_AX210) in iwx_alloc_rx_ring()
2010 size = sizeof(*ring->stat); in iwx_alloc_rx_ring()
2011 err = iwx_dma_contig_alloc(sc->sc_dmat, &ring->stat_dma, size, 16); in iwx_alloc_rx_ring()
2013 device_printf(sc->sc_dev, in iwx_alloc_rx_ring()
2017 ring->stat = ring->stat_dma.vaddr; in iwx_alloc_rx_ring()
2019 if (sc->sc_device_family >= IWX_DEVICE_FAMILY_AX210) in iwx_alloc_rx_ring()
2023 err = iwx_dma_contig_alloc(sc->sc_dmat, &ring->used_desc_dma, in iwx_alloc_rx_ring()
2026 device_printf(sc->sc_dev, in iwx_alloc_rx_ring()
2031 err = bus_dma_tag_create(sc->sc_dmat, 1, 0, BUS_SPACE_MAXADDR_32BIT, in iwx_alloc_rx_ring()
2033 0, NULL, NULL, &ring->data_dmat); in iwx_alloc_rx_ring()
2036 struct iwx_rx_data *data = &ring->data[i]; in iwx_alloc_rx_ring()
2039 err = bus_dmamap_create(ring->data_dmat, 0, &data->map); in iwx_alloc_rx_ring()
2041 device_printf(sc->sc_dev, in iwx_alloc_rx_ring()
2062 if (sc->sc_device_family >= IWX_DEVICE_FAMILY_AX210) in iwx_disable_rx_dma()
2067 if (sc->sc_device_family >= IWX_DEVICE_FAMILY_AX210) { in iwx_disable_rx_dma()
2085 ring->cur = 0; in iwx_reset_rx_ring()
2086 bus_dmamap_sync(sc->sc_dmat, ring->stat_dma.map, in iwx_reset_rx_ring()
2088 if (sc->sc_device_family >= IWX_DEVICE_FAMILY_AX210) { in iwx_reset_rx_ring()
2089 uint16_t *status = sc->rxq.stat_dma.vaddr; in iwx_reset_rx_ring()
2092 memset(ring->stat, 0, sizeof(*ring->stat)); in iwx_reset_rx_ring()
2093 bus_dmamap_sync(sc->sc_dmat, ring->stat_dma.map, in iwx_reset_rx_ring()
2103 iwx_dma_contig_free(&ring->free_desc_dma); in iwx_free_rx_ring()
2104 iwx_dma_contig_free(&ring->stat_dma); in iwx_free_rx_ring()
2105 iwx_dma_contig_free(&ring->used_desc_dma); in iwx_free_rx_ring()
2108 struct iwx_rx_data *data = &ring->data[i]; in iwx_free_rx_ring()
2109 if (data->m != NULL) { in iwx_free_rx_ring()
2110 bus_dmamap_sync(ring->data_dmat, data->map, in iwx_free_rx_ring()
2112 bus_dmamap_unload(ring->data_dmat, data->map); in iwx_free_rx_ring()
2113 m_freem(data->m); in iwx_free_rx_ring()
2114 data->m = NULL; in iwx_free_rx_ring()
2116 if (data->map != NULL) { in iwx_free_rx_ring()
2117 bus_dmamap_destroy(ring->data_dmat, data->map); in iwx_free_rx_ring()
2118 data->map = NULL; in iwx_free_rx_ring()
2121 if (ring->data_dmat != NULL) { in iwx_free_rx_ring()
2122 bus_dma_tag_destroy(ring->data_dmat); in iwx_free_rx_ring()
2123 ring->data_dmat = NULL; in iwx_free_rx_ring()
2137 ring->qid = qid; in iwx_alloc_tx_ring()
2138 ring->queued = 0; in iwx_alloc_tx_ring()
2139 ring->cur = 0; in iwx_alloc_tx_ring()
2140 ring->cur_hw = 0; in iwx_alloc_tx_ring()
2141 ring->tail = 0; in iwx_alloc_tx_ring()
2142 ring->tail_hw = 0; in iwx_alloc_tx_ring()
2144 /* Allocate TX descriptors (256-byte aligned). */ in iwx_alloc_tx_ring()
2146 err = iwx_dma_contig_alloc(sc->sc_dmat, &ring->desc_dma, size, 256); in iwx_alloc_tx_ring()
2148 device_printf(sc->sc_dev, in iwx_alloc_tx_ring()
2152 ring->desc = ring->desc_dma.vaddr; in iwx_alloc_tx_ring()
2159 * management, control, and non-QoS data frames. in iwx_alloc_tx_ring()
2160 * The command is queue sc->txq[0], our default queue is sc->txq[1]. in iwx_alloc_tx_ring()
2163 * which aggregation is enabled. We map TID 0-7 to sc->txq[2:9]. in iwx_alloc_tx_ring()
2166 * The driver maintains a table mapping driver-side queue IDs in iwx_alloc_tx_ring()
2167 * to firmware-side queue IDs. in iwx_alloc_tx_ring()
2170 if (sc->sc_device_family >= IWX_DEVICE_FAMILY_AX210) { in iwx_alloc_tx_ring()
2178 err = iwx_dma_contig_alloc(sc->sc_dmat, &ring->bc_tbl, bc_tbl_size, in iwx_alloc_tx_ring()
2181 device_printf(sc->sc_dev, in iwx_alloc_tx_ring()
2187 err = iwx_dma_contig_alloc(sc->sc_dmat, &ring->cmd_dma, size, in iwx_alloc_tx_ring()
2190 device_printf(sc->sc_dev, in iwx_alloc_tx_ring()
2194 ring->cmd = ring->cmd_dma.vaddr; in iwx_alloc_tx_ring()
2202 err = bus_dma_tag_create(sc->sc_dmat, 1, 0, BUS_SPACE_MAXADDR_32BIT, in iwx_alloc_tx_ring()
2203 BUS_SPACE_MAXADDR, NULL, NULL, mapsize, IWX_TFH_NUM_TBS - 2, in iwx_alloc_tx_ring()
2204 mapsize, 0, NULL, NULL, &ring->data_dmat); in iwx_alloc_tx_ring()
2206 paddr = ring->cmd_dma.paddr; in iwx_alloc_tx_ring()
2208 struct iwx_tx_data *data = &ring->data[i]; in iwx_alloc_tx_ring()
2210 data->cmd_paddr = paddr; in iwx_alloc_tx_ring()
2213 err = bus_dmamap_create(ring->data_dmat, 0, &data->map); in iwx_alloc_tx_ring()
2215 device_printf(sc->sc_dev, in iwx_alloc_tx_ring()
2220 KASSERT(paddr == ring->cmd_dma.paddr + size, ("bad paddr in txr alloc")); in iwx_alloc_tx_ring()
2233 struct iwx_tx_data *data = &ring->data[i]; in iwx_reset_tx_ring()
2235 if (data->m != NULL) { in iwx_reset_tx_ring()
2236 bus_dmamap_sync(ring->data_dmat, data->map, in iwx_reset_tx_ring()
2238 bus_dmamap_unload(ring->data_dmat, data->map); in iwx_reset_tx_ring()
2239 m_freem(data->m); in iwx_reset_tx_ring()
2240 data->m = NULL; in iwx_reset_tx_ring()
2245 memset(ring->bc_tbl.vaddr, 0, ring->bc_tbl.size); in iwx_reset_tx_ring()
2248 memset(ring->desc, 0, ring->desc_dma.size); in iwx_reset_tx_ring()
2249 bus_dmamap_sync(ring->desc_dma.tag, ring->desc_dma.map, in iwx_reset_tx_ring()
2251 sc->qfullmsk &= ~(1 << ring->qid); in iwx_reset_tx_ring()
2252 sc->qenablemsk &= ~(1 << ring->qid); in iwx_reset_tx_ring()
2253 for (i = 0; i < nitems(sc->aggqid); i++) { in iwx_reset_tx_ring()
2254 if (sc->aggqid[i] == ring->qid) { in iwx_reset_tx_ring()
2255 sc->aggqid[i] = 0; in iwx_reset_tx_ring()
2259 ring->queued = 0; in iwx_reset_tx_ring()
2260 ring->cur = 0; in iwx_reset_tx_ring()
2261 ring->cur_hw = 0; in iwx_reset_tx_ring()
2262 ring->tail = 0; in iwx_reset_tx_ring()
2263 ring->tail_hw = 0; in iwx_reset_tx_ring()
2264 ring->tid = 0; in iwx_reset_tx_ring()
2272 iwx_dma_contig_free(&ring->desc_dma); in iwx_free_tx_ring()
2273 iwx_dma_contig_free(&ring->cmd_dma); in iwx_free_tx_ring()
2274 iwx_dma_contig_free(&ring->bc_tbl); in iwx_free_tx_ring()
2277 struct iwx_tx_data *data = &ring->data[i]; in iwx_free_tx_ring()
2279 if (data->m != NULL) { in iwx_free_tx_ring()
2280 bus_dmamap_sync(ring->data_dmat, data->map, in iwx_free_tx_ring()
2282 bus_dmamap_unload(ring->data_dmat, data->map); in iwx_free_tx_ring()
2283 m_freem(data->m); in iwx_free_tx_ring()
2284 data->m = NULL; in iwx_free_tx_ring()
2286 if (data->map != NULL) { in iwx_free_tx_ring()
2287 bus_dmamap_destroy(ring->data_dmat, data->map); in iwx_free_tx_ring()
2288 data->map = NULL; in iwx_free_tx_ring()
2291 if (ring->data_dmat != NULL) { in iwx_free_tx_ring()
2292 bus_dma_tag_destroy(ring->data_dmat); in iwx_free_tx_ring()
2293 ring->data_dmat = NULL; in iwx_free_tx_ring()
2300 if (!sc->sc_msix) { in iwx_enable_rfkill_int()
2301 sc->sc_intmask = IWX_CSR_INT_BIT_RF_KILL; in iwx_enable_rfkill_int()
2302 IWX_WRITE(sc, IWX_CSR_INT_MASK, sc->sc_intmask); in iwx_enable_rfkill_int()
2305 sc->sc_fh_init_mask); in iwx_enable_rfkill_int()
2308 sc->sc_hw_mask = IWX_MSIX_HW_INT_CAUSES_REG_RF_KILL; in iwx_enable_rfkill_int()
2324 * Indicates state of (platform's) hardware RF-Kill switch in iwx_check_rfkill()
2331 sc->sc_flags |= IWX_FLAG_RFKILL; in iwx_check_rfkill()
2333 sc->sc_flags &= ~IWX_FLAG_RFKILL; in iwx_check_rfkill()
2342 if (!sc->sc_msix) { in iwx_enable_interrupts()
2343 sc->sc_intmask = IWX_CSR_INI_SET_MASK; in iwx_enable_interrupts()
2344 IWX_WRITE(sc, IWX_CSR_INT_MASK, sc->sc_intmask); in iwx_enable_interrupts()
2350 sc->sc_hw_mask = sc->sc_hw_init_mask; in iwx_enable_interrupts()
2351 sc->sc_fh_mask = sc->sc_fh_init_mask; in iwx_enable_interrupts()
2353 ~sc->sc_fh_mask); in iwx_enable_interrupts()
2355 ~sc->sc_hw_mask); in iwx_enable_interrupts()
2362 if (!sc->sc_msix) { in iwx_enable_fwload_interrupt()
2363 sc->sc_intmask = IWX_CSR_INT_BIT_ALIVE | IWX_CSR_INT_BIT_FH_RX; in iwx_enable_fwload_interrupt()
2364 IWX_WRITE(sc, IWX_CSR_INT_MASK, sc->sc_intmask); in iwx_enable_fwload_interrupt()
2368 sc->sc_hw_mask = IWX_MSIX_HW_INT_CAUSES_REG_ALIVE; in iwx_enable_fwload_interrupt()
2374 ~sc->sc_fh_init_mask); in iwx_enable_fwload_interrupt()
2375 sc->sc_fh_mask = sc->sc_fh_init_mask; in iwx_enable_fwload_interrupt()
2383 IWX_WRITE(sc, IWX_CSR_INT_MASK, sc->sc_intmask);
2390 if (!sc->sc_msix) { in iwx_disable_interrupts()
2398 sc->sc_fh_init_mask); in iwx_disable_interrupts()
2400 sc->sc_hw_init_mask); in iwx_disable_interrupts()
2409 memset(sc->ict_dma.vaddr, 0, IWX_ICT_SIZE); in iwx_ict_reset()
2410 sc->ict_cur = 0; in iwx_ict_reset()
2417 | sc->ict_dma.paddr >> IWX_ICT_PADDR_SHIFT); in iwx_ict_reset()
2420 sc->sc_flags |= IWX_FLAG_USE_ICT; in iwx_ict_reset()
2513 error = pci_find_cap(sc->sc_dev, PCIY_EXPRESS, &pcie_ptr); in iwx_apm_config()
2519 lctl = pci_read_config(sc->sc_dev, pcie_ptr + PCIER_LINK_CTL, in iwx_apm_config()
2522 sc->sc_pm_support = !(lctl & PCI_PCIE_LCSR_ASPM_L0S); in iwx_apm_config()
2524 cap = pci_read_config(sc->sc_dev, pcie_ptr + PCI_PCIE_DCSR2, in iwx_apm_config()
2527 sc->sc_ltr_enabled = (cap & PCI_PCIE_DCSR2_LTREN) ? 1 : 0; in iwx_apm_config()
2529 DPRINTF(("%s: L1 %sabled - LTR %sabled\n", in iwx_apm_config()
2532 sc->sc_ltr_enabled ? "En" : "Dis")); in iwx_apm_config()
2540 * Start up NIC's basic functionality after it has been reset
2561 * wake device's PCI Express link L1a -> L0s in iwx_apm_init()
2570 * D0U* --> D0A* (powered-up active) state. in iwx_apm_init()
2576 * device-internal resources is supported, e.g. iwx_write_prph() in iwx_apm_init()
2616 * D0A* (powered-up Active) --> D0U* (Uninitialized) state. in iwx_apm_stop()
2627 if (!sc->sc_msix) in iwx_init_msix_hw()
2630 sc->sc_fh_init_mask = ~IWX_READ(sc, IWX_CSR_MSIX_FH_INT_MASK_AD); in iwx_init_msix_hw()
2631 sc->sc_fh_mask = sc->sc_fh_init_mask; in iwx_init_msix_hw()
2632 sc->sc_hw_init_mask = ~IWX_READ(sc, IWX_CSR_MSIX_HW_INT_MASK_AD); in iwx_init_msix_hw()
2633 sc->sc_hw_mask = sc->sc_hw_init_mask; in iwx_init_msix_hw()
2641 if (!sc->sc_msix) { in iwx_conf_msix_hw()
2661 /* Map fallback-queue (command/mgmt) to a single vector */ in iwx_conf_msix_hw()
2672 /* Map non-RX causes to the same vector */ in iwx_conf_msix_hw()
2704 /* Enable non-RX causes interrupts */ in iwx_conf_msix_hw()
2753 if (sc->sc_device_family == IWX_DEVICE_FAMILY_22000) { in iwx_start_hw()
2759 /* Reset the entire device */ in iwx_start_hw()
2763 if (sc->sc_device_family == IWX_DEVICE_FAMILY_22000 && in iwx_start_hw()
2764 sc->sc_integrated) { in iwx_start_hw()
2780 /* Reset the entire device */ in iwx_start_hw()
2803 sc->sc_flags &= ~IWX_FLAG_USE_ICT; in iwx_stop_device()
2806 iwx_reset_rx_ring(sc, &sc->rxq); in iwx_stop_device()
2807 for (i = 0; i < nitems(sc->txq); i++) in iwx_stop_device()
2808 iwx_reset_tx_ring(sc, &sc->txq[i]); in iwx_stop_device()
2810 /* XXX-THJ: Tidy up BA state on stop */ in iwx_stop_device()
2812 struct ieee80211_tx_ba *ba = &ni->ni_tx_ba[i]; in iwx_stop_device()
2813 if (ba->ba_state != IEEE80211_BA_AGREED) in iwx_stop_device()
2821 if (sc->sc_nic_locks > 0) in iwx_stop_device()
2823 DEVNAME(sc), sc->sc_nic_locks); in iwx_stop_device()
2824 sc->sc_nic_locks = 0; in iwx_stop_device()
2829 /* Reset the on-board processor. */ in iwx_stop_device()
2834 * Upon stop, the IVAR table gets erased, so msi-x won't in iwx_stop_device()
2835 * work. This causes a bug in RF-KILL flows, since the interrupt in iwx_stop_device()
2838 * Configure the IVAR table again after reset. in iwx_stop_device()
2855 iwx_dma_contig_free(&sc->pnvm_dma); in iwx_stop_device()
2864 radio_cfg_type = (sc->sc_fw_phy_config & IWX_FW_PHY_CFG_RADIO_TYPE) >> in iwx_nic_config()
2866 radio_cfg_step = (sc->sc_fw_phy_config & IWX_FW_PHY_CFG_RADIO_STEP) >> in iwx_nic_config()
2868 radio_cfg_dash = (sc->sc_fw_phy_config & IWX_FW_PHY_CFG_RADIO_DASH) >> in iwx_nic_config()
2871 reg_val |= IWX_CSR_HW_REV_STEP(sc->sc_hw_rev) << in iwx_nic_config()
2873 reg_val |= IWX_CSR_HW_REV_DASH(sc->sc_hw_rev) << in iwx_nic_config()
2913 if (sc->sc_device_family < IWX_DEVICE_FAMILY_AX210) in iwx_nic_init()
2945 struct iwx_tx_ring *ring = &sc->txq[qid]; in iwx_enable_txq()
2962 cmd_v0.byte_cnt_addr = htole64(ring->bc_tbl.paddr); in iwx_enable_txq()
2963 cmd_v0.tfdq_addr = htole64(ring->desc_dma.paddr); in iwx_enable_txq()
2970 cmd_v3.u.add.tfdq_dram_addr = htole64(ring->desc_dma.paddr); in iwx_enable_txq()
2971 cmd_v3.u.add.bc_dram_addr = htole64(ring->bc_tbl.paddr); in iwx_enable_txq()
2991 if (!pkt || (pkt->hdr.flags & IWX_CMD_FAILED_MSK)) { in iwx_enable_txq()
3002 resp = (void *)pkt->data; in iwx_enable_txq()
3003 fwqid = le16toh(resp->queue_number); in iwx_enable_txq()
3004 wr_idx = le16toh(resp->write_pointer); in iwx_enable_txq()
3013 if (wr_idx != ring->cur_hw) { in iwx_enable_txq()
3014 DPRINTF(("%s: === (wr_idx != ring->cur_hw)\n", __func__)); in iwx_enable_txq()
3019 sc->qenablemsk |= (1 << qid); in iwx_enable_txq()
3020 ring->tid = tid; in iwx_enable_txq()
3037 struct iwx_tx_ring *ring = &sc->txq[qid]; in iwx_disable_txq()
3073 if (!pkt || (pkt->hdr.flags & IWX_CMD_FAILED_MSK)) { in iwx_disable_txq()
3078 sc->qenablemsk &= ~(1 << qid); in iwx_disable_txq()
3094 sc->sc_rate_n_flags_version = 2; in iwx_post_alive()
3096 sc->sc_rate_n_flags_version = 1; in iwx_post_alive()
3107 .id_and_color = htole32(IWX_FW_CMD_ID_AND_COLOR(in->in_id, in iwx_schedule_session_protection()
3108 in->in_color)), in iwx_schedule_session_protection()
3119 sc->sc_flags |= IWX_FLAG_TE_ACTIVE; in iwx_schedule_session_protection()
3127 .id_and_color = htole32(IWX_FW_CMD_ID_AND_COLOR(in->in_id, in iwx_unprotect_session()
3128 in->in_color)), in iwx_unprotect_session()
3136 if ((sc->sc_flags & IWX_FLAG_TE_ACTIVE) == 0) in iwx_unprotect_session()
3141 sc->sc_flags &= ~IWX_FLAG_TE_ACTIVE; in iwx_unprotect_session()
3154 tx_ant = ((sc->sc_fw_phy_config & IWX_FW_PHY_CFG_TX_CHAIN) in iwx_fw_valid_tx_ant()
3157 if (sc->sc_nvm.valid_tx_ant) in iwx_fw_valid_tx_ant()
3158 tx_ant &= sc->sc_nvm.valid_tx_ant; in iwx_fw_valid_tx_ant()
3168 rx_ant = ((sc->sc_fw_phy_config & IWX_FW_PHY_CFG_RX_CHAIN) in iwx_fw_valid_rx_ant()
3171 if (sc->sc_nvm.valid_rx_ant) in iwx_fw_valid_rx_ant()
3172 rx_ant &= sc->sc_nvm.valid_rx_ant; in iwx_fw_valid_rx_ant()
3181 struct iwx_softc *sc = ic->ic_softc; in iwx_init_channel_map()
3182 struct iwx_nvm_data *data = &sc->sc_nvm; in iwx_init_channel_map()
3188 if (sc->sc_uhb_supported) { in iwx_init_channel_map()
3196 /* 2.4Ghz; 1-13: 11b/g channels. */ in iwx_init_channel_map()
3197 if (!data->sku_cap_band_24GHz_enable) in iwx_init_channel_map()
3211 if (sc->sc_rsp_vers == IWX_FBSD_RSP_V4) { in iwx_init_channel_map()
3213 sc->sc_rsp_info.rsp_v4.regulatory.channel_profile + ch_idx); in iwx_init_channel_map()
3216 sc->sc_rsp_info.rsp_v3.regulatory.channel_profile + ch_idx); in iwx_init_channel_map()
3224 /* XXX-BZ nflags RADAR/DFS/INDOOR */ in iwx_init_channel_map()
3235 if (!data->sku_cap_band_52GHz_enable) in iwx_init_channel_map()
3250 if (sc->sc_rsp_vers == IWX_FBSD_RSP_V4) in iwx_init_channel_map()
3252 sc->sc_rsp_info.rsp_v4.regulatory.channel_profile + ch_idx); in iwx_init_channel_map()
3255 sc->sc_rsp_info.rsp_v3.regulatory.channel_profile + ch_idx); in iwx_init_channel_map()
3267 /* XXX-BZ nflags RADAR/DFS/INDOOR */ in iwx_init_channel_map()
3284 return !sc->sc_nvm.sku_cap_mimo_disable; in iwx_mimo_enabled()
3291 reorder_buf->head_sn = ssn; in iwx_init_reorder_buffer()
3292 reorder_buf->num_stored = 0; in iwx_init_reorder_buffer()
3293 reorder_buf->buf_size = buf_size; in iwx_init_reorder_buffer()
3294 reorder_buf->last_amsdu = 0; in iwx_init_reorder_buffer()
3295 reorder_buf->last_sub_index = 0; in iwx_init_reorder_buffer()
3296 reorder_buf->removed = 0; in iwx_init_reorder_buffer()
3297 reorder_buf->valid = 0; in iwx_init_reorder_buffer()
3298 reorder_buf->consec_oldsn_drops = 0; in iwx_init_reorder_buffer()
3299 reorder_buf->consec_oldsn_ampdu_gp2 = 0; in iwx_init_reorder_buffer()
3300 reorder_buf->consec_oldsn_prev_drop = 0; in iwx_init_reorder_buffer()
3306 struct iwx_reorder_buffer *reorder_buf = &rxba->reorder_buf; in iwx_clear_reorder_buffer()
3308 reorder_buf->removed = 1; in iwx_clear_reorder_buffer()
3309 rxba->baid = IWX_RX_REORDER_DATA_INVALID_BAID; in iwx_clear_reorder_buffer()
3319 for (i = 0; i < nitems(sc->sc_rxba_data); i++) { in iwx_find_rxba_data()
3320 if (sc->sc_rxba_data[i].baid == in iwx_find_rxba_data()
3323 if (sc->sc_rxba_data[i].tid == tid) in iwx_find_rxba_data()
3324 return &sc->sc_rxba_data[i]; in iwx_find_rxba_data()
3355 *baid = rxba->baid; in iwx_sta_rx_agg_baid_cfg_cmd()
3360 cmd.remove_v1.baid = rxba->baid; in iwx_sta_rx_agg_baid_cfg_cmd()
3373 if (new_baid >= nitems(sc->sc_rxba_data)) in iwx_sta_rx_agg_baid_cfg_cmd()
3389 if (start && sc->sc_rx_ba_sessions >= IWX_MAX_RX_BA_SESSIONS) { in iwx_sta_rx_agg()
3393 if (isset(sc->sc_enabled_capa, IWX_UCODE_TLV_CAPA_BAID_ML_SUPPORT)) { in iwx_sta_rx_agg()
3405 rxba = &sc->sc_rxba_data[baid]; in iwx_sta_rx_agg()
3409 if (rxba->baid != IWX_RX_REORDER_DATA_INVALID_BAID) { in iwx_sta_rx_agg()
3412 rxba->sta_id = IWX_STATION_ID; in iwx_sta_rx_agg()
3413 rxba->tid = tid; in iwx_sta_rx_agg()
3414 rxba->baid = baid; in iwx_sta_rx_agg()
3415 rxba->timeout = timeout_val; in iwx_sta_rx_agg()
3416 getmicrouptime(&rxba->last_rx); in iwx_sta_rx_agg()
3417 iwx_init_reorder_buffer(&rxba->reorder_buf, ssn, in iwx_sta_rx_agg()
3427 sc->sc_rx_ba_sessions++; in iwx_sta_rx_agg()
3428 } else if (sc->sc_rx_ba_sessions > 0) in iwx_sta_rx_agg()
3429 sc->sc_rx_ba_sessions--; in iwx_sta_rx_agg()
3433 * @brief Allocate an A-MPDU / aggregation session for the given node and TID.
3446 qid = sc->aggqid[tid]; in iwx_sta_tx_agg_start()
3449 qid = fls(sc->qenablemsk); in iwx_sta_tx_agg_start()
3458 if ((sc->qenablemsk & (1 << qid)) == 0) { in iwx_sta_tx_agg_start()
3471 ni->ni_tx_ampdu[tid].txa_flags = IEEE80211_AGGR_RUNNING; in iwx_sta_tx_agg_start()
3472 DPRINTF(("%s: will set sc->aggqid[%i]=%i\n", __func__, tid, qid)); in iwx_sta_tx_agg_start()
3473 sc->aggqid[tid] = qid; in iwx_sta_tx_agg_start()
3480 struct ieee80211com *ic = &sc->sc_ic; in iwx_ba_rx_task()
3481 struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); in iwx_ba_rx_task()
3482 struct ieee80211_node *ni = vap->iv_bss; in iwx_ba_rx_task()
3487 if (sc->sc_flags & IWX_FLAG_SHUTDOWN) in iwx_ba_rx_task()
3489 if (sc->ba_rx.start_tidmask & (1 << tid)) { in iwx_ba_rx_task()
3490 struct iwx_rx_ba *ba = &sc->ni_rx_ba[tid]; in iwx_ba_rx_task()
3491 DPRINTF(("%s: ba->ba_flags=%x\n", __func__, in iwx_ba_rx_task()
3492 ba->ba_flags)); in iwx_ba_rx_task()
3493 if (ba->ba_flags == IWX_BA_DONE) { in iwx_ba_rx_task()
3501 iwx_sta_rx_agg(sc, ni, tid, ba->ba_winstart, in iwx_ba_rx_task()
3502 ba->ba_winsize, ba->ba_timeout_val, 1); in iwx_ba_rx_task()
3503 sc->ba_rx.start_tidmask &= ~(1 << tid); in iwx_ba_rx_task()
3504 ba->ba_flags = IWX_BA_DONE; in iwx_ba_rx_task()
3505 } else if (sc->ba_rx.stop_tidmask & (1 << tid)) { in iwx_ba_rx_task()
3507 sc->ba_rx.stop_tidmask &= ~(1 << tid); in iwx_ba_rx_task()
3514 * @brief Task called to setup a deferred block-ack session.
3517 * in sc->ba_tx.start_tidmask.
3525 struct ieee80211com *ic = &sc->sc_ic; in iwx_ba_tx_task()
3526 struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); in iwx_ba_tx_task()
3527 struct ieee80211_node *ni = vap->iv_bss; in iwx_ba_tx_task()
3535 if (sc->sc_flags & IWX_FLAG_SHUTDOWN) in iwx_ba_tx_task()
3537 tap = &ni->ni_tx_ampdu[tid]; in iwx_ba_tx_task()
3540 if (sc->ba_tx.start_tidmask & (1 << tid)) { in iwx_ba_tx_task()
3544 sc->ba_tx.start_tidmask &= ~(1 << tid); in iwx_ba_tx_task()
3567 memset(data->hw_addr, 0, sizeof(data->hw_addr)); in iwx_set_mac_addr_from_csr()
3575 iwx_flip_hw_address(mac_addr0, mac_addr1, data->hw_addr); in iwx_set_mac_addr_from_csr()
3578 if (iwx_is_valid_mac_addr(data->hw_addr)) { in iwx_set_mac_addr_from_csr()
3586 iwx_flip_hw_address(mac_addr0, mac_addr1, data->hw_addr); in iwx_set_mac_addr_from_csr()
3624 struct iwx_nvm_data *nvm = &sc->sc_nvm; in iwx_nvm_get()
3642 int v4 = isset(sc->sc_ucode_api, IWX_UCODE_TLV_API_REGULATORY_NVM_INFO); in iwx_nvm_get()
3663 if (!iwx_is_valid_mac_addr(nvm->hw_addr)) { in iwx_nvm_get()
3669 rsp = (void *)hcmd.resp_pkt->data; in iwx_nvm_get()
3672 nvm->nvm_version = le16toh(rsp->general.nvm_version); in iwx_nvm_get()
3673 nvm->n_hw_addrs = rsp->general.n_hw_addrs; in iwx_nvm_get()
3676 mac_flags = le32toh(rsp->mac_sku.mac_sku_flags); in iwx_nvm_get()
3677 nvm->sku_cap_11ac_enable = in iwx_nvm_get()
3679 nvm->sku_cap_11n_enable = in iwx_nvm_get()
3681 nvm->sku_cap_11ax_enable = in iwx_nvm_get()
3683 nvm->sku_cap_band_24GHz_enable = in iwx_nvm_get()
3685 nvm->sku_cap_band_52GHz_enable = in iwx_nvm_get()
3687 nvm->sku_cap_mimo_disable = in iwx_nvm_get()
3691 nvm->valid_tx_ant = (uint8_t)le32toh(rsp->phy_sku.tx_chains); in iwx_nvm_get()
3692 nvm->valid_rx_ant = (uint8_t)le32toh(rsp->phy_sku.rx_chains); in iwx_nvm_get()
3694 if (le32toh(rsp->regulatory.lar_enabled) && in iwx_nvm_get()
3695 isset(sc->sc_enabled_capa, IWX_UCODE_TLV_CAPA_LAR_SUPPORT)) { in iwx_nvm_get()
3696 nvm->lar_enabled = 1; in iwx_nvm_get()
3699 memcpy(&sc->sc_rsp_info, rsp, resp_len); in iwx_nvm_get()
3701 sc->sc_rsp_vers = IWX_FBSD_RSP_V4; in iwx_nvm_get()
3703 sc->sc_rsp_vers = IWX_FBSD_RSP_V3; in iwx_nvm_get()
3718 sc->sc_uc.uc_intr = 0; in iwx_load_firmware()
3719 sc->sc_uc.uc_ok = 0; in iwx_load_firmware()
3721 fws = &sc->sc_fw.fw_sects[IWX_UCODE_TYPE_REGULAR]; in iwx_load_firmware()
3722 if (sc->sc_device_family >= IWX_DEVICE_FAMILY_AX210) in iwx_load_firmware()
3732 err = msleep(&sc->sc_uc, &sc->sc_mtx, 0, "iwxuc", hz); in iwx_load_firmware()
3733 if (err || !sc->sc_uc.uc_ok) { in iwx_load_firmware()
3738 iwx_dma_contig_free(&sc->iml_dma); in iwx_load_firmware()
3741 if (!sc->sc_uc.uc_ok) in iwx_load_firmware()
3790 len -= sizeof(*tlv); in iwx_pnvm_handle_section()
3793 tlv_len = le32toh(tlv->length); in iwx_pnvm_handle_section()
3794 tlv_type = le32toh(tlv->type); in iwx_pnvm_handle_section()
3823 if (mac_type == IWX_CSR_HW_REV_TYPE(sc->sc_hw_rev) && in iwx_pnvm_handle_section()
3824 rf_id == IWX_CSR_HW_RFID_TYPE(sc->sc_hw_rf_id)) in iwx_pnvm_handle_section()
3832 data_len = tlv_len - sizeof(*section); in iwx_pnvm_handle_section()
3846 memcpy(tmp + size, section->data, data_len); in iwx_pnvm_handle_section()
3861 len -= roundup(tlv_len, 4); in iwx_pnvm_handle_section()
3870 err = iwx_dma_contig_alloc(sc->sc_dmat, &sc->pnvm_dma, size, 1); in iwx_pnvm_handle_section()
3877 memcpy(sc->pnvm_dma.vaddr, pnvm_data, size); in iwx_pnvm_handle_section()
3879 sc->sc_pnvm_ver = sha1; in iwx_pnvm_handle_section()
3893 len -= sizeof(*tlv); in iwx_pnvm_parse()
3896 tlv_len = le32toh(tlv->length); in iwx_pnvm_parse()
3897 tlv_type = le32toh(tlv->type); in iwx_pnvm_parse()
3907 len -= roundup(tlv_len, 4); in iwx_pnvm_parse()
3909 if (sc->sc_sku_id[0] == le32toh(sku_id->data[0]) && in iwx_pnvm_parse()
3910 sc->sc_sku_id[1] == le32toh(sku_id->data[1]) && in iwx_pnvm_parse()
3911 sc->sc_sku_id[2] == le32toh(sku_id->data[2]) && in iwx_pnvm_parse()
3916 len -= roundup(tlv_len, 4); in iwx_pnvm_parse()
3930 prph_scratch = sc->prph_scratch_dma.vaddr; in iwx_ctxt_info_gen3_set_pnvm()
3931 prph_sc_ctrl = &prph_scratch->ctrl_cfg; in iwx_ctxt_info_gen3_set_pnvm()
3933 prph_sc_ctrl->pnvm_cfg.pnvm_base_addr = htole64(sc->pnvm_dma.paddr); in iwx_ctxt_info_gen3_set_pnvm()
3934 prph_sc_ctrl->pnvm_cfg.pnvm_size = htole32(sc->pnvm_dma.size); in iwx_ctxt_info_gen3_set_pnvm()
3936 bus_dmamap_sync(sc->sc_dmat, sc->pnvm_dma.map, BUS_DMASYNC_PREWRITE); in iwx_ctxt_info_gen3_set_pnvm()
3940 * Load platform-NVM (non-volatile-memory) data from the filesystem.
3944 * Pre-AX210 devices store NVM data onboard.
3953 if (sc->sc_sku_id[0] == 0 && in iwx_load_pnvm()
3954 sc->sc_sku_id[1] == 0 && in iwx_load_pnvm()
3955 sc->sc_sku_id[2] == 0) in iwx_load_pnvm()
3958 if (sc->sc_pnvm_name) { in iwx_load_pnvm()
3959 if (sc->pnvm_dma.vaddr == NULL) { in iwx_load_pnvm()
3961 pnvm = firmware_get(sc->sc_pnvm_name); in iwx_load_pnvm()
3964 DEVNAME(sc), sc->sc_pnvm_name, err); in iwx_load_pnvm()
3968 sc->sc_pnvm = pnvm; in iwx_load_pnvm()
3970 err = iwx_pnvm_parse(sc, pnvm->data, pnvm->datasize); in iwx_load_pnvm()
3992 while ((sc->sc_init_complete & wait_flags) != wait_flags) { in iwx_load_pnvm()
3993 err = msleep(&sc->sc_init_complete, &sc->sc_mtx, 0, "iwxinit", 2 * hz); in iwx_load_pnvm()
4019 phy_cfg_cmd.phy_cfg = htole32(sc->sc_fw_phy_config); in iwx_send_phy_cfg_cmd()
4021 sc->sc_default_calib[IWX_UCODE_TYPE_REGULAR].event_trigger; in iwx_send_phy_cfg_cmd()
4023 sc->sc_default_calib[IWX_UCODE_TYPE_REGULAR].flow_trigger; in iwx_send_phy_cfg_cmd()
4056 if (sc->sc_device_family >= IWX_DEVICE_FAMILY_AX210) { in iwx_load_ucode_wait_alive()
4078 if ((sc->sc_flags & IWX_FLAG_RFKILL) && !readnvm) { in iwx_run_init_mvm_ucode()
4084 sc->sc_init_complete = 0; in iwx_run_init_mvm_ucode()
4114 while ((sc->sc_init_complete & wait_flags) != wait_flags) { in iwx_run_init_mvm_ucode()
4115 err = msleep(&sc->sc_init_complete, &sc->sc_mtx, 0, "iwxinit", 2 * hz); in iwx_run_init_mvm_ucode()
4135 IEEE80211_ADDR_COPY(sc->sc_ic.ic_macaddr, sc->sc_nvm.hw_addr); in iwx_run_init_mvm_ucode()
4147 if (!sc->sc_ltr_enabled) in iwx_config_ltr()
4157 struct iwx_rx_data *data = &ring->data[idx]; in iwx_update_rx_desc()
4159 if (sc->sc_device_family >= IWX_DEVICE_FAMILY_AX210) { in iwx_update_rx_desc()
4160 struct iwx_rx_transfer_desc *desc = ring->desc; in iwx_update_rx_desc()
4163 bus_dmamap_sync(ring->data_dmat, data->map, in iwx_update_rx_desc()
4166 ((uint64_t *)ring->desc)[idx] = in iwx_update_rx_desc()
4168 bus_dmamap_sync(ring->data_dmat, data->map, in iwx_update_rx_desc()
4176 struct iwx_rx_ring *ring = &sc->rxq; in iwx_rx_addbuf()
4177 struct iwx_rx_data *data = &ring->data[idx]; in iwx_rx_addbuf()
4188 if (data->m != NULL) { in iwx_rx_addbuf()
4189 bus_dmamap_unload(ring->data_dmat, data->map); in iwx_rx_addbuf()
4193 m->m_len = m->m_pkthdr.len = m->m_ext.ext_size; in iwx_rx_addbuf()
4194 err = bus_dmamap_load_mbuf_sg(ring->data_dmat, data->map, m, &seg, in iwx_rx_addbuf()
4203 data->m = m; in iwx_rx_addbuf()
4204 bus_dmamap_sync(ring->data_dmat, data->map, BUS_DMASYNC_PREREAD); in iwx_rx_addbuf()
4217 if (sc->sc_device_family >= IWX_DEVICE_FAMILY_AX210) { in iwx_rxmq_get_signal_strength()
4218 energy_a = desc->v3.energy_a; in iwx_rxmq_get_signal_strength()
4219 energy_b = desc->v3.energy_b; in iwx_rxmq_get_signal_strength()
4221 energy_a = desc->v1.energy_a; in iwx_rxmq_get_signal_strength()
4222 energy_b = desc->v1.energy_b; in iwx_rxmq_get_signal_strength()
4224 energy_a = energy_a ? -energy_a : -256; in iwx_rxmq_get_signal_strength()
4225 energy_b = energy_b ? -energy_b : -256; in iwx_rxmq_get_signal_strength()
4234 if (sc->sc_device_family >= IWX_DEVICE_FAMILY_AX210) in iwx_rxmq_get_chains()
4235 return ((desc->v3.rate_n_flags & IWX_RATE_MCS_ANT_AB_MSK) >> in iwx_rxmq_get_chains()
4238 return ((desc->v1.rate_n_flags & IWX_RATE_MCS_ANT_AB_MSK) >> in iwx_rxmq_get_chains()
4246 struct iwx_rx_phy_info *phy_info = (void *)pkt->data; in iwx_rx_rx_phy_cmd()
4247 struct iwx_cmd_header *cmd_hdr = &pkt->hdr; in iwx_rx_rx_phy_cmd()
4248 int qid = cmd_hdr->qid; in iwx_rx_rx_phy_cmd()
4249 struct iwx_tx_ring *ring = &sc->txq[qid]; in iwx_rx_rx_phy_cmd()
4251 bus_dmamap_sync(ring->data_dmat, data->map, BUS_DMASYNC_PREREAD); in iwx_rx_rx_phy_cmd()
4252 memcpy(&sc->sc_last_phy_info, phy_info, sizeof(sc->sc_last_phy_info)); in iwx_rx_rx_phy_cmd()
4265 noise = le32toh(stats->beacon_silence_rssi[i]) & 0xff; in iwx_get_noise()
4273 return (nbant == 0) ? -127 : (total / nbant) - 107; in iwx_get_noise()
4281 struct ieee80211com *ic = &sc->sc_ic;
4295 if (k == NULL || k->k_cipher != IEEE80211_CIPHER_CCMP)
4304 prsc = &k->k_rsc[tid];
4306 /* Extract the 48-bit PN from the CCMP header. */
4313 if (rxi->rxi_flags & IEEE80211_RXI_HWDEC_SAME_PN) {
4315 ic->ic_stats.is_ccmp_replays++;
4319 ic->ic_stats.is_ccmp_replays++;
4345 type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK; in iwx_rx_hwdecrypt()
4350 subtype = wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK; in iwx_rx_hwdecrypt()
4356 if (((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) != in iwx_rx_hwdecrypt()
4358 && (wh->i_fc[1] & IEEE80211_FC1_PROTECTED)) { in iwx_rx_hwdecrypt()
4385 struct ieee80211com *ic = &sc->sc_ic; in iwx_rx_frame()
4386 struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); in iwx_rx_frame()
4394 if (chanidx < 0 || chanidx >= nitems(ic->ic_channels)) { in iwx_rx_frame()
4404 for (int i = 0; i < ic->ic_nchans; i++) { in iwx_rx_frame()
4405 if (ic->ic_channels[i].ic_ieee == channel) { in iwx_rx_frame()
4409 ic->ic_curchan = &ic->ic_channels[chanidx]; in iwx_rx_frame()
4415 if ((rxi->rxi_flags & IEEE80211_RXI_HWDEC) && in iwx_rx_frame()
4423 struct iwx_rx_radiotap_header *tap = &sc->sc_rxtap; in iwx_rx_frame()
4428 tap->wr_flags = 0; in iwx_rx_frame()
4430 tap->wr_flags |= IEEE80211_RADIOTAP_F_SHORTPRE; in iwx_rx_frame()
4431 tap->wr_chan_freq = in iwx_rx_frame()
4432 htole16(ic->ic_channels[chanidx].ic_freq); in iwx_rx_frame()
4433 chan_flags = ic->ic_channels[chanidx].ic_flags; in iwx_rx_frame()
4435 if (ic->ic_curmode != IEEE80211_MODE_11N && in iwx_rx_frame()
4436 ic->ic_curmode != IEEE80211_MODE_11AC) { in iwx_rx_frame()
4440 if (ic->ic_curmode != IEEE80211_MODE_11AC) in iwx_rx_frame()
4445 tap->wr_chan_flags = htole16(chan_flags); in iwx_rx_frame()
4446 tap->wr_dbm_antsignal = rssi; in iwx_rx_frame()
4447 tap->wr_dbm_antnoise = (int8_t)sc->sc_noise; in iwx_rx_frame()
4448 tap->wr_tsft = device_timestamp; in iwx_rx_frame()
4450 if (sc->sc_rate_n_flags_version >= 2) { in iwx_rx_frame()
4463 if (rs && ridx < rs->rs_nrates) { in iwx_rx_frame()
4464 rate = (rs->rs_rates[ridx] & in iwx_rx_frame()
4478 tap->wr_rate = (0x80 | mcs); in iwx_rx_frame()
4482 case 10: tap->wr_rate = 2; break; in iwx_rx_frame()
4483 case 20: tap->wr_rate = 4; break; in iwx_rx_frame()
4484 case 55: tap->wr_rate = 11; break; in iwx_rx_frame()
4485 case 110: tap->wr_rate = 22; break; in iwx_rx_frame()
4487 case 0xd: tap->wr_rate = 12; break; in iwx_rx_frame()
4488 case 0xf: tap->wr_rate = 18; break; in iwx_rx_frame()
4489 case 0x5: tap->wr_rate = 24; break; in iwx_rx_frame()
4490 case 0x7: tap->wr_rate = 36; break; in iwx_rx_frame()
4491 case 0x9: tap->wr_rate = 48; break; in iwx_rx_frame()
4492 case 0xb: tap->wr_rate = 72; break; in iwx_rx_frame()
4493 case 0x1: tap->wr_rate = 96; break; in iwx_rx_frame()
4494 case 0x3: tap->wr_rate = 108; break; in iwx_rx_frame()
4496 default: tap->wr_rate = 0; in iwx_rx_frame()
4498 // XXX hack - this needs rebased with the new rate stuff anyway in iwx_rx_frame()
4499 tap->wr_rate = rate; in iwx_rx_frame()
4505 if (ieee80211_input_mimo_all(ic, m) == -1) in iwx_rx_frame()
4506 printf("%s:%d input_all returned -1\n", __func__, __LINE__); in iwx_rx_frame()
4509 if (ieee80211_input_mimo(ni, m) == -1) in iwx_rx_frame()
4510 printf("%s:%d input_all returned -1\n", __func__, __LINE__); in iwx_rx_frame()
4520 struct ieee80211com *ic = &sc->sc_ic; in iwx_rx_mpdu_mq()
4521 struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); in iwx_rx_mpdu_mq()
4522 struct ieee80211_node *ni = vap->iv_bss; in iwx_rx_mpdu_mq()
4533 if (sc->sc_device_family >= IWX_DEVICE_FAMILY_AX210) in iwx_rx_mpdu_mq()
4545 if (!(desc->status & htole16(IWX_RX_MPDU_RES_STATUS_CRC_OK)) || in iwx_rx_mpdu_mq()
4546 !(desc->status & htole16(IWX_RX_MPDU_RES_STATUS_OVERRUN_OK))) { in iwx_rx_mpdu_mq()
4547 printf("%s: Bad CRC or FIFO: 0x%08X\n", __func__, desc->status); in iwx_rx_mpdu_mq()
4552 len = le16toh(desc->mpdu_len); in iwx_rx_mpdu_mq()
4553 if (ic->ic_opmode == IEEE80211_M_MONITOR) { in iwx_rx_mpdu_mq()
4564 if (len > maxlen - desc_size) { in iwx_rx_mpdu_mq()
4570 m->m_data = (char *)pktdata + desc_size; in iwx_rx_mpdu_mq()
4571 m->m_pkthdr.len = m->m_len = len; in iwx_rx_mpdu_mq()
4574 if (desc->mac_flags2 & IWX_RX_MPDU_MFLG2_PAD) { in iwx_rx_mpdu_mq()
4576 int type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK; in iwx_rx_mpdu_mq()
4578 switch (wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK) { in iwx_rx_mpdu_mq()
4592 if ((le16toh(desc->status) & in iwx_rx_mpdu_mq()
4599 memmove(m->m_data + 2, m->m_data, hdrlen); in iwx_rx_mpdu_mq()
4604 if ((le16toh(desc->status) & in iwx_rx_mpdu_mq()
4610 /* If it's a HT node then perform re-order processing */ in iwx_rx_mpdu_mq()
4611 if (ni->ni_flags & IEEE80211_NODE_HT) in iwx_rx_mpdu_mq()
4612 m->m_flags |= M_AMPDU; in iwx_rx_mpdu_mq()
4615 * Hardware de-aggregates A-MSDUs and copies the same MAC header in iwx_rx_mpdu_mq()
4616 * in place for each subframe. But it leaves the 'A-MSDU present' in iwx_rx_mpdu_mq()
4627 if (desc->mac_flags2 & IWX_RX_MPDU_MFLG2_AMSDU) { in iwx_rx_mpdu_mq()
4629 uint8_t subframe_idx = (desc->amsdu_info & in iwx_rx_mpdu_mq()
4652 (k->wk_cipher->ic_cipher == IEEE80211_CIPHER_AES_CCM) && in iwx_rx_mpdu_mq()
4653 iwx_rx_hwdecrypt(sc, m, le16toh(desc->status)/*, &rxi*/)) { in iwx_rx_mpdu_mq()
4659 if (sc->sc_device_family >= IWX_DEVICE_FAMILY_AX210) { in iwx_rx_mpdu_mq()
4660 rate_n_flags = le32toh(desc->v3.rate_n_flags); in iwx_rx_mpdu_mq()
4661 chanidx = desc->v3.channel; in iwx_rx_mpdu_mq()
4662 device_timestamp = le32toh(desc->v3.gp2_on_air_rise); in iwx_rx_mpdu_mq()
4664 rate_n_flags = le32toh(desc->v1.rate_n_flags); in iwx_rx_mpdu_mq()
4665 chanidx = desc->v1.channel; in iwx_rx_mpdu_mq()
4666 device_timestamp = le32toh(desc->v1.gp2_on_air_rise); in iwx_rx_mpdu_mq()
4669 phy_info = le16toh(desc->phy_info); in iwx_rx_mpdu_mq()
4672 rssi = (0 - IWX_MIN_DBM) + rssi; /* normalize */ in iwx_rx_mpdu_mq()
4673 rssi = MIN(rssi, (IWX_MAX_DBM - IWX_MIN_DBM)); /* clip to max. 100% */ in iwx_rx_mpdu_mq()
4692 rxs.c_nf = sc->sc_noise; in iwx_rx_mpdu_mq()
4717 memmove(m->m_data + TRIM, m->m_data, hdrlen); in iwx_rx_mpdu_mq()
4722 iwx_rx_frame(sc, m, chanidx, le16toh(desc->status), in iwx_rx_mpdu_mq()
4730 struct iwx_tfh_tfd *desc = &ring->desc[idx]; in iwx_clear_tx_desc()
4731 uint8_t num_tbs = le16toh(desc->num_tbs) & 0x1f; in iwx_clear_tx_desc()
4734 /* First TB is never cleared - it is bidirectional DMA data. */ in iwx_clear_tx_desc()
4736 struct iwx_tfh_tb *tb = &desc->tbs[i]; in iwx_clear_tx_desc()
4739 desc->num_tbs = htole16(1); in iwx_clear_tx_desc()
4741 bus_dmamap_sync(ring->desc_dma.tag, ring->desc_dma.map, in iwx_clear_tx_desc()
4749 bus_dmamap_sync(ring->data_dmat, txd->map, BUS_DMASYNC_POSTWRITE); in iwx_txd_done()
4750 bus_dmamap_unload(ring->data_dmat, txd->map); in iwx_txd_done()
4752 ieee80211_tx_complete(&txd->in->in_ni, txd->m, 0); in iwx_txd_done()
4753 txd->m = NULL; in iwx_txd_done()
4754 txd->in = NULL; in iwx_txd_done()
4762 while (ring->tail_hw != idx) { in iwx_txq_advance()
4763 txd = &ring->data[ring->tail]; in iwx_txq_advance()
4764 if (txd->m != NULL) { in iwx_txq_advance()
4765 iwx_clear_tx_desc(sc, ring, ring->tail); in iwx_txq_advance()
4766 iwx_tx_update_byte_tbl(sc, ring, ring->tail, 0, 0); in iwx_txq_advance()
4768 ring->queued--; in iwx_txq_advance()
4769 if (ring->queued < 0) in iwx_txq_advance()
4772 ring->tail = (ring->tail + 1) % IWX_TX_RING_COUNT; in iwx_txq_advance()
4773 ring->tail_hw = (ring->tail_hw + 1) % sc->max_tfd_queue_size; in iwx_txq_advance()
4781 struct ieee80211com *ic = &sc->sc_ic; in iwx_rx_tx_cmd()
4783 struct iwx_cmd_header *cmd_hdr = &pkt->hdr; in iwx_rx_tx_cmd()
4784 int qid = cmd_hdr->qid, status, txfail; in iwx_rx_tx_cmd()
4785 struct iwx_tx_ring *ring = &sc->txq[qid]; in iwx_rx_tx_cmd()
4786 struct iwx_tx_resp *tx_resp = (void *)pkt->data; in iwx_rx_tx_cmd()
4789 int idx = cmd_hdr->idx; in iwx_rx_tx_cmd()
4790 struct iwx_tx_data *txd = &ring->data[idx]; in iwx_rx_tx_cmd()
4791 struct mbuf *m = txd->m; in iwx_rx_tx_cmd()
4793 bus_dmamap_sync(ring->data_dmat, data->map, BUS_DMASYNC_POSTREAD); in iwx_rx_tx_cmd()
4798 if (qid < IWX_FIRST_AGG_TX_QUEUE && tx_resp->frame_count > 1) in iwx_rx_tx_cmd()
4801 tx_resp->frame_count * sizeof(tx_resp->status) > len) in iwx_rx_tx_cmd()
4804 sc->sc_tx_timer[qid] = 0; in iwx_rx_tx_cmd()
4806 if (tx_resp->frame_count > 1) /* A-MPDU */ in iwx_rx_tx_cmd()
4809 status = le16toh(tx_resp->status.status) & IWX_TX_STATUS_MSK; in iwx_rx_tx_cmd()
4815 ieee80211_tx_complete(&in->in_ni, m, txfail); in iwx_rx_tx_cmd()
4820 if_inc_counter(ifp, IFCOUNTER_OBYTES, m->m_pkthdr.len); in iwx_rx_tx_cmd()
4822 if (m->m_flags & M_MCAST) in iwx_rx_tx_cmd()
4829 * Frames up to this index (non-inclusive) can now be freed. in iwx_rx_tx_cmd()
4831 memcpy(&ssn, &tx_resp->status + tx_resp->frame_count, sizeof(ssn)); in iwx_rx_tx_cmd()
4833 if (ssn < sc->max_tfd_queue_size) { in iwx_rx_tx_cmd()
4844 if (ring->queued < iwx_lomark) { in iwx_clear_oactive()
4845 sc->qfullmsk &= ~(1 << ring->qid); in iwx_clear_oactive()
4846 if (sc->qfullmsk == 0 /* && ifq_is_oactive(&ifp->if_snd) */) { in iwx_clear_oactive()
4860 struct iwx_compressed_ba_notif *ba_res = (void *)pkt->data; in iwx_rx_compressed_ba()
4861 struct ieee80211com *ic = &sc->sc_ic; in iwx_rx_compressed_ba()
4862 struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); in iwx_rx_compressed_ba()
4863 struct iwx_node *in = IWX_NODE(vap->iv_bss); in iwx_rx_compressed_ba()
4864 struct ieee80211_node *ni = &in->in_ni; in iwx_rx_compressed_ba()
4869 // if (ic->ic_state != IEEE80211_S_RUN) in iwx_rx_compressed_ba()
4875 if (ba_res->sta_id != IWX_STATION_ID) in iwx_rx_compressed_ba()
4880 tfd_cnt = le16toh(ba_res->tfd_cnt); in iwx_rx_compressed_ba()
4881 ra_tid_cnt = le16toh(ba_res->ra_tid_cnt); in iwx_rx_compressed_ba()
4883 sizeof(ba_res->ra_tid[0]) * ra_tid_cnt + in iwx_rx_compressed_ba()
4884 sizeof(ba_res->tfd[0]) * tfd_cnt)) in iwx_rx_compressed_ba()
4888 struct iwx_compressed_ba_tfd *ba_tfd = &ba_res->tfd[i]; in iwx_rx_compressed_ba()
4891 tid = ba_tfd->tid; in iwx_rx_compressed_ba()
4892 if (tid >= nitems(sc->aggqid)) in iwx_rx_compressed_ba()
4895 qid = sc->aggqid[tid]; in iwx_rx_compressed_ba()
4896 if (qid != htole16(ba_tfd->q_num)) in iwx_rx_compressed_ba()
4899 ring = &sc->txq[qid]; in iwx_rx_compressed_ba()
4902 ba = &ni->ni_tx_ba[tid]; in iwx_rx_compressed_ba()
4903 if (ba->ba_state != IEEE80211_BA_AGREED) in iwx_rx_compressed_ba()
4906 idx = le16toh(ba_tfd->tfd_index); in iwx_rx_compressed_ba()
4907 sc->sc_tx_timer[qid] = 0; in iwx_rx_compressed_ba()
4917 struct ieee80211com *ic = &sc->sc_ic; in iwx_rx_bmiss()
4918 struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); in iwx_rx_bmiss()
4919 struct iwx_missed_beacons_notif *mbn = (void *)pkt->data; in iwx_rx_bmiss()
4922 if ((ic->ic_opmode != IEEE80211_M_STA) || in iwx_rx_bmiss()
4923 (vap->iv_state != IEEE80211_S_RUN)) in iwx_rx_bmiss()
4926 bus_dmamap_sync(sc->rxq.data_dmat, data->map, in iwx_rx_bmiss()
4932 le32toh(mbn->mac_id), in iwx_rx_bmiss()
4933 le32toh(mbn->consec_missed_beacons_since_last_rx), in iwx_rx_bmiss()
4934 le32toh(mbn->consec_missed_beacons), in iwx_rx_bmiss()
4935 le32toh(mbn->num_expected_beacons), in iwx_rx_bmiss()
4936 le32toh(mbn->num_recvd_beacons)); in iwx_rx_bmiss()
4938 missed = le32toh(mbn->consec_missed_beacons_since_last_rx); in iwx_rx_bmiss()
4939 if (missed > vap->iv_bmissthreshold) { in iwx_rx_bmiss()
4948 struct ieee80211com *ic = &sc->sc_ic; in iwx_binding_cmd()
4949 struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); in iwx_binding_cmd()
4951 struct iwx_phy_ctxt *phyctxt = ivp->phy_ctxt; in iwx_binding_cmd()
4952 uint32_t mac_id = IWX_FW_CMD_ID_AND_COLOR(in->in_id, in->in_color); in iwx_binding_cmd()
4953 int i, err, active = (sc->sc_flags & IWX_FLAG_BINDING_ACTIVE); in iwx_binding_cmd()
4967 = htole32(IWX_FW_CMD_ID_AND_COLOR(phyctxt->id, phyctxt->color)); in iwx_binding_cmd()
4969 cmd.phy = htole32(IWX_FW_CMD_ID_AND_COLOR(phyctxt->id, phyctxt->color)); in iwx_binding_cmd()
4975 if (IEEE80211_IS_CHAN_2GHZ(phyctxt->channel) || in iwx_binding_cmd()
4976 !isset(sc->sc_enabled_capa, IWX_UCODE_TLV_CAPA_CDB_SUPPORT)) in iwx_binding_cmd()
4994 int midpoint = chan->ic_vht_ch_freq1; in iwx_get_vht_ctrl_pos()
5003 switch (ctlchan - midpoint) { in iwx_get_vht_ctrl_pos()
5004 case -6: in iwx_get_vht_ctrl_pos()
5007 case -2: in iwx_get_vht_ctrl_pos()
5028 struct ieee80211com *ic = &sc->sc_ic; in iwx_phy_ctxt_cmd_uhb_v3_v4()
5031 struct ieee80211_channel *chan = ctxt->channel; in iwx_phy_ctxt_cmd_uhb_v3_v4()
5034 cmd.id_and_color = htole32(IWX_FW_CMD_ID_AND_COLOR(ctxt->id, in iwx_phy_ctxt_cmd_uhb_v3_v4()
5035 ctxt->color)); in iwx_phy_ctxt_cmd_uhb_v3_v4()
5039 !isset(sc->sc_enabled_capa, IWX_UCODE_TLV_CAPA_CDB_SUPPORT)) in iwx_phy_ctxt_cmd_uhb_v3_v4()
5083 struct ieee80211com *ic = &sc->sc_ic;
5086 struct ieee80211_channel *chan = ctxt->channel;
5089 cmd.id_and_color = htole32(IWX_FW_CMD_ID_AND_COLOR(ctxt->id,
5090 ctxt->color));
5093 if (IEEE80211_IS_CHAN_2GHZ(ctxt->channel) ||
5094 !isset(sc->sc_enabled_capa, IWX_UCODE_TLV_CAPA_CDB_SUPPORT))
5105 } else if (chan->ic_flags & IEEE80211_CHAN_40MHZ) {
5107 /* secondary chan above -> control chan below */
5111 /* secondary chan below -> control chan above */
5148 printf("%s: firmware does not support phy-context-cmd v3/v4\n", in iwx_phy_ctxt_cmd()
5160 if (isset(sc->sc_enabled_capa, IWX_UCODE_TLV_CAPA_ULTRA_HB_CHANNELS)) { in iwx_phy_ctxt_cmd()
5175 struct iwx_tx_ring *ring = &sc->txq[IWX_DQA_CMD_QUEUE]; in iwx_send_cmd()
5186 int generation = sc->sc_generation; in iwx_send_cmd()
5190 code = hcmd->id; in iwx_send_cmd()
5191 async = hcmd->flags & IWX_CMD_ASYNC; in iwx_send_cmd()
5192 idx = ring->cur; in iwx_send_cmd()
5194 for (i = 0, paylen = 0; i < nitems(hcmd->len); i++) { in iwx_send_cmd()
5195 paylen += hcmd->len[i]; in iwx_send_cmd()
5199 hcmd->resp_pkt = NULL; in iwx_send_cmd()
5200 if (hcmd->flags & IWX_CMD_WANT_RESP) { in iwx_send_cmd()
5203 KASSERT(hcmd->resp_pkt_len >= sizeof(struct iwx_rx_packet), in iwx_send_cmd()
5205 KASSERT(hcmd->resp_pkt_len <= IWX_CMD_RESP_MAX, in iwx_send_cmd()
5207 if (sc->sc_cmd_resp_pkt[idx] != NULL) in iwx_send_cmd()
5209 resp_buf = malloc(hcmd->resp_pkt_len, M_DEVBUF, in iwx_send_cmd()
5213 sc->sc_cmd_resp_pkt[idx] = resp_buf; in iwx_send_cmd()
5214 sc->sc_cmd_resp_len[idx] = hcmd->resp_pkt_len; in iwx_send_cmd()
5216 sc->sc_cmd_resp_pkt[idx] = NULL; in iwx_send_cmd()
5219 desc = &ring->desc[idx]; in iwx_send_cmd()
5220 txdata = &ring->data[idx]; in iwx_send_cmd()
5224 * Firmware API versions >= 50 reject old-style commands in in iwx_send_cmd()
5231 txdata->flags |= IWX_TXDATA_FLAG_CMD_IS_NARROW; in iwx_send_cmd()
5233 txdata->flags &= ~IWX_TXDATA_FLAG_CMD_IS_NARROW; in iwx_send_cmd()
5237 hdrlen = sizeof(cmd->hdr_wide); in iwx_send_cmd()
5238 datasz = sizeof(cmd->data_wide); in iwx_send_cmd()
5241 /* Command is too large to fit in pre-allocated space. */ in iwx_send_cmd()
5258 m->m_len = m->m_pkthdr.len = m->m_ext.ext_size; in iwx_send_cmd()
5259 err = bus_dmamap_load_mbuf_sg(ring->data_dmat, txdata->map, m, in iwx_send_cmd()
5270 txdata->m = m; /* mbuf will be freed in iwx_cmd_done() */ in iwx_send_cmd()
5274 cmd = &ring->cmd[idx]; in iwx_send_cmd()
5275 paddr = txdata->cmd_paddr; in iwx_send_cmd()
5279 cmd->hdr_wide.opcode = iwx_cmd_opcode(code); in iwx_send_cmd()
5280 cmd->hdr_wide.group_id = group_id; in iwx_send_cmd()
5281 cmd->hdr_wide.qid = ring->qid; in iwx_send_cmd()
5282 cmd->hdr_wide.idx = idx; in iwx_send_cmd()
5283 cmd->hdr_wide.length = htole16(paylen); in iwx_send_cmd()
5284 cmd->hdr_wide.version = iwx_cmd_version(code); in iwx_send_cmd()
5285 data = cmd->data_wide; in iwx_send_cmd()
5287 for (i = 0, off = 0; i < nitems(hcmd->data); i++) { in iwx_send_cmd()
5288 if (hcmd->len[i] == 0) in iwx_send_cmd()
5290 memcpy(data + off, hcmd->data[i], hcmd->len[i]); in iwx_send_cmd()
5291 off += hcmd->len[i]; in iwx_send_cmd()
5295 desc->tbs[0].tb_len = htole16(MIN(hdrlen + paylen, IWX_FIRST_TB_SIZE)); in iwx_send_cmd()
5297 memcpy(&desc->tbs[0].addr, &addr, sizeof(addr)); in iwx_send_cmd()
5301 desc->tbs[1].tb_len = htole16(hdrlen + paylen - in iwx_send_cmd()
5304 memcpy(&desc->tbs[1].addr, &addr, sizeof(addr)); in iwx_send_cmd()
5305 desc->num_tbs = htole16(2); in iwx_send_cmd()
5307 desc->num_tbs = htole16(1); in iwx_send_cmd()
5310 bus_dmamap_sync(ring->data_dmat, txdata->map, in iwx_send_cmd()
5313 bus_dmamap_sync(ring->cmd_dma.tag, ring->cmd_dma.map, in iwx_send_cmd()
5316 bus_dmamap_sync(ring->desc_dma.tag, ring->desc_dma.map, in iwx_send_cmd()
5320 ring->queued++; in iwx_send_cmd()
5321 ring->cur = (ring->cur + 1) % IWX_TX_RING_COUNT; in iwx_send_cmd()
5322 ring->cur_hw = (ring->cur_hw + 1) % sc->max_tfd_queue_size; in iwx_send_cmd()
5323 DPRINTF(("%s: ring->cur_hw=%i\n", __func__, ring->cur_hw)); in iwx_send_cmd()
5324 IWX_WRITE(sc, IWX_HBUS_TARG_WRPTR, ring->qid << 16 | ring->cur_hw); in iwx_send_cmd()
5327 err = msleep(desc, &sc->sc_mtx, PCATCH, "iwxcmd", hz); in iwx_send_cmd()
5330 if (generation != sc->sc_generation) { in iwx_send_cmd()
5336 hcmd->resp_pkt = (void *)sc->sc_cmd_resp_pkt[idx]; in iwx_send_cmd()
5337 sc->sc_cmd_resp_pkt[idx] = NULL; in iwx_send_cmd()
5338 } else if (generation == sc->sc_generation) { in iwx_send_cmd()
5339 free(sc->sc_cmd_resp_pkt[idx], M_DEVBUF); in iwx_send_cmd()
5340 sc->sc_cmd_resp_pkt[idx] = NULL; in iwx_send_cmd()
5369 KASSERT(((cmd->flags & IWX_CMD_WANT_RESP) == 0), ("IWX_CMD_WANT_RESP")); in iwx_send_cmd_status()
5370 cmd->flags |= IWX_CMD_WANT_RESP; in iwx_send_cmd_status()
5371 cmd->resp_pkt_len = sizeof(*pkt) + sizeof(*resp); in iwx_send_cmd_status()
5377 pkt = cmd->resp_pkt; in iwx_send_cmd_status()
5378 if (pkt == NULL || (pkt->hdr.flags & IWX_CMD_FAILED_MSK)) in iwx_send_cmd_status()
5387 resp = (void *)pkt->data; in iwx_send_cmd_status()
5388 *status = le32toh(resp->status); in iwx_send_cmd_status()
5409 KASSERT((hcmd->flags & (IWX_CMD_WANT_RESP)) == IWX_CMD_WANT_RESP, in iwx_free_resp()
5411 free(hcmd->resp_pkt, M_DEVBUF); in iwx_free_resp()
5412 hcmd->resp_pkt = NULL; in iwx_free_resp()
5418 struct iwx_tx_ring *ring = &sc->txq[IWX_DQA_CMD_QUEUE]; in iwx_cmd_done()
5425 data = &ring->data[idx]; in iwx_cmd_done()
5427 if (data->m != NULL) { in iwx_cmd_done()
5428 bus_dmamap_sync(ring->data_dmat, data->map, in iwx_cmd_done()
5430 bus_dmamap_unload(ring->data_dmat, data->map); in iwx_cmd_done()
5431 m_freem(data->m); in iwx_cmd_done()
5432 data->m = NULL; in iwx_cmd_done()
5434 wakeup(&ring->desc[idx]); in iwx_cmd_done()
5437 if (ring->queued == 0) { in iwx_cmd_done()
5440 } else if (ring->queued > 0) in iwx_cmd_done()
5441 ring->queued--; in iwx_cmd_done()
5451 for (i = 0; i < rs->rs_nrates; i++) { in iwx_fw_rateidx_ofdm()
5452 if ((rs->rs_rates[i] & IEEE80211_RATE_VAL) == rval) in iwx_fw_rateidx_ofdm()
5466 for (i = 0; i < rs->rs_nrates; i++) { in iwx_fw_rateidx_cck()
5467 if ((rs->rs_rates[i] & IEEE80211_RATE_VAL) == rval) in iwx_fw_rateidx_cck()
5477 struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); in iwx_min_basic_rate()
5478 struct ieee80211_node *ni = vap->iv_bss; in iwx_min_basic_rate()
5479 struct ieee80211_rateset *rs = &ni->ni_rates; in iwx_min_basic_rate()
5480 struct ieee80211_channel *c = ni->ni_chan; in iwx_min_basic_rate()
5483 min = -1; in iwx_min_basic_rate()
5487 return -1; in iwx_min_basic_rate()
5490 for (i = 0; i < rs->rs_nrates; i++) { in iwx_min_basic_rate()
5491 if ((rs->rs_rates[i] & IEEE80211_RATE_BASIC) == 0) in iwx_min_basic_rate()
5493 rval = (rs->rs_rates[i] & IEEE80211_RATE_VAL); in iwx_min_basic_rate()
5494 if (min == -1) in iwx_min_basic_rate()
5501 if (min == -1) in iwx_min_basic_rate()
5516 struct ieee80211com *ic = &sc->sc_ic; in iwx_tx_fill_cmd()
5517 struct ieee80211_node *ni = &in->in_ni; in iwx_tx_fill_cmd()
5518 struct ieee80211_rateset *rs = &ni->ni_rates; in iwx_tx_fill_cmd()
5520 int type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK; in iwx_tx_fill_cmd()
5526 if (ridx == -1) in iwx_tx_fill_cmd()
5533 if (IEEE80211_IS_MULTICAST(wh->i_addr1) || in iwx_tx_fill_cmd()
5535 /* for non-data, use the lowest supported rate */ in iwx_tx_fill_cmd()
5538 } else if (ni->ni_flags & IEEE80211_NODE_VHT) { in iwx_tx_fill_cmd()
5539 /* TODO: VHT - the ridx / rate array doesn't have VHT rates yet */ in iwx_tx_fill_cmd()
5541 } else if (ni->ni_flags & IEEE80211_NODE_HT) { in iwx_tx_fill_cmd()
5545 rval = (rs->rs_rates[ieee80211_node_get_txrate_dot11rate(ni)] in iwx_tx_fill_cmd()
5552 if (m->m_flags & M_EAPOL) in iwx_tx_fill_cmd()
5575 if (sc->sc_rate_n_flags_version >= 2) in iwx_tx_fill_cmd()
5579 } else if (sc->sc_rate_n_flags_version >= 2) in iwx_tx_fill_cmd()
5582 rval = (rs->rs_rates[ieee80211_node_get_txrate_dot11rate(ni)] in iwx_tx_fill_cmd()
5585 rval, rs->rs_rates[ieee80211_node_get_txrate_dot11rate(ni)]); in iwx_tx_fill_cmd()
5587 if (sc->sc_rate_n_flags_version >= 2) { in iwx_tx_fill_cmd()
5596 rate_flags |= rinfo->plcp; in iwx_tx_fill_cmd()
5604 if (sc->sc_debug & IWX_DEBUG_TXRATE) in iwx_tx_fill_cmd()
5606 *rate_n_flags, sc->sc_rate_n_flags_version); in iwx_tx_fill_cmd()
5624 * to SRAM- 0 for one chunk, 1 for 2 and so on. in iwx_tx_update_byte_tbl()
5629 num_fetch_chunks = howmany(filled_tfd_size, 64) - 1; in iwx_tx_update_byte_tbl()
5631 if (sc->sc_device_family >= IWX_DEVICE_FAMILY_AX210) { in iwx_tx_update_byte_tbl()
5632 struct iwx_gen3_bc_tbl_entry *scd_bc_tbl = txq->bc_tbl.vaddr; in iwx_tx_update_byte_tbl()
5637 struct iwx_agn_scd_bc_tbl *scd_bc_tbl = txq->bc_tbl.vaddr; in iwx_tx_update_byte_tbl()
5641 scd_bc_tbl->tfd_offset[idx] = bc_ent; in iwx_tx_update_byte_tbl()
5644 bus_dmamap_sync(sc->sc_dmat, txq->bc_tbl.map, BUS_DMASYNC_PREWRITE); in iwx_tx_update_byte_tbl()
5650 struct ieee80211com *ic = &sc->sc_ic; in iwx_tx()
5651 struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); in iwx_tx()
5676 qid = sc->first_data_qid; in iwx_tx()
5682 struct ieee80211_tx_ampdu *tap = &ni->ni_tx_ampdu[tid]; in iwx_tx()
5686 * except for A-MPDU queues. We should be able to choose in iwx_tx()
5692 * Only QoS data goes into an A-MPDU queue; in iwx_tx()
5697 !IEEE80211_IS_MULTICAST(wh->i_addr1) && in iwx_tx()
5698 sc->aggqid[tid] != 0) { in iwx_tx()
5699 qid = sc->aggqid[tid]; in iwx_tx()
5703 ring = &sc->txq[qid]; in iwx_tx()
5704 desc = &ring->desc[ring->cur]; in iwx_tx()
5706 data = &ring->data[ring->cur]; in iwx_tx()
5708 cmd = &ring->cmd[ring->cur]; in iwx_tx()
5709 cmd->hdr.code = IWX_TX_CMD; in iwx_tx()
5710 cmd->hdr.flags = 0; in iwx_tx()
5711 cmd->hdr.qid = ring->qid; in iwx_tx()
5712 cmd->hdr.idx = ring->cur; in iwx_tx()
5718 /* Offloaded sequence number assignment; non-AMPDU case */ in iwx_tx()
5719 if ((m->m_flags & M_AMPDU_MPDU) == 0) in iwx_tx()
5720 ieee80211_output_seqno_assign(ni, -1, m); in iwx_tx()
5724 struct iwx_tx_radiotap_header *tap = &sc->sc_txtap; in iwx_tx()
5726 tap->wt_flags = 0; in iwx_tx()
5727 tap->wt_chan_freq = htole16(ni->ni_chan->ic_freq); in iwx_tx()
5728 tap->wt_chan_flags = htole16(ni->ni_chan->ic_flags); in iwx_tx()
5729 tap->wt_rate = rinfo->rate; in iwx_tx()
5731 tap->wt_flags |= IEEE80211_RADIOTAP_F_WEP; in iwx_tx()
5735 /* Encrypt - CCMP via direct HW path, TKIP/WEP indirected openbsd-style for now */ in iwx_tx()
5736 if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) { in iwx_tx()
5742 } else if (k->wk_cipher->ic_cipher == IEEE80211_CIPHER_AES_CCM) { in iwx_tx()
5743 k->wk_keytsc++; in iwx_tx()
5745 k->wk_cipher->ic_encap(k, m); in iwx_tx()
5754 totlen = m->m_pkthdr.len; in iwx_tx()
5758 pad = 4 - (hdrlen & 3); in iwx_tx()
5763 if (sc->sc_device_family >= IWX_DEVICE_FAMILY_AX210) { in iwx_tx()
5764 struct iwx_tx_cmd_gen3 *tx = (void *)cmd->data; in iwx_tx()
5766 tx->len = htole16(totlen); in iwx_tx()
5767 tx->offload_assist = htole32(offload_assist); in iwx_tx()
5768 tx->flags = htole16(flags); in iwx_tx()
5769 tx->rate_n_flags = htole32(rate_n_flags); in iwx_tx()
5770 memcpy(tx->hdr, wh, hdrlen); in iwx_tx()
5773 struct iwx_tx_cmd_gen2 *tx = (void *)cmd->data; in iwx_tx()
5775 tx->len = htole16(totlen); in iwx_tx()
5776 tx->offload_assist = htole16(offload_assist); in iwx_tx()
5777 tx->flags = htole32(flags); in iwx_tx()
5778 tx->rate_n_flags = htole32(rate_n_flags); in iwx_tx()
5779 memcpy(tx->hdr, wh, hdrlen); in iwx_tx()
5786 err = bus_dmamap_load_mbuf_sg(ring->data_dmat, data->map, m, segs, in iwx_tx()
5795 m1 = m_collapse(m, M_NOWAIT, IWM_MAX_SCATTER - 2); in iwx_tx()
5802 err = bus_dmamap_load_mbuf_sg(ring->data_dmat, data->map, m, in iwx_tx()
5811 data->m = m; in iwx_tx()
5812 data->in = in; in iwx_tx()
5816 desc->num_tbs = htole16(num_tbs); in iwx_tx()
5818 desc->tbs[0].tb_len = htole16(IWX_FIRST_TB_SIZE); in iwx_tx()
5819 paddr = htole64(data->cmd_paddr); in iwx_tx()
5820 memcpy(&desc->tbs[0].addr, &paddr, sizeof(paddr)); in iwx_tx()
5821 if (data->cmd_paddr >> 32 != (data->cmd_paddr + le32toh(desc->tbs[0].tb_len)) >> 32) in iwx_tx()
5823 desc->tbs[1].tb_len = htole16(sizeof(struct iwx_cmd_header) + in iwx_tx()
5824 txcmd_size + hdrlen + pad - IWX_FIRST_TB_SIZE); in iwx_tx()
5825 paddr = htole64(data->cmd_paddr + IWX_FIRST_TB_SIZE); in iwx_tx()
5826 memcpy(&desc->tbs[1].addr, &paddr, sizeof(paddr)); in iwx_tx()
5828 if (data->cmd_paddr >> 32 != (data->cmd_paddr + le32toh(desc->tbs[1].tb_len)) >> 32) in iwx_tx()
5834 desc->tbs[i + 2].tb_len = htole16(seg->ds_len); in iwx_tx()
5835 paddr = htole64(seg->ds_addr); in iwx_tx()
5836 memcpy(&desc->tbs[i + 2].addr, &paddr, sizeof(paddr)); in iwx_tx()
5837 if (data->cmd_paddr >> 32 != (data->cmd_paddr + le32toh(desc->tbs[i + 2].tb_len)) >> 32) in iwx_tx()
5841 bus_dmamap_sync(ring->data_dmat, data->map, BUS_DMASYNC_PREWRITE); in iwx_tx()
5842 bus_dmamap_sync(ring->cmd_dma.tag, ring->cmd_dma.map, in iwx_tx()
5844 bus_dmamap_sync(ring->desc_dma.tag, ring->desc_dma.map, in iwx_tx()
5847 iwx_tx_update_byte_tbl(sc, ring, ring->cur, totlen, num_tbs); in iwx_tx()
5850 ring->cur = (ring->cur + 1) % IWX_TX_RING_COUNT; in iwx_tx()
5851 ring->cur_hw = (ring->cur_hw + 1) % sc->max_tfd_queue_size; in iwx_tx()
5852 IWX_WRITE(sc, IWX_HBUS_TARG_WRPTR, ring->qid << 16 | ring->cur_hw); in iwx_tx()
5855 if (++ring->queued > iwx_himark) { in iwx_tx()
5856 sc->qfullmsk |= 1 << ring->qid; in iwx_tx()
5859 sc->sc_tx_timer[ring->qid] = 15; in iwx_tx()
5887 if (!pkt || (pkt->hdr.flags & IWX_CMD_FAILED_MSK)) { in iwx_flush_sta_tids()
5901 resp = (void *)pkt->data; in iwx_flush_sta_tids()
5903 if (le16toh(resp->sta_id) != sta_id) { in iwx_flush_sta_tids()
5908 num_flushed_queues = le16toh(resp->num_flushed_queues); in iwx_flush_sta_tids()
5915 struct iwx_flush_queue_info *queue_info = &resp->queues[i]; in iwx_flush_sta_tids()
5916 uint16_t tid = le16toh(queue_info->tid); in iwx_flush_sta_tids()
5917 uint16_t read_after = le16toh(queue_info->read_after_flush); in iwx_flush_sta_tids()
5918 uint16_t qid = le16toh(queue_info->queue_num); in iwx_flush_sta_tids()
5921 if (qid >= nitems(sc->txq)) in iwx_flush_sta_tids()
5924 txq = &sc->txq[qid]; in iwx_flush_sta_tids()
5925 if (tid != txq->tid) in iwx_flush_sta_tids()
5945 cmd.mac_id_n_color = htole32(IWX_FW_CMD_ID_AND_COLOR(in->in_id, in iwx_drain_sta()
5946 in->in_color)); in iwx_drain_sta()
5981 sc->sc_flags |= IWX_FLAG_TXFLUSH; in iwx_flush_sta()
5995 * XXX-THJ: iwx_wait_tx_queues_empty was here, but it was a nope in the in iwx_flush_sta()
6001 sc->sc_flags &= ~IWX_FLAG_TXFLUSH; in iwx_flush_sta()
6024 if (!sc->sc_bf.bf_enabled) in iwx_update_beacon_abort()
6027 sc->sc_bf.ba_enabled = enable; in iwx_update_beacon_abort()
6035 struct ieee80211com *ic = &sc->sc_ic; in iwx_power_build_cmd()
6036 struct ieee80211_node *ni = &in->in_ni; in iwx_power_build_cmd()
6037 struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); in iwx_power_build_cmd()
6040 cmd->id_and_color = htole32(IWX_FW_CMD_ID_AND_COLOR(in->in_id, in iwx_power_build_cmd()
6041 in->in_color)); in iwx_power_build_cmd()
6042 if (vap->iv_dtim_period) in iwx_power_build_cmd()
6043 dtim_period = vap->iv_dtim_period; in iwx_power_build_cmd()
6053 dtim_msec = dtim_period * ni->ni_intval; in iwx_power_build_cmd()
6056 cmd->keep_alive_seconds = htole16(keep_alive); in iwx_power_build_cmd()
6058 if (ic->ic_opmode != IEEE80211_M_MONITOR) in iwx_power_build_cmd()
6059 cmd->flags = htole16(IWX_POWER_FLAGS_POWER_SAVE_ENA_MSK); in iwx_power_build_cmd()
6087 struct ieee80211com *ic = &sc->sc_ic; in iwx_power_update_device()
6089 if (ic->ic_opmode != IEEE80211_M_MONITOR) in iwx_power_update_device()
6102 .ba_enable_beacon_abort = htole32(sc->sc_bf.ba_enabled),
6108 sc->sc_bf.bf_enabled = 1;
6123 sc->sc_bf.bf_enabled = 0; in iwx_disable_beacon_filter()
6136 struct ieee80211com *ic = &sc->sc_ic; in iwx_add_sta_cmd()
6137 struct ieee80211_node *ni = &in->in_ni; in iwx_add_sta_cmd()
6138 struct ieee80211_htrateset *htrs = &ni->ni_htrates; in iwx_add_sta_cmd()
6140 if (!update && (sc->sc_flags & IWX_FLAG_STA_ACTIVE)) in iwx_add_sta_cmd()
6145 if (ic->ic_opmode == IEEE80211_M_MONITOR) { in iwx_add_sta_cmd()
6153 = htole32(IWX_FW_CMD_ID_AND_COLOR(in->in_id, in->in_color)); in iwx_add_sta_cmd()
6155 if (ic->ic_opmode == IEEE80211_M_MONITOR) in iwx_add_sta_cmd()
6160 in->in_macaddr); in iwx_add_sta_cmd()
6168 if (in->in_ni.ni_flags & IEEE80211_NODE_HT) { in iwx_add_sta_cmd()
6174 if (ni->ni_flags & IEEE80211_NODE_VHT) { in iwx_add_sta_cmd()
6179 for (i = 0; i < htrs->rs_nrates; i++) { in iwx_add_sta_cmd()
6180 if (htrs->rs_rates[i] > 7) { in iwx_add_sta_cmd()
6192 if (ni->ni_flags & IEEE80211_NODE_HT && in iwx_add_sta_cmd()
6193 IEEE80211_IS_CHAN_HT40(ni->ni_chan)) { in iwx_add_sta_cmd()
6199 if (ni->ni_flags & IEEE80211_NODE_VHT) { in iwx_add_sta_cmd()
6200 if (IEEE80211_IS_CHAN_VHT80(ni->ni_chan)) { in iwx_add_sta_cmd()
6204 // XXX-misha: TODO get real ampdu size in iwx_add_sta_cmd()
6207 aggsize = _IEEE80211_MASKSHIFT(le16toh(ni->ni_htparam), in iwx_add_sta_cmd()
6217 switch (_IEEE80211_MASKSHIFT(le16toh(ni->ni_htparam), in iwx_add_sta_cmd()
6252 struct ieee80211com *ic = &sc->sc_ic; in iwx_rm_sta_cmd()
6256 if ((sc->sc_flags & IWX_FLAG_STA_ACTIVE) == 0) in iwx_rm_sta_cmd()
6260 if (ic->ic_opmode == IEEE80211_M_MONITOR) in iwx_rm_sta_cmd()
6295 struct iwx_tx_ring *ring = &sc->txq[i]; in iwx_rm_sta()
6296 if ((sc->qenablemsk & (1 << i)) == 0) in iwx_rm_sta()
6299 ring->qid, ring->tid); in iwx_rm_sta()
6302 "(error %d)\n", DEVNAME(sc), ring->qid, in iwx_rm_sta()
6316 in->in_flags = 0; in iwx_rm_sta()
6318 sc->sc_rx_ba_sessions = 0; in iwx_rm_sta()
6319 sc->ba_rx.start_tidmask = 0; in iwx_rm_sta()
6320 sc->ba_rx.stop_tidmask = 0; in iwx_rm_sta()
6321 memset(sc->aggqid, 0, sizeof(sc->aggqid)); in iwx_rm_sta()
6322 sc->ba_tx.start_tidmask = 0; in iwx_rm_sta()
6323 sc->ba_tx.stop_tidmask = 0; in iwx_rm_sta()
6325 sc->qenablemsk &= ~(1 << i); in iwx_rm_sta()
6329 struct ieee80211_tx_ba *ba = &ni->ni_tx_ba[i]; in iwx_rm_sta()
6330 if (ba->ba_state != IEEE80211_BA_AGREED) in iwx_rm_sta()
6335 /* Clear ampdu rx state (GOS-1525) */ in iwx_rm_sta()
6337 struct iwx_rx_ba *ba = &sc->ni_rx_ba[i]; in iwx_rm_sta()
6338 ba->ba_flags = 0; in iwx_rm_sta()
6349 struct ieee80211com *ic = &sc->sc_ic; in iwx_umac_scan_fill_channels()
6350 struct ieee80211_scan_state *ss = ic->ic_scan; in iwx_umac_scan_fill_channels()
6356 j < ss->ss_last && in iwx_umac_scan_fill_channels()
6357 nchan < sc->sc_capa_n_scan_channels; in iwx_umac_scan_fill_channels()
6361 c = ss->ss_chans[j]; in iwx_umac_scan_fill_channels()
6362 channel_num = ieee80211_mhz2ieee(c->ic_freq, 0); in iwx_umac_scan_fill_channels()
6363 if (isset(sc->sc_ucode_api, in iwx_umac_scan_fill_channels()
6365 chan->v2.channel_num = channel_num; in iwx_umac_scan_fill_channels()
6367 chan->v2.band = IWX_PHY_BAND_24; in iwx_umac_scan_fill_channels()
6369 chan->v2.band = IWX_PHY_BAND_5; in iwx_umac_scan_fill_channels()
6370 chan->v2.iter_count = 1; in iwx_umac_scan_fill_channels()
6371 chan->v2.iter_interval = 0; in iwx_umac_scan_fill_channels()
6373 chan->v1.channel_num = channel_num; in iwx_umac_scan_fill_channels()
6374 chan->v1.iter_count = 1; in iwx_umac_scan_fill_channels()
6375 chan->v1.iter_interval = htole16(0); in iwx_umac_scan_fill_channels()
6377 chan->flags |= htole32(channel_cfg_flags); in iwx_umac_scan_fill_channels()
6388 struct ieee80211com *ic = &sc->sc_ic; in iwx_fill_probe_req()
6389 struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); in iwx_fill_probe_req()
6390 struct ieee80211_frame *wh = (struct ieee80211_frame *)preq->buf; in iwx_fill_probe_req()
6392 size_t remain = sizeof(preq->buf); in iwx_fill_probe_req()
6404 wh->i_fc[0] = IEEE80211_FC0_VERSION_0 | IEEE80211_FC0_TYPE_MGT | in iwx_fill_probe_req()
6406 wh->i_fc[1] = IEEE80211_FC1_DIR_NODS; in iwx_fill_probe_req()
6407 IEEE80211_ADDR_COPY(wh->i_addr1, etherbroadcastaddr); in iwx_fill_probe_req()
6408 IEEE80211_ADDR_COPY(wh->i_addr2, vap ? vap->iv_myaddr : ic->ic_macaddr); in iwx_fill_probe_req()
6409 IEEE80211_ADDR_COPY(wh->i_addr3, etherbroadcastaddr); in iwx_fill_probe_req()
6410 *(uint16_t *)&wh->i_dur[0] = 0; /* filled by HW */ in iwx_fill_probe_req()
6411 *(uint16_t *)&wh->i_seq[0] = 0; /* filled by HW */ in iwx_fill_probe_req()
6419 preq->mac_header.offset = 0; in iwx_fill_probe_req()
6420 preq->mac_header.len = htole16(frm - (uint8_t *)wh); in iwx_fill_probe_req()
6421 remain -= frm - (uint8_t *)wh; in iwx_fill_probe_req()
6424 rs = &ic->ic_sup_rates[IEEE80211_MODE_11G]; in iwx_fill_probe_req()
6425 if (rs->rs_nrates > IEEE80211_RATE_SIZE) { in iwx_fill_probe_req()
6426 if (remain < 4 + rs->rs_nrates) in iwx_fill_probe_req()
6428 } else if (remain < 2 + rs->rs_nrates) in iwx_fill_probe_req()
6430 preq->band_data[0].offset = htole16(frm - (uint8_t *)wh); in iwx_fill_probe_req()
6433 if (rs->rs_nrates > IEEE80211_RATE_SIZE) in iwx_fill_probe_req()
6435 remain -= frm - pos; in iwx_fill_probe_req()
6437 if (isset(sc->sc_enabled_capa, in iwx_fill_probe_req()
6444 remain -= 3; in iwx_fill_probe_req()
6446 preq->band_data[0].len = htole16(frm - pos); in iwx_fill_probe_req()
6448 if (sc->sc_nvm.sku_cap_band_52GHz_enable) { in iwx_fill_probe_req()
6450 rs = &ic->ic_sup_rates[IEEE80211_MODE_11A]; in iwx_fill_probe_req()
6451 if (rs->rs_nrates > IEEE80211_RATE_SIZE) { in iwx_fill_probe_req()
6452 if (remain < 4 + rs->rs_nrates) in iwx_fill_probe_req()
6454 } else if (remain < 2 + rs->rs_nrates) in iwx_fill_probe_req()
6456 preq->band_data[1].offset = htole16(frm - (uint8_t *)wh); in iwx_fill_probe_req()
6459 if (rs->rs_nrates > IEEE80211_RATE_SIZE) in iwx_fill_probe_req()
6461 preq->band_data[1].len = htole16(frm - pos); in iwx_fill_probe_req()
6462 remain -= frm - pos; in iwx_fill_probe_req()
6463 if (vap->iv_vht_flags & IEEE80211_FVHT_VHT) { in iwx_fill_probe_req()
6466 frm = ieee80211_add_vhtcap(frm, vap->iv_bss); in iwx_fill_probe_req()
6467 remain -= frm - pos; in iwx_fill_probe_req()
6468 preq->band_data[1].len = htole16(frm - pos); in iwx_fill_probe_req()
6473 preq->common_data.offset = htole16(frm - (uint8_t *)wh); in iwx_fill_probe_req()
6475 if (vap->iv_flags_ht & IEEE80211_FHT_HT) { in iwx_fill_probe_req()
6478 frm = ieee80211_add_htcap(frm, vap->iv_bss); in iwx_fill_probe_req()
6480 remain -= frm - pos; in iwx_fill_probe_req()
6483 preq->common_data.len = htole16(frm - pos); in iwx_fill_probe_req()
6500 if (!isset(sc->sc_ucode_api, IWX_UCODE_TLV_API_REDUCED_SCAN_CONFIG)) { in iwx_config_umac_scan_reduced()
6525 struct ieee80211com *ic = &sc->sc_ic; in iwx_scan_umac_flags_v2()
6526 struct ieee80211_scan_state *ss = ic->ic_scan; in iwx_scan_umac_flags_v2()
6529 if (ss->ss_nssid == 0) { in iwx_scan_umac_flags_v2()
6569 general_params->adwell_default_social_chn = in iwx_scan_umac_dwell_v10()
6571 general_params->adwell_default_2g = IWX_SCAN_ADWELL_DEFAULT_LB_N_APS; in iwx_scan_umac_dwell_v10()
6572 general_params->adwell_default_5g = IWX_SCAN_ADWELL_DEFAULT_HB_N_APS; in iwx_scan_umac_dwell_v10()
6575 general_params->adwell_max_budget = in iwx_scan_umac_dwell_v10()
6578 general_params->adwell_max_budget = in iwx_scan_umac_dwell_v10()
6581 general_params->scan_priority = htole32(IWX_SCAN_PRIORITY_EXT_6); in iwx_scan_umac_dwell_v10()
6589 general_params->max_out_of_time[IWX_SCAN_LB_LMAC_IDX] = in iwx_scan_umac_dwell_v10()
6591 general_params->suspend_time[IWX_SCAN_LB_LMAC_IDX] = in iwx_scan_umac_dwell_v10()
6593 general_params->max_out_of_time[IWX_SCAN_HB_LMAC_IDX] = in iwx_scan_umac_dwell_v10()
6595 general_params->suspend_time[IWX_SCAN_HB_LMAC_IDX] = in iwx_scan_umac_dwell_v10()
6598 general_params->active_dwell[IWX_SCAN_LB_LMAC_IDX] = active_dwell; in iwx_scan_umac_dwell_v10()
6599 general_params->passive_dwell[IWX_SCAN_LB_LMAC_IDX] = passive_dwell; in iwx_scan_umac_dwell_v10()
6600 general_params->active_dwell[IWX_SCAN_HB_LMAC_IDX] = active_dwell; in iwx_scan_umac_dwell_v10()
6601 general_params->passive_dwell[IWX_SCAN_HB_LMAC_IDX] = passive_dwell; in iwx_scan_umac_dwell_v10()
6610 gp->flags = htole16(gen_flags); in iwx_scan_umac_fill_general_p_v10()
6613 gp->num_of_fragments[IWX_SCAN_LB_LMAC_IDX] = 3; in iwx_scan_umac_fill_general_p_v10()
6615 gp->num_of_fragments[IWX_SCAN_HB_LMAC_IDX] = 3; in iwx_scan_umac_fill_general_p_v10()
6617 gp->scan_start_mac_id = 0; in iwx_scan_umac_fill_general_p_v10()
6625 cp->flags = IWX_SCAN_CHANNEL_FLAG_ENABLE_CHAN_ORDER; in iwx_scan_umac_fill_ch_p_v6()
6627 cp->count = iwx_umac_scan_fill_channels(sc, cp->channel_config, in iwx_scan_umac_fill_ch_p_v6()
6628 nitems(cp->channel_config), n_ssid, channel_cfg_flags); in iwx_scan_umac_fill_ch_p_v6()
6630 cp->n_aps_override[0] = IWX_SCAN_ADWELL_N_APS_GO_FRIENDLY; in iwx_scan_umac_fill_ch_p_v6()
6631 cp->n_aps_override[1] = IWX_SCAN_ADWELL_N_APS_SOCIAL_CHS; in iwx_scan_umac_fill_ch_p_v6()
6637 struct ieee80211com *ic = &sc->sc_ic; in iwx_umac_scan_v14()
6638 struct ieee80211_scan_state *ss = ic->ic_scan; in iwx_umac_scan_v14()
6645 struct iwx_scan_req_umac_v14 *cmd = &sc->sc_umac_v14_cmd; in iwx_umac_scan_v14()
6655 scan_p = &cmd->scan_params; in iwx_umac_scan_v14()
6657 cmd->ooc_priority = htole32(IWX_SCAN_PRIORITY_EXT_6); in iwx_umac_scan_v14()
6658 cmd->uid = htole32(0); in iwx_umac_scan_v14()
6661 iwx_scan_umac_fill_general_p_v10(sc, &scan_p->general_params, in iwx_umac_scan_v14()
6664 scan_p->periodic_params.schedule[0].interval = htole16(0); in iwx_umac_scan_v14()
6665 scan_p->periodic_params.schedule[0].iter_count = 1; in iwx_umac_scan_v14()
6667 err = iwx_fill_probe_req(sc, &scan_p->probe_params.preq); in iwx_umac_scan_v14()
6674 for (int i=0; i < ss->ss_nssid; i++) { in iwx_umac_scan_v14()
6675 scan_p->probe_params.direct_scan[i].id = IEEE80211_ELEMID_SSID; in iwx_umac_scan_v14()
6676 scan_p->probe_params.direct_scan[i].len = in iwx_umac_scan_v14()
6677 MIN(ss->ss_ssid[i].len, IEEE80211_NWID_LEN); in iwx_umac_scan_v14()
6679 memcpy(scan_p->probe_params.direct_scan[i].ssid, in iwx_umac_scan_v14()
6680 ss->ss_ssid[i].ssid, ss->ss_ssid[i].len); in iwx_umac_scan_v14()
6686 iwx_scan_umac_fill_ch_p_v6(sc, &scan_p->channel_params, bitmap_ssid, in iwx_umac_scan_v14()
6703 (le16toh(notif->mcc) & 0xff00) >> 8, le16toh(notif->mcc) & 0xff); in iwx_mcc_update()
6706 "(0x%x)\n", DEVNAME(sc), alpha2, le16toh(notif->mcc)); in iwx_mcc_update()
6717 for (i = 0; i < rs->rs_nrates; i++) { in iwx_ridx2rate()
6718 rval = (rs->rs_rates[i] & IEEE80211_RATE_VAL); in iwx_ridx2rate()
6720 return rs->rs_rates[i]; in iwx_ridx2rate()
6745 struct ieee80211_node *ni = &in->in_ni; in iwx_ack_rates()
6746 struct ieee80211_rateset *rs = &ni->ni_rates; in iwx_ack_rates()
6747 int lowest_present_ofdm = -1; in iwx_ack_rates()
6748 int lowest_present_cck = -1; in iwx_ack_rates()
6753 if (ni->ni_chan == IEEE80211_CHAN_ANYC || in iwx_ack_rates()
6754 IEEE80211_IS_CHAN_2GHZ(ni->ni_chan)) { in iwx_ack_rates()
6759 if (lowest_present_cck == -1 || lowest_present_cck > i) in iwx_ack_rates()
6766 ofdm |= (1 << (i - IWX_FIRST_OFDM_RATE)); in iwx_ack_rates()
6767 if (lowest_present_ofdm == -1 || lowest_present_ofdm > i) in iwx_ack_rates()
6776 * and 6 Mbps because the 802.11-2007 standard says in 9.6: in iwx_ack_rates()
6804 * - if no CCK rates are basic, it must be ERP since there must in iwx_ack_rates()
6807 * - if 11M is a basic rate, it must be ERP as well, so add 5.5M in iwx_ack_rates()
6808 * - if 5.5M is basic, 1M and 2M are mandatory in iwx_ack_rates()
6809 * - if 2M is basic, 1M is mandatory in iwx_ack_rates()
6810 * - if 1M is basic, that's the only valid ACK rate. in iwx_ack_rates()
6831 #define IWX_EXP2(x) ((1 << (x)) - 1) /* CWmin = 2^ECWmin - 1 */ in iwx_mac_ctxt_cmd_common()
6832 struct ieee80211com *ic = &sc->sc_ic; in iwx_mac_ctxt_cmd_common()
6833 struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); in iwx_mac_ctxt_cmd_common()
6834 struct ieee80211_node *ni = vap->iv_bss; in iwx_mac_ctxt_cmd_common()
6837 cmd->id_and_color = htole32(IWX_FW_CMD_ID_AND_COLOR(in->in_id, in iwx_mac_ctxt_cmd_common()
6838 in->in_color)); in iwx_mac_ctxt_cmd_common()
6839 cmd->action = htole32(action); in iwx_mac_ctxt_cmd_common()
6844 if (ic->ic_opmode == IEEE80211_M_MONITOR) in iwx_mac_ctxt_cmd_common()
6845 cmd->mac_type = htole32(IWX_FW_MAC_TYPE_LISTENER); in iwx_mac_ctxt_cmd_common()
6846 else if (ic->ic_opmode == IEEE80211_M_STA) in iwx_mac_ctxt_cmd_common()
6847 cmd->mac_type = htole32(IWX_FW_MAC_TYPE_BSS_STA); in iwx_mac_ctxt_cmd_common()
6849 panic("unsupported operating mode %d", ic->ic_opmode); in iwx_mac_ctxt_cmd_common()
6850 cmd->tsf_id = htole32(IWX_TSF_ID_A); in iwx_mac_ctxt_cmd_common()
6852 IEEE80211_ADDR_COPY(cmd->node_addr, vap->iv_myaddr); in iwx_mac_ctxt_cmd_common()
6853 DPRINTF(("%s: cmd->node_addr=%s\n", __func__, in iwx_mac_ctxt_cmd_common()
6854 ether_sprintf(cmd->node_addr))); in iwx_mac_ctxt_cmd_common()
6855 if (ic->ic_opmode == IEEE80211_M_MONITOR) { in iwx_mac_ctxt_cmd_common()
6856 IEEE80211_ADDR_COPY(cmd->bssid_addr, etherbroadcastaddr); in iwx_mac_ctxt_cmd_common()
6860 IEEE80211_ADDR_COPY(cmd->bssid_addr, in->in_macaddr); in iwx_mac_ctxt_cmd_common()
6861 DPRINTF(("%s: cmd->bssid_addr=%s\n", __func__, in iwx_mac_ctxt_cmd_common()
6862 ether_sprintf(cmd->bssid_addr))); in iwx_mac_ctxt_cmd_common()
6864 cmd->cck_rates = htole32(cck_ack_rates); in iwx_mac_ctxt_cmd_common()
6865 cmd->ofdm_rates = htole32(ofdm_ack_rates); in iwx_mac_ctxt_cmd_common()
6867 cmd->cck_short_preamble in iwx_mac_ctxt_cmd_common()
6868 = htole32((ic->ic_flags & IEEE80211_F_SHPREAMBLE) in iwx_mac_ctxt_cmd_common()
6870 cmd->short_slot in iwx_mac_ctxt_cmd_common()
6871 = htole32((ic->ic_flags & IEEE80211_F_SHSLOT) in iwx_mac_ctxt_cmd_common()
6879 cmd->ac[txf].cw_min = IWX_EXP2(chp.cap_wmeParams[i].wmep_logcwmin); in iwx_mac_ctxt_cmd_common()
6880 cmd->ac[txf].cw_max = IWX_EXP2(chp.cap_wmeParams[i].wmep_logcwmax); in iwx_mac_ctxt_cmd_common()
6881 cmd->ac[txf].aifsn = chp.cap_wmeParams[i].wmep_aifsn; in iwx_mac_ctxt_cmd_common()
6882 cmd->ac[txf].fifos_mask = (1 << txf); in iwx_mac_ctxt_cmd_common()
6883 cmd->ac[txf].edca_txop = chp.cap_wmeParams[i].wmep_txopLimit; in iwx_mac_ctxt_cmd_common()
6885 cmd->ac[txf].edca_txop = htole16(chp.cap_wmeParams[i].wmep_txopLimit * 32); in iwx_mac_ctxt_cmd_common()
6888 if (ni->ni_flags & IEEE80211_NODE_QOS) { in iwx_mac_ctxt_cmd_common()
6890 cmd->qos_flags |= htole32(IWX_MAC_QOS_FLG_UPDATE_EDCA); in iwx_mac_ctxt_cmd_common()
6893 if (ni->ni_flags & IEEE80211_NODE_HT) { in iwx_mac_ctxt_cmd_common()
6894 switch (vap->iv_curhtprotmode) { in iwx_mac_ctxt_cmd_common()
6899 cmd->protection_flags |= in iwx_mac_ctxt_cmd_common()
6904 if (in->in_phyctxt && in iwx_mac_ctxt_cmd_common()
6905 (in->in_phyctxt->sco == IEEE80211_HTINFO_2NDCHAN_ABOVE || in iwx_mac_ctxt_cmd_common()
6906 in->in_phyctxt->sco == IEEE80211_HTINFO_2NDCHAN_BELOW)) { in iwx_mac_ctxt_cmd_common()
6907 cmd->protection_flags |= in iwx_mac_ctxt_cmd_common()
6915 cmd->qos_flags |= htole32(IWX_MAC_QOS_FLG_TGN); in iwx_mac_ctxt_cmd_common()
6919 if (ic->ic_flags & IEEE80211_F_USEPROT) in iwx_mac_ctxt_cmd_common()
6920 cmd->protection_flags |= htole32(IWX_MAC_PROT_FLG_TGG_PROTECT); in iwx_mac_ctxt_cmd_common()
6921 cmd->filter_flags = htole32(IWX_MAC_FILTER_ACCEPT_GRP); in iwx_mac_ctxt_cmd_common()
6929 struct ieee80211_node *ni = &in->in_ni; in iwx_mac_ctxt_cmd_fill_sta()
6930 struct ieee80211com *ic = &sc->sc_ic; in iwx_mac_ctxt_cmd_fill_sta()
6931 struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); in iwx_mac_ctxt_cmd_fill_sta()
6936 dtim_off = ni->ni_dtim_count * ni->ni_intval * IEEE80211_DUR_TU; in iwx_mac_ctxt_cmd_fill_sta()
6937 tsf = le64toh(ni->ni_tstamp.tsf); in iwx_mac_ctxt_cmd_fill_sta()
6938 dtim_period = vap->iv_dtim_period; in iwx_mac_ctxt_cmd_fill_sta()
6940 sta->is_assoc = htole32(assoc); in iwx_mac_ctxt_cmd_fill_sta()
6943 sta->dtim_time = htole32(tsf + dtim_off); in iwx_mac_ctxt_cmd_fill_sta()
6944 sta->dtim_tsf = htole64(tsf + dtim_off); in iwx_mac_ctxt_cmd_fill_sta()
6946 sta->assoc_beacon_arrive_time = 0; in iwx_mac_ctxt_cmd_fill_sta()
6948 sta->bi = htole32(ni->ni_intval); in iwx_mac_ctxt_cmd_fill_sta()
6949 sta->dtim_interval = htole32(ni->ni_intval * dtim_period); in iwx_mac_ctxt_cmd_fill_sta()
6950 sta->data_policy = htole32(0); in iwx_mac_ctxt_cmd_fill_sta()
6951 sta->listen_interval = htole32(10); in iwx_mac_ctxt_cmd_fill_sta()
6952 sta->assoc_id = htole32(ni->ni_associd); in iwx_mac_ctxt_cmd_fill_sta()
6959 struct ieee80211com *ic = &sc->sc_ic; in iwx_mac_ctxt_cmd()
6960 struct ieee80211_node *ni = &in->in_ni; in iwx_mac_ctxt_cmd()
6962 int active = (sc->sc_flags & IWX_FLAG_MAC_ACTIVE); in iwx_mac_ctxt_cmd()
6978 if (ic->ic_opmode == IEEE80211_M_MONITOR) { in iwx_mac_ctxt_cmd()
6986 } else if (!assoc || !ni->ni_associd /*|| !ni->ni_dtimperiod*/) { in iwx_mac_ctxt_cmd()
7036 struct iwx_softc *sc = ic->ic_softc; in iwx_bgscan()
7052 sc->first_data_qid = IWX_DQA_CMD_QUEUE + 1; in iwx_enable_mgmt_queue()
7055 * Non-QoS frames use the "MGMT" TID and queue. in iwx_enable_mgmt_queue()
7058 err = iwx_enable_txq(sc, IWX_STATION_ID, sc->first_data_qid, in iwx_enable_mgmt_queue()
7062 DEVNAME(sc), sc->first_data_qid, err); in iwx_enable_mgmt_queue()
7080 sc->first_data_qid = IWX_DQA_CMD_QUEUE + 1; in iwx_disable_mgmt_queue()
7082 err = iwx_disable_txq(sc, IWX_STATION_ID, sc->first_data_qid, in iwx_disable_mgmt_queue()
7086 DEVNAME(sc), sc->first_data_qid, err); in iwx_disable_mgmt_queue()
7100 for (i = 0; i < rs->rs_nrates; i++) { in iwx_rs_rval2idx()
7101 if ((rs->rs_rates[i] & IEEE80211_RATE_VAL) == rval) in iwx_rs_rval2idx()
7105 return -1; in iwx_rs_rval2idx()
7112 struct ieee80211_htrateset *htrs = &ni->ni_htrates; in iwx_rs_ht_rates()
7116 for (i = 0; i < htrs->rs_nrates; i++) { in iwx_rs_ht_rates()
7117 if (htrs->rs_rates[i] <= 7) in iwx_rs_ht_rates()
7118 htrates |= (1 << htrs->rs_rates[i]); in iwx_rs_ht_rates()
7121 for (i = 0; i < htrs->rs_nrates; i++) { in iwx_rs_ht_rates()
7122 if (htrs->rs_rates[i] > 7 && htrs->rs_rates[i] <= 15) in iwx_rs_ht_rates()
7123 htrates |= (1 << (htrs->rs_rates[i] - 8)); in iwx_rs_ht_rates()
7138 int max_mcs = -1; in iwx_rs_vht_rates()
7139 #define IEEE80211_VHT_MCS_FOR_SS_MASK(n) (0x3 << (2*((n)-1))) in iwx_rs_vht_rates()
7140 #define IEEE80211_VHT_MCS_FOR_SS_SHIFT(n) (2*((n)-1)) in iwx_rs_vht_rates()
7141 rx_mcs = (ni->ni_vht_mcsinfo.tx_mcs_map & in iwx_rs_vht_rates()
7155 /* Disable VHT MCS 9 for 20MHz-only stations. */ in iwx_rs_vht_rates()
7156 if ((ni->ni_htcap & IEEE80211_HTCAP_CHWIDTH40) == 0) in iwx_rs_vht_rates()
7166 return ((1 << (max_mcs + 1)) - 1); in iwx_rs_vht_rates()
7175 struct ieee80211_node *ni = &in->in_ni; in iwx_rs_init_v3()
7176 struct ieee80211_rateset *rs = &ni->ni_rates; in iwx_rs_init_v3()
7184 for (i = 0; i < rs->rs_nrates; i++) { in iwx_rs_init_v3()
7185 uint8_t rval = rs->rs_rates[i] & IEEE80211_RATE_VAL; in iwx_rs_init_v3()
7187 if (idx == -1) in iwx_rs_init_v3()
7192 if (ni->ni_flags & IEEE80211_NODE_VHT) { in iwx_rs_init_v3()
7198 } else if (ni->ni_flags & IEEE80211_NODE_HT) { in iwx_rs_init_v3()
7210 if (in->in_phyctxt->vht_chan_width == IEEE80211_VHTOP0_CHAN_WIDTH_80) in iwx_rs_init_v3()
7212 else if (in->in_phyctxt->sco == IEEE80211_HTOP0_SCO_SCA || in iwx_rs_init_v3()
7213 in->in_phyctxt->sco == IEEE80211_HTOP0_SCO_SCB) in iwx_rs_init_v3()
7218 if (ni->ni_flags & IEEE80211_NODE_VHT) in iwx_rs_init_v3()
7222 if (ni->ni_flags & IEEE80211_NODE_HT) { in iwx_rs_init_v3()
7232 if ((ni->ni_flags & IEEE80211_NODE_VHT) && in iwx_rs_init_v3()
7244 struct ieee80211_node *ni = &in->in_ni; in iwx_rs_init_v4()
7245 struct ieee80211_rateset *rs = &ni->ni_rates; in iwx_rs_init_v4()
7246 struct ieee80211_htrateset *htrs = &ni->ni_htrates; in iwx_rs_init_v4()
7255 for (i = 0; i < rs->rs_nrates; i++) { in iwx_rs_init_v4()
7256 uint8_t rval = rs->rs_rates[i] & IEEE80211_RATE_VAL; in iwx_rs_init_v4()
7258 if (idx == -1) in iwx_rs_init_v4()
7262 for (i = 0; i < htrs->rs_nrates; i++) { in iwx_rs_init_v4()
7263 DPRINTF(("%s: htrate=%i\n", __func__, htrs->rs_rates[i])); in iwx_rs_init_v4()
7266 if (ni->ni_flags & IEEE80211_NODE_VHT) { in iwx_rs_init_v4()
7279 } else if (ni->ni_flags & IEEE80211_NODE_HT) { in iwx_rs_init_v4()
7299 if (in->in_phyctxt->vht_chan_width == IEEE80211_VHTOP0_CHAN_WIDTH_80) in iwx_rs_init_v4()
7301 else if (in->in_phyctxt->sco == IEEE80211_HTOP0_SCO_SCA || in iwx_rs_init_v4()
7302 in->in_phyctxt->sco == IEEE80211_HTOP0_SCO_SCB) in iwx_rs_init_v4()
7307 if (IEEE80211_IS_CHAN_VHT80(in->in_ni.ni_chan)) { in iwx_rs_init_v4()
7309 } else if (IEEE80211_IS_CHAN_HT40(in->in_ni.ni_chan)) { in iwx_rs_init_v4()
7316 if (ni->ni_flags & IEEE80211_NODE_VHT) in iwx_rs_init_v4()
7320 if (ni->ni_flags & IEEE80211_NODE_HT) { in iwx_rs_init_v4()
7321 if (ni->ni_htcap & IEEE80211_HTCAP_SHORTGI20) { in iwx_rs_init_v4()
7325 if (ni->ni_htcap & IEEE80211_HTCAP_SHORTGI40) { in iwx_rs_init_v4()
7330 sgi80 = _IEEE80211_MASKSHIFT(ni->ni_vhtcap, in iwx_rs_init_v4()
7332 if ((ni->ni_flags & IEEE80211_NODE_VHT) && sgi80) { in iwx_rs_init_v4()
7368 struct ieee80211com *ic = &sc->sc_ic; in iwx_rs_update_node_txrate()
7377 rate_n_flags = le32toh(notif->rate); in iwx_rs_update_node_txrate()
7379 if (sc->sc_rate_n_flags_version != 2) { in iwx_rs_update_node_txrate()
7383 sc->sc_rate_n_flags_version); in iwx_rs_update_node_txrate()
7387 if (sc->sc_debug & IWX_DEBUG_TXRATE) in iwx_rs_update_node_txrate()
7389 rate_n_flags, sc->sc_rate_n_flags_version); in iwx_rs_update_node_txrate()
7440 struct ieee80211com *ic = &sc->sc_ic; in iwx_rs_update()
7441 struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); in iwx_rs_update()
7443 struct ieee80211_node *ni = (void *)vap->iv_bss; in iwx_rs_update()
7449 if (notif->sta_id != IWX_STATION_ID || in iwx_rs_update()
7450 (le32toh(notif->flags) & IWX_TLC_NOTIF_FLAG_RATE) == 0) in iwx_rs_update()
7469 cmd.phy_id = htole32(phyctxt->id); in iwx_phy_send_rlc()
7490 printf("%s: GOS-3833: IEEE80211_CHAN_ANYC triggered\n", in iwx_phy_ctxt_update()
7495 if (isset(sc->sc_enabled_capa, in iwx_phy_ctxt_update()
7497 (phyctxt->channel->ic_flags & band_flags) != in iwx_phy_ctxt_update()
7498 (chan->ic_flags & band_flags)) { in iwx_phy_ctxt_update()
7507 phyctxt->channel = chan; in iwx_phy_ctxt_update()
7517 phyctxt->channel = chan; in iwx_phy_ctxt_update()
7528 phyctxt->sco = sco; in iwx_phy_ctxt_update()
7529 phyctxt->vht_chan_width = vht_chan_width; in iwx_phy_ctxt_update()
7531 DPRINTF(("%s: phyctxt->channel->ic_ieee=%d\n", __func__, in iwx_phy_ctxt_update()
7532 phyctxt->channel->ic_ieee)); in iwx_phy_ctxt_update()
7533 DPRINTF(("%s: phyctxt->sco=%d\n", __func__, phyctxt->sco)); in iwx_phy_ctxt_update()
7534 DPRINTF(("%s: phyctxt->vht_chan_width=%d\n", __func__, in iwx_phy_ctxt_update()
7535 phyctxt->vht_chan_width)); in iwx_phy_ctxt_update()
7548 struct ieee80211com *ic = &sc->sc_ic; in iwx_auth()
7553 int generation = sc->sc_generation, err; in iwx_auth()
7557 ni = ieee80211_ref_node(vap->iv_bss); in iwx_auth()
7560 if (ic->ic_opmode == IEEE80211_M_MONITOR) { in iwx_auth()
7561 err = iwx_phy_ctxt_update(sc, &sc->sc_phyctxt[0], in iwx_auth()
7562 ic->ic_bsschan, 1, 1, 0, IEEE80211_HTOP0_SCO_SCN, in iwx_auth()
7567 err = iwx_phy_ctxt_update(sc, &sc->sc_phyctxt[0], in iwx_auth()
7568 in->in_ni.ni_chan, 1, 1, 0, IEEE80211_HTOP0_SCO_SCN, in iwx_auth()
7573 ivp->phy_ctxt = &sc->sc_phyctxt[0]; in iwx_auth()
7574 IEEE80211_ADDR_COPY(in->in_macaddr, in->in_ni.ni_macaddr); in iwx_auth()
7575 DPRINTF(("%s: in-in_macaddr=%s\n", __func__, in iwx_auth()
7576 ether_sprintf(in->in_macaddr))); in iwx_auth()
7584 sc->sc_flags |= IWX_FLAG_MAC_ACTIVE; in iwx_auth()
7592 sc->sc_flags |= IWX_FLAG_BINDING_ACTIVE; in iwx_auth()
7600 sc->sc_flags |= IWX_FLAG_STA_ACTIVE; in iwx_auth()
7602 if (ic->ic_opmode == IEEE80211_M_MONITOR) { in iwx_auth()
7623 if (in->in_ni.ni_intval) in iwx_auth()
7624 duration = in->in_ni.ni_intval * 9; in iwx_auth()
7630 if (generation == sc->sc_generation) in iwx_auth()
7633 if (generation == sc->sc_generation) { in iwx_auth()
7635 sc->sc_flags &= ~IWX_FLAG_STA_ACTIVE; in iwx_auth()
7638 if (generation == sc->sc_generation) { in iwx_auth()
7640 sc->sc_flags &= ~IWX_FLAG_BINDING_ACTIVE; in iwx_auth()
7643 if (generation == sc->sc_generation) { in iwx_auth()
7645 sc->sc_flags &= ~IWX_FLAG_MAC_ACTIVE; in iwx_auth()
7653 struct ieee80211com *ic = &sc->sc_ic; in iwx_deauth()
7654 struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); in iwx_deauth()
7655 struct iwx_node *in = IWX_NODE(vap->iv_bss); in iwx_deauth()
7662 if (sc->sc_flags & IWX_FLAG_STA_ACTIVE) { in iwx_deauth()
7666 sc->sc_flags &= ~IWX_FLAG_STA_ACTIVE; in iwx_deauth()
7669 if (sc->sc_flags & IWX_FLAG_BINDING_ACTIVE) { in iwx_deauth()
7676 sc->sc_flags &= ~IWX_FLAG_BINDING_ACTIVE; in iwx_deauth()
7679 DPRINTF(("%s: IWX_FLAG_MAC_ACTIVE=%d\n", __func__, sc->sc_flags & in iwx_deauth()
7681 if (sc->sc_flags & IWX_FLAG_MAC_ACTIVE) { in iwx_deauth()
7688 sc->sc_flags &= ~IWX_FLAG_MAC_ACTIVE; in iwx_deauth()
7692 //TODO uncommented in obsd, but stays on the way of auth->auth in iwx_deauth()
7693 err = iwx_phy_ctxt_update(sc, &sc->sc_phyctxt[0], in iwx_deauth()
7694 &ic->ic_channels[1], 1, 1, 0, IEEE80211_HTOP0_SCO_SCN, in iwx_deauth()
7705 struct ieee80211com *ic = &sc->sc_ic; in iwx_run()
7706 struct iwx_node *in = IWX_NODE(vap->iv_bss); in iwx_run()
7707 struct ieee80211_node *ni = &in->in_ni; in iwx_run()
7713 if (ni->ni_flags & IEEE80211_NODE_HT) { in iwx_run()
7717 if ((ni->ni_flags & IEEE80211_NODE_VHT) && in iwx_run()
7718 IEEE80211_IS_CHAN_VHT80(ni->ni_chan)) in iwx_run()
7722 err = iwx_phy_ctxt_update(sc, ivp->phy_ctxt, in iwx_run()
7723 ivp->phy_ctxt->channel, chains, chains, in iwx_run()
7786 if (ic->ic_opmode == IEEE80211_M_MONITOR) in iwx_run()
7802 struct ieee80211com *ic = &sc->sc_ic; in iwx_run_stop()
7803 struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); in iwx_run_stop()
7804 struct iwx_node *in = IWX_NODE(vap->iv_bss); in iwx_run_stop()
7805 struct ieee80211_node *ni = &in->in_ni; in iwx_run_stop()
7821 * Note that in->in_ni (struct ieee80211_node) already represents in iwx_run_stop()
7827 for (i = 0; i < nitems(sc->sc_rxba_data); i++) { in iwx_run_stop()
7828 struct iwx_rxba_data *rxba = &sc->sc_rxba_data[i]; in iwx_run_stop()
7829 if (rxba->baid == IWX_RX_REORDER_DATA_INVALID_BAID) in iwx_run_stop()
7831 iwx_sta_rx_agg(sc, ni, rxba->tid, 0, 0, 0, 0); in iwx_run_stop()
7867 struct iwx_softc *sc = ic->ic_softc;
7872 if (k->k_cipher != IEEE80211_CIPHER_CCMP) {
7875 if (!err && in != NULL && (k->k_flags & IEEE80211_KEY_GROUP))
7876 in->in_flags |= IWX_NODE_FLAG_HAVE_GROUP_KEY;
7880 if (sc->setkey_nkeys >= nitems(sc->setkey_arg))
7883 a = &sc->setkey_arg[sc->setkey_cur];
7884 a->sta_id = IWX_STATION_ID;
7885 a->ni = ni;
7886 a->k = k;
7887 sc->setkey_cur = (sc->setkey_cur + 1) % nitems(sc->setkey_arg);
7888 sc->setkey_nkeys++;
7889 iwx_add_task(sc, systq, &sc->setkey_task);
7897 struct ieee80211com *ic = &sc->sc_ic;
7908 * ic->ic_bss so there is no need to validate arguments beyond this:
7910 KASSERT(ni == ic->ic_bss);
7916 ((k->k_id << IWX_STA_KEY_FLG_KEYID_POS) &
7918 if (k->k_flags & IEEE80211_KEY_GROUP) {
7924 memcpy(cmd.common.key, k->k_key, MIN(sizeof(cmd.common.key), k->k_len));
7927 cmd.transmit_seq_cnt = htole64(k->k_tsc);
7932 if (sc->sc_flags & IWX_FLAG_SHUTDOWN)
7939 ieee80211_new_state(ic, IEEE80211_S_SCAN, -1);
7943 if (k->k_flags & IEEE80211_KEY_GROUP)
7944 in->in_flags |= IWX_NODE_FLAG_HAVE_GROUP_KEY;
7946 in->in_flags |= IWX_NODE_FLAG_HAVE_PAIRWISE_KEY;
7948 if ((in->in_flags & want_keymask) == want_keymask) {
7950 ether_sprintf(ni->ni_macaddr)));
7951 ni->ni_port_valid = 1;
7965 while (sc->setkey_nkeys > 0) {
7966 if (err || (sc->sc_flags & IWX_FLAG_SHUTDOWN))
7968 a = &sc->setkey_arg[sc->setkey_tail];
7969 err = iwx_add_sta_key(sc, a->sta_id, a->ni, a->k);
7970 a->sta_id = 0;
7971 a->ni = NULL;
7972 a->k = NULL;
7973 sc->setkey_tail = (sc->setkey_tail + 1) %
7974 nitems(sc->setkey_arg);
7975 sc->setkey_nkeys--;
7978 refcnt_rele_wake(&sc->task_refs);
7986 struct iwx_softc *sc = ic->ic_softc;
7989 if (k->k_cipher != IEEE80211_CIPHER_CCMP) {
7995 if ((sc->sc_flags & IWX_FLAG_STA_ACTIVE) == 0)
8002 ((k->k_id << IWX_STA_KEY_FLG_KEYID_POS) &
8004 memcpy(cmd.common.key, k->k_key, MIN(sizeof(cmd.common.key), k->k_len));
8005 if (k->k_flags & IEEE80211_KEY_GROUP)
8018 struct ieee80211com *ic = vap->iv_ic; in iwx_newstate_sub()
8019 struct iwx_softc *sc = ic->ic_softc; in iwx_newstate_sub()
8020 enum ieee80211_state ostate = vap->iv_state; in iwx_newstate_sub()
8047 // if (sc->sc_flags & IWX_FLAG_SHUTDOWN) { in iwx_newstate_sub()
8048 // refcnt_rele_wake(&sc->task_refs); in iwx_newstate_sub()
8085 struct ieee80211com *ic = vap->iv_ic; in iwx_newstate()
8086 enum ieee80211_state ostate = vap->iv_state; in iwx_newstate()
8091 * we are scanning in which case a SCAN -> SCAN transition in iwx_newstate()
8092 * triggers another scan iteration. And AUTH -> AUTH is needed in iwx_newstate()
8093 * to support band-steering. in iwx_newstate()
8102 err = ivp->iv_newstate(vap, nstate, arg); in iwx_newstate()
8110 struct ieee80211com *ic = &sc->sc_ic; in iwx_endscan()
8111 struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); in iwx_endscan()
8113 if ((sc->sc_flags & (IWX_FLAG_SCANNING | IWX_FLAG_BGSCAN)) == 0) in iwx_endscan()
8116 sc->sc_flags &= ~(IWX_FLAG_SCANNING | IWX_FLAG_BGSCAN); in iwx_endscan()
8118 ieee80211_scan_done(TAILQ_FIRST(&ic->ic_vaps)); in iwx_endscan()
8119 wakeup(&vap->iv_state); /* wake up iwx_newstate */ in iwx_endscan()
8184 sf_cmd->watermark[IWX_SF_LONG_DELAY_ON] = htole32(IWX_SF_W_MARK_SCAN); in iwx_fill_sf_command()
8187 * If we are in association flow - check antenna configuration in iwx_fill_sf_command()
8191 if (ni->ni_flags & IEEE80211_NODE_HT) { in iwx_fill_sf_command()
8192 struct ieee80211_htrateset *htrs = &ni->ni_htrates; in iwx_fill_sf_command()
8194 for (i = 0; i < htrs->rs_nrates; i++) { in iwx_fill_sf_command()
8195 if (htrs->rs_rates[i] > 7) { in iwx_fill_sf_command()
8211 sf_cmd->watermark[IWX_SF_FULL_ON] = htole32(watermark); in iwx_fill_sf_command()
8215 sf_cmd->long_delay_timeouts[i][j] = in iwx_fill_sf_command()
8221 memcpy(sf_cmd->full_on_timeouts, iwx_sf_full_timeout, in iwx_fill_sf_command()
8224 memcpy(sf_cmd->full_on_timeouts, iwx_sf_full_timeout_def, in iwx_fill_sf_command()
8233 struct ieee80211com *ic = &sc->sc_ic; in iwx_sf_config()
8234 struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); in iwx_sf_config()
8235 struct ieee80211_node *ni = vap->iv_bss; in iwx_sf_config()
8286 * values in VER_1, this is backwards-compatible with VER_2, in iwx_send_soc_conf()
8289 if (!sc->sc_integrated) { /* VER_1 */ in iwx_send_soc_conf()
8293 if (sc->sc_ltr_delay != IWX_SOC_FLAGS_LTR_APPLY_DELAY_NONE) in iwx_send_soc_conf()
8294 flags |= (sc->sc_ltr_delay & in iwx_send_soc_conf()
8299 scan_cmd_ver >= 2 && sc->sc_low_latency_xtal) in iwx_send_soc_conf()
8304 cmd.latency = htole32(sc->sc_xtal_latency); in iwx_send_soc_conf()
8329 if (isset(sc->sc_ucode_api, IWX_UCODE_TLV_API_WIFI_MCC_UPDATE) || in iwx_send_update_mcc_cmd()
8330 isset(sc->sc_enabled_capa, IWX_UCODE_TLV_CAPA_LAR_MULTI_MCC)) in iwx_send_update_mcc_cmd()
8343 if (!pkt || (pkt->hdr.flags & IWX_CMD_FAILED_MSK)) { in iwx_send_update_mcc_cmd()
8354 resp = (void *)pkt->data; in iwx_send_update_mcc_cmd()
8356 resp->n_channels * sizeof(resp->channels[0])) { in iwx_send_update_mcc_cmd()
8362 …resp->status, resp->mcc, resp->cap, resp->time, resp->geo_info, resp->source_id, resp->n_channels)… in iwx_send_update_mcc_cmd()
8377 * In order to give responsibility for critical-temperature-kill in iwx_send_temp_report_ths_cmd()
8396 struct ieee80211com *ic = &sc->sc_ic; in iwx_init_hw()
8413 if (sc->sc_tx_with_siso_diversity) { in iwx_init_hw()
8435 if (isset(sc->sc_enabled_capa, IWX_UCODE_TLV_CAPA_DQA_SUPPORT)) { in iwx_init_hw()
8451 sc->sc_phyctxt[i].id = i; in iwx_init_hw()
8452 sc->sc_phyctxt[i].channel = &ic->ic_channels[1]; in iwx_init_hw()
8453 err = iwx_phy_ctxt_cmd(sc, &sc->sc_phyctxt[i], 1, 1, in iwx_init_hw()
8462 err = iwx_phy_send_rlc(sc, &sc->sc_phyctxt[i], 1, 1); in iwx_init_hw()
8477 if (isset(sc->sc_enabled_capa, IWX_UCODE_TLV_CAPA_CT_KILL_BY_FW)) { in iwx_init_hw()
8493 if (sc->sc_nvm.lar_enabled) { in iwx_init_hw()
8525 struct ieee80211com *ic = &sc->sc_ic; in iwx_allow_mcast()
8526 struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); in iwx_allow_mcast()
8527 struct iwx_node *in = IWX_NODE(vap->iv_bss); in iwx_allow_mcast()
8536 cmd->filter_own = 1; in iwx_allow_mcast()
8537 cmd->port_id = 0; in iwx_allow_mcast()
8538 cmd->count = 0; in iwx_allow_mcast()
8539 cmd->pass_all = 1; in iwx_allow_mcast()
8540 IEEE80211_ADDR_COPY(cmd->bssid, in->in_macaddr); in iwx_allow_mcast()
8552 generation = ++sc->sc_generation; in iwx_init()
8563 if (generation == sc->sc_generation) in iwx_init()
8569 sc->sc_flags |= IWX_FLAG_HW_INITED; in iwx_init()
8570 callout_reset(&sc->watchdog_to, hz, iwx_watchdog, sc); in iwx_init()
8583 while (sc->qfullmsk == 0 && (m = mbufq_dequeue(&sc->sc_snd)) != NULL) { in iwx_start()
8584 ni = (struct ieee80211_node *)m->m_pkthdr.rcvif; in iwx_start()
8586 if_inc_counter(ni->ni_vap->iv_ifp, IFCOUNTER_OERRORS, 1); in iwx_start()
8595 struct ieee80211com *ic = &sc->sc_ic; in iwx_stop()
8596 struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); in iwx_stop()
8601 /* Reset soft state. */ in iwx_stop()
8602 sc->sc_generation++; in iwx_stop()
8603 ivp->phy_ctxt = NULL; in iwx_stop()
8605 sc->sc_flags &= ~(IWX_FLAG_SCANNING | IWX_FLAG_BGSCAN); in iwx_stop()
8606 sc->sc_flags &= ~IWX_FLAG_MAC_ACTIVE; in iwx_stop()
8607 sc->sc_flags &= ~IWX_FLAG_BINDING_ACTIVE; in iwx_stop()
8608 sc->sc_flags &= ~IWX_FLAG_STA_ACTIVE; in iwx_stop()
8609 sc->sc_flags &= ~IWX_FLAG_TE_ACTIVE; in iwx_stop()
8610 sc->sc_flags &= ~IWX_FLAG_HW_ERR; in iwx_stop()
8611 sc->sc_flags &= ~IWX_FLAG_SHUTDOWN; in iwx_stop()
8612 sc->sc_flags &= ~IWX_FLAG_TXFLUSH; in iwx_stop()
8614 sc->sc_rx_ba_sessions = 0; in iwx_stop()
8615 sc->ba_rx.start_tidmask = 0; in iwx_stop()
8616 sc->ba_rx.stop_tidmask = 0; in iwx_stop()
8617 memset(sc->aggqid, 0, sizeof(sc->aggqid)); in iwx_stop()
8618 sc->ba_tx.start_tidmask = 0; in iwx_stop()
8619 sc->ba_tx.stop_tidmask = 0; in iwx_stop()
8626 struct ieee80211com *ic = &sc->sc_ic; in iwx_watchdog()
8634 for (i = 0; i < nitems(sc->sc_tx_timer); i++) { in iwx_watchdog()
8635 if (sc->sc_tx_timer[i] > 0) { in iwx_watchdog()
8636 if (--sc->sc_tx_timer[i] == 0) { in iwx_watchdog()
8646 callout_reset(&sc->watchdog_to, hz, iwx_watchdog, sc); in iwx_watchdog()
8652 * read with uint32_t-sized accesses, any members with a different size
8663 uint32_t data1; /* error-specific data */
8664 uint32_t data2; /* error-specific data */
8665 uint32_t data3; /* error-specific data */
8704 * UMAC error struct - relevant starting from family 8000 chip.
8707 * read with u32-sized accesses, any members with a different size
8717 uint32_t data1; /* error-specific data */
8718 uint32_t data2; /* error-specific data */
8719 uint32_t data3; /* error-specific data */
8724 uint32_t cmd_header; /* latest host cmd sent to UMAC */
8737 base = sc->sc_uc.uc_umac_error_event_table; in iwx_nic_umac_error()
8751 printf("%s: Start UMAC Error Log Dump:\n", DEVNAME(sc)); in iwx_nic_umac_error()
8753 sc->sc_flags, table.valid); in iwx_nic_umac_error()
8758 printf("%s: 0x%08X | umac branchlink1\n", DEVNAME(sc), table.blink1); in iwx_nic_umac_error()
8759 printf("%s: 0x%08X | umac branchlink2\n", DEVNAME(sc), table.blink2); in iwx_nic_umac_error()
8760 printf("%s: 0x%08X | umac interruptlink1\n", DEVNAME(sc), table.ilink1); in iwx_nic_umac_error()
8761 printf("%s: 0x%08X | umac interruptlink2\n", DEVNAME(sc), table.ilink2); in iwx_nic_umac_error()
8762 printf("%s: 0x%08X | umac data1\n", DEVNAME(sc), table.data1); in iwx_nic_umac_error()
8763 printf("%s: 0x%08X | umac data2\n", DEVNAME(sc), table.data2); in iwx_nic_umac_error()
8764 printf("%s: 0x%08X | umac data3\n", DEVNAME(sc), table.data3); in iwx_nic_umac_error()
8765 printf("%s: 0x%08X | umac major\n", DEVNAME(sc), table.umac_major); in iwx_nic_umac_error()
8766 printf("%s: 0x%08X | umac minor\n", DEVNAME(sc), table.umac_minor); in iwx_nic_umac_error()
8808 for (i = 0; i < nitems(advanced_lookup) - 1; i++) in iwx_desc_lookup()
8831 printf("%s: GOS-3758: 1\n", __func__); in iwx_nic_error()
8832 base = sc->sc_uc.uc_lmac_error_event_table[0]; in iwx_nic_error()
8833 printf("%s: GOS-3758: 2\n", __func__); in iwx_nic_error()
8840 printf("%s: GOS-3758: 3\n", __func__); in iwx_nic_error()
8846 printf("%s: GOS-3758: 4\n", __func__); in iwx_nic_error()
8852 printf("%s: GOS-3758: 5\n", __func__); in iwx_nic_error()
8856 sc->sc_flags, table.valid); in iwx_nic_error()
8859 printf("%s: GOS-3758: 6\n", __func__); in iwx_nic_error()
8860 printf("%s: 0x%08X | %-28s\n", DEVNAME(sc), table.error_id, in iwx_nic_error()
8901 if (sc->sc_uc.uc_umac_error_event_table) in iwx_nic_error()
8908 struct ieee80211com *ic = &sc->sc_ic; in iwx_dump_driver_status()
8909 struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); in iwx_dump_driver_status()
8910 enum ieee80211_state state = vap->iv_state; in iwx_dump_driver_status()
8914 for (i = 0; i < nitems(sc->txq); i++) { in iwx_dump_driver_status()
8915 struct iwx_tx_ring *ring = &sc->txq[i]; in iwx_dump_driver_status()
8916 printf(" tx ring %2d: qid=%-2d cur=%-3d " in iwx_dump_driver_status()
8917 "cur_hw=%-3d queued=%-3d\n", in iwx_dump_driver_status()
8918 i, ring->qid, ring->cur, ring->cur_hw, in iwx_dump_driver_status()
8919 ring->queued); in iwx_dump_driver_status()
8921 printf(" rx ring: cur=%d\n", sc->rxq.cur); in iwx_dump_driver_status()
8927 bus_dmamap_sync(sc->rxq.data_dmat, data->map, BUS_DMASYNC_POSTREAD); \
8936 qid = pkt->hdr.qid & ~0x80; in iwx_rx_pkt_valid()
8937 idx = pkt->hdr.idx; in iwx_rx_pkt_valid()
8938 code = IWX_WIDE_ID(pkt->hdr.flags, pkt->hdr.code); in iwx_rx_pkt_valid()
8941 pkt->len_n_flags != htole32(IWX_FH_RSCSR_FRAME_INVALID)); in iwx_rx_pkt_valid()
8947 struct ieee80211com *ic = &sc->sc_ic; in iwx_rx_pkt()
8951 const size_t minsz = sizeof(pkt->len_n_flags) + sizeof(pkt->hdr); in iwx_rx_pkt()
8954 m0 = data->m; in iwx_rx_pkt()
8956 pkt = (struct iwx_rx_packet *)(m0->m_data + offset); in iwx_rx_pkt()
8957 qid = pkt->hdr.qid; in iwx_rx_pkt()
8958 idx = pkt->hdr.idx; in iwx_rx_pkt()
8959 code = IWX_WIDE_ID(pkt->hdr.flags, pkt->hdr.code); in iwx_rx_pkt()
8971 struct iwx_tx_ring *ring = &sc->txq[qid]; in iwx_rx_pkt()
8972 struct iwx_tx_data *txdata = &ring->data[idx]; in iwx_rx_pkt()
8973 if (txdata->flags & IWX_TXDATA_FLAG_CMD_IS_NARROW) in iwx_rx_pkt()
8977 len = sizeof(pkt->len_n_flags) + iwx_rx_packet_len(pkt); in iwx_rx_pkt()
8978 if (len < minsz || len > (IWX_RBUF_SIZE - offset)) in iwx_rx_pkt()
8984 if (iwx_rx_addbuf(sc, IWX_RBUF_SIZE, sc->rxq.cur)) { in iwx_rx_pkt()
8987 KASSERT((data->m != m0), ("%s: data->m != m0", __func__)); in iwx_rx_pkt()
8992 /* XXX-THJ: I've not managed to hit this path in testing */ in iwx_rx_pkt()
8997 size_t maxlen = IWX_RBUF_SIZE - offset - minsz; in iwx_rx_pkt()
9001 (m0->m_data + nextoff); in iwx_rx_pkt()
9003 if (sc->sc_device_family >= IWX_DEVICE_FAMILY_AX210 || in iwx_rx_pkt()
9009 iwx_rx_mpdu_mq(sc, m0, pkt->data, maxlen); in iwx_rx_pkt()
9024 iwx_rx_mpdu_mq(sc, m, pkt->data, maxlen); in iwx_rx_pkt()
9057 sc->sc_uc.uc_ok = 0; in iwx_rx_pkt()
9068 sc->sc_uc.uc_intr = 1; in iwx_rx_pkt()
9069 wakeup(&sc->sc_uc); in iwx_rx_pkt()
9072 sc->sc_uc.uc_lmac_error_event_table[0] = le32toh( in iwx_rx_pkt()
9073 resp6->lmac_data[0].dbg_ptrs.error_event_table_ptr); in iwx_rx_pkt()
9074 sc->sc_uc.uc_lmac_error_event_table[1] = le32toh( in iwx_rx_pkt()
9075 resp6->lmac_data[1].dbg_ptrs.error_event_table_ptr); in iwx_rx_pkt()
9076 sc->sc_uc.uc_log_event_table = le32toh( in iwx_rx_pkt()
9077 resp6->lmac_data[0].dbg_ptrs.log_event_table_ptr); in iwx_rx_pkt()
9078 sc->sc_uc.uc_umac_error_event_table = le32toh( in iwx_rx_pkt()
9079 resp6->umac_data.dbg_ptrs.error_info_addr); in iwx_rx_pkt()
9080 sc->sc_sku_id[0] = in iwx_rx_pkt()
9081 le32toh(resp6->sku_id.data[0]); in iwx_rx_pkt()
9082 sc->sc_sku_id[1] = in iwx_rx_pkt()
9083 le32toh(resp6->sku_id.data[1]); in iwx_rx_pkt()
9084 sc->sc_sku_id[2] = in iwx_rx_pkt()
9085 le32toh(resp6->sku_id.data[2]); in iwx_rx_pkt()
9086 if (resp6->status == IWX_ALIVE_STATUS_OK) { in iwx_rx_pkt()
9087 sc->sc_uc.uc_ok = 1; in iwx_rx_pkt()
9094 sc->sc_uc.uc_intr = 1; in iwx_rx_pkt()
9095 wakeup(&sc->sc_uc); in iwx_rx_pkt()
9098 sc->sc_uc.uc_lmac_error_event_table[0] = le32toh( in iwx_rx_pkt()
9099 resp5->lmac_data[0].dbg_ptrs.error_event_table_ptr); in iwx_rx_pkt()
9100 sc->sc_uc.uc_lmac_error_event_table[1] = le32toh( in iwx_rx_pkt()
9101 resp5->lmac_data[1].dbg_ptrs.error_event_table_ptr); in iwx_rx_pkt()
9102 sc->sc_uc.uc_log_event_table = le32toh( in iwx_rx_pkt()
9103 resp5->lmac_data[0].dbg_ptrs.log_event_table_ptr); in iwx_rx_pkt()
9104 sc->sc_uc.uc_umac_error_event_table = le32toh( in iwx_rx_pkt()
9105 resp5->umac_data.dbg_ptrs.error_info_addr); in iwx_rx_pkt()
9106 sc->sc_sku_id[0] = in iwx_rx_pkt()
9107 le32toh(resp5->sku_id.data[0]); in iwx_rx_pkt()
9108 sc->sc_sku_id[1] = in iwx_rx_pkt()
9109 le32toh(resp5->sku_id.data[1]); in iwx_rx_pkt()
9110 sc->sc_sku_id[2] = in iwx_rx_pkt()
9111 le32toh(resp5->sku_id.data[2]); in iwx_rx_pkt()
9112 if (resp5->status == IWX_ALIVE_STATUS_OK) in iwx_rx_pkt()
9113 sc->sc_uc.uc_ok = 1; in iwx_rx_pkt()
9116 sc->sc_uc.uc_lmac_error_event_table[0] = le32toh( in iwx_rx_pkt()
9117 resp4->lmac_data[0].dbg_ptrs.error_event_table_ptr); in iwx_rx_pkt()
9118 sc->sc_uc.uc_lmac_error_event_table[1] = le32toh( in iwx_rx_pkt()
9119 resp4->lmac_data[1].dbg_ptrs.error_event_table_ptr); in iwx_rx_pkt()
9120 sc->sc_uc.uc_log_event_table = le32toh( in iwx_rx_pkt()
9121 resp4->lmac_data[0].dbg_ptrs.log_event_table_ptr); in iwx_rx_pkt()
9122 sc->sc_uc.uc_umac_error_event_table = le32toh( in iwx_rx_pkt()
9123 resp4->umac_data.dbg_ptrs.error_info_addr); in iwx_rx_pkt()
9124 if (resp4->status == IWX_ALIVE_STATUS_OK) in iwx_rx_pkt()
9125 sc->sc_uc.uc_ok = 1; in iwx_rx_pkt()
9129 sc->sc_uc.uc_intr = 1; in iwx_rx_pkt()
9130 wakeup(&sc->sc_uc); in iwx_rx_pkt()
9137 memcpy(&sc->sc_stats, stats, sizeof(sc->sc_stats)); in iwx_rx_pkt()
9138 sc->sc_noise = iwx_get_noise(&stats->rx.general); in iwx_rx_pkt()
9155 DEVNAME(sc), le16toh(notif->temperature)); in iwx_rx_pkt()
9156 sc->sc_flags |= IWX_FLAG_HW_ERR; in iwx_rx_pkt()
9194 if (sc->sc_cmd_resp_pkt[idx] == NULL) in iwx_rx_pkt()
9197 bus_dmamap_sync(sc->rxq.data_dmat, data->map, in iwx_rx_pkt()
9200 pkt_len = sizeof(pkt->len_n_flags) + in iwx_rx_pkt()
9203 if ((pkt->hdr.flags & IWX_CMD_FAILED_MSK) || in iwx_rx_pkt()
9205 pkt_len > sc->sc_cmd_resp_len[idx]) { in iwx_rx_pkt()
9206 free(sc->sc_cmd_resp_pkt[idx], M_DEVBUF); in iwx_rx_pkt()
9207 sc->sc_cmd_resp_pkt[idx] = NULL; in iwx_rx_pkt()
9211 bus_dmamap_sync(sc->rxq.data_dmat, data->map, in iwx_rx_pkt()
9213 memcpy(sc->sc_cmd_resp_pkt[idx], pkt, pkt_len); in iwx_rx_pkt()
9218 sc->sc_init_complete |= IWX_INIT_COMPLETE; in iwx_rx_pkt()
9219 wakeup(&sc->sc_init_complete); in iwx_rx_pkt()
9226 DPRINTF(("%s: scan complete notif->status=%d\n", __func__, in iwx_rx_pkt()
9227 notif->status)); in iwx_rx_pkt()
9228 ieee80211_runtask(&sc->sc_ic, &sc->sc_es_task); in iwx_rx_pkt()
9238 DPRINTF(("%s: iter scan complete notif->status=%d\n", __func__, in iwx_rx_pkt()
9239 notif->status)); in iwx_rx_pkt()
9255 DEVNAME(sc), le32toh(resp->error_type), in iwx_rx_pkt()
9256 resp->cmd_id); in iwx_rx_pkt()
9265 if (sc->sc_time_event_uid != le32toh(notif->unique_id)) in iwx_rx_pkt()
9267 action = le32toh(notif->action); in iwx_rx_pkt()
9269 sc->sc_flags &= ~IWX_FLAG_TE_ACTIVE; in iwx_rx_pkt()
9280 status = le32toh(notif->status); in iwx_rx_pkt()
9281 start = le32toh(notif->start); in iwx_rx_pkt()
9282 conf_id = le32toh(notif->conf_id); in iwx_rx_pkt()
9286 sc->sc_flags &= ~IWX_FLAG_TE_ACTIVE; in iwx_rx_pkt()
9336 /* undocumented notification from iwx-ty-a0-gf-a0-77 image */ in iwx_rx_pkt()
9343 sc->sc_init_complete |= IWX_PNVM_COMPLETE; in iwx_rx_pkt()
9344 wakeup(&sc->sc_init_complete); in iwx_rx_pkt()
9349 /* XXX wulf: Get rid of bluetooth-related spam */ in iwx_rx_pkt()
9350 if ((code == 0xc2 && pkt->len_n_flags == 0x0000000c) || in iwx_rx_pkt()
9351 (code == 0xce && pkt->len_n_flags == 0x2000002c)) in iwx_rx_pkt()
9355 DEVNAME(sc), code, pkt->len_n_flags, in iwx_rx_pkt()
9374 if (sc->sc_device_family >= IWX_DEVICE_FAMILY_AX210) in iwx_rx_pkt()
9378 if (m0 && m0 != data->m) in iwx_rx_pkt()
9388 bus_dmamap_sync(sc->rxq.stat_dma.tag, sc->rxq.stat_dma.map, in iwx_notif_intr()
9391 if (sc->sc_device_family >= IWX_DEVICE_FAMILY_AX210) { in iwx_notif_intr()
9392 uint16_t *status = sc->rxq.stat_dma.vaddr; in iwx_notif_intr()
9395 hw = le16toh(sc->rxq.stat->closed_rb_num) & 0xfff; in iwx_notif_intr()
9396 hw &= (IWX_RX_MQ_RING_COUNT - 1); in iwx_notif_intr()
9397 while (sc->rxq.cur != hw) { in iwx_notif_intr()
9398 struct iwx_rx_data *data = &sc->rxq.data[sc->rxq.cur]; in iwx_notif_intr()
9400 bus_dmamap_sync(sc->rxq.data_dmat, data->map, in iwx_notif_intr()
9404 sc->rxq.cur = (sc->rxq.cur + 1) % IWX_RX_MQ_RING_COUNT; in iwx_notif_intr()
9411 hw = (hw == 0) ? IWX_RX_MQ_RING_COUNT - 1 : hw - 1; in iwx_notif_intr()
9420 struct ieee80211com *ic = &sc->sc_ic;
9426 if (sc->sc_flags & IWX_FLAG_USE_ICT) {
9427 uint32_t *ict = sc->ict_dma.vaddr;
9430 tmp = htole32(ict[sc->ict_cur]);
9440 ict[sc->ict_cur] = 0;
9441 sc->ict_cur = (sc->ict_cur+1) % IWX_ICT_COUNT;
9442 tmp = htole32(ict[sc->ict_cur]);
9463 IWX_WRITE(sc, IWX_CSR_INT, r1 | ~sc->sc_intmask);
9470 iwx_update_rx_desc(sc, &sc->rxq, i);
9483 if (ifp->if_flags & IFF_DEBUG) {
9505 sc->sc_fw_chunk_done = 1;
9506 wakeup(&sc->sc_fw);
9518 /* Disable periodic interrupt; we use it as just a one-shot. */
9526 * to extend the periodic interrupt; one-shot is enough.
9548 struct ieee80211com *ic = &sc->sc_ic; in iwx_intr_msix()
9558 inta_fh &= sc->sc_fh_mask; in iwx_intr_msix()
9559 inta_hw &= sc->sc_hw_mask; in iwx_intr_msix()
9568 sc->sc_fw_chunk_done = 1; in iwx_intr_msix()
9569 wakeup(&sc->sc_fw); in iwx_intr_msix()
9575 if (sc->sc_debug) { in iwx_intr_msix()
9590 sc->sc_flags |= IWX_FLAG_HW_ERR; in iwx_intr_msix()
9601 * XXX-THJ: we don't have the dma segment handy. This is hacked in iwx_intr_msix()
9607 iwx_update_rx_desc(sc, &sc->rxq, i); in iwx_intr_msix()
9616 * re-enabled by clearing this bit. This register is defined as in iwx_intr_msix()
9627 * The device info table below contains device-specific config overrides.
9640 * in some work-in-progress state for quite a while. Linux commits moving
9650 * Some "old"-style entries are required to identify the firmware image to use.
9911 /* So-F with Hr */
9928 /* So-F with GF */
9990 struct ieee80211com *ic = &sc->sc_ic; in iwx_preinit()
9999 if (sc->attached) { in iwx_preinit()
10017 sc->attached = 1; in iwx_preinit()
10018 if (sc->sc_pnvm_ver) { in iwx_preinit()
10021 DEVNAME(sc), sc->sc_hw_rev & IWX_CSR_HW_REV_TYPE_MSK, in iwx_preinit()
10022 sc->sc_fwver, sc->sc_pnvm_ver, in iwx_preinit()
10023 ether_sprintf(sc->sc_nvm.hw_addr)); in iwx_preinit()
10026 DEVNAME(sc), sc->sc_hw_rev & IWX_CSR_HW_REV_TYPE_MSK, in iwx_preinit()
10027 sc->sc_fwver, ether_sprintf(sc->sc_nvm.hw_addr)); in iwx_preinit()
10031 if (!sc->sc_nvm.sku_cap_band_52GHz_enable) in iwx_preinit()
10032 memset(&ic->ic_sup_rates[IEEE80211_MODE_11A], 0, in iwx_preinit()
10033 sizeof(ic->ic_sup_rates[IEEE80211_MODE_11A])); in iwx_preinit()
10042 struct ieee80211com *ic = &sc->sc_ic; in iwx_attach_hook()
10051 iwx_init_channel_map(ic, IEEE80211_CHAN_MAX, &ic->ic_nchans, in iwx_attach_hook()
10052 ic->ic_channels); in iwx_attach_hook()
10055 ic->ic_vap_create = iwx_vap_create; in iwx_attach_hook()
10056 ic->ic_vap_delete = iwx_vap_delete; in iwx_attach_hook()
10057 ic->ic_raw_xmit = iwx_raw_xmit; in iwx_attach_hook()
10058 ic->ic_node_alloc = iwx_node_alloc; in iwx_attach_hook()
10059 ic->ic_scan_start = iwx_scan_start; in iwx_attach_hook()
10060 ic->ic_scan_end = iwx_scan_end; in iwx_attach_hook()
10061 ic->ic_update_mcast = iwx_update_mcast; in iwx_attach_hook()
10062 ic->ic_getradiocaps = iwx_init_channel_map; in iwx_attach_hook()
10064 ic->ic_set_channel = iwx_set_channel; in iwx_attach_hook()
10065 ic->ic_scan_curchan = iwx_scan_curchan; in iwx_attach_hook()
10066 ic->ic_scan_mindwell = iwx_scan_mindwell; in iwx_attach_hook()
10067 ic->ic_wme.wme_update = iwx_wme_update; in iwx_attach_hook()
10068 ic->ic_parent = iwx_parent; in iwx_attach_hook()
10069 ic->ic_transmit = iwx_transmit; in iwx_attach_hook()
10071 sc->sc_ampdu_rx_start = ic->ic_ampdu_rx_start; in iwx_attach_hook()
10072 ic->ic_ampdu_rx_start = iwx_ampdu_rx_start; in iwx_attach_hook()
10073 sc->sc_ampdu_rx_stop = ic->ic_ampdu_rx_stop; in iwx_attach_hook()
10074 ic->ic_ampdu_rx_stop = iwx_ampdu_rx_stop; in iwx_attach_hook()
10076 sc->sc_addba_request = ic->ic_addba_request; in iwx_attach_hook()
10077 ic->ic_addba_request = iwx_addba_request; in iwx_attach_hook()
10078 sc->sc_addba_response = ic->ic_addba_response; in iwx_attach_hook()
10079 ic->ic_addba_response = iwx_addba_response; in iwx_attach_hook()
10084 config_intrhook_disestablish(&sc->sc_preinit_hook); in iwx_attach_hook()
10094 sdev_id = pci_get_subdevice(sc->sc_dev); in iwx_find_device_cfg()
10095 mac_type = IWX_CSR_HW_REV_TYPE(sc->sc_hw_rev); in iwx_find_device_cfg()
10096 mac_step = IWX_CSR_HW_REV_STEP(sc->sc_hw_rev << 2); in iwx_find_device_cfg()
10097 rf_type = IWX_CSR_HW_RFID_TYPE(sc->sc_hw_rf_id); in iwx_find_device_cfg()
10098 cdb = IWX_CSR_HW_RFID_IS_CDB(sc->sc_hw_rf_id); in iwx_find_device_cfg()
10099 jacket = IWX_CSR_HW_RFID_IS_JACKET(sc->sc_hw_rf_id); in iwx_find_device_cfg()
10105 for (i = nitems(iwx_dev_info_table) - 1; i >= 0; i--) { in iwx_find_device_cfg()
10108 if (dev_info->device != (uint16_t)IWX_CFG_ANY && in iwx_find_device_cfg()
10109 dev_info->device != sc->sc_pid) in iwx_find_device_cfg()
10112 if (dev_info->subdevice != (uint16_t)IWX_CFG_ANY && in iwx_find_device_cfg()
10113 dev_info->subdevice != sdev_id) in iwx_find_device_cfg()
10116 if (dev_info->mac_type != (uint16_t)IWX_CFG_ANY && in iwx_find_device_cfg()
10117 dev_info->mac_type != mac_type) in iwx_find_device_cfg()
10120 if (dev_info->mac_step != (uint8_t)IWX_CFG_ANY && in iwx_find_device_cfg()
10121 dev_info->mac_step != mac_step) in iwx_find_device_cfg()
10124 if (dev_info->rf_type != (uint16_t)IWX_CFG_ANY && in iwx_find_device_cfg()
10125 dev_info->rf_type != rf_type) in iwx_find_device_cfg()
10128 if (dev_info->cdb != (uint8_t)IWX_CFG_ANY && in iwx_find_device_cfg()
10129 dev_info->cdb != cdb) in iwx_find_device_cfg()
10132 if (dev_info->jacket != (uint8_t)IWX_CFG_ANY && in iwx_find_device_cfg()
10133 dev_info->jacket != jacket) in iwx_find_device_cfg()
10136 if (dev_info->rf_id != (uint8_t)IWX_CFG_ANY && in iwx_find_device_cfg()
10137 dev_info->rf_id != rf_id) in iwx_find_device_cfg()
10140 if (dev_info->no_160 != (uint8_t)IWX_CFG_ANY && in iwx_find_device_cfg()
10141 dev_info->no_160 != no_160) in iwx_find_device_cfg()
10144 if (dev_info->cores != (uint8_t)IWX_CFG_ANY && in iwx_find_device_cfg()
10145 dev_info->cores != cores) in iwx_find_device_cfg()
10148 return dev_info->cfg; in iwx_find_device_cfg()
10185 struct ieee80211com *ic = &sc->sc_ic; in iwx_attach()
10193 sc->sc_dev = dev; in iwx_attach()
10194 sc->sc_pid = pci_get_device(dev); in iwx_attach()
10195 sc->sc_dmat = bus_get_dma_tag(sc->sc_dev); in iwx_attach()
10197 TASK_INIT(&sc->sc_es_task, 0, iwx_endscan_cb, sc); in iwx_attach()
10199 mbufq_init(&sc->sc_snd, ifqmaxlen); in iwx_attach()
10200 TASK_INIT(&sc->ba_rx_task, 0, iwx_ba_rx_task, sc); in iwx_attach()
10201 TASK_INIT(&sc->ba_tx_task, 0, iwx_ba_tx_task, sc); in iwx_attach()
10202 sc->sc_tq = taskqueue_create("iwm_taskq", M_WAITOK, in iwx_attach()
10203 taskqueue_thread_enqueue, &sc->sc_tq); in iwx_attach()
10204 error = taskqueue_start_threads(&sc->sc_tq, 1, 0, "iwm_taskq"); in iwx_attach()
10211 pci_find_cap(dev, PCIY_EXPRESS, &sc->sc_cap_off); in iwx_attach()
10212 if (sc->sc_cap_off == 0) { in iwx_attach()
10224 sc->sc_msix = 1; in iwx_attach()
10226 device_printf(dev, "no MSI-X found\n"); in iwx_attach()
10232 sc->sc_mem = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, in iwx_attach()
10234 if (sc->sc_mem == NULL) { in iwx_attach()
10235 device_printf(sc->sc_dev, "can't map mem space\n"); in iwx_attach()
10238 sc->sc_st = rman_get_bustag(sc->sc_mem); in iwx_attach()
10239 sc->sc_sh = rman_get_bushandle(sc->sc_mem); in iwx_attach()
10246 sc->sc_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, RF_ACTIVE | in iwx_attach()
10248 if (sc->sc_irq == NULL) { in iwx_attach()
10252 error = bus_setup_intr(dev, sc->sc_irq, INTR_TYPE_NET | INTR_MPSAFE, in iwx_attach()
10253 NULL, iwx_intr_msix, sc, &sc->sc_ih); in iwx_attach()
10264 sc->sc_hw_rev = IWX_READ(sc, IWX_CSR_HW_REV); in iwx_attach()
10265 DPRINTF(("%s: sc->sc_hw_rev=%d\n", __func__, sc->sc_hw_rev)); in iwx_attach()
10266 sc->sc_hw_rf_id = IWX_READ(sc, IWX_CSR_HW_RF_ID); in iwx_attach()
10267 DPRINTF(("%s: sc->sc_hw_rf_id =%d\n", __func__, sc->sc_hw_rf_id)); in iwx_attach()
10271 * changed, and now the revision step also includes bit 0-1 (no more in iwx_attach()
10272 * "dash" value). To keep hw_rev backwards compatible - we'll store it in iwx_attach()
10275 sc->sc_hw_rev = (sc->sc_hw_rev & 0xfff0) | in iwx_attach()
10276 (IWX_CSR_HW_REV_STEP(sc->sc_hw_rev << 2) << 2); in iwx_attach()
10278 switch (sc->sc_pid) { in iwx_attach()
10280 sc->sc_fwname = IWX_CC_A_FW; in iwx_attach()
10281 sc->sc_device_family = IWX_DEVICE_FAMILY_22000; in iwx_attach()
10282 sc->sc_integrated = 0; in iwx_attach()
10283 sc->sc_ltr_delay = IWX_SOC_FLAGS_LTR_APPLY_DELAY_NONE; in iwx_attach()
10284 sc->sc_low_latency_xtal = 0; in iwx_attach()
10285 sc->sc_xtal_latency = 0; in iwx_attach()
10286 sc->sc_tx_with_siso_diversity = 0; in iwx_attach()
10287 sc->sc_uhb_supported = 0; in iwx_attach()
10292 if (sc->sc_hw_rev != IWX_CSR_HW_REV_TYPE_QUZ) { in iwx_attach()
10296 sc->sc_fwname = IWX_QUZ_A_HR_B_FW; in iwx_attach()
10297 sc->sc_device_family = IWX_DEVICE_FAMILY_22000; in iwx_attach()
10298 sc->sc_integrated = 1; in iwx_attach()
10299 sc->sc_ltr_delay = IWX_SOC_FLAGS_LTR_APPLY_DELAY_200; in iwx_attach()
10300 sc->sc_low_latency_xtal = 0; in iwx_attach()
10301 sc->sc_xtal_latency = 500; in iwx_attach()
10302 sc->sc_tx_with_siso_diversity = 0; in iwx_attach()
10303 sc->sc_uhb_supported = 0; in iwx_attach()
10306 if (sc->sc_hw_rev == IWX_CSR_HW_REV_TYPE_QU_C0) in iwx_attach()
10307 sc->sc_fwname = IWX_QU_C_HR_B_FW; in iwx_attach()
10308 else if (sc->sc_hw_rev == IWX_CSR_HW_REV_TYPE_QUZ) in iwx_attach()
10309 sc->sc_fwname = IWX_QUZ_A_HR_B_FW; in iwx_attach()
10311 sc->sc_fwname = IWX_QU_B_HR_B_FW; in iwx_attach()
10312 sc->sc_device_family = IWX_DEVICE_FAMILY_22000; in iwx_attach()
10313 sc->sc_integrated = 1; in iwx_attach()
10314 sc->sc_ltr_delay = IWX_SOC_FLAGS_LTR_APPLY_DELAY_200; in iwx_attach()
10315 sc->sc_low_latency_xtal = 0; in iwx_attach()
10316 sc->sc_xtal_latency = 500; in iwx_attach()
10317 sc->sc_tx_with_siso_diversity = 0; in iwx_attach()
10318 sc->sc_uhb_supported = 0; in iwx_attach()
10323 if (sc->sc_hw_rev == IWX_CSR_HW_REV_TYPE_QU_C0) in iwx_attach()
10324 sc->sc_fwname = IWX_QU_C_HR_B_FW; in iwx_attach()
10325 else if (sc->sc_hw_rev == IWX_CSR_HW_REV_TYPE_QUZ) in iwx_attach()
10326 sc->sc_fwname = IWX_QUZ_A_HR_B_FW; in iwx_attach()
10328 sc->sc_fwname = IWX_QU_B_HR_B_FW; in iwx_attach()
10329 sc->sc_device_family = IWX_DEVICE_FAMILY_22000; in iwx_attach()
10330 sc->sc_integrated = 1; in iwx_attach()
10331 sc->sc_ltr_delay = IWX_SOC_FLAGS_LTR_APPLY_DELAY_1820; in iwx_attach()
10332 sc->sc_low_latency_xtal = 0; in iwx_attach()
10333 sc->sc_xtal_latency = 1820; in iwx_attach()
10334 sc->sc_tx_with_siso_diversity = 0; in iwx_attach()
10335 sc->sc_uhb_supported = 0; in iwx_attach()
10338 if (sc->sc_hw_rev == IWX_CSR_HW_REV_TYPE_QU_C0) in iwx_attach()
10339 sc->sc_fwname = IWX_QU_C_HR_B_FW; in iwx_attach()
10340 else if (sc->sc_hw_rev == IWX_CSR_HW_REV_TYPE_QUZ) in iwx_attach()
10341 sc->sc_fwname = IWX_QUZ_A_HR_B_FW; in iwx_attach()
10343 sc->sc_fwname = IWX_QU_B_HR_B_FW; in iwx_attach()
10344 sc->sc_device_family = IWX_DEVICE_FAMILY_22000; in iwx_attach()
10345 sc->sc_integrated = 1; in iwx_attach()
10346 sc->sc_ltr_delay = IWX_SOC_FLAGS_LTR_APPLY_DELAY_2500; in iwx_attach()
10347 sc->sc_low_latency_xtal = 1; in iwx_attach()
10348 sc->sc_xtal_latency = 12000; in iwx_attach()
10349 sc->sc_tx_with_siso_diversity = 0; in iwx_attach()
10350 sc->sc_uhb_supported = 0; in iwx_attach()
10359 sc->sc_fwname = IWX_SO_A_GF_A_FW; in iwx_attach()
10360 sc->sc_pnvm_name = IWX_SO_A_GF_A_PNVM; in iwx_attach()
10361 sc->sc_device_family = IWX_DEVICE_FAMILY_AX210; in iwx_attach()
10362 sc->sc_integrated = 0; in iwx_attach()
10363 sc->sc_ltr_delay = IWX_SOC_FLAGS_LTR_APPLY_DELAY_NONE; in iwx_attach()
10364 sc->sc_low_latency_xtal = 0; in iwx_attach()
10365 sc->sc_xtal_latency = 0; in iwx_attach()
10366 sc->sc_tx_with_siso_diversity = 0; in iwx_attach()
10367 sc->sc_uhb_supported = 1; in iwx_attach()
10371 sc->sc_fwname = IWX_SO_A_GF_A_FW; in iwx_attach()
10372 sc->sc_pnvm_name = IWX_SO_A_GF_A_PNVM; in iwx_attach()
10373 sc->sc_device_family = IWX_DEVICE_FAMILY_AX210; in iwx_attach()
10374 sc->sc_integrated = 1; in iwx_attach()
10375 sc->sc_ltr_delay = IWX_SOC_FLAGS_LTR_APPLY_DELAY_2500; in iwx_attach()
10376 sc->sc_low_latency_xtal = 1; in iwx_attach()
10377 sc->sc_xtal_latency = 12000; in iwx_attach()
10378 sc->sc_tx_with_siso_diversity = 0; in iwx_attach()
10379 sc->sc_uhb_supported = 0; in iwx_attach()
10380 sc->sc_imr_enabled = 1; in iwx_attach()
10390 sc->sc_fwname = cfg->fw_name; in iwx_attach()
10391 sc->sc_pnvm_name = cfg->pnvm_name; in iwx_attach()
10392 sc->sc_tx_with_siso_diversity = cfg->tx_with_siso_diversity; in iwx_attach()
10393 sc->sc_uhb_supported = cfg->uhb_supported; in iwx_attach()
10394 if (cfg->xtal_latency) { in iwx_attach()
10395 sc->sc_xtal_latency = cfg->xtal_latency; in iwx_attach()
10396 sc->sc_low_latency_xtal = cfg->low_latency_xtal; in iwx_attach()
10400 sc->mac_addr_from_csr = 0x380; /* differs on BZ hw generation */ in iwx_attach()
10402 if (sc->sc_device_family >= IWX_DEVICE_FAMILY_AX210) { in iwx_attach()
10403 sc->sc_umac_prph_offset = 0x300000; in iwx_attach()
10404 sc->max_tfd_queue_size = IWX_TFD_QUEUE_SIZE_MAX_GEN3; in iwx_attach()
10406 sc->max_tfd_queue_size = IWX_TFD_QUEUE_SIZE_MAX; in iwx_attach()
10409 if (sc->sc_device_family >= IWX_DEVICE_FAMILY_AX210) in iwx_attach()
10413 err = iwx_dma_contig_alloc(sc->sc_dmat, &sc->ctxt_info_dma, in iwx_attach()
10421 if (sc->sc_device_family >= IWX_DEVICE_FAMILY_AX210) { in iwx_attach()
10422 err = iwx_dma_contig_alloc(sc->sc_dmat, &sc->prph_scratch_dma, in iwx_attach()
10433 * some dummy TR/CR tail pointers - which shouldn't be in iwx_attach()
10440 err = iwx_dma_contig_alloc(sc->sc_dmat, &sc->prph_info_dma, in iwx_attach()
10450 err = iwx_dma_contig_alloc(sc->sc_dmat, &sc->ict_dma, in iwx_attach()
10457 for (txq_i = 0; txq_i < nitems(sc->txq); txq_i++) { in iwx_attach()
10458 err = iwx_alloc_tx_ring(sc, &sc->txq[txq_i], txq_i); in iwx_attach()
10466 err = iwx_alloc_rx_ring(sc, &sc->rxq); in iwx_attach()
10468 device_printf(sc->sc_dev, "could not allocate RX ring\n"); in iwx_attach()
10475 CTLFLAG_RWTUN, &sc->sc_debug, 0, "bitmask to control debugging"); in iwx_attach()
10486 CTLFLAG_RD, &sc->qfullmsk, 0, "queue fullmask"); in iwx_attach()
10490 CTLFLAG_RD, &sc->txq[0].queued, 0, "queue 0"); in iwx_attach()
10493 CTLFLAG_RD, &sc->txq[1].queued, 0, "queue 1"); in iwx_attach()
10496 CTLFLAG_RD, &sc->txq[2].queued, 0, "queue 2"); in iwx_attach()
10499 CTLFLAG_RD, &sc->txq[3].queued, 0, "queue 3"); in iwx_attach()
10502 CTLFLAG_RD, &sc->txq[4].queued, 0, "queue 4"); in iwx_attach()
10505 CTLFLAG_RD, &sc->txq[5].queued, 0, "queue 5"); in iwx_attach()
10508 CTLFLAG_RD, &sc->txq[6].queued, 0, "queue 6"); in iwx_attach()
10511 CTLFLAG_RD, &sc->txq[7].queued, 0, "queue 7"); in iwx_attach()
10513 ic->ic_softc = sc; in iwx_attach()
10514 ic->ic_name = device_get_nameunit(sc->sc_dev); in iwx_attach()
10515 ic->ic_phytype = IEEE80211_T_OFDM; /* not only, but not used */ in iwx_attach()
10516 ic->ic_opmode = IEEE80211_M_STA; /* default to BSS mode */ in iwx_attach()
10519 ic->ic_caps = in iwx_attach()
10529 ic->ic_flags_ext = IEEE80211_FEXT_SCAN_OFFLOAD; in iwx_attach()
10531 ic->ic_flags_ext |= IEEE80211_FEXT_SEQNO_OFFLOAD; in iwx_attach()
10533 ic->ic_flags_ext |= IEEE80211_FEXT_NO_NULLDATA; in iwx_attach()
10535 ic->ic_txstream = 2; in iwx_attach()
10536 ic->ic_rxstream = 2; in iwx_attach()
10537 ic->ic_htcaps |= IEEE80211_HTC_HT in iwx_attach()
10542 | IEEE80211_HTC_AMPDU /* tx A-MPDU */ in iwx_attach()
10544 | IEEE80211_HTCAP_MAXAMSDU_3839; /* max A-MSDU length */ in iwx_attach()
10546 ic->ic_cryptocaps |= IEEE80211_CRYPTO_AES_CCM; in iwx_attach()
10549 * XXX: setupcurchan() expects vhtcaps to be non-zero in iwx_attach()
10552 ic->ic_vht_cap.vht_cap_info |= IEEE80211_VHTCAP_MAX_MPDU_LENGTH_3895 in iwx_attach()
10558 ic->ic_flags_ext |= IEEE80211_FEXT_VHT; in iwx_attach()
10567 ic->ic_vht_cap.supp_mcs.tx_mcs_map = htole16(mcsmap); in iwx_attach()
10568 ic->ic_vht_cap.supp_mcs.rx_mcs_map = htole16(mcsmap); in iwx_attach()
10570 callout_init_mtx(&sc->watchdog_to, &sc->sc_mtx, 0); in iwx_attach()
10571 for (i = 0; i < nitems(sc->sc_rxba_data); i++) { in iwx_attach()
10572 struct iwx_rxba_data *rxba = &sc->sc_rxba_data[i]; in iwx_attach()
10573 rxba->baid = IWX_RX_REORDER_DATA_INVALID_BAID; in iwx_attach()
10574 rxba->sc = sc; in iwx_attach()
10575 for (j = 0; j < nitems(rxba->entries); j++) in iwx_attach()
10576 mbufq_init(&rxba->entries[j].frames, ifqmaxlen); in iwx_attach()
10579 sc->sc_preinit_hook.ich_func = iwx_attach_hook; in iwx_attach()
10580 sc->sc_preinit_hook.ich_arg = sc; in iwx_attach()
10581 if (config_intrhook_establish(&sc->sc_preinit_hook) != 0) { in iwx_attach()
10590 while (--txq_i >= 0) in iwx_attach()
10591 iwx_free_tx_ring(sc, &sc->txq[txq_i]); in iwx_attach()
10592 iwx_free_rx_ring(sc, &sc->rxq); in iwx_attach()
10593 if (sc->ict_dma.vaddr != NULL) in iwx_attach()
10594 iwx_dma_contig_free(&sc->ict_dma); in iwx_attach()
10597 iwx_dma_contig_free(&sc->ctxt_info_dma); in iwx_attach()
10598 iwx_dma_contig_free(&sc->prph_scratch_dma); in iwx_attach()
10599 iwx_dma_contig_free(&sc->prph_info_dma); in iwx_attach()
10611 taskqueue_drain_all(sc->sc_tq); in iwx_detach()
10612 taskqueue_free(sc->sc_tq); in iwx_detach()
10614 ieee80211_ifdetach(&sc->sc_ic); in iwx_detach()
10616 callout_drain(&sc->watchdog_to); in iwx_detach()
10618 for (txq_i = 0; txq_i < nitems(sc->txq); txq_i++) in iwx_detach()
10619 iwx_free_tx_ring(sc, &sc->txq[txq_i]); in iwx_detach()
10620 iwx_free_rx_ring(sc, &sc->rxq); in iwx_detach()
10622 if (sc->sc_fwp != NULL) { in iwx_detach()
10623 firmware_put(sc->sc_fwp, FIRMWARE_UNLOAD); in iwx_detach()
10624 sc->sc_fwp = NULL; in iwx_detach()
10627 if (sc->sc_pnvm != NULL) { in iwx_detach()
10628 firmware_put(sc->sc_pnvm, FIRMWARE_UNLOAD); in iwx_detach()
10629 sc->sc_pnvm = NULL; in iwx_detach()
10632 if (sc->sc_irq != NULL) { in iwx_detach()
10633 bus_teardown_intr(dev, sc->sc_irq, sc->sc_ih); in iwx_detach()
10635 rman_get_rid(sc->sc_irq), sc->sc_irq); in iwx_detach()
10638 if (sc->sc_mem != NULL) in iwx_detach()
10640 rman_get_rid(sc->sc_mem), sc->sc_mem); in iwx_detach()
10650 struct ieee80211com *ic = &sc->sc_ic; in iwx_radiotap_attach()
10653 "->%s begin\n", __func__); in iwx_radiotap_attach()
10656 &sc->sc_txtap.wt_ihdr, sizeof(sc->sc_txtap), in iwx_radiotap_attach()
10658 &sc->sc_rxtap.wr_ihdr, sizeof(sc->sc_rxtap), in iwx_radiotap_attach()
10662 "->%s end\n", __func__); in iwx_radiotap_attach()
10674 if (!TAILQ_EMPTY(&ic->ic_vaps)) /* only one at a time */ in iwx_vap_create()
10677 vap = &ivp->iv_vap; in iwx_vap_create()
10679 vap->iv_bmissthreshold = 10; /* override default */ in iwx_vap_create()
10681 ivp->iv_newstate = vap->iv_newstate; in iwx_vap_create()
10682 vap->iv_newstate = iwx_newstate; in iwx_vap_create()
10684 ivp->id = IWX_DEFAULT_MACID; in iwx_vap_create()
10685 ivp->color = IWX_DEFAULT_COLOR; in iwx_vap_create()
10687 ivp->have_wme = TRUE; in iwx_vap_create()
10688 ivp->ps_disabled = FALSE; in iwx_vap_create()
10690 vap->iv_ampdu_rxmax = IEEE80211_HTCAP_MAXRXAMPDU_64K; in iwx_vap_create()
10691 vap->iv_ampdu_density = IEEE80211_HTCAP_MPDUDENSITY_4; in iwx_vap_create()
10694 vap->iv_key_alloc = iwx_key_alloc; in iwx_vap_create()
10695 vap->iv_key_delete = iwx_key_delete; in iwx_vap_create()
10696 vap->iv_key_set = iwx_key_set; in iwx_vap_create()
10697 vap->iv_key_update_begin = iwx_key_update_begin; in iwx_vap_create()
10698 vap->iv_key_update_end = iwx_key_update_end; in iwx_vap_create()
10704 ic->ic_opmode = opmode; in iwx_vap_create()
10722 struct iwx_softc *sc = ic->ic_softc; in iwx_parent()
10725 if (sc->sc_flags & IWX_FLAG_HW_INITED) { in iwx_parent()
10727 sc->sc_flags &= ~IWX_FLAG_HW_INITED; in iwx_parent()
10739 struct ieee80211com *ic = &sc->sc_ic; in iwx_suspend()
10747 if (sc->sc_flags & IWX_FLAG_HW_INITED) { in iwx_suspend()
10749 sc->sc_flags &= ~IWX_FLAG_HW_INITED; in iwx_suspend()
10758 struct ieee80211com *ic = &sc->sc_ic; in iwx_resume()
10769 if (sc->sc_flags & IWX_FLAG_HW_INITED) { in iwx_resume()
10771 sc->sc_flags &= ~IWX_FLAG_HW_INITED; in iwx_resume()
10784 struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); in iwx_scan_start()
10785 struct iwx_softc *sc = ic->ic_softc; in iwx_scan_start()
10789 if ((ic->ic_flags_ext & IEEE80211_FEXT_BGSCAN) == 0) in iwx_scan_start()
10818 iwx_endscan(ic->ic_softc); in iwx_scan_end()
10825 struct iwx_softc *sc = ic->ic_softc; in iwx_set_channel()
10826 struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); in iwx_set_channel()
10837 struct ieee80211com *ic = &sc->sc_ic; in iwx_endscan_cb()
10840 ieee80211_scan_done(TAILQ_FIRST(&ic->ic_vaps)); in iwx_endscan_cb()
10853 struct ieee80211com *ic = ni->ni_ic; in iwx_raw_xmit()
10854 struct iwx_softc *sc = ic->ic_softc; in iwx_raw_xmit()
10858 if (sc->sc_flags & IWX_FLAG_STA_ACTIVE) { in iwx_raw_xmit()
10871 struct iwx_softc *sc = ic->ic_softc; in iwx_transmit()
10877 error = mbufq_enqueue(&sc->sc_snd, m); in iwx_transmit()
10892 struct ieee80211com *ic = ni->ni_ic; in iwx_ampdu_rx_start()
10893 struct iwx_softc *sc = ic->ic_softc; in iwx_ampdu_rx_start()
10897 sc->ni_rx_ba[tid].ba_winstart = in iwx_ampdu_rx_start()
10899 sc->ni_rx_ba[tid].ba_winsize = in iwx_ampdu_rx_start()
10901 sc->ni_rx_ba[tid].ba_timeout_val = batimeout; in iwx_ampdu_rx_start()
10903 if (sc->sc_rx_ba_sessions >= IWX_MAX_RX_BA_SESSIONS || in iwx_ampdu_rx_start()
10907 if (sc->ba_rx.start_tidmask & (1 << tid)) { in iwx_ampdu_rx_start()
10911 DPRINTF(("%s: sc->ba_rx.start_tidmask=%x\n", __func__, sc->ba_rx.start_tidmask)); in iwx_ampdu_rx_start()
10913 sc->ba_rx.start_tidmask |= (1 << tid); in iwx_ampdu_rx_start()
10915 DPRINTF(("%s: ba_winstart=%i\n", __func__, sc->ni_rx_ba[tid].ba_winstart)); in iwx_ampdu_rx_start()
10916 DPRINTF(("%s: ba_winsize=%i\n", __func__, sc->ni_rx_ba[tid].ba_winsize)); in iwx_ampdu_rx_start()
10917 DPRINTF(("%s: ba_timeout_val=%i\n", __func__, sc->ni_rx_ba[tid].ba_timeout_val)); in iwx_ampdu_rx_start()
10919 taskqueue_enqueue(sc->sc_tq, &sc->ba_rx_task); in iwx_ampdu_rx_start()
10922 sc->sc_ampdu_rx_start(ni, rap, baparamset, batimeout, baseqctl); in iwx_ampdu_rx_start()
10934 * @brief Called by net80211 to request an A-MPDU session be established.
10936 * This is called by net80211 to see if an A-MPDU session can be established.
10945 * @param ni ieee80211_node to establish A-MPDU session for
10946 * @param tap pointer to the per-TID state struct
10951 * @returns 0 so net80211 doesn't send the BA action frame to establish A-MPDU.
10957 struct iwx_softc *sc = ni->ni_ic->ic_softc; in iwx_addba_request()
10968 tap->txa_nextrequest = ticks + hz; in iwx_addba_request()
10971 sc->ba_tx.start_tidmask |= (1 << tid); in iwx_addba_request()
10974 taskqueue_enqueue(sc->sc_tq, &sc->ba_tx_task); in iwx_addba_request()
11004 if (k->wk_cipher->ic_cipher == IEEE80211_CIPHER_AES_CCM) { in iwx_key_alloc()
11024 struct ieee80211com *ic = vap->iv_ic; in iwx_key_set()
11025 struct iwx_softc *sc = ic->ic_softc; in iwx_key_set()
11031 if (k->wk_cipher->ic_cipher != IEEE80211_CIPHER_AES_CCM) { in iwx_key_set()
11038 * ic->ic_bss so there is no need to validate arguments beyond this: in iwx_key_set()
11072 memcpy(cmd.common.key, k->wk_key, MIN(sizeof(cmd.common.key), in iwx_key_set()
11073 k->wk_keylen)); in iwx_key_set()
11075 __func__, id, k->wk_keylen, k->wk_keylen, in iwx_key_set()
11076 (const unsigned char *) k->wk_key, ""); in iwx_key_set()
11079 cmd.transmit_seq_cnt = htole64(k->wk_keytsc); in iwx_key_set()
11080 IWX_DPRINTF(sc, IWX_DEBUG_KEYMGMT, "%s: k->wk_keytsc=%lu\n", __func__, in iwx_key_set()
11081 k->wk_keytsc); in iwx_key_set()
11104 * Note: since there's no key allocations to track - it's either in iwx_key_delete()
11105 * the 4 static WEP keys or the single unicast key - there's nothing in iwx_key_delete()