1 /*- 2 * SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) AND ISC 3 */ 4 5 /* $OpenBSD: if_iwx.c,v 1.175 2023/07/05 15:07:28 stsp Exp $ */ 6 7 /* 8 * 9 * Copyright (c) 2025 The FreeBSD Foundation 10 * 11 * Portions of this software were developed by Tom Jones <thj@FreeBSD.org> 12 * under sponsorship from the FreeBSD Foundation. 13 * 14 * Permission to use, copy, modify, and distribute this software for any 15 * purpose with or without fee is hereby granted, provided that the above 16 * copyright notice and this permission notice appear in all copies. 17 * 18 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 19 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 20 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 21 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 22 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 23 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 24 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 25 * 26 */ 27 28 /*- 29 * Copyright (c) 2024 Future Crew, LLC 30 * Author: Mikhail Pchelin <misha@FreeBSD.org> 31 * 32 * Permission to use, copy, modify, and distribute this software for any 33 * purpose with or without fee is hereby granted, provided that the above 34 * copyright notice and this permission notice appear in all copies. 35 * 36 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 37 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 38 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 39 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 40 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 41 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 42 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 43 */ 44 45 /* 46 * Copyright (c) 2014, 2016 genua gmbh <info@genua.de> 47 * Author: Stefan Sperling <stsp@openbsd.org> 48 * Copyright (c) 2014 Fixup Software Ltd. 49 * Copyright (c) 2017, 2019, 2020 Stefan Sperling <stsp@openbsd.org> 50 * 51 * Permission to use, copy, modify, and distribute this software for any 52 * purpose with or without fee is hereby granted, provided that the above 53 * copyright notice and this permission notice appear in all copies. 54 * 55 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 56 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 57 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 58 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 59 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 60 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 61 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 62 */ 63 64 /*- 65 * Based on BSD-licensed source modules in the Linux iwlwifi driver, 66 * which were used as the reference documentation for this implementation. 67 * 68 ****************************************************************************** 69 * 70 * This file is provided under a dual BSD/GPLv2 license. When using or 71 * redistributing this file, you may do so under either license. 72 * 73 * GPL LICENSE SUMMARY 74 * 75 * Copyright(c) 2017 Intel Deutschland GmbH 76 * Copyright(c) 2018 - 2019 Intel Corporation 77 * 78 * This program is free software; you can redistribute it and/or modify 79 * it under the terms of version 2 of the GNU General Public License as 80 * published by the Free Software Foundation. 81 * 82 * This program is distributed in the hope that it will be useful, but 83 * WITHOUT ANY WARRANTY; without even the implied warranty of 84 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 85 * General Public License for more details. 86 * 87 * BSD LICENSE 88 * 89 * Copyright(c) 2017 Intel Deutschland GmbH 90 * Copyright(c) 2018 - 2019 Intel Corporation 91 * All rights reserved. 92 * 93 * Redistribution and use in source and binary forms, with or without 94 * modification, are permitted provided that the following conditions 95 * are met: 96 * 97 * * Redistributions of source code must retain the above copyright 98 * notice, this list of conditions and the following disclaimer. 99 * * Redistributions in binary form must reproduce the above copyright 100 * notice, this list of conditions and the following disclaimer in 101 * the documentation and/or other materials provided with the 102 * distribution. 103 * * Neither the name Intel Corporation nor the names of its 104 * contributors may be used to endorse or promote products derived 105 * from this software without specific prior written permission. 106 * 107 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 108 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 109 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 110 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 111 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 112 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 113 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 114 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 115 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 116 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 117 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 118 * 119 ***************************************************************************** 120 */ 121 122 /*- 123 * Copyright (c) 2007-2010 Damien Bergamini <damien.bergamini@free.fr> 124 * 125 * Permission to use, copy, modify, and distribute this software for any 126 * purpose with or without fee is hereby granted, provided that the above 127 * copyright notice and this permission notice appear in all copies. 128 * 129 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 130 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 131 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 132 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 133 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 134 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 135 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 136 */ 137 138 #include <sys/param.h> 139 #include <sys/bus.h> 140 #include <sys/module.h> 141 #include <sys/conf.h> 142 #include <sys/kernel.h> 143 #include <sys/malloc.h> 144 #include <sys/mbuf.h> 145 #include <sys/mutex.h> 146 #include <sys/proc.h> 147 #include <sys/rman.h> 148 #include <sys/rwlock.h> 149 #include <sys/socket.h> 150 #include <sys/sockio.h> 151 #include <sys/systm.h> 152 #include <sys/endian.h> 153 #include <sys/linker.h> 154 #include <sys/firmware.h> 155 #include <sys/epoch.h> 156 #include <sys/kdb.h> 157 158 #include <machine/bus.h> 159 #include <machine/endian.h> 160 #include <machine/resource.h> 161 162 #include <dev/pci/pcireg.h> 163 #include <dev/pci/pcivar.h> 164 165 #include <net/bpf.h> 166 167 #include <net/if.h> 168 #include <net/if_var.h> 169 #include <net/if_dl.h> 170 #include <net/if_media.h> 171 172 #include <netinet/in.h> 173 #include <netinet/if_ether.h> 174 175 #include <net80211/ieee80211_var.h> 176 #include <net80211/ieee80211_radiotap.h> 177 #include <net80211/ieee80211_regdomain.h> 178 #include <net80211/ieee80211_ratectl.h> 179 #include <net80211/ieee80211_vht.h> 180 181 int iwx_himark = 224; 182 int iwx_lomark = 192; 183 184 #define IWX_FBSD_RSP_V3 3 185 #define IWX_FBSD_RSP_V4 4 186 187 #define DEVNAME(_sc) (device_get_nameunit((_sc)->sc_dev)) 188 #define IC2IFP(ic) (((struct ieee80211vap *)TAILQ_FIRST(&(ic)->ic_vaps))->iv_ifp) 189 190 #define le16_to_cpup(_a_) (le16toh(*(const uint16_t *)(_a_))) 191 #define le32_to_cpup(_a_) (le32toh(*(const uint32_t *)(_a_))) 192 193 #include <dev/iwx/if_iwxreg.h> 194 #include <dev/iwx/if_iwxvar.h> 195 196 #include <dev/iwx/if_iwx_debug.h> 197 198 #define PCI_CFG_RETRY_TIMEOUT 0x41 199 200 #define PCI_VENDOR_INTEL 0x8086 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 */ 218 219 static const struct iwx_devices { 220 uint16_t device; 221 char *name; 222 } iwx_devices[] = { 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" }, 240 }; 241 242 static const uint8_t iwx_nvm_channels_8000[] = { 243 /* 2.4 GHz */ 244 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 245 /* 5 GHz */ 246 36, 40, 44, 48, 52, 56, 60, 64, 68, 72, 76, 80, 84, 88, 92, 247 96, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 144, 248 149, 153, 157, 161, 165, 169, 173, 177, 181 249 }; 250 251 static const uint8_t iwx_nvm_channels_uhb[] = { 252 /* 2.4 GHz */ 253 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 254 /* 5 GHz */ 255 36, 40, 44, 48, 52, 56, 60, 64, 68, 72, 76, 80, 84, 88, 92, 256 96, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 144, 257 149, 153, 157, 161, 165, 169, 173, 177, 181, 258 /* 6-7 GHz */ 259 1, 5, 9, 13, 17, 21, 25, 29, 33, 37, 41, 45, 49, 53, 57, 61, 65, 69, 260 73, 77, 81, 85, 89, 93, 97, 101, 105, 109, 113, 117, 121, 125, 129, 261 133, 137, 141, 145, 149, 153, 157, 161, 165, 169, 173, 177, 181, 185, 262 189, 193, 197, 201, 205, 209, 213, 217, 221, 225, 229, 233 263 }; 264 265 #define IWX_NUM_2GHZ_CHANNELS 14 266 #define IWX_NUM_5GHZ_CHANNELS 37 267 268 const struct iwx_rate { 269 uint16_t rate; 270 uint8_t plcp; 271 uint8_t ht_plcp; 272 } iwx_rates[] = { 273 /* Legacy */ /* HT */ 274 { 2, IWX_RATE_1M_PLCP, IWX_RATE_HT_SISO_MCS_INV_PLCP }, 275 { 4, IWX_RATE_2M_PLCP, IWX_RATE_HT_SISO_MCS_INV_PLCP }, 276 { 11, IWX_RATE_5M_PLCP, IWX_RATE_HT_SISO_MCS_INV_PLCP }, 277 { 22, IWX_RATE_11M_PLCP, IWX_RATE_HT_SISO_MCS_INV_PLCP }, 278 { 12, IWX_RATE_6M_PLCP, IWX_RATE_HT_SISO_MCS_0_PLCP }, 279 { 18, IWX_RATE_9M_PLCP, IWX_RATE_HT_SISO_MCS_INV_PLCP }, 280 { 24, IWX_RATE_12M_PLCP, IWX_RATE_HT_SISO_MCS_1_PLCP }, 281 { 26, IWX_RATE_INVM_PLCP, IWX_RATE_HT_MIMO2_MCS_8_PLCP }, 282 { 36, IWX_RATE_18M_PLCP, IWX_RATE_HT_SISO_MCS_2_PLCP }, 283 { 48, IWX_RATE_24M_PLCP, IWX_RATE_HT_SISO_MCS_3_PLCP }, 284 { 52, IWX_RATE_INVM_PLCP, IWX_RATE_HT_MIMO2_MCS_9_PLCP }, 285 { 72, IWX_RATE_36M_PLCP, IWX_RATE_HT_SISO_MCS_4_PLCP }, 286 { 78, IWX_RATE_INVM_PLCP, IWX_RATE_HT_MIMO2_MCS_10_PLCP }, 287 { 96, IWX_RATE_48M_PLCP, IWX_RATE_HT_SISO_MCS_5_PLCP }, 288 { 104, IWX_RATE_INVM_PLCP, IWX_RATE_HT_MIMO2_MCS_11_PLCP }, 289 { 108, IWX_RATE_54M_PLCP, IWX_RATE_HT_SISO_MCS_6_PLCP }, 290 { 128, IWX_RATE_INVM_PLCP, IWX_RATE_HT_SISO_MCS_7_PLCP }, 291 { 156, IWX_RATE_INVM_PLCP, IWX_RATE_HT_MIMO2_MCS_12_PLCP }, 292 { 208, IWX_RATE_INVM_PLCP, IWX_RATE_HT_MIMO2_MCS_13_PLCP }, 293 { 234, IWX_RATE_INVM_PLCP, IWX_RATE_HT_MIMO2_MCS_14_PLCP }, 294 { 260, IWX_RATE_INVM_PLCP, IWX_RATE_HT_MIMO2_MCS_15_PLCP }, 295 }; 296 #define IWX_RIDX_CCK 0 297 #define IWX_RIDX_OFDM 4 298 #define IWX_RIDX_MAX (nitems(iwx_rates)-1) 299 #define IWX_RIDX_IS_CCK(_i_) ((_i_) < IWX_RIDX_OFDM) 300 #define IWX_RIDX_IS_OFDM(_i_) ((_i_) >= IWX_RIDX_OFDM) 301 #define IWX_RVAL_IS_OFDM(_i_) ((_i_) >= 12 && (_i_) != 22) 302 303 /* Convert an MCS index into an iwx_rates[] index. */ 304 const int iwx_mcs2ridx[] = { 305 IWX_RATE_MCS_0_INDEX, 306 IWX_RATE_MCS_1_INDEX, 307 IWX_RATE_MCS_2_INDEX, 308 IWX_RATE_MCS_3_INDEX, 309 IWX_RATE_MCS_4_INDEX, 310 IWX_RATE_MCS_5_INDEX, 311 IWX_RATE_MCS_6_INDEX, 312 IWX_RATE_MCS_7_INDEX, 313 IWX_RATE_MCS_8_INDEX, 314 IWX_RATE_MCS_9_INDEX, 315 IWX_RATE_MCS_10_INDEX, 316 IWX_RATE_MCS_11_INDEX, 317 IWX_RATE_MCS_12_INDEX, 318 IWX_RATE_MCS_13_INDEX, 319 IWX_RATE_MCS_14_INDEX, 320 IWX_RATE_MCS_15_INDEX, 321 }; 322 323 static uint8_t iwx_lookup_cmd_ver(struct iwx_softc *, uint8_t, uint8_t); 324 static uint8_t iwx_lookup_notif_ver(struct iwx_softc *, uint8_t, uint8_t); 325 static int iwx_store_cscheme(struct iwx_softc *, const uint8_t *, size_t); 326 #if 0 327 static int iwx_alloc_fw_monitor_block(struct iwx_softc *, uint8_t, uint8_t); 328 static int iwx_alloc_fw_monitor(struct iwx_softc *, uint8_t); 329 #endif 330 static int iwx_apply_debug_destination(struct iwx_softc *); 331 static void iwx_set_ltr(struct iwx_softc *); 332 static int iwx_ctxt_info_init(struct iwx_softc *, const struct iwx_fw_sects *); 333 static int iwx_ctxt_info_gen3_init(struct iwx_softc *, 334 const struct iwx_fw_sects *); 335 static void iwx_ctxt_info_free_fw_img(struct iwx_softc *); 336 static void iwx_ctxt_info_free_paging(struct iwx_softc *); 337 static int iwx_init_fw_sec(struct iwx_softc *, const struct iwx_fw_sects *, 338 struct iwx_context_info_dram *); 339 static void iwx_fw_version_str(char *, size_t, uint32_t, uint32_t, uint32_t); 340 static int iwx_firmware_store_section(struct iwx_softc *, enum iwx_ucode_type, 341 const uint8_t *, size_t); 342 static int iwx_set_default_calib(struct iwx_softc *, const void *); 343 static void iwx_fw_info_free(struct iwx_fw_info *); 344 static int iwx_read_firmware(struct iwx_softc *); 345 static uint32_t iwx_prph_addr_mask(struct iwx_softc *); 346 static uint32_t iwx_read_prph_unlocked(struct iwx_softc *, uint32_t); 347 static uint32_t iwx_read_prph(struct iwx_softc *, uint32_t); 348 static void iwx_write_prph_unlocked(struct iwx_softc *, uint32_t, uint32_t); 349 static void iwx_write_prph(struct iwx_softc *, uint32_t, uint32_t); 350 static uint32_t iwx_read_umac_prph(struct iwx_softc *, uint32_t); 351 static void iwx_write_umac_prph(struct iwx_softc *, uint32_t, uint32_t); 352 static int iwx_read_mem(struct iwx_softc *, uint32_t, void *, int); 353 static int iwx_poll_bit(struct iwx_softc *, int, uint32_t, uint32_t, int); 354 static int iwx_nic_lock(struct iwx_softc *); 355 static void iwx_nic_assert_locked(struct iwx_softc *); 356 static void iwx_nic_unlock(struct iwx_softc *); 357 static int iwx_set_bits_mask_prph(struct iwx_softc *, uint32_t, uint32_t, 358 uint32_t); 359 static int iwx_set_bits_prph(struct iwx_softc *, uint32_t, uint32_t); 360 static int iwx_clear_bits_prph(struct iwx_softc *, uint32_t, uint32_t); 361 static void iwx_dma_map_addr(void *, bus_dma_segment_t *, int, int); 362 static int iwx_dma_contig_alloc(bus_dma_tag_t, struct iwx_dma_info *, 363 bus_size_t, bus_size_t); 364 static void iwx_dma_contig_free(struct iwx_dma_info *); 365 static int iwx_alloc_rx_ring(struct iwx_softc *, struct iwx_rx_ring *); 366 static void iwx_disable_rx_dma(struct iwx_softc *); 367 static void iwx_reset_rx_ring(struct iwx_softc *, struct iwx_rx_ring *); 368 static void iwx_free_rx_ring(struct iwx_softc *, struct iwx_rx_ring *); 369 static int iwx_alloc_tx_ring(struct iwx_softc *, struct iwx_tx_ring *, int); 370 static void iwx_reset_tx_ring(struct iwx_softc *, struct iwx_tx_ring *); 371 static void iwx_free_tx_ring(struct iwx_softc *, struct iwx_tx_ring *); 372 static void iwx_enable_rfkill_int(struct iwx_softc *); 373 static int iwx_check_rfkill(struct iwx_softc *); 374 static void iwx_enable_interrupts(struct iwx_softc *); 375 static void iwx_enable_fwload_interrupt(struct iwx_softc *); 376 #if 0 377 static void iwx_restore_interrupts(struct iwx_softc *); 378 #endif 379 static void iwx_disable_interrupts(struct iwx_softc *); 380 static void iwx_ict_reset(struct iwx_softc *); 381 static int iwx_set_hw_ready(struct iwx_softc *); 382 static int iwx_prepare_card_hw(struct iwx_softc *); 383 static int iwx_force_power_gating(struct iwx_softc *); 384 static void iwx_apm_config(struct iwx_softc *); 385 static int iwx_apm_init(struct iwx_softc *); 386 static void iwx_apm_stop(struct iwx_softc *); 387 static int iwx_allow_mcast(struct iwx_softc *); 388 static void iwx_init_msix_hw(struct iwx_softc *); 389 static void iwx_conf_msix_hw(struct iwx_softc *, int); 390 static int iwx_clear_persistence_bit(struct iwx_softc *); 391 static int iwx_start_hw(struct iwx_softc *); 392 static void iwx_stop_device(struct iwx_softc *); 393 static void iwx_nic_config(struct iwx_softc *); 394 static int iwx_nic_rx_init(struct iwx_softc *); 395 static int iwx_nic_init(struct iwx_softc *); 396 static int iwx_enable_txq(struct iwx_softc *, int, int, int, int); 397 static int iwx_disable_txq(struct iwx_softc *sc, int, int, uint8_t); 398 static void iwx_post_alive(struct iwx_softc *); 399 static int iwx_schedule_session_protection(struct iwx_softc *, 400 struct iwx_node *, uint32_t); 401 static void iwx_unprotect_session(struct iwx_softc *, struct iwx_node *); 402 static void iwx_init_channel_map(struct ieee80211com *, int, int *, 403 struct ieee80211_channel[]); 404 static int iwx_mimo_enabled(struct iwx_softc *); 405 static void iwx_init_reorder_buffer(struct iwx_reorder_buffer *, uint16_t, 406 uint16_t); 407 static void iwx_clear_reorder_buffer(struct iwx_softc *, struct iwx_rxba_data *); 408 static void iwx_sta_rx_agg(struct iwx_softc *, struct ieee80211_node *, uint8_t, 409 uint16_t, uint16_t, int, int); 410 static void iwx_sta_tx_agg_start(struct iwx_softc *, 411 struct ieee80211_node *, uint8_t); 412 static void iwx_ba_rx_task(void *, int); 413 static void iwx_ba_tx_task(void *, int); 414 static void iwx_set_mac_addr_from_csr(struct iwx_softc *, struct iwx_nvm_data *); 415 static int iwx_is_valid_mac_addr(const uint8_t *); 416 static void iwx_flip_hw_address(uint32_t, uint32_t, uint8_t *); 417 static int iwx_nvm_get(struct iwx_softc *); 418 static int iwx_load_firmware(struct iwx_softc *); 419 static int iwx_start_fw(struct iwx_softc *); 420 static int iwx_pnvm_handle_section(struct iwx_softc *, const uint8_t *, size_t); 421 static int iwx_pnvm_parse(struct iwx_softc *, const uint8_t *, size_t); 422 static void iwx_ctxt_info_gen3_set_pnvm(struct iwx_softc *); 423 static int iwx_load_pnvm(struct iwx_softc *); 424 static int iwx_send_tx_ant_cfg(struct iwx_softc *, uint8_t); 425 static int iwx_send_phy_cfg_cmd(struct iwx_softc *); 426 static int iwx_load_ucode_wait_alive(struct iwx_softc *); 427 static int iwx_send_dqa_cmd(struct iwx_softc *); 428 static int iwx_run_init_mvm_ucode(struct iwx_softc *, int); 429 static int iwx_config_ltr(struct iwx_softc *); 430 static void iwx_update_rx_desc(struct iwx_softc *, struct iwx_rx_ring *, int, bus_dma_segment_t *); 431 static int iwx_rx_addbuf(struct iwx_softc *, int, int); 432 static int iwx_rxmq_get_signal_strength(struct iwx_softc *, struct iwx_rx_mpdu_desc *); 433 static void iwx_rx_rx_phy_cmd(struct iwx_softc *, struct iwx_rx_packet *, 434 struct iwx_rx_data *); 435 static int iwx_get_noise(const struct iwx_statistics_rx_non_phy *); 436 static int iwx_rx_hwdecrypt(struct iwx_softc *, struct mbuf *, uint32_t); 437 #if 0 438 int iwx_ccmp_decap(struct iwx_softc *, struct mbuf *, 439 struct ieee80211_node *, struct ieee80211_rxinfo *); 440 #endif 441 static void iwx_rx_frame(struct iwx_softc *, struct mbuf *, int, uint32_t, 442 int, int, uint32_t, uint8_t); 443 static void iwx_clear_tx_desc(struct iwx_softc *, struct iwx_tx_ring *, int); 444 static void iwx_txd_done(struct iwx_softc *, struct iwx_tx_ring *, 445 struct iwx_tx_data *); 446 static void iwx_txq_advance(struct iwx_softc *, struct iwx_tx_ring *, uint16_t); 447 static void iwx_rx_tx_cmd(struct iwx_softc *, struct iwx_rx_packet *, 448 struct iwx_rx_data *); 449 static void iwx_clear_oactive(struct iwx_softc *, struct iwx_tx_ring *); 450 static void iwx_rx_bmiss(struct iwx_softc *, struct iwx_rx_packet *, 451 struct iwx_rx_data *); 452 static int iwx_binding_cmd(struct iwx_softc *, struct iwx_node *, uint32_t); 453 static uint8_t iwx_get_vht_ctrl_pos(struct ieee80211com *, struct ieee80211_channel *); 454 static int iwx_phy_ctxt_cmd_uhb_v3_v4(struct iwx_softc *, 455 struct iwx_phy_ctxt *, uint8_t, uint8_t, uint32_t, uint8_t, uint8_t, int); 456 #if 0 457 static int iwx_phy_ctxt_cmd_v3_v4(struct iwx_softc *, struct iwx_phy_ctxt *, 458 uint8_t, uint8_t, uint32_t, uint8_t, uint8_t, int); 459 #endif 460 static int iwx_phy_ctxt_cmd(struct iwx_softc *, struct iwx_phy_ctxt *, 461 uint8_t, uint8_t, uint32_t, uint32_t, uint8_t, uint8_t); 462 static int iwx_send_cmd(struct iwx_softc *, struct iwx_host_cmd *); 463 static int iwx_send_cmd_pdu(struct iwx_softc *, uint32_t, uint32_t, uint16_t, 464 const void *); 465 static int iwx_send_cmd_status(struct iwx_softc *, struct iwx_host_cmd *, 466 uint32_t *); 467 static int iwx_send_cmd_pdu_status(struct iwx_softc *, uint32_t, uint16_t, 468 const void *, uint32_t *); 469 static void iwx_free_resp(struct iwx_softc *, struct iwx_host_cmd *); 470 static void iwx_cmd_done(struct iwx_softc *, int, int, int); 471 static uint32_t iwx_fw_rateidx_ofdm(uint8_t); 472 static uint32_t iwx_fw_rateidx_cck(uint8_t); 473 static const struct iwx_rate *iwx_tx_fill_cmd(struct iwx_softc *, 474 struct iwx_node *, struct ieee80211_frame *, uint16_t *, uint32_t *, 475 struct mbuf *); 476 static void iwx_tx_update_byte_tbl(struct iwx_softc *, struct iwx_tx_ring *, int, 477 uint16_t, uint16_t); 478 static int iwx_tx(struct iwx_softc *, struct mbuf *, 479 struct ieee80211_node *); 480 static int iwx_flush_sta_tids(struct iwx_softc *, int, uint16_t); 481 static int iwx_drain_sta(struct iwx_softc *sc, struct iwx_node *, int); 482 static int iwx_flush_sta(struct iwx_softc *, struct iwx_node *); 483 static int iwx_beacon_filter_send_cmd(struct iwx_softc *, 484 struct iwx_beacon_filter_cmd *); 485 static int iwx_update_beacon_abort(struct iwx_softc *, struct iwx_node *, 486 int); 487 static void iwx_power_build_cmd(struct iwx_softc *, struct iwx_node *, 488 struct iwx_mac_power_cmd *); 489 static int iwx_power_mac_update_mode(struct iwx_softc *, struct iwx_node *); 490 static int iwx_power_update_device(struct iwx_softc *); 491 #if 0 492 static int iwx_enable_beacon_filter(struct iwx_softc *, struct iwx_node *); 493 #endif 494 static int iwx_disable_beacon_filter(struct iwx_softc *); 495 static int iwx_add_sta_cmd(struct iwx_softc *, struct iwx_node *, int); 496 static int iwx_rm_sta_cmd(struct iwx_softc *, struct iwx_node *); 497 static int iwx_rm_sta(struct iwx_softc *, struct iwx_node *); 498 static int iwx_fill_probe_req(struct iwx_softc *, 499 struct iwx_scan_probe_req *); 500 static int iwx_config_umac_scan_reduced(struct iwx_softc *); 501 static uint16_t iwx_scan_umac_flags_v2(struct iwx_softc *, int); 502 static void iwx_scan_umac_dwell_v10(struct iwx_softc *, 503 struct iwx_scan_general_params_v10 *, int); 504 static void iwx_scan_umac_fill_general_p_v10(struct iwx_softc *, 505 struct iwx_scan_general_params_v10 *, uint16_t, int); 506 static void iwx_scan_umac_fill_ch_p_v6(struct iwx_softc *, 507 struct iwx_scan_channel_params_v6 *, uint32_t, int); 508 static int iwx_umac_scan_v14(struct iwx_softc *, int); 509 static void iwx_mcc_update(struct iwx_softc *, struct iwx_mcc_chub_notif *); 510 static uint8_t iwx_ridx2rate(struct ieee80211_rateset *, int); 511 static int iwx_rval2ridx(int); 512 static void iwx_ack_rates(struct iwx_softc *, struct iwx_node *, int *, 513 int *); 514 static void iwx_mac_ctxt_cmd_common(struct iwx_softc *, struct iwx_node *, 515 struct iwx_mac_ctx_cmd *, uint32_t); 516 static void iwx_mac_ctxt_cmd_fill_sta(struct iwx_softc *, struct iwx_node *, 517 struct iwx_mac_data_sta *, int); 518 static int iwx_mac_ctxt_cmd(struct iwx_softc *, struct iwx_node *, 519 uint32_t, int); 520 static int iwx_clear_statistics(struct iwx_softc *); 521 static int iwx_scan(struct iwx_softc *); 522 static int iwx_bgscan(struct ieee80211com *); 523 static int iwx_enable_mgmt_queue(struct iwx_softc *); 524 static int iwx_disable_mgmt_queue(struct iwx_softc *); 525 static int iwx_rs_rval2idx(uint8_t); 526 static uint16_t iwx_rs_ht_rates(struct iwx_softc *, struct ieee80211_node *, 527 int); 528 static uint16_t iwx_rs_vht_rates(struct iwx_softc *, struct ieee80211_node *, int); 529 static int iwx_rs_init_v3(struct iwx_softc *, struct iwx_node *); 530 static int iwx_rs_init_v4(struct iwx_softc *, struct iwx_node *); 531 static int iwx_rs_init(struct iwx_softc *, struct iwx_node *); 532 static int iwx_phy_send_rlc(struct iwx_softc *, struct iwx_phy_ctxt *, 533 uint8_t, uint8_t); 534 static int iwx_phy_ctxt_update(struct iwx_softc *, struct iwx_phy_ctxt *, 535 struct ieee80211_channel *, uint8_t, uint8_t, uint32_t, uint8_t, 536 uint8_t); 537 static int iwx_auth(struct ieee80211vap *, struct iwx_softc *); 538 static int iwx_deauth(struct iwx_softc *); 539 static int iwx_run(struct ieee80211vap *, struct iwx_softc *); 540 static int iwx_run_stop(struct iwx_softc *); 541 static struct ieee80211_node * iwx_node_alloc(struct ieee80211vap *, 542 const uint8_t[IEEE80211_ADDR_LEN]); 543 #if 0 544 int iwx_set_key(struct ieee80211com *, struct ieee80211_node *, 545 struct ieee80211_key *); 546 void iwx_setkey_task(void *); 547 void iwx_delete_key(struct ieee80211com *, 548 struct ieee80211_node *, struct ieee80211_key *); 549 #endif 550 static int iwx_newstate(struct ieee80211vap *, enum ieee80211_state, int); 551 static void iwx_endscan(struct iwx_softc *); 552 static void iwx_fill_sf_command(struct iwx_softc *, struct iwx_sf_cfg_cmd *, 553 struct ieee80211_node *); 554 static int iwx_sf_config(struct iwx_softc *, int); 555 static int iwx_send_bt_init_conf(struct iwx_softc *); 556 static int iwx_send_soc_conf(struct iwx_softc *); 557 static int iwx_send_update_mcc_cmd(struct iwx_softc *, const char *); 558 static int iwx_send_temp_report_ths_cmd(struct iwx_softc *); 559 static int iwx_init_hw(struct iwx_softc *); 560 static int iwx_init(struct iwx_softc *); 561 static void iwx_stop(struct iwx_softc *); 562 static void iwx_watchdog(void *); 563 static const char *iwx_desc_lookup(uint32_t); 564 static void iwx_nic_error(struct iwx_softc *); 565 static void iwx_dump_driver_status(struct iwx_softc *); 566 static void iwx_nic_umac_error(struct iwx_softc *); 567 static void iwx_rx_mpdu_mq(struct iwx_softc *, struct mbuf *, void *, size_t); 568 static int iwx_rx_pkt_valid(struct iwx_rx_packet *); 569 static void iwx_rx_pkt(struct iwx_softc *, struct iwx_rx_data *, 570 struct mbuf *); 571 static void iwx_notif_intr(struct iwx_softc *); 572 #if 0 573 /* XXX-THJ - I don't have hardware for this */ 574 static int iwx_intr(void *); 575 #endif 576 static void iwx_intr_msix(void *); 577 static int iwx_preinit(struct iwx_softc *); 578 static void iwx_attach_hook(void *); 579 static const struct iwx_device_cfg *iwx_find_device_cfg(struct iwx_softc *); 580 static int iwx_probe(device_t); 581 static int iwx_attach(device_t); 582 static int iwx_detach(device_t); 583 584 /* FreeBSD specific glue */ 585 u_int8_t etherbroadcastaddr[ETHER_ADDR_LEN] = 586 { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; 587 588 u_int8_t etheranyaddr[ETHER_ADDR_LEN] = 589 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; 590 591 #if IWX_DEBUG 592 #define DPRINTF(x) do { if (sc->sc_debug == IWX_DEBUG_ANY) { printf x; } } while (0) 593 #else 594 #define DPRINTF(x) do { ; } while (0) 595 #endif 596 597 /* FreeBSD specific functions */ 598 static struct ieee80211vap * iwx_vap_create(struct ieee80211com *, 599 const char[IFNAMSIZ], int, enum ieee80211_opmode, int, 600 const uint8_t[IEEE80211_ADDR_LEN], const uint8_t[IEEE80211_ADDR_LEN]); 601 static void iwx_vap_delete(struct ieee80211vap *); 602 static void iwx_parent(struct ieee80211com *); 603 static void iwx_scan_start(struct ieee80211com *); 604 static void iwx_scan_end(struct ieee80211com *); 605 static void iwx_update_mcast(struct ieee80211com *ic); 606 static void iwx_scan_curchan(struct ieee80211_scan_state *, unsigned long); 607 static void iwx_scan_mindwell(struct ieee80211_scan_state *); 608 static void iwx_set_channel(struct ieee80211com *); 609 static void iwx_endscan_cb(void *, int ); 610 static int iwx_wme_update(struct ieee80211com *); 611 static int iwx_raw_xmit(struct ieee80211_node *, struct mbuf *, 612 const struct ieee80211_bpf_params *); 613 static int iwx_transmit(struct ieee80211com *, struct mbuf *); 614 static void iwx_start(struct iwx_softc *); 615 static int iwx_ampdu_rx_start(struct ieee80211_node *, 616 struct ieee80211_rx_ampdu *, int, int, int); 617 static void iwx_ampdu_rx_stop(struct ieee80211_node *, 618 struct ieee80211_rx_ampdu *); 619 static int iwx_addba_request(struct ieee80211_node *, 620 struct ieee80211_tx_ampdu *, int, int, int); 621 static int iwx_addba_response(struct ieee80211_node *, 622 struct ieee80211_tx_ampdu *, int, int, int); 623 static void iwx_key_update_begin(struct ieee80211vap *); 624 static void iwx_key_update_end(struct ieee80211vap *); 625 static int iwx_key_alloc(struct ieee80211vap *, struct ieee80211_key *, 626 ieee80211_keyix *,ieee80211_keyix *); 627 static int iwx_key_set(struct ieee80211vap *, const struct ieee80211_key *); 628 static int iwx_key_delete(struct ieee80211vap *, 629 const struct ieee80211_key *); 630 static int iwx_suspend(device_t); 631 static int iwx_resume(device_t); 632 static void iwx_radiotap_attach(struct iwx_softc *); 633 634 /* OpenBSD compat defines */ 635 #define IEEE80211_HTOP0_SCO_SCN 0 636 #define IEEE80211_VHTOP0_CHAN_WIDTH_HT 0 637 #define IEEE80211_VHTOP0_CHAN_WIDTH_80 1 638 639 #define IEEE80211_HT_RATESET_SISO 0 640 #define IEEE80211_HT_RATESET_MIMO2 2 641 642 const struct ieee80211_rateset ieee80211_std_rateset_11a = 643 { 8, { 12, 18, 24, 36, 48, 72, 96, 108 } }; 644 645 const struct ieee80211_rateset ieee80211_std_rateset_11b = 646 { 4, { 2, 4, 11, 22 } }; 647 648 const struct ieee80211_rateset ieee80211_std_rateset_11g = 649 { 12, { 2, 4, 11, 22, 12, 18, 24, 36, 48, 72, 96, 108 } }; 650 651 inline int 652 ieee80211_has_addr4(const struct ieee80211_frame *wh) 653 { 654 return (wh->i_fc[1] & IEEE80211_FC1_DIR_MASK) == 655 IEEE80211_FC1_DIR_DSTODS; 656 } 657 658 static uint8_t 659 iwx_lookup_cmd_ver(struct iwx_softc *sc, uint8_t grp, uint8_t cmd) 660 { 661 const struct iwx_fw_cmd_version *entry; 662 int i; 663 664 for (i = 0; i < sc->n_cmd_versions; i++) { 665 entry = &sc->cmd_versions[i]; 666 if (entry->group == grp && entry->cmd == cmd) 667 return entry->cmd_ver; 668 } 669 670 return IWX_FW_CMD_VER_UNKNOWN; 671 } 672 673 uint8_t 674 iwx_lookup_notif_ver(struct iwx_softc *sc, uint8_t grp, uint8_t cmd) 675 { 676 const struct iwx_fw_cmd_version *entry; 677 int i; 678 679 for (i = 0; i < sc->n_cmd_versions; i++) { 680 entry = &sc->cmd_versions[i]; 681 if (entry->group == grp && entry->cmd == cmd) 682 return entry->notif_ver; 683 } 684 685 return IWX_FW_CMD_VER_UNKNOWN; 686 } 687 688 static int 689 iwx_store_cscheme(struct iwx_softc *sc, const uint8_t *data, size_t dlen) 690 { 691 const struct iwx_fw_cscheme_list *l = (const void *)data; 692 693 if (dlen < sizeof(*l) || 694 dlen < sizeof(l->size) + l->size * sizeof(*l->cs)) 695 return EINVAL; 696 697 /* we don't actually store anything for now, always use s/w crypto */ 698 699 return 0; 700 } 701 702 static int 703 iwx_ctxt_info_alloc_dma(struct iwx_softc *sc, 704 const struct iwx_fw_onesect *sec, struct iwx_dma_info *dram) 705 { 706 int err = iwx_dma_contig_alloc(sc->sc_dmat, dram, sec->fws_len, 1); 707 if (err) { 708 printf("%s: could not allocate context info DMA memory\n", 709 DEVNAME(sc)); 710 return err; 711 } 712 713 memcpy(dram->vaddr, sec->fws_data, sec->fws_len); 714 715 return 0; 716 } 717 718 static void 719 iwx_ctxt_info_free_paging(struct iwx_softc *sc) 720 { 721 struct iwx_self_init_dram *dram = &sc->init_dram; 722 int i; 723 724 if (!dram->paging) 725 return; 726 727 /* free paging*/ 728 for (i = 0; i < dram->paging_cnt; i++) 729 iwx_dma_contig_free(&dram->paging[i]); 730 731 free(dram->paging, M_DEVBUF); 732 dram->paging_cnt = 0; 733 dram->paging = NULL; 734 } 735 736 static int 737 iwx_get_num_sections(const struct iwx_fw_sects *fws, int start) 738 { 739 int i = 0; 740 741 while (start < fws->fw_count && 742 fws->fw_sect[start].fws_devoff != IWX_CPU1_CPU2_SEPARATOR_SECTION && 743 fws->fw_sect[start].fws_devoff != IWX_PAGING_SEPARATOR_SECTION) { 744 start++; 745 i++; 746 } 747 748 return i; 749 } 750 751 static int 752 iwx_init_fw_sec(struct iwx_softc *sc, const struct iwx_fw_sects *fws, 753 struct iwx_context_info_dram *ctxt_dram) 754 { 755 struct iwx_self_init_dram *dram = &sc->init_dram; 756 int i, ret, fw_cnt = 0; 757 758 KASSERT(dram->paging == NULL, ("iwx_init_fw_sec")); 759 760 dram->lmac_cnt = iwx_get_num_sections(fws, 0); 761 /* add 1 due to separator */ 762 dram->umac_cnt = iwx_get_num_sections(fws, dram->lmac_cnt + 1); 763 /* add 2 due to separators */ 764 dram->paging_cnt = iwx_get_num_sections(fws, 765 dram->lmac_cnt + dram->umac_cnt + 2); 766 767 IWX_UNLOCK(sc); 768 dram->fw = mallocarray(dram->umac_cnt + dram->lmac_cnt, 769 sizeof(*dram->fw), M_DEVBUF, M_ZERO | M_NOWAIT); 770 if (!dram->fw) { 771 printf("%s: could not allocate memory for firmware sections\n", 772 DEVNAME(sc)); 773 IWX_LOCK(sc); 774 return ENOMEM; 775 } 776 777 dram->paging = mallocarray(dram->paging_cnt, sizeof(*dram->paging), 778 M_DEVBUF, M_ZERO | M_WAITOK); 779 IWX_LOCK(sc); 780 if (!dram->paging) { 781 printf("%s: could not allocate memory for firmware paging\n", 782 DEVNAME(sc)); 783 return ENOMEM; 784 } 785 786 /* initialize lmac sections */ 787 for (i = 0; i < dram->lmac_cnt; i++) { 788 ret = iwx_ctxt_info_alloc_dma(sc, &fws->fw_sect[i], 789 &dram->fw[fw_cnt]); 790 if (ret) 791 return ret; 792 ctxt_dram->lmac_img[i] = 793 htole64(dram->fw[fw_cnt].paddr); 794 IWX_DPRINTF(sc, IWX_DEBUG_FIRMWARE_TLV, 795 "%s: firmware LMAC section %d at 0x%llx size %lld\n", 796 __func__, i, 797 (unsigned long long)dram->fw[fw_cnt].paddr, 798 (unsigned long long)dram->fw[fw_cnt].size); 799 fw_cnt++; 800 } 801 802 /* initialize umac sections */ 803 for (i = 0; i < dram->umac_cnt; i++) { 804 /* access FW with +1 to make up for lmac separator */ 805 ret = iwx_ctxt_info_alloc_dma(sc, 806 &fws->fw_sect[fw_cnt + 1], &dram->fw[fw_cnt]); 807 if (ret) 808 return ret; 809 ctxt_dram->umac_img[i] = 810 htole64(dram->fw[fw_cnt].paddr); 811 IWX_DPRINTF(sc, IWX_DEBUG_FIRMWARE_TLV, 812 "%s: firmware UMAC section %d at 0x%llx size %lld\n", 813 __func__, i, 814 (unsigned long long)dram->fw[fw_cnt].paddr, 815 (unsigned long long)dram->fw[fw_cnt].size); 816 fw_cnt++; 817 } 818 819 /* 820 * Initialize paging. 821 * Paging memory isn't stored in dram->fw as the umac and lmac - it is 822 * stored separately. 823 * This is since the timing of its release is different - 824 * while fw memory can be released on alive, the paging memory can be 825 * freed only when the device goes down. 826 * Given that, the logic here in accessing the fw image is a bit 827 * different - fw_cnt isn't changing so loop counter is added to it. 828 */ 829 for (i = 0; i < dram->paging_cnt; i++) { 830 /* access FW with +2 to make up for lmac & umac separators */ 831 int fw_idx = fw_cnt + i + 2; 832 833 ret = iwx_ctxt_info_alloc_dma(sc, 834 &fws->fw_sect[fw_idx], &dram->paging[i]); 835 if (ret) 836 return ret; 837 838 ctxt_dram->virtual_img[i] = htole64(dram->paging[i].paddr); 839 IWX_DPRINTF(sc, IWX_DEBUG_FIRMWARE_TLV, 840 "%s: firmware paging section %d at 0x%llx size %lld\n", 841 __func__, i, 842 (unsigned long long)dram->paging[i].paddr, 843 (unsigned long long)dram->paging[i].size); 844 } 845 846 return 0; 847 } 848 849 static void 850 iwx_fw_version_str(char *buf, size_t bufsize, 851 uint32_t major, uint32_t minor, uint32_t api) 852 { 853 /* 854 * Starting with major version 35 the Linux driver prints the minor 855 * version in hexadecimal. 856 */ 857 if (major >= 35) 858 snprintf(buf, bufsize, "%u.%08x.%u", major, minor, api); 859 else 860 snprintf(buf, bufsize, "%u.%u.%u", major, minor, api); 861 } 862 #if 0 863 static int 864 iwx_alloc_fw_monitor_block(struct iwx_softc *sc, uint8_t max_power, 865 uint8_t min_power) 866 { 867 struct iwx_dma_info *fw_mon = &sc->fw_mon; 868 uint32_t size = 0; 869 uint8_t power; 870 int err; 871 872 if (fw_mon->size) 873 return 0; 874 875 for (power = max_power; power >= min_power; power--) { 876 size = (1 << power); 877 878 err = iwx_dma_contig_alloc(sc->sc_dmat, fw_mon, size, 0); 879 if (err) 880 continue; 881 882 IWX_DPRINTF(sc, IWX_DEBUG_FIRMWARE_TLV, 883 "%s: allocated 0x%08x bytes for firmware monitor.\n", 884 DEVNAME(sc), size); 885 break; 886 } 887 888 if (err) { 889 fw_mon->size = 0; 890 return err; 891 } 892 893 if (power != max_power) 894 IWX_DPRINTF(sc, IWX_DEBUG_FIRMWARE_TLV, 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))); 898 899 return 0; 900 } 901 902 static int 903 iwx_alloc_fw_monitor(struct iwx_softc *sc, uint8_t max_power) 904 { 905 if (!max_power) { 906 /* default max_power is maximum */ 907 max_power = 26; 908 } else { 909 max_power += 11; 910 } 911 912 if (max_power > 26) { 913 IWX_DPRINTF(sc, IWX_DEBUG_FIRMWARE_TLV, 914 "%s: External buffer size for monitor is too big %d, " 915 "check the FW TLV\n", DEVNAME(sc), max_power); 916 return 0; 917 } 918 919 if (sc->fw_mon.size) 920 return 0; 921 922 return iwx_alloc_fw_monitor_block(sc, max_power, 11); 923 } 924 #endif 925 926 static int 927 iwx_apply_debug_destination(struct iwx_softc *sc) 928 { 929 #if 0 930 struct iwx_fw_dbg_dest_tlv_v1 *dest_v1; 931 int i, err; 932 uint8_t mon_mode, size_power, base_shift, end_shift; 933 uint32_t base_reg, end_reg; 934 935 dest_v1 = sc->sc_fw.dbg_dest_tlv_v1; 936 mon_mode = dest_v1->monitor_mode; 937 size_power = dest_v1->size_power; 938 base_reg = le32toh(dest_v1->base_reg); 939 end_reg = le32toh(dest_v1->end_reg); 940 base_shift = dest_v1->base_shift; 941 end_shift = dest_v1->end_shift; 942 943 DPRINTF(("%s: applying debug destination %d\n", DEVNAME(sc), mon_mode)); 944 945 if (mon_mode == EXTERNAL_MODE) { 946 err = iwx_alloc_fw_monitor(sc, size_power); 947 if (err) 948 return err; 949 } 950 951 if (!iwx_nic_lock(sc)) 952 return EBUSY; 953 954 for (i = 0; i < sc->sc_fw.n_dest_reg; i++) { 955 uint32_t addr, val; 956 uint8_t op; 957 958 addr = le32toh(dest_v1->reg_ops[i].addr); 959 val = le32toh(dest_v1->reg_ops[i].val); 960 op = dest_v1->reg_ops[i].op; 961 962 DPRINTF(("%s: op=%u addr=%u val=%u\n", __func__, op, addr, val)); 963 switch (op) { 964 case CSR_ASSIGN: 965 IWX_WRITE(sc, addr, val); 966 break; 967 case CSR_SETBIT: 968 IWX_SETBITS(sc, addr, (1 << val)); 969 break; 970 case CSR_CLEARBIT: 971 IWX_CLRBITS(sc, addr, (1 << val)); 972 break; 973 case PRPH_ASSIGN: 974 iwx_write_prph(sc, addr, val); 975 break; 976 case PRPH_SETBIT: 977 err = iwx_set_bits_prph(sc, addr, (1 << val)); 978 if (err) 979 return err; 980 break; 981 case PRPH_CLEARBIT: 982 err = iwx_clear_bits_prph(sc, addr, (1 << val)); 983 if (err) 984 return err; 985 break; 986 case PRPH_BLOCKBIT: 987 if (iwx_read_prph(sc, addr) & (1 << val)) 988 goto monitor; 989 break; 990 default: 991 DPRINTF(("%s: FW debug - unknown OP %d\n", 992 DEVNAME(sc), op)); 993 break; 994 } 995 } 996 997 monitor: 998 if (mon_mode == EXTERNAL_MODE && sc->fw_mon.size) { 999 iwx_write_prph(sc, le32toh(base_reg), 1000 sc->fw_mon.paddr >> base_shift); 1001 iwx_write_prph(sc, end_reg, 1002 (sc->fw_mon.paddr + sc->fw_mon.size - 256) 1003 >> end_shift); 1004 } 1005 1006 iwx_nic_unlock(sc); 1007 return 0; 1008 #else 1009 return 0; 1010 #endif 1011 } 1012 1013 static void 1014 iwx_set_ltr(struct iwx_softc *sc) 1015 { 1016 uint32_t ltr_val = IWX_CSR_LTR_LONG_VAL_AD_NO_SNOOP_REQ | 1017 ((IWX_CSR_LTR_LONG_VAL_AD_SCALE_USEC << 1018 IWX_CSR_LTR_LONG_VAL_AD_NO_SNOOP_SCALE_SHIFT) & 1019 IWX_CSR_LTR_LONG_VAL_AD_NO_SNOOP_SCALE_MASK) | 1020 ((250 << IWX_CSR_LTR_LONG_VAL_AD_NO_SNOOP_VAL_SHIFT) & 1021 IWX_CSR_LTR_LONG_VAL_AD_NO_SNOOP_VAL_MASK) | 1022 IWX_CSR_LTR_LONG_VAL_AD_SNOOP_REQ | 1023 ((IWX_CSR_LTR_LONG_VAL_AD_SCALE_USEC << 1024 IWX_CSR_LTR_LONG_VAL_AD_SNOOP_SCALE_SHIFT) & 1025 IWX_CSR_LTR_LONG_VAL_AD_SNOOP_SCALE_MASK) | 1026 (250 & IWX_CSR_LTR_LONG_VAL_AD_SNOOP_VAL); 1027 1028 /* 1029 * To workaround hardware latency issues during the boot process, 1030 * initialize the LTR to ~250 usec (see ltr_val above). 1031 * The firmware initializes this again later (to a smaller value). 1032 */ 1033 if (!sc->sc_integrated) { 1034 IWX_WRITE(sc, IWX_CSR_LTR_LONG_VAL_AD, ltr_val); 1035 } else if (sc->sc_integrated && 1036 sc->sc_device_family == IWX_DEVICE_FAMILY_22000) { 1037 iwx_write_prph(sc, IWX_HPM_MAC_LTR_CSR, 1038 IWX_HPM_MAC_LRT_ENABLE_ALL); 1039 iwx_write_prph(sc, IWX_HPM_UMAC_LTR, ltr_val); 1040 } 1041 } 1042 1043 int 1044 iwx_ctxt_info_init(struct iwx_softc *sc, const struct iwx_fw_sects *fws) 1045 { 1046 struct iwx_context_info *ctxt_info; 1047 struct iwx_context_info_rbd_cfg *rx_cfg; 1048 uint32_t control_flags = 0; 1049 uint64_t paddr; 1050 int err; 1051 1052 ctxt_info = sc->ctxt_info_dma.vaddr; 1053 memset(ctxt_info, 0, sizeof(*ctxt_info)); 1054 1055 ctxt_info->version.version = 0; 1056 ctxt_info->version.mac_id = 1057 htole16((uint16_t)IWX_READ(sc, IWX_CSR_HW_REV)); 1058 /* size is in DWs */ 1059 ctxt_info->version.size = htole16(sizeof(*ctxt_info) / 4); 1060 1061 KASSERT(IWX_RX_QUEUE_CB_SIZE(IWX_MQ_RX_TABLE_SIZE) < 0xF, 1062 ("IWX_RX_QUEUE_CB_SIZE exceeds rate table size")); 1063 1064 control_flags = IWX_CTXT_INFO_TFD_FORMAT_LONG | 1065 (IWX_RX_QUEUE_CB_SIZE(IWX_MQ_RX_TABLE_SIZE) << 1066 IWX_CTXT_INFO_RB_CB_SIZE_POS) | 1067 (IWX_CTXT_INFO_RB_SIZE_4K << IWX_CTXT_INFO_RB_SIZE_POS); 1068 ctxt_info->control.control_flags = htole32(control_flags); 1069 1070 /* initialize RX default queue */ 1071 rx_cfg = &ctxt_info->rbd_cfg; 1072 rx_cfg->free_rbd_addr = htole64(sc->rxq.free_desc_dma.paddr); 1073 rx_cfg->used_rbd_addr = htole64(sc->rxq.used_desc_dma.paddr); 1074 rx_cfg->status_wr_ptr = htole64(sc->rxq.stat_dma.paddr); 1075 1076 /* initialize TX command queue */ 1077 ctxt_info->hcmd_cfg.cmd_queue_addr = 1078 htole64(sc->txq[IWX_DQA_CMD_QUEUE].desc_dma.paddr); 1079 ctxt_info->hcmd_cfg.cmd_queue_size = 1080 IWX_TFD_QUEUE_CB_SIZE(IWX_TX_RING_COUNT); 1081 1082 /* allocate ucode sections in dram and set addresses */ 1083 err = iwx_init_fw_sec(sc, fws, &ctxt_info->dram); 1084 if (err) { 1085 iwx_ctxt_info_free_fw_img(sc); 1086 return err; 1087 } 1088 1089 /* Configure debug, if exists */ 1090 if (sc->sc_fw.dbg_dest_tlv_v1) { 1091 #if 1 1092 err = iwx_apply_debug_destination(sc); 1093 if (err) { 1094 iwx_ctxt_info_free_fw_img(sc); 1095 return err; 1096 } 1097 #endif 1098 } 1099 1100 /* 1101 * Write the context info DMA base address. The device expects a 1102 * 64-bit address but a simple bus_space_write_8 to this register 1103 * won't work on some devices, such as the AX201. 1104 */ 1105 paddr = sc->ctxt_info_dma.paddr; 1106 IWX_WRITE(sc, IWX_CSR_CTXT_INFO_BA, paddr & 0xffffffff); 1107 IWX_WRITE(sc, IWX_CSR_CTXT_INFO_BA + 4, paddr >> 32); 1108 1109 /* kick FW self load */ 1110 if (!iwx_nic_lock(sc)) { 1111 iwx_ctxt_info_free_fw_img(sc); 1112 return EBUSY; 1113 } 1114 1115 iwx_set_ltr(sc); 1116 iwx_write_prph(sc, IWX_UREG_CPU_INIT_RUN, 1); 1117 iwx_nic_unlock(sc); 1118 1119 /* Context info will be released upon alive or failure to get one */ 1120 1121 return 0; 1122 } 1123 1124 static int 1125 iwx_ctxt_info_gen3_init(struct iwx_softc *sc, const struct iwx_fw_sects *fws) 1126 { 1127 struct iwx_context_info_gen3 *ctxt_info_gen3; 1128 struct iwx_prph_scratch *prph_scratch; 1129 struct iwx_prph_scratch_ctrl_cfg *prph_sc_ctrl; 1130 uint16_t cb_size; 1131 uint32_t control_flags, scratch_size; 1132 uint64_t paddr; 1133 int err; 1134 1135 if (sc->sc_fw.iml == NULL || sc->sc_fw.iml_len == 0) { 1136 printf("%s: no image loader found in firmware file\n", 1137 DEVNAME(sc)); 1138 iwx_ctxt_info_free_fw_img(sc); 1139 return EINVAL; 1140 } 1141 1142 err = iwx_dma_contig_alloc(sc->sc_dmat, &sc->iml_dma, 1143 sc->sc_fw.iml_len, 1); 1144 if (err) { 1145 printf("%s: could not allocate DMA memory for " 1146 "firmware image loader\n", DEVNAME(sc)); 1147 iwx_ctxt_info_free_fw_img(sc); 1148 return ENOMEM; 1149 } 1150 1151 prph_scratch = sc->prph_scratch_dma.vaddr; 1152 memset(prph_scratch, 0, sizeof(*prph_scratch)); 1153 prph_sc_ctrl = &prph_scratch->ctrl_cfg; 1154 prph_sc_ctrl->version.version = 0; 1155 prph_sc_ctrl->version.mac_id = htole16(IWX_READ(sc, IWX_CSR_HW_REV)); 1156 prph_sc_ctrl->version.size = htole16(sizeof(*prph_scratch) / 4); 1157 1158 control_flags = IWX_PRPH_SCRATCH_RB_SIZE_4K | 1159 IWX_PRPH_SCRATCH_MTR_MODE | 1160 (IWX_PRPH_MTR_FORMAT_256B & IWX_PRPH_SCRATCH_MTR_FORMAT); 1161 if (sc->sc_imr_enabled) 1162 control_flags |= IWX_PRPH_SCRATCH_IMR_DEBUG_EN; 1163 prph_sc_ctrl->control.control_flags = htole32(control_flags); 1164 1165 /* initialize RX default queue */ 1166 prph_sc_ctrl->rbd_cfg.free_rbd_addr = 1167 htole64(sc->rxq.free_desc_dma.paddr); 1168 1169 /* allocate ucode sections in dram and set addresses */ 1170 err = iwx_init_fw_sec(sc, fws, &prph_scratch->dram); 1171 if (err) { 1172 iwx_dma_contig_free(&sc->iml_dma); 1173 iwx_ctxt_info_free_fw_img(sc); 1174 return err; 1175 } 1176 1177 ctxt_info_gen3 = sc->ctxt_info_dma.vaddr; 1178 memset(ctxt_info_gen3, 0, sizeof(*ctxt_info_gen3)); 1179 ctxt_info_gen3->prph_info_base_addr = htole64(sc->prph_info_dma.paddr); 1180 ctxt_info_gen3->prph_scratch_base_addr = 1181 htole64(sc->prph_scratch_dma.paddr); 1182 scratch_size = sizeof(*prph_scratch); 1183 ctxt_info_gen3->prph_scratch_size = htole32(scratch_size); 1184 ctxt_info_gen3->cr_head_idx_arr_base_addr = 1185 htole64(sc->rxq.stat_dma.paddr); 1186 ctxt_info_gen3->tr_tail_idx_arr_base_addr = 1187 htole64(sc->prph_info_dma.paddr + PAGE_SIZE / 2); 1188 ctxt_info_gen3->cr_tail_idx_arr_base_addr = 1189 htole64(sc->prph_info_dma.paddr + 3 * PAGE_SIZE / 4); 1190 ctxt_info_gen3->mtr_base_addr = 1191 htole64(sc->txq[IWX_DQA_CMD_QUEUE].desc_dma.paddr); 1192 ctxt_info_gen3->mcr_base_addr = htole64(sc->rxq.used_desc_dma.paddr); 1193 cb_size = IWX_TFD_QUEUE_CB_SIZE(IWX_TX_RING_COUNT); 1194 ctxt_info_gen3->mtr_size = htole16(cb_size); 1195 cb_size = IWX_RX_QUEUE_CB_SIZE(IWX_MQ_RX_TABLE_SIZE); 1196 ctxt_info_gen3->mcr_size = htole16(cb_size); 1197 1198 memcpy(sc->iml_dma.vaddr, sc->sc_fw.iml, sc->sc_fw.iml_len); 1199 1200 paddr = sc->ctxt_info_dma.paddr; 1201 IWX_WRITE(sc, IWX_CSR_CTXT_INFO_ADDR, paddr & 0xffffffff); 1202 IWX_WRITE(sc, IWX_CSR_CTXT_INFO_ADDR + 4, paddr >> 32); 1203 1204 paddr = sc->iml_dma.paddr; 1205 IWX_WRITE(sc, IWX_CSR_IML_DATA_ADDR, paddr & 0xffffffff); 1206 IWX_WRITE(sc, IWX_CSR_IML_DATA_ADDR + 4, paddr >> 32); 1207 IWX_WRITE(sc, IWX_CSR_IML_SIZE_ADDR, sc->sc_fw.iml_len); 1208 1209 IWX_SETBITS(sc, IWX_CSR_CTXT_INFO_BOOT_CTRL, 1210 IWX_CSR_AUTO_FUNC_BOOT_ENA); 1211 1212 IWX_DPRINTF(sc, IWX_DEBUG_FIRMWARE_TLV, 1213 "%s:%d kicking fw to get going\n", __func__, __LINE__); 1214 1215 /* kick FW self load */ 1216 if (!iwx_nic_lock(sc)) { 1217 iwx_dma_contig_free(&sc->iml_dma); 1218 iwx_ctxt_info_free_fw_img(sc); 1219 return EBUSY; 1220 } 1221 iwx_set_ltr(sc); 1222 iwx_write_umac_prph(sc, IWX_UREG_CPU_INIT_RUN, 1); 1223 iwx_nic_unlock(sc); 1224 1225 /* Context info will be released upon alive or failure to get one */ 1226 return 0; 1227 } 1228 1229 static void 1230 iwx_ctxt_info_free_fw_img(struct iwx_softc *sc) 1231 { 1232 struct iwx_self_init_dram *dram = &sc->init_dram; 1233 int i; 1234 1235 if (!dram->fw) 1236 return; 1237 1238 for (i = 0; i < dram->lmac_cnt + dram->umac_cnt; i++) 1239 iwx_dma_contig_free(&dram->fw[i]); 1240 1241 free(dram->fw, M_DEVBUF); 1242 dram->lmac_cnt = 0; 1243 dram->umac_cnt = 0; 1244 dram->fw = NULL; 1245 } 1246 1247 static int 1248 iwx_firmware_store_section(struct iwx_softc *sc, enum iwx_ucode_type type, 1249 const uint8_t *data, size_t dlen) 1250 { 1251 struct iwx_fw_sects *fws; 1252 struct iwx_fw_onesect *fwone; 1253 1254 if (type >= IWX_UCODE_TYPE_MAX) 1255 return EINVAL; 1256 if (dlen < sizeof(uint32_t)) 1257 return EINVAL; 1258 1259 fws = &sc->sc_fw.fw_sects[type]; 1260 IWX_DPRINTF(sc, IWX_DEBUG_FIRMWARE_TLV, 1261 "%s: ucode type %d section %d\n", DEVNAME(sc), type, fws->fw_count); 1262 if (fws->fw_count >= IWX_UCODE_SECT_MAX) 1263 return EINVAL; 1264 1265 fwone = &fws->fw_sect[fws->fw_count]; 1266 1267 /* first 32bit are device load offset */ 1268 memcpy(&fwone->fws_devoff, data, sizeof(uint32_t)); 1269 1270 /* rest is data */ 1271 fwone->fws_data = data + sizeof(uint32_t); 1272 fwone->fws_len = dlen - sizeof(uint32_t); 1273 1274 fws->fw_count++; 1275 fws->fw_totlen += fwone->fws_len; 1276 1277 return 0; 1278 } 1279 1280 #define IWX_DEFAULT_SCAN_CHANNELS 40 1281 /* Newer firmware might support more channels. Raise this value if needed. */ 1282 #define IWX_MAX_SCAN_CHANNELS 67 /* as of iwx-cc-a0-62 firmware */ 1283 1284 struct iwx_tlv_calib_data { 1285 uint32_t ucode_type; 1286 struct iwx_tlv_calib_ctrl calib; 1287 } __packed; 1288 1289 static int 1290 iwx_set_default_calib(struct iwx_softc *sc, const void *data) 1291 { 1292 const struct iwx_tlv_calib_data *def_calib = data; 1293 uint32_t ucode_type = le32toh(def_calib->ucode_type); 1294 1295 if (ucode_type >= IWX_UCODE_TYPE_MAX) 1296 return EINVAL; 1297 1298 sc->sc_default_calib[ucode_type].flow_trigger = 1299 def_calib->calib.flow_trigger; 1300 sc->sc_default_calib[ucode_type].event_trigger = 1301 def_calib->calib.event_trigger; 1302 1303 return 0; 1304 } 1305 1306 static void 1307 iwx_fw_info_free(struct iwx_fw_info *fw) 1308 { 1309 free(fw->fw_rawdata, M_DEVBUF); 1310 fw->fw_rawdata = NULL; 1311 fw->fw_rawsize = 0; 1312 /* don't touch fw->fw_status */ 1313 memset(fw->fw_sects, 0, sizeof(fw->fw_sects)); 1314 free(fw->iml, M_DEVBUF); 1315 fw->iml = NULL; 1316 fw->iml_len = 0; 1317 } 1318 1319 #define IWX_FW_ADDR_CACHE_CONTROL 0xC0000000 1320 1321 static int 1322 iwx_read_firmware(struct iwx_softc *sc) 1323 { 1324 struct iwx_fw_info *fw = &sc->sc_fw; 1325 const struct iwx_tlv_ucode_header *uhdr; 1326 struct iwx_ucode_tlv tlv; 1327 uint32_t tlv_type; 1328 const uint8_t *data; 1329 int err = 0; 1330 size_t len; 1331 const struct firmware *fwp; 1332 1333 if (fw->fw_status == IWX_FW_STATUS_DONE) 1334 return 0; 1335 1336 fw->fw_status = IWX_FW_STATUS_INPROGRESS; 1337 fwp = firmware_get(sc->sc_fwname); 1338 sc->sc_fwp = fwp; 1339 1340 if (fwp == NULL) { 1341 printf("%s: could not read firmware %s\n", 1342 DEVNAME(sc), sc->sc_fwname); 1343 err = ENOENT; 1344 goto out; 1345 } 1346 1347 IWX_DPRINTF(sc, IWX_DEBUG_FW, "%s:%d %s: using firmware %s\n", 1348 __func__, __LINE__, DEVNAME(sc), sc->sc_fwname); 1349 1350 1351 sc->sc_capaflags = 0; 1352 sc->sc_capa_n_scan_channels = IWX_DEFAULT_SCAN_CHANNELS; 1353 memset(sc->sc_enabled_capa, 0, sizeof(sc->sc_enabled_capa)); 1354 memset(sc->sc_ucode_api, 0, sizeof(sc->sc_ucode_api)); 1355 sc->n_cmd_versions = 0; 1356 1357 uhdr = (const void *)(fwp->data); 1358 if (*(const uint32_t *)fwp->data != 0 1359 || le32toh(uhdr->magic) != IWX_TLV_UCODE_MAGIC) { 1360 printf("%s: invalid firmware %s\n", 1361 DEVNAME(sc), sc->sc_fwname); 1362 err = EINVAL; 1363 goto out; 1364 } 1365 1366 iwx_fw_version_str(sc->sc_fwver, sizeof(sc->sc_fwver), 1367 IWX_UCODE_MAJOR(le32toh(uhdr->ver)), 1368 IWX_UCODE_MINOR(le32toh(uhdr->ver)), 1369 IWX_UCODE_API(le32toh(uhdr->ver))); 1370 1371 data = uhdr->data; 1372 len = fwp->datasize - sizeof(*uhdr); 1373 1374 while (len >= sizeof(tlv)) { 1375 size_t tlv_len; 1376 const void *tlv_data; 1377 1378 memcpy(&tlv, data, sizeof(tlv)); 1379 tlv_len = le32toh(tlv.length); 1380 tlv_type = le32toh(tlv.type); 1381 1382 len -= sizeof(tlv); 1383 data += sizeof(tlv); 1384 tlv_data = data; 1385 1386 if (len < tlv_len) { 1387 printf("%s: firmware too short: %zu bytes\n", 1388 DEVNAME(sc), len); 1389 err = EINVAL; 1390 goto parse_out; 1391 } 1392 1393 switch (tlv_type) { 1394 case IWX_UCODE_TLV_PROBE_MAX_LEN: 1395 if (tlv_len < sizeof(uint32_t)) { 1396 err = EINVAL; 1397 goto parse_out; 1398 } 1399 sc->sc_capa_max_probe_len 1400 = le32toh(*(const uint32_t *)tlv_data); 1401 if (sc->sc_capa_max_probe_len > 1402 IWX_SCAN_OFFLOAD_PROBE_REQ_SIZE) { 1403 err = EINVAL; 1404 goto parse_out; 1405 } 1406 break; 1407 case IWX_UCODE_TLV_PAN: 1408 if (tlv_len) { 1409 err = EINVAL; 1410 goto parse_out; 1411 } 1412 sc->sc_capaflags |= IWX_UCODE_TLV_FLAGS_PAN; 1413 break; 1414 case IWX_UCODE_TLV_FLAGS: 1415 if (tlv_len < sizeof(uint32_t)) { 1416 err = EINVAL; 1417 goto parse_out; 1418 } 1419 /* 1420 * Apparently there can be many flags, but Linux driver 1421 * parses only the first one, and so do we. 1422 * 1423 * XXX: why does this override IWX_UCODE_TLV_PAN? 1424 * Intentional or a bug? Observations from 1425 * current firmware file: 1426 * 1) TLV_PAN is parsed first 1427 * 2) TLV_FLAGS contains TLV_FLAGS_PAN 1428 * ==> this resets TLV_PAN to itself... hnnnk 1429 */ 1430 sc->sc_capaflags = le32toh(*(const uint32_t *)tlv_data); 1431 break; 1432 case IWX_UCODE_TLV_CSCHEME: 1433 err = iwx_store_cscheme(sc, tlv_data, tlv_len); 1434 if (err) 1435 goto parse_out; 1436 break; 1437 case IWX_UCODE_TLV_NUM_OF_CPU: { 1438 uint32_t num_cpu; 1439 if (tlv_len != sizeof(uint32_t)) { 1440 err = EINVAL; 1441 goto parse_out; 1442 } 1443 num_cpu = le32toh(*(const uint32_t *)tlv_data); 1444 if (num_cpu < 1 || num_cpu > 2) { 1445 err = EINVAL; 1446 goto parse_out; 1447 } 1448 break; 1449 } 1450 case IWX_UCODE_TLV_SEC_RT: 1451 err = iwx_firmware_store_section(sc, 1452 IWX_UCODE_TYPE_REGULAR, tlv_data, tlv_len); 1453 if (err) 1454 goto parse_out; 1455 break; 1456 case IWX_UCODE_TLV_SEC_INIT: 1457 err = iwx_firmware_store_section(sc, 1458 IWX_UCODE_TYPE_INIT, tlv_data, tlv_len); 1459 if (err) 1460 goto parse_out; 1461 break; 1462 case IWX_UCODE_TLV_SEC_WOWLAN: 1463 err = iwx_firmware_store_section(sc, 1464 IWX_UCODE_TYPE_WOW, tlv_data, tlv_len); 1465 if (err) 1466 goto parse_out; 1467 break; 1468 case IWX_UCODE_TLV_DEF_CALIB: 1469 if (tlv_len != sizeof(struct iwx_tlv_calib_data)) { 1470 err = EINVAL; 1471 goto parse_out; 1472 } 1473 err = iwx_set_default_calib(sc, tlv_data); 1474 if (err) 1475 goto parse_out; 1476 break; 1477 case IWX_UCODE_TLV_PHY_SKU: 1478 if (tlv_len != sizeof(uint32_t)) { 1479 err = EINVAL; 1480 goto parse_out; 1481 } 1482 sc->sc_fw_phy_config = le32toh(*(const uint32_t *)tlv_data); 1483 break; 1484 1485 case IWX_UCODE_TLV_API_CHANGES_SET: { 1486 const struct iwx_ucode_api *api; 1487 int idx, i; 1488 if (tlv_len != sizeof(*api)) { 1489 err = EINVAL; 1490 goto parse_out; 1491 } 1492 api = (const struct iwx_ucode_api *)tlv_data; 1493 idx = le32toh(api->api_index); 1494 if (idx >= howmany(IWX_NUM_UCODE_TLV_API, 32)) { 1495 err = EINVAL; 1496 goto parse_out; 1497 } 1498 for (i = 0; i < 32; i++) { 1499 if ((le32toh(api->api_flags) & (1 << i)) == 0) 1500 continue; 1501 setbit(sc->sc_ucode_api, i + (32 * idx)); 1502 } 1503 break; 1504 } 1505 1506 case IWX_UCODE_TLV_ENABLED_CAPABILITIES: { 1507 const struct iwx_ucode_capa *capa; 1508 int idx, i; 1509 if (tlv_len != sizeof(*capa)) { 1510 err = EINVAL; 1511 goto parse_out; 1512 } 1513 capa = (const struct iwx_ucode_capa *)tlv_data; 1514 idx = le32toh(capa->api_index); 1515 if (idx >= howmany(IWX_NUM_UCODE_TLV_CAPA, 32)) { 1516 goto parse_out; 1517 } 1518 for (i = 0; i < 32; i++) { 1519 if ((le32toh(capa->api_capa) & (1 << i)) == 0) 1520 continue; 1521 setbit(sc->sc_enabled_capa, i + (32 * idx)); 1522 } 1523 break; 1524 } 1525 1526 case IWX_UCODE_TLV_SDIO_ADMA_ADDR: 1527 case IWX_UCODE_TLV_FW_GSCAN_CAPA: 1528 /* ignore, not used by current driver */ 1529 break; 1530 1531 case IWX_UCODE_TLV_SEC_RT_USNIFFER: 1532 err = iwx_firmware_store_section(sc, 1533 IWX_UCODE_TYPE_REGULAR_USNIFFER, tlv_data, 1534 tlv_len); 1535 if (err) 1536 goto parse_out; 1537 break; 1538 1539 case IWX_UCODE_TLV_PAGING: 1540 if (tlv_len != sizeof(uint32_t)) { 1541 err = EINVAL; 1542 goto parse_out; 1543 } 1544 break; 1545 1546 case IWX_UCODE_TLV_N_SCAN_CHANNELS: 1547 if (tlv_len != sizeof(uint32_t)) { 1548 err = EINVAL; 1549 goto parse_out; 1550 } 1551 sc->sc_capa_n_scan_channels = 1552 le32toh(*(const uint32_t *)tlv_data); 1553 if (sc->sc_capa_n_scan_channels > IWX_MAX_SCAN_CHANNELS) { 1554 err = ERANGE; 1555 goto parse_out; 1556 } 1557 break; 1558 1559 case IWX_UCODE_TLV_FW_VERSION: 1560 if (tlv_len != sizeof(uint32_t) * 3) { 1561 err = EINVAL; 1562 goto parse_out; 1563 } 1564 1565 iwx_fw_version_str(sc->sc_fwver, sizeof(sc->sc_fwver), 1566 le32toh(((const uint32_t *)tlv_data)[0]), 1567 le32toh(((const uint32_t *)tlv_data)[1]), 1568 le32toh(((const uint32_t *)tlv_data)[2])); 1569 break; 1570 1571 case IWX_UCODE_TLV_FW_DBG_DEST: { 1572 const struct iwx_fw_dbg_dest_tlv_v1 *dest_v1 = NULL; 1573 1574 fw->dbg_dest_ver = (const uint8_t *)tlv_data; 1575 if (*fw->dbg_dest_ver != 0) { 1576 err = EINVAL; 1577 goto parse_out; 1578 } 1579 1580 if (fw->dbg_dest_tlv_init) 1581 break; 1582 fw->dbg_dest_tlv_init = true; 1583 1584 dest_v1 = (const void *)tlv_data; 1585 fw->dbg_dest_tlv_v1 = dest_v1; 1586 fw->n_dest_reg = tlv_len - 1587 offsetof(struct iwx_fw_dbg_dest_tlv_v1, reg_ops); 1588 fw->n_dest_reg /= sizeof(dest_v1->reg_ops[0]); 1589 IWX_DPRINTF(sc, IWX_DEBUG_FIRMWARE_TLV, 1590 "%s: found debug dest; n_dest_reg=%d\n", 1591 __func__, fw->n_dest_reg); 1592 break; 1593 } 1594 1595 case IWX_UCODE_TLV_FW_DBG_CONF: { 1596 const struct iwx_fw_dbg_conf_tlv *conf = (const void *)tlv_data; 1597 1598 if (!fw->dbg_dest_tlv_init || 1599 conf->id >= nitems(fw->dbg_conf_tlv) || 1600 fw->dbg_conf_tlv[conf->id] != NULL) 1601 break; 1602 1603 IWX_DPRINTF(sc, IWX_DEBUG_FIRMWARE_TLV, 1604 "Found debug configuration: %d\n", conf->id); 1605 fw->dbg_conf_tlv[conf->id] = conf; 1606 fw->dbg_conf_tlv_len[conf->id] = tlv_len; 1607 break; 1608 } 1609 1610 case IWX_UCODE_TLV_UMAC_DEBUG_ADDRS: { 1611 const struct iwx_umac_debug_addrs *dbg_ptrs = 1612 (const void *)tlv_data; 1613 1614 if (tlv_len != sizeof(*dbg_ptrs)) { 1615 err = EINVAL; 1616 goto parse_out; 1617 } 1618 if (sc->sc_device_family < IWX_DEVICE_FAMILY_22000) 1619 break; 1620 sc->sc_uc.uc_umac_error_event_table = 1621 le32toh(dbg_ptrs->error_info_addr) & 1622 ~IWX_FW_ADDR_CACHE_CONTROL; 1623 sc->sc_uc.error_event_table_tlv_status |= 1624 IWX_ERROR_EVENT_TABLE_UMAC; 1625 break; 1626 } 1627 1628 case IWX_UCODE_TLV_LMAC_DEBUG_ADDRS: { 1629 const struct iwx_lmac_debug_addrs *dbg_ptrs = 1630 (const void *)tlv_data; 1631 1632 if (tlv_len != sizeof(*dbg_ptrs)) { 1633 err = EINVAL; 1634 goto parse_out; 1635 } 1636 if (sc->sc_device_family < IWX_DEVICE_FAMILY_22000) 1637 break; 1638 sc->sc_uc.uc_lmac_error_event_table[0] = 1639 le32toh(dbg_ptrs->error_event_table_ptr) & 1640 ~IWX_FW_ADDR_CACHE_CONTROL; 1641 sc->sc_uc.error_event_table_tlv_status |= 1642 IWX_ERROR_EVENT_TABLE_LMAC1; 1643 break; 1644 } 1645 1646 case IWX_UCODE_TLV_FW_MEM_SEG: 1647 break; 1648 1649 case IWX_UCODE_TLV_IML: 1650 if (sc->sc_fw.iml != NULL) { 1651 free(fw->iml, M_DEVBUF); 1652 fw->iml_len = 0; 1653 } 1654 sc->sc_fw.iml = malloc(tlv_len, M_DEVBUF, 1655 M_WAITOK | M_ZERO); 1656 if (sc->sc_fw.iml == NULL) { 1657 err = ENOMEM; 1658 goto parse_out; 1659 } 1660 memcpy(sc->sc_fw.iml, tlv_data, tlv_len); 1661 sc->sc_fw.iml_len = tlv_len; 1662 break; 1663 1664 case IWX_UCODE_TLV_CMD_VERSIONS: 1665 if (tlv_len % sizeof(struct iwx_fw_cmd_version)) { 1666 tlv_len /= sizeof(struct iwx_fw_cmd_version); 1667 tlv_len *= sizeof(struct iwx_fw_cmd_version); 1668 } 1669 if (sc->n_cmd_versions != 0) { 1670 err = EINVAL; 1671 goto parse_out; 1672 } 1673 if (tlv_len > sizeof(sc->cmd_versions)) { 1674 err = EINVAL; 1675 goto parse_out; 1676 } 1677 memcpy(&sc->cmd_versions[0], tlv_data, tlv_len); 1678 sc->n_cmd_versions = tlv_len / sizeof(struct iwx_fw_cmd_version); 1679 break; 1680 1681 case IWX_UCODE_TLV_FW_RECOVERY_INFO: 1682 break; 1683 1684 case IWX_UCODE_TLV_FW_FSEQ_VERSION: 1685 case IWX_UCODE_TLV_PHY_INTEGRATION_VERSION: 1686 case IWX_UCODE_TLV_FW_NUM_STATIONS: 1687 case IWX_UCODE_TLV_FW_NUM_BEACONS: 1688 break; 1689 1690 /* undocumented TLVs found in iwx-cc-a0-46 image */ 1691 case 58: 1692 case 0x1000003: 1693 case 0x1000004: 1694 break; 1695 1696 /* undocumented TLVs found in iwx-cc-a0-48 image */ 1697 case 0x1000000: 1698 case 0x1000002: 1699 break; 1700 1701 case IWX_UCODE_TLV_TYPE_DEBUG_INFO: 1702 case IWX_UCODE_TLV_TYPE_BUFFER_ALLOCATION: 1703 case IWX_UCODE_TLV_TYPE_HCMD: 1704 case IWX_UCODE_TLV_TYPE_REGIONS: 1705 case IWX_UCODE_TLV_TYPE_TRIGGERS: 1706 case IWX_UCODE_TLV_TYPE_CONF_SET: 1707 case IWX_UCODE_TLV_SEC_TABLE_ADDR: 1708 case IWX_UCODE_TLV_D3_KEK_KCK_ADDR: 1709 case IWX_UCODE_TLV_CURRENT_PC: 1710 break; 1711 1712 /* undocumented TLV found in iwx-cc-a0-67 image */ 1713 case 0x100000b: 1714 break; 1715 1716 /* undocumented TLV found in iwx-ty-a0-gf-a0-73 image */ 1717 case 0x101: 1718 break; 1719 1720 /* undocumented TLV found in iwx-ty-a0-gf-a0-77 image */ 1721 case 0x100000c: 1722 break; 1723 1724 /* undocumented TLV found in iwx-ty-a0-gf-a0-89 image */ 1725 case 69: 1726 break; 1727 1728 default: 1729 err = EINVAL; 1730 goto parse_out; 1731 } 1732 1733 /* 1734 * Check for size_t overflow and ignore missing padding at 1735 * end of firmware file. 1736 */ 1737 if (roundup(tlv_len, 4) > len) 1738 break; 1739 1740 len -= roundup(tlv_len, 4); 1741 data += roundup(tlv_len, 4); 1742 } 1743 1744 KASSERT(err == 0, ("unhandled fw parse error")); 1745 1746 parse_out: 1747 if (err) { 1748 printf("%s: firmware parse error %d, " 1749 "section type %d\n", DEVNAME(sc), err, tlv_type); 1750 } 1751 1752 out: 1753 if (err) { 1754 fw->fw_status = IWX_FW_STATUS_NONE; 1755 if (fw->fw_rawdata != NULL) 1756 iwx_fw_info_free(fw); 1757 } else 1758 fw->fw_status = IWX_FW_STATUS_DONE; 1759 return err; 1760 } 1761 1762 static uint32_t 1763 iwx_prph_addr_mask(struct iwx_softc *sc) 1764 { 1765 if (sc->sc_device_family >= IWX_DEVICE_FAMILY_AX210) 1766 return 0x00ffffff; 1767 else 1768 return 0x000fffff; 1769 } 1770 1771 static uint32_t 1772 iwx_read_prph_unlocked(struct iwx_softc *sc, uint32_t addr) 1773 { 1774 uint32_t mask = iwx_prph_addr_mask(sc); 1775 IWX_WRITE(sc, IWX_HBUS_TARG_PRPH_RADDR, ((addr & mask) | (3 << 24))); 1776 IWX_BARRIER_READ_WRITE(sc); 1777 return IWX_READ(sc, IWX_HBUS_TARG_PRPH_RDAT); 1778 } 1779 1780 uint32_t 1781 iwx_read_prph(struct iwx_softc *sc, uint32_t addr) 1782 { 1783 iwx_nic_assert_locked(sc); 1784 return iwx_read_prph_unlocked(sc, addr); 1785 } 1786 1787 static void 1788 iwx_write_prph_unlocked(struct iwx_softc *sc, uint32_t addr, uint32_t val) 1789 { 1790 uint32_t mask = iwx_prph_addr_mask(sc); 1791 IWX_WRITE(sc, IWX_HBUS_TARG_PRPH_WADDR, ((addr & mask) | (3 << 24))); 1792 IWX_BARRIER_WRITE(sc); 1793 IWX_WRITE(sc, IWX_HBUS_TARG_PRPH_WDAT, val); 1794 } 1795 1796 static void 1797 iwx_write_prph(struct iwx_softc *sc, uint32_t addr, uint32_t val) 1798 { 1799 iwx_nic_assert_locked(sc); 1800 iwx_write_prph_unlocked(sc, addr, val); 1801 } 1802 1803 static uint32_t 1804 iwx_read_umac_prph(struct iwx_softc *sc, uint32_t addr) 1805 { 1806 return iwx_read_prph(sc, addr + sc->sc_umac_prph_offset); 1807 } 1808 1809 static void 1810 iwx_write_umac_prph(struct iwx_softc *sc, uint32_t addr, uint32_t val) 1811 { 1812 iwx_write_prph(sc, addr + sc->sc_umac_prph_offset, val); 1813 } 1814 1815 static int 1816 iwx_read_mem(struct iwx_softc *sc, uint32_t addr, void *buf, int dwords) 1817 { 1818 int offs, err = 0; 1819 uint32_t *vals = buf; 1820 1821 if (iwx_nic_lock(sc)) { 1822 IWX_WRITE(sc, IWX_HBUS_TARG_MEM_RADDR, addr); 1823 for (offs = 0; offs < dwords; offs++) 1824 vals[offs] = le32toh(IWX_READ(sc, IWX_HBUS_TARG_MEM_RDAT)); 1825 iwx_nic_unlock(sc); 1826 } else { 1827 err = EBUSY; 1828 } 1829 return err; 1830 } 1831 1832 static int 1833 iwx_poll_bit(struct iwx_softc *sc, int reg, uint32_t bits, uint32_t mask, 1834 int timo) 1835 { 1836 for (;;) { 1837 if ((IWX_READ(sc, reg) & mask) == (bits & mask)) { 1838 return 1; 1839 } 1840 if (timo < 10) { 1841 return 0; 1842 } 1843 timo -= 10; 1844 DELAY(10); 1845 } 1846 } 1847 1848 static int 1849 iwx_nic_lock(struct iwx_softc *sc) 1850 { 1851 if (sc->sc_nic_locks > 0) { 1852 iwx_nic_assert_locked(sc); 1853 sc->sc_nic_locks++; 1854 return 1; /* already locked */ 1855 } 1856 1857 IWX_SETBITS(sc, IWX_CSR_GP_CNTRL, 1858 IWX_CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); 1859 1860 DELAY(2); 1861 1862 if (iwx_poll_bit(sc, IWX_CSR_GP_CNTRL, 1863 IWX_CSR_GP_CNTRL_REG_VAL_MAC_ACCESS_EN, 1864 IWX_CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY 1865 | IWX_CSR_GP_CNTRL_REG_FLAG_GOING_TO_SLEEP, 150000)) { 1866 sc->sc_nic_locks++; 1867 return 1; 1868 } 1869 1870 printf("%s: acquiring device failed\n", DEVNAME(sc)); 1871 return 0; 1872 } 1873 1874 static void 1875 iwx_nic_assert_locked(struct iwx_softc *sc) 1876 { 1877 if (sc->sc_nic_locks <= 0) 1878 panic("%s: nic locks counter %d", DEVNAME(sc), sc->sc_nic_locks); 1879 } 1880 1881 static void 1882 iwx_nic_unlock(struct iwx_softc *sc) 1883 { 1884 if (sc->sc_nic_locks > 0) { 1885 if (--sc->sc_nic_locks == 0) 1886 IWX_CLRBITS(sc, IWX_CSR_GP_CNTRL, 1887 IWX_CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); 1888 } else 1889 printf("%s: NIC already unlocked\n", DEVNAME(sc)); 1890 } 1891 1892 static int 1893 iwx_set_bits_mask_prph(struct iwx_softc *sc, uint32_t reg, uint32_t bits, 1894 uint32_t mask) 1895 { 1896 uint32_t val; 1897 1898 if (iwx_nic_lock(sc)) { 1899 val = iwx_read_prph(sc, reg) & mask; 1900 val |= bits; 1901 iwx_write_prph(sc, reg, val); 1902 iwx_nic_unlock(sc); 1903 return 0; 1904 } 1905 return EBUSY; 1906 } 1907 1908 static int 1909 iwx_set_bits_prph(struct iwx_softc *sc, uint32_t reg, uint32_t bits) 1910 { 1911 return iwx_set_bits_mask_prph(sc, reg, bits, ~0); 1912 } 1913 1914 static int 1915 iwx_clear_bits_prph(struct iwx_softc *sc, uint32_t reg, uint32_t bits) 1916 { 1917 return iwx_set_bits_mask_prph(sc, reg, 0, ~bits); 1918 } 1919 1920 static void 1921 iwx_dma_map_addr(void *arg, bus_dma_segment_t *segs, int nsegs, int error) 1922 { 1923 if (error != 0) 1924 return; 1925 KASSERT(nsegs == 1, ("too many DMA segments, %d should be 1", nsegs)); 1926 *(bus_addr_t *)arg = segs[0].ds_addr; 1927 } 1928 1929 static int 1930 iwx_dma_contig_alloc(bus_dma_tag_t tag, struct iwx_dma_info *dma, 1931 bus_size_t size, bus_size_t alignment) 1932 { 1933 int error; 1934 1935 dma->tag = NULL; 1936 dma->map = NULL; 1937 dma->size = size; 1938 dma->vaddr = NULL; 1939 1940 error = bus_dma_tag_create(tag, alignment, 1941 0, BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL, size, 1942 1, size, 0, NULL, NULL, &dma->tag); 1943 if (error != 0) 1944 goto fail; 1945 1946 error = bus_dmamem_alloc(dma->tag, (void **)&dma->vaddr, 1947 BUS_DMA_NOWAIT | BUS_DMA_ZERO | BUS_DMA_COHERENT, &dma->map); 1948 if (error != 0) 1949 goto fail; 1950 1951 error = bus_dmamap_load(dma->tag, dma->map, dma->vaddr, size, 1952 iwx_dma_map_addr, &dma->paddr, BUS_DMA_NOWAIT); 1953 if (error != 0) { 1954 bus_dmamem_free(dma->tag, dma->vaddr, dma->map); 1955 dma->vaddr = NULL; 1956 goto fail; 1957 } 1958 1959 bus_dmamap_sync(dma->tag, dma->map, BUS_DMASYNC_PREWRITE); 1960 1961 return 0; 1962 1963 fail: 1964 iwx_dma_contig_free(dma); 1965 return error; 1966 } 1967 1968 static void 1969 iwx_dma_contig_free(struct iwx_dma_info *dma) 1970 { 1971 if (dma->vaddr != NULL) { 1972 bus_dmamap_sync(dma->tag, dma->map, 1973 BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); 1974 bus_dmamap_unload(dma->tag, dma->map); 1975 bus_dmamem_free(dma->tag, dma->vaddr, dma->map); 1976 dma->vaddr = NULL; 1977 } 1978 if (dma->tag != NULL) { 1979 bus_dma_tag_destroy(dma->tag); 1980 dma->tag = NULL; 1981 } 1982 } 1983 1984 static int 1985 iwx_alloc_rx_ring(struct iwx_softc *sc, struct iwx_rx_ring *ring) 1986 { 1987 bus_size_t size; 1988 int i, err; 1989 1990 ring->cur = 0; 1991 1992 /* Allocate RX descriptors (256-byte aligned). */ 1993 if (sc->sc_device_family >= IWX_DEVICE_FAMILY_AX210) 1994 size = sizeof(struct iwx_rx_transfer_desc); 1995 else 1996 size = sizeof(uint64_t); 1997 err = iwx_dma_contig_alloc(sc->sc_dmat, &ring->free_desc_dma, 1998 size * IWX_RX_MQ_RING_COUNT, 256); 1999 if (err) { 2000 device_printf(sc->sc_dev, 2001 "could not allocate RX ring DMA memory\n"); 2002 goto fail; 2003 } 2004 ring->desc = ring->free_desc_dma.vaddr; 2005 2006 /* Allocate RX status area (16-byte aligned). */ 2007 if (sc->sc_device_family >= IWX_DEVICE_FAMILY_AX210) 2008 size = sizeof(uint16_t); 2009 else 2010 size = sizeof(*ring->stat); 2011 err = iwx_dma_contig_alloc(sc->sc_dmat, &ring->stat_dma, size, 16); 2012 if (err) { 2013 device_printf(sc->sc_dev, 2014 "could not allocate RX status DMA memory\n"); 2015 goto fail; 2016 } 2017 ring->stat = ring->stat_dma.vaddr; 2018 2019 if (sc->sc_device_family >= IWX_DEVICE_FAMILY_AX210) 2020 size = sizeof(struct iwx_rx_completion_desc); 2021 else 2022 size = sizeof(uint32_t); 2023 err = iwx_dma_contig_alloc(sc->sc_dmat, &ring->used_desc_dma, 2024 size * IWX_RX_MQ_RING_COUNT, 256); 2025 if (err) { 2026 device_printf(sc->sc_dev, 2027 "could not allocate RX ring DMA memory\n"); 2028 goto fail; 2029 } 2030 2031 err = bus_dma_tag_create(sc->sc_dmat, 1, 0, BUS_SPACE_MAXADDR_32BIT, 2032 BUS_SPACE_MAXADDR, NULL, NULL, IWX_RBUF_SIZE, 1, IWX_RBUF_SIZE, 2033 0, NULL, NULL, &ring->data_dmat); 2034 2035 for (i = 0; i < IWX_RX_MQ_RING_COUNT; i++) { 2036 struct iwx_rx_data *data = &ring->data[i]; 2037 2038 memset(data, 0, sizeof(*data)); 2039 err = bus_dmamap_create(ring->data_dmat, 0, &data->map); 2040 if (err) { 2041 device_printf(sc->sc_dev, 2042 "could not create RX buf DMA map\n"); 2043 goto fail; 2044 } 2045 2046 err = iwx_rx_addbuf(sc, IWX_RBUF_SIZE, i); 2047 if (err) 2048 goto fail; 2049 } 2050 return 0; 2051 2052 fail: iwx_free_rx_ring(sc, ring); 2053 return err; 2054 } 2055 2056 static void 2057 iwx_disable_rx_dma(struct iwx_softc *sc) 2058 { 2059 int ntries; 2060 2061 if (iwx_nic_lock(sc)) { 2062 if (sc->sc_device_family >= IWX_DEVICE_FAMILY_AX210) 2063 iwx_write_umac_prph(sc, IWX_RFH_RXF_DMA_CFG_GEN3, 0); 2064 else 2065 iwx_write_prph(sc, IWX_RFH_RXF_DMA_CFG, 0); 2066 for (ntries = 0; ntries < 1000; ntries++) { 2067 if (sc->sc_device_family >= IWX_DEVICE_FAMILY_AX210) { 2068 if (iwx_read_umac_prph(sc, 2069 IWX_RFH_GEN_STATUS_GEN3) & IWX_RXF_DMA_IDLE) 2070 break; 2071 } else { 2072 if (iwx_read_prph(sc, IWX_RFH_GEN_STATUS) & 2073 IWX_RXF_DMA_IDLE) 2074 break; 2075 } 2076 DELAY(10); 2077 } 2078 iwx_nic_unlock(sc); 2079 } 2080 } 2081 2082 static void 2083 iwx_reset_rx_ring(struct iwx_softc *sc, struct iwx_rx_ring *ring) 2084 { 2085 ring->cur = 0; 2086 bus_dmamap_sync(sc->sc_dmat, ring->stat_dma.map, 2087 BUS_DMASYNC_PREWRITE); 2088 if (sc->sc_device_family >= IWX_DEVICE_FAMILY_AX210) { 2089 uint16_t *status = sc->rxq.stat_dma.vaddr; 2090 *status = 0; 2091 } else 2092 memset(ring->stat, 0, sizeof(*ring->stat)); 2093 bus_dmamap_sync(sc->sc_dmat, ring->stat_dma.map, 2094 BUS_DMASYNC_POSTWRITE); 2095 2096 } 2097 2098 static void 2099 iwx_free_rx_ring(struct iwx_softc *sc, struct iwx_rx_ring *ring) 2100 { 2101 int i; 2102 2103 iwx_dma_contig_free(&ring->free_desc_dma); 2104 iwx_dma_contig_free(&ring->stat_dma); 2105 iwx_dma_contig_free(&ring->used_desc_dma); 2106 2107 for (i = 0; i < IWX_RX_MQ_RING_COUNT; i++) { 2108 struct iwx_rx_data *data = &ring->data[i]; 2109 if (data->m != NULL) { 2110 bus_dmamap_sync(ring->data_dmat, data->map, 2111 BUS_DMASYNC_POSTREAD); 2112 bus_dmamap_unload(ring->data_dmat, data->map); 2113 m_freem(data->m); 2114 data->m = NULL; 2115 } 2116 if (data->map != NULL) { 2117 bus_dmamap_destroy(ring->data_dmat, data->map); 2118 data->map = NULL; 2119 } 2120 } 2121 if (ring->data_dmat != NULL) { 2122 bus_dma_tag_destroy(ring->data_dmat); 2123 ring->data_dmat = NULL; 2124 } 2125 } 2126 2127 static int 2128 iwx_alloc_tx_ring(struct iwx_softc *sc, struct iwx_tx_ring *ring, int qid) 2129 { 2130 bus_addr_t paddr; 2131 bus_size_t size; 2132 int i, err; 2133 size_t bc_tbl_size; 2134 bus_size_t bc_align; 2135 size_t mapsize; 2136 2137 ring->qid = qid; 2138 ring->queued = 0; 2139 ring->cur = 0; 2140 ring->cur_hw = 0; 2141 ring->tail = 0; 2142 ring->tail_hw = 0; 2143 2144 /* Allocate TX descriptors (256-byte aligned). */ 2145 size = IWX_TX_RING_COUNT * sizeof(struct iwx_tfh_tfd); 2146 err = iwx_dma_contig_alloc(sc->sc_dmat, &ring->desc_dma, size, 256); 2147 if (err) { 2148 device_printf(sc->sc_dev, 2149 "could not allocate TX ring DMA memory\n"); 2150 goto fail; 2151 } 2152 ring->desc = ring->desc_dma.vaddr; 2153 2154 /* 2155 * The hardware supports up to 512 Tx rings which is more 2156 * than we currently need. 2157 * 2158 * In DQA mode we use 1 command queue + 1 default queue for 2159 * management, control, and non-QoS data frames. 2160 * The command is queue sc->txq[0], our default queue is sc->txq[1]. 2161 * 2162 * Tx aggregation requires additional queues, one queue per TID for 2163 * which aggregation is enabled. We map TID 0-7 to sc->txq[2:9]. 2164 * Firmware may assign its own internal IDs for these queues 2165 * depending on which TID gets aggregation enabled first. 2166 * The driver maintains a table mapping driver-side queue IDs 2167 * to firmware-side queue IDs. 2168 */ 2169 2170 if (sc->sc_device_family >= IWX_DEVICE_FAMILY_AX210) { 2171 bc_tbl_size = sizeof(struct iwx_gen3_bc_tbl_entry) * 2172 IWX_TFD_QUEUE_BC_SIZE_GEN3_AX210; 2173 bc_align = 128; 2174 } else { 2175 bc_tbl_size = sizeof(struct iwx_agn_scd_bc_tbl); 2176 bc_align = 64; 2177 } 2178 err = iwx_dma_contig_alloc(sc->sc_dmat, &ring->bc_tbl, bc_tbl_size, 2179 bc_align); 2180 if (err) { 2181 device_printf(sc->sc_dev, 2182 "could not allocate byte count table DMA memory\n"); 2183 goto fail; 2184 } 2185 2186 size = IWX_TX_RING_COUNT * sizeof(struct iwx_device_cmd); 2187 err = iwx_dma_contig_alloc(sc->sc_dmat, &ring->cmd_dma, size, 2188 IWX_FIRST_TB_SIZE_ALIGN); 2189 if (err) { 2190 device_printf(sc->sc_dev, 2191 "could not allocate cmd DMA memory\n"); 2192 goto fail; 2193 } 2194 ring->cmd = ring->cmd_dma.vaddr; 2195 2196 /* FW commands may require more mapped space than packets. */ 2197 if (qid == IWX_DQA_CMD_QUEUE) 2198 mapsize = (sizeof(struct iwx_cmd_header) + 2199 IWX_MAX_CMD_PAYLOAD_SIZE); 2200 else 2201 mapsize = MCLBYTES; 2202 err = bus_dma_tag_create(sc->sc_dmat, 1, 0, BUS_SPACE_MAXADDR_32BIT, 2203 BUS_SPACE_MAXADDR, NULL, NULL, mapsize, IWX_TFH_NUM_TBS - 2, 2204 mapsize, 0, NULL, NULL, &ring->data_dmat); 2205 2206 paddr = ring->cmd_dma.paddr; 2207 for (i = 0; i < IWX_TX_RING_COUNT; i++) { 2208 struct iwx_tx_data *data = &ring->data[i]; 2209 2210 data->cmd_paddr = paddr; 2211 paddr += sizeof(struct iwx_device_cmd); 2212 2213 err = bus_dmamap_create(ring->data_dmat, 0, &data->map); 2214 if (err) { 2215 device_printf(sc->sc_dev, 2216 "could not create TX buf DMA map\n"); 2217 goto fail; 2218 } 2219 } 2220 KASSERT(paddr == ring->cmd_dma.paddr + size, ("bad paddr in txr alloc")); 2221 return 0; 2222 2223 fail: 2224 return err; 2225 } 2226 2227 static void 2228 iwx_reset_tx_ring(struct iwx_softc *sc, struct iwx_tx_ring *ring) 2229 { 2230 int i; 2231 2232 for (i = 0; i < IWX_TX_RING_COUNT; i++) { 2233 struct iwx_tx_data *data = &ring->data[i]; 2234 2235 if (data->m != NULL) { 2236 bus_dmamap_sync(ring->data_dmat, data->map, 2237 BUS_DMASYNC_POSTWRITE); 2238 bus_dmamap_unload(ring->data_dmat, data->map); 2239 m_freem(data->m); 2240 data->m = NULL; 2241 } 2242 } 2243 2244 /* Clear byte count table. */ 2245 memset(ring->bc_tbl.vaddr, 0, ring->bc_tbl.size); 2246 2247 /* Clear TX descriptors. */ 2248 memset(ring->desc, 0, ring->desc_dma.size); 2249 bus_dmamap_sync(ring->desc_dma.tag, ring->desc_dma.map, 2250 BUS_DMASYNC_PREWRITE); 2251 sc->qfullmsk &= ~(1 << ring->qid); 2252 sc->qenablemsk &= ~(1 << ring->qid); 2253 for (i = 0; i < nitems(sc->aggqid); i++) { 2254 if (sc->aggqid[i] == ring->qid) { 2255 sc->aggqid[i] = 0; 2256 break; 2257 } 2258 } 2259 ring->queued = 0; 2260 ring->cur = 0; 2261 ring->cur_hw = 0; 2262 ring->tail = 0; 2263 ring->tail_hw = 0; 2264 ring->tid = 0; 2265 } 2266 2267 static void 2268 iwx_free_tx_ring(struct iwx_softc *sc, struct iwx_tx_ring *ring) 2269 { 2270 int i; 2271 2272 iwx_dma_contig_free(&ring->desc_dma); 2273 iwx_dma_contig_free(&ring->cmd_dma); 2274 iwx_dma_contig_free(&ring->bc_tbl); 2275 2276 for (i = 0; i < IWX_TX_RING_COUNT; i++) { 2277 struct iwx_tx_data *data = &ring->data[i]; 2278 2279 if (data->m != NULL) { 2280 bus_dmamap_sync(ring->data_dmat, data->map, 2281 BUS_DMASYNC_POSTWRITE); 2282 bus_dmamap_unload(ring->data_dmat, data->map); 2283 m_freem(data->m); 2284 data->m = NULL; 2285 } 2286 if (data->map != NULL) { 2287 bus_dmamap_destroy(ring->data_dmat, data->map); 2288 data->map = NULL; 2289 } 2290 } 2291 if (ring->data_dmat != NULL) { 2292 bus_dma_tag_destroy(ring->data_dmat); 2293 ring->data_dmat = NULL; 2294 } 2295 } 2296 2297 static void 2298 iwx_enable_rfkill_int(struct iwx_softc *sc) 2299 { 2300 if (!sc->sc_msix) { 2301 sc->sc_intmask = IWX_CSR_INT_BIT_RF_KILL; 2302 IWX_WRITE(sc, IWX_CSR_INT_MASK, sc->sc_intmask); 2303 } else { 2304 IWX_WRITE(sc, IWX_CSR_MSIX_FH_INT_MASK_AD, 2305 sc->sc_fh_init_mask); 2306 IWX_WRITE(sc, IWX_CSR_MSIX_HW_INT_MASK_AD, 2307 ~IWX_MSIX_HW_INT_CAUSES_REG_RF_KILL); 2308 sc->sc_hw_mask = IWX_MSIX_HW_INT_CAUSES_REG_RF_KILL; 2309 } 2310 2311 IWX_SETBITS(sc, IWX_CSR_GP_CNTRL, 2312 IWX_CSR_GP_CNTRL_REG_FLAG_RFKILL_WAKE_L1A_EN); 2313 } 2314 2315 static int 2316 iwx_check_rfkill(struct iwx_softc *sc) 2317 { 2318 uint32_t v; 2319 int rv; 2320 2321 /* 2322 * "documentation" is not really helpful here: 2323 * 27: HW_RF_KILL_SW 2324 * Indicates state of (platform's) hardware RF-Kill switch 2325 * 2326 * But apparently when it's off, it's on ... 2327 */ 2328 v = IWX_READ(sc, IWX_CSR_GP_CNTRL); 2329 rv = (v & IWX_CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW) == 0; 2330 if (rv) { 2331 sc->sc_flags |= IWX_FLAG_RFKILL; 2332 } else { 2333 sc->sc_flags &= ~IWX_FLAG_RFKILL; 2334 } 2335 2336 return rv; 2337 } 2338 2339 static void 2340 iwx_enable_interrupts(struct iwx_softc *sc) 2341 { 2342 if (!sc->sc_msix) { 2343 sc->sc_intmask = IWX_CSR_INI_SET_MASK; 2344 IWX_WRITE(sc, IWX_CSR_INT_MASK, sc->sc_intmask); 2345 } else { 2346 /* 2347 * fh/hw_mask keeps all the unmasked causes. 2348 * Unlike msi, in msix cause is enabled when it is unset. 2349 */ 2350 sc->sc_hw_mask = sc->sc_hw_init_mask; 2351 sc->sc_fh_mask = sc->sc_fh_init_mask; 2352 IWX_WRITE(sc, IWX_CSR_MSIX_FH_INT_MASK_AD, 2353 ~sc->sc_fh_mask); 2354 IWX_WRITE(sc, IWX_CSR_MSIX_HW_INT_MASK_AD, 2355 ~sc->sc_hw_mask); 2356 } 2357 } 2358 2359 static void 2360 iwx_enable_fwload_interrupt(struct iwx_softc *sc) 2361 { 2362 if (!sc->sc_msix) { 2363 sc->sc_intmask = IWX_CSR_INT_BIT_ALIVE | IWX_CSR_INT_BIT_FH_RX; 2364 IWX_WRITE(sc, IWX_CSR_INT_MASK, sc->sc_intmask); 2365 } else { 2366 IWX_WRITE(sc, IWX_CSR_MSIX_HW_INT_MASK_AD, 2367 ~IWX_MSIX_HW_INT_CAUSES_REG_ALIVE); 2368 sc->sc_hw_mask = IWX_MSIX_HW_INT_CAUSES_REG_ALIVE; 2369 /* 2370 * Leave all the FH causes enabled to get the ALIVE 2371 * notification. 2372 */ 2373 IWX_WRITE(sc, IWX_CSR_MSIX_FH_INT_MASK_AD, 2374 ~sc->sc_fh_init_mask); 2375 sc->sc_fh_mask = sc->sc_fh_init_mask; 2376 } 2377 } 2378 2379 #if 0 2380 static void 2381 iwx_restore_interrupts(struct iwx_softc *sc) 2382 { 2383 IWX_WRITE(sc, IWX_CSR_INT_MASK, sc->sc_intmask); 2384 } 2385 #endif 2386 2387 static void 2388 iwx_disable_interrupts(struct iwx_softc *sc) 2389 { 2390 if (!sc->sc_msix) { 2391 IWX_WRITE(sc, IWX_CSR_INT_MASK, 0); 2392 2393 /* acknowledge all interrupts */ 2394 IWX_WRITE(sc, IWX_CSR_INT, ~0); 2395 IWX_WRITE(sc, IWX_CSR_FH_INT_STATUS, ~0); 2396 } else { 2397 IWX_WRITE(sc, IWX_CSR_MSIX_FH_INT_MASK_AD, 2398 sc->sc_fh_init_mask); 2399 IWX_WRITE(sc, IWX_CSR_MSIX_HW_INT_MASK_AD, 2400 sc->sc_hw_init_mask); 2401 } 2402 } 2403 2404 static void 2405 iwx_ict_reset(struct iwx_softc *sc) 2406 { 2407 iwx_disable_interrupts(sc); 2408 2409 memset(sc->ict_dma.vaddr, 0, IWX_ICT_SIZE); 2410 sc->ict_cur = 0; 2411 2412 /* Set physical address of ICT (4KB aligned). */ 2413 IWX_WRITE(sc, IWX_CSR_DRAM_INT_TBL_REG, 2414 IWX_CSR_DRAM_INT_TBL_ENABLE 2415 | IWX_CSR_DRAM_INIT_TBL_WRAP_CHECK 2416 | IWX_CSR_DRAM_INIT_TBL_WRITE_POINTER 2417 | sc->ict_dma.paddr >> IWX_ICT_PADDR_SHIFT); 2418 2419 /* Switch to ICT interrupt mode in driver. */ 2420 sc->sc_flags |= IWX_FLAG_USE_ICT; 2421 2422 IWX_WRITE(sc, IWX_CSR_INT, ~0); 2423 iwx_enable_interrupts(sc); 2424 } 2425 2426 #define IWX_HW_READY_TIMEOUT 50 2427 static int 2428 iwx_set_hw_ready(struct iwx_softc *sc) 2429 { 2430 int ready; 2431 2432 IWX_SETBITS(sc, IWX_CSR_HW_IF_CONFIG_REG, 2433 IWX_CSR_HW_IF_CONFIG_REG_BIT_NIC_READY); 2434 2435 ready = iwx_poll_bit(sc, IWX_CSR_HW_IF_CONFIG_REG, 2436 IWX_CSR_HW_IF_CONFIG_REG_BIT_NIC_READY, 2437 IWX_CSR_HW_IF_CONFIG_REG_BIT_NIC_READY, 2438 IWX_HW_READY_TIMEOUT); 2439 if (ready) 2440 IWX_SETBITS(sc, IWX_CSR_MBOX_SET_REG, 2441 IWX_CSR_MBOX_SET_REG_OS_ALIVE); 2442 2443 DPRINTF(("%s: ready=%d\n", __func__, ready)); 2444 return ready; 2445 } 2446 #undef IWX_HW_READY_TIMEOUT 2447 2448 static int 2449 iwx_prepare_card_hw(struct iwx_softc *sc) 2450 { 2451 int t = 0; 2452 int ntries; 2453 2454 if (iwx_set_hw_ready(sc)) 2455 return 0; 2456 2457 IWX_SETBITS(sc, IWX_CSR_DBG_LINK_PWR_MGMT_REG, 2458 IWX_CSR_RESET_LINK_PWR_MGMT_DISABLED); 2459 DELAY(1000); 2460 2461 for (ntries = 0; ntries < 10; ntries++) { 2462 /* If HW is not ready, prepare the conditions to check again */ 2463 IWX_SETBITS(sc, IWX_CSR_HW_IF_CONFIG_REG, 2464 IWX_CSR_HW_IF_CONFIG_REG_PREPARE); 2465 2466 do { 2467 if (iwx_set_hw_ready(sc)) 2468 return 0; 2469 DELAY(200); 2470 t += 200; 2471 } while (t < 150000); 2472 DELAY(25000); 2473 } 2474 2475 return ETIMEDOUT; 2476 } 2477 2478 static int 2479 iwx_force_power_gating(struct iwx_softc *sc) 2480 { 2481 int err; 2482 2483 err = iwx_set_bits_prph(sc, IWX_HPM_HIPM_GEN_CFG, 2484 IWX_HPM_HIPM_GEN_CFG_CR_FORCE_ACTIVE); 2485 if (err) 2486 return err; 2487 DELAY(20); 2488 err = iwx_set_bits_prph(sc, IWX_HPM_HIPM_GEN_CFG, 2489 IWX_HPM_HIPM_GEN_CFG_CR_PG_EN | 2490 IWX_HPM_HIPM_GEN_CFG_CR_SLP_EN); 2491 if (err) 2492 return err; 2493 DELAY(20); 2494 err = iwx_clear_bits_prph(sc, IWX_HPM_HIPM_GEN_CFG, 2495 IWX_HPM_HIPM_GEN_CFG_CR_FORCE_ACTIVE); 2496 return err; 2497 } 2498 2499 static void 2500 iwx_apm_config(struct iwx_softc *sc) 2501 { 2502 uint16_t lctl, cap; 2503 int pcie_ptr; 2504 int error; 2505 2506 /* 2507 * L0S states have been found to be unstable with our devices 2508 * and in newer hardware they are not officially supported at 2509 * all, so we must always set the L0S_DISABLED bit. 2510 */ 2511 IWX_SETBITS(sc, IWX_CSR_GIO_REG, IWX_CSR_GIO_REG_VAL_L0S_DISABLED); 2512 2513 error = pci_find_cap(sc->sc_dev, PCIY_EXPRESS, &pcie_ptr); 2514 if (error != 0) { 2515 printf("can't fill pcie_ptr\n"); 2516 return; 2517 } 2518 2519 lctl = pci_read_config(sc->sc_dev, pcie_ptr + PCIER_LINK_CTL, 2520 sizeof(lctl)); 2521 #define PCI_PCIE_LCSR_ASPM_L0S 0x00000001 2522 sc->sc_pm_support = !(lctl & PCI_PCIE_LCSR_ASPM_L0S); 2523 #define PCI_PCIE_DCSR2 0x28 2524 cap = pci_read_config(sc->sc_dev, pcie_ptr + PCI_PCIE_DCSR2, 2525 sizeof(lctl)); 2526 #define PCI_PCIE_DCSR2_LTREN 0x00000400 2527 sc->sc_ltr_enabled = (cap & PCI_PCIE_DCSR2_LTREN) ? 1 : 0; 2528 #define PCI_PCIE_LCSR_ASPM_L1 0x00000002 2529 DPRINTF(("%s: L1 %sabled - LTR %sabled\n", 2530 DEVNAME(sc), 2531 (lctl & PCI_PCIE_LCSR_ASPM_L1) ? "En" : "Dis", 2532 sc->sc_ltr_enabled ? "En" : "Dis")); 2533 #undef PCI_PCIE_LCSR_ASPM_L0S 2534 #undef PCI_PCIE_DCSR2 2535 #undef PCI_PCIE_DCSR2_LTREN 2536 #undef PCI_PCIE_LCSR_ASPM_L1 2537 } 2538 2539 /* 2540 * Start up NIC's basic functionality after it has been reset 2541 * e.g. after platform boot or shutdown. 2542 * NOTE: This does not load uCode nor start the embedded processor 2543 */ 2544 static int 2545 iwx_apm_init(struct iwx_softc *sc) 2546 { 2547 int err = 0; 2548 2549 /* 2550 * Disable L0s without affecting L1; 2551 * don't wait for ICH L0s (ICH bug W/A) 2552 */ 2553 IWX_SETBITS(sc, IWX_CSR_GIO_CHICKEN_BITS, 2554 IWX_CSR_GIO_CHICKEN_BITS_REG_BIT_L1A_NO_L0S_RX); 2555 2556 /* Set FH wait threshold to maximum (HW error during stress W/A) */ 2557 IWX_SETBITS(sc, IWX_CSR_DBG_HPET_MEM_REG, IWX_CSR_DBG_HPET_MEM_REG_VAL); 2558 2559 /* 2560 * Enable HAP INTA (interrupt from management bus) to 2561 * wake device's PCI Express link L1a -> L0s 2562 */ 2563 IWX_SETBITS(sc, IWX_CSR_HW_IF_CONFIG_REG, 2564 IWX_CSR_HW_IF_CONFIG_REG_BIT_HAP_WAKE_L1A); 2565 2566 iwx_apm_config(sc); 2567 2568 /* 2569 * Set "initialization complete" bit to move adapter from 2570 * D0U* --> D0A* (powered-up active) state. 2571 */ 2572 IWX_SETBITS(sc, IWX_CSR_GP_CNTRL, IWX_CSR_GP_CNTRL_REG_FLAG_INIT_DONE); 2573 2574 /* 2575 * Wait for clock stabilization; once stabilized, access to 2576 * device-internal resources is supported, e.g. iwx_write_prph() 2577 * and accesses to uCode SRAM. 2578 */ 2579 if (!iwx_poll_bit(sc, IWX_CSR_GP_CNTRL, 2580 IWX_CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 2581 IWX_CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000)) { 2582 printf("%s: timeout waiting for clock stabilization\n", 2583 DEVNAME(sc)); 2584 err = ETIMEDOUT; 2585 goto out; 2586 } 2587 out: 2588 if (err) 2589 printf("%s: apm init error %d\n", DEVNAME(sc), err); 2590 return err; 2591 } 2592 2593 static void 2594 iwx_apm_stop(struct iwx_softc *sc) 2595 { 2596 IWX_SETBITS(sc, IWX_CSR_DBG_LINK_PWR_MGMT_REG, 2597 IWX_CSR_RESET_LINK_PWR_MGMT_DISABLED); 2598 IWX_SETBITS(sc, IWX_CSR_HW_IF_CONFIG_REG, 2599 IWX_CSR_HW_IF_CONFIG_REG_PREPARE | 2600 IWX_CSR_HW_IF_CONFIG_REG_ENABLE_PME); 2601 DELAY(1000); 2602 IWX_CLRBITS(sc, IWX_CSR_DBG_LINK_PWR_MGMT_REG, 2603 IWX_CSR_RESET_LINK_PWR_MGMT_DISABLED); 2604 DELAY(5000); 2605 2606 /* stop device's busmaster DMA activity */ 2607 IWX_SETBITS(sc, IWX_CSR_RESET, IWX_CSR_RESET_REG_FLAG_STOP_MASTER); 2608 2609 if (!iwx_poll_bit(sc, IWX_CSR_RESET, 2610 IWX_CSR_RESET_REG_FLAG_MASTER_DISABLED, 2611 IWX_CSR_RESET_REG_FLAG_MASTER_DISABLED, 100)) 2612 printf("%s: timeout waiting for bus master\n", DEVNAME(sc)); 2613 2614 /* 2615 * Clear "initialization complete" bit to move adapter from 2616 * D0A* (powered-up Active) --> D0U* (Uninitialized) state. 2617 */ 2618 IWX_CLRBITS(sc, IWX_CSR_GP_CNTRL, 2619 IWX_CSR_GP_CNTRL_REG_FLAG_INIT_DONE); 2620 } 2621 2622 static void 2623 iwx_init_msix_hw(struct iwx_softc *sc) 2624 { 2625 iwx_conf_msix_hw(sc, 0); 2626 2627 if (!sc->sc_msix) 2628 return; 2629 2630 sc->sc_fh_init_mask = ~IWX_READ(sc, IWX_CSR_MSIX_FH_INT_MASK_AD); 2631 sc->sc_fh_mask = sc->sc_fh_init_mask; 2632 sc->sc_hw_init_mask = ~IWX_READ(sc, IWX_CSR_MSIX_HW_INT_MASK_AD); 2633 sc->sc_hw_mask = sc->sc_hw_init_mask; 2634 } 2635 2636 static void 2637 iwx_conf_msix_hw(struct iwx_softc *sc, int stopped) 2638 { 2639 int vector = 0; 2640 2641 if (!sc->sc_msix) { 2642 /* Newer chips default to MSIX. */ 2643 if (!stopped && iwx_nic_lock(sc)) { 2644 iwx_write_umac_prph(sc, IWX_UREG_CHICK, 2645 IWX_UREG_CHICK_MSI_ENABLE); 2646 iwx_nic_unlock(sc); 2647 } 2648 return; 2649 } 2650 2651 if (!stopped && iwx_nic_lock(sc)) { 2652 iwx_write_umac_prph(sc, IWX_UREG_CHICK, 2653 IWX_UREG_CHICK_MSIX_ENABLE); 2654 iwx_nic_unlock(sc); 2655 } 2656 2657 /* Disable all interrupts */ 2658 IWX_WRITE(sc, IWX_CSR_MSIX_FH_INT_MASK_AD, ~0); 2659 IWX_WRITE(sc, IWX_CSR_MSIX_HW_INT_MASK_AD, ~0); 2660 2661 /* Map fallback-queue (command/mgmt) to a single vector */ 2662 IWX_WRITE_1(sc, IWX_CSR_MSIX_RX_IVAR(0), 2663 vector | IWX_MSIX_NON_AUTO_CLEAR_CAUSE); 2664 /* Map RSS queue (data) to the same vector */ 2665 IWX_WRITE_1(sc, IWX_CSR_MSIX_RX_IVAR(1), 2666 vector | IWX_MSIX_NON_AUTO_CLEAR_CAUSE); 2667 2668 /* Enable the RX queues cause interrupts */ 2669 IWX_CLRBITS(sc, IWX_CSR_MSIX_FH_INT_MASK_AD, 2670 IWX_MSIX_FH_INT_CAUSES_Q0 | IWX_MSIX_FH_INT_CAUSES_Q1); 2671 2672 /* Map non-RX causes to the same vector */ 2673 IWX_WRITE_1(sc, IWX_CSR_MSIX_IVAR(IWX_MSIX_IVAR_CAUSE_D2S_CH0_NUM), 2674 vector | IWX_MSIX_NON_AUTO_CLEAR_CAUSE); 2675 IWX_WRITE_1(sc, IWX_CSR_MSIX_IVAR(IWX_MSIX_IVAR_CAUSE_D2S_CH1_NUM), 2676 vector | IWX_MSIX_NON_AUTO_CLEAR_CAUSE); 2677 IWX_WRITE_1(sc, IWX_CSR_MSIX_IVAR(IWX_MSIX_IVAR_CAUSE_S2D), 2678 vector | IWX_MSIX_NON_AUTO_CLEAR_CAUSE); 2679 IWX_WRITE_1(sc, IWX_CSR_MSIX_IVAR(IWX_MSIX_IVAR_CAUSE_FH_ERR), 2680 vector | IWX_MSIX_NON_AUTO_CLEAR_CAUSE); 2681 IWX_WRITE_1(sc, IWX_CSR_MSIX_IVAR(IWX_MSIX_IVAR_CAUSE_REG_ALIVE), 2682 vector | IWX_MSIX_NON_AUTO_CLEAR_CAUSE); 2683 IWX_WRITE_1(sc, IWX_CSR_MSIX_IVAR(IWX_MSIX_IVAR_CAUSE_REG_WAKEUP), 2684 vector | IWX_MSIX_NON_AUTO_CLEAR_CAUSE); 2685 IWX_WRITE_1(sc, IWX_CSR_MSIX_IVAR(IWX_MSIX_IVAR_CAUSE_REG_RESET_DONE), 2686 vector | IWX_MSIX_NON_AUTO_CLEAR_CAUSE); 2687 IWX_WRITE_1(sc, IWX_CSR_MSIX_IVAR(IWX_MSIX_IVAR_CAUSE_REG_CT_KILL), 2688 vector | IWX_MSIX_NON_AUTO_CLEAR_CAUSE); 2689 IWX_WRITE_1(sc, IWX_CSR_MSIX_IVAR(IWX_MSIX_IVAR_CAUSE_REG_RF_KILL), 2690 vector | IWX_MSIX_NON_AUTO_CLEAR_CAUSE); 2691 IWX_WRITE_1(sc, IWX_CSR_MSIX_IVAR(IWX_MSIX_IVAR_CAUSE_REG_PERIODIC), 2692 vector | IWX_MSIX_NON_AUTO_CLEAR_CAUSE); 2693 IWX_WRITE_1(sc, IWX_CSR_MSIX_IVAR(IWX_MSIX_IVAR_CAUSE_REG_SW_ERR), 2694 vector | IWX_MSIX_NON_AUTO_CLEAR_CAUSE); 2695 IWX_WRITE_1(sc, IWX_CSR_MSIX_IVAR(IWX_MSIX_IVAR_CAUSE_REG_SCD), 2696 vector | IWX_MSIX_NON_AUTO_CLEAR_CAUSE); 2697 IWX_WRITE_1(sc, IWX_CSR_MSIX_IVAR(IWX_MSIX_IVAR_CAUSE_REG_FH_TX), 2698 vector | IWX_MSIX_NON_AUTO_CLEAR_CAUSE); 2699 IWX_WRITE_1(sc, IWX_CSR_MSIX_IVAR(IWX_MSIX_IVAR_CAUSE_REG_HW_ERR), 2700 vector | IWX_MSIX_NON_AUTO_CLEAR_CAUSE); 2701 IWX_WRITE_1(sc, IWX_CSR_MSIX_IVAR(IWX_MSIX_IVAR_CAUSE_REG_HAP), 2702 vector | IWX_MSIX_NON_AUTO_CLEAR_CAUSE); 2703 2704 /* Enable non-RX causes interrupts */ 2705 IWX_CLRBITS(sc, IWX_CSR_MSIX_FH_INT_MASK_AD, 2706 IWX_MSIX_FH_INT_CAUSES_D2S_CH0_NUM | 2707 IWX_MSIX_FH_INT_CAUSES_D2S_CH1_NUM | 2708 IWX_MSIX_FH_INT_CAUSES_S2D | 2709 IWX_MSIX_FH_INT_CAUSES_FH_ERR); 2710 IWX_CLRBITS(sc, IWX_CSR_MSIX_HW_INT_MASK_AD, 2711 IWX_MSIX_HW_INT_CAUSES_REG_ALIVE | 2712 IWX_MSIX_HW_INT_CAUSES_REG_WAKEUP | 2713 IWX_MSIX_HW_INT_CAUSES_REG_RESET_DONE | 2714 IWX_MSIX_HW_INT_CAUSES_REG_CT_KILL | 2715 IWX_MSIX_HW_INT_CAUSES_REG_RF_KILL | 2716 IWX_MSIX_HW_INT_CAUSES_REG_PERIODIC | 2717 IWX_MSIX_HW_INT_CAUSES_REG_SW_ERR | 2718 IWX_MSIX_HW_INT_CAUSES_REG_SCD | 2719 IWX_MSIX_HW_INT_CAUSES_REG_FH_TX | 2720 IWX_MSIX_HW_INT_CAUSES_REG_HW_ERR | 2721 IWX_MSIX_HW_INT_CAUSES_REG_HAP); 2722 } 2723 2724 static int 2725 iwx_clear_persistence_bit(struct iwx_softc *sc) 2726 { 2727 uint32_t hpm, wprot; 2728 2729 hpm = iwx_read_prph_unlocked(sc, IWX_HPM_DEBUG); 2730 if (hpm != 0xa5a5a5a0 && (hpm & IWX_PERSISTENCE_BIT)) { 2731 wprot = iwx_read_prph_unlocked(sc, IWX_PREG_PRPH_WPROT_22000); 2732 if (wprot & IWX_PREG_WFPM_ACCESS) { 2733 printf("%s: cannot clear persistence bit\n", 2734 DEVNAME(sc)); 2735 return EPERM; 2736 } 2737 iwx_write_prph_unlocked(sc, IWX_HPM_DEBUG, 2738 hpm & ~IWX_PERSISTENCE_BIT); 2739 } 2740 2741 return 0; 2742 } 2743 2744 static int 2745 iwx_start_hw(struct iwx_softc *sc) 2746 { 2747 int err; 2748 2749 err = iwx_prepare_card_hw(sc); 2750 if (err) 2751 return err; 2752 2753 if (sc->sc_device_family == IWX_DEVICE_FAMILY_22000) { 2754 err = iwx_clear_persistence_bit(sc); 2755 if (err) 2756 return err; 2757 } 2758 2759 /* Reset the entire device */ 2760 IWX_SETBITS(sc, IWX_CSR_RESET, IWX_CSR_RESET_REG_FLAG_SW_RESET); 2761 DELAY(5000); 2762 2763 if (sc->sc_device_family == IWX_DEVICE_FAMILY_22000 && 2764 sc->sc_integrated) { 2765 IWX_SETBITS(sc, IWX_CSR_GP_CNTRL, 2766 IWX_CSR_GP_CNTRL_REG_FLAG_INIT_DONE); 2767 DELAY(20); 2768 if (!iwx_poll_bit(sc, IWX_CSR_GP_CNTRL, 2769 IWX_CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 2770 IWX_CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000)) { 2771 printf("%s: timeout waiting for clock stabilization\n", 2772 DEVNAME(sc)); 2773 return ETIMEDOUT; 2774 } 2775 2776 err = iwx_force_power_gating(sc); 2777 if (err) 2778 return err; 2779 2780 /* Reset the entire device */ 2781 IWX_SETBITS(sc, IWX_CSR_RESET, IWX_CSR_RESET_REG_FLAG_SW_RESET); 2782 DELAY(5000); 2783 } 2784 2785 err = iwx_apm_init(sc); 2786 if (err) 2787 return err; 2788 2789 iwx_init_msix_hw(sc); 2790 2791 iwx_enable_rfkill_int(sc); 2792 iwx_check_rfkill(sc); 2793 2794 return 0; 2795 } 2796 2797 static void 2798 iwx_stop_device(struct iwx_softc *sc) 2799 { 2800 int i; 2801 2802 iwx_disable_interrupts(sc); 2803 sc->sc_flags &= ~IWX_FLAG_USE_ICT; 2804 2805 iwx_disable_rx_dma(sc); 2806 iwx_reset_rx_ring(sc, &sc->rxq); 2807 for (i = 0; i < nitems(sc->txq); i++) 2808 iwx_reset_tx_ring(sc, &sc->txq[i]); 2809 #if 0 2810 /* XXX-THJ: Tidy up BA state on stop */ 2811 for (i = 0; i < IEEE80211_NUM_TID; i++) { 2812 struct ieee80211_tx_ba *ba = &ni->ni_tx_ba[i]; 2813 if (ba->ba_state != IEEE80211_BA_AGREED) 2814 continue; 2815 ieee80211_delba_request(ic, ni, 0, 1, i); 2816 } 2817 #endif 2818 /* Make sure (redundant) we've released our request to stay awake */ 2819 IWX_CLRBITS(sc, IWX_CSR_GP_CNTRL, 2820 IWX_CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); 2821 if (sc->sc_nic_locks > 0) 2822 printf("%s: %d active NIC locks forcefully cleared\n", 2823 DEVNAME(sc), sc->sc_nic_locks); 2824 sc->sc_nic_locks = 0; 2825 2826 /* Stop the device, and put it in low power state */ 2827 iwx_apm_stop(sc); 2828 2829 /* Reset the on-board processor. */ 2830 IWX_SETBITS(sc, IWX_CSR_RESET, IWX_CSR_RESET_REG_FLAG_SW_RESET); 2831 DELAY(5000); 2832 2833 /* 2834 * Upon stop, the IVAR table gets erased, so msi-x won't 2835 * work. This causes a bug in RF-KILL flows, since the interrupt 2836 * that enables radio won't fire on the correct irq, and the 2837 * driver won't be able to handle the interrupt. 2838 * Configure the IVAR table again after reset. 2839 */ 2840 iwx_conf_msix_hw(sc, 1); 2841 2842 /* 2843 * Upon stop, the APM issues an interrupt if HW RF kill is set. 2844 * Clear the interrupt again. 2845 */ 2846 iwx_disable_interrupts(sc); 2847 2848 /* Even though we stop the HW we still want the RF kill interrupt. */ 2849 iwx_enable_rfkill_int(sc); 2850 iwx_check_rfkill(sc); 2851 2852 iwx_prepare_card_hw(sc); 2853 2854 iwx_ctxt_info_free_paging(sc); 2855 iwx_dma_contig_free(&sc->pnvm_dma); 2856 } 2857 2858 static void 2859 iwx_nic_config(struct iwx_softc *sc) 2860 { 2861 uint8_t radio_cfg_type, radio_cfg_step, radio_cfg_dash; 2862 uint32_t mask, val, reg_val = 0; 2863 2864 radio_cfg_type = (sc->sc_fw_phy_config & IWX_FW_PHY_CFG_RADIO_TYPE) >> 2865 IWX_FW_PHY_CFG_RADIO_TYPE_POS; 2866 radio_cfg_step = (sc->sc_fw_phy_config & IWX_FW_PHY_CFG_RADIO_STEP) >> 2867 IWX_FW_PHY_CFG_RADIO_STEP_POS; 2868 radio_cfg_dash = (sc->sc_fw_phy_config & IWX_FW_PHY_CFG_RADIO_DASH) >> 2869 IWX_FW_PHY_CFG_RADIO_DASH_POS; 2870 2871 reg_val |= IWX_CSR_HW_REV_STEP(sc->sc_hw_rev) << 2872 IWX_CSR_HW_IF_CONFIG_REG_POS_MAC_STEP; 2873 reg_val |= IWX_CSR_HW_REV_DASH(sc->sc_hw_rev) << 2874 IWX_CSR_HW_IF_CONFIG_REG_POS_MAC_DASH; 2875 2876 /* radio configuration */ 2877 reg_val |= radio_cfg_type << IWX_CSR_HW_IF_CONFIG_REG_POS_PHY_TYPE; 2878 reg_val |= radio_cfg_step << IWX_CSR_HW_IF_CONFIG_REG_POS_PHY_STEP; 2879 reg_val |= radio_cfg_dash << IWX_CSR_HW_IF_CONFIG_REG_POS_PHY_DASH; 2880 2881 mask = IWX_CSR_HW_IF_CONFIG_REG_MSK_MAC_DASH | 2882 IWX_CSR_HW_IF_CONFIG_REG_MSK_MAC_STEP | 2883 IWX_CSR_HW_IF_CONFIG_REG_MSK_PHY_STEP | 2884 IWX_CSR_HW_IF_CONFIG_REG_MSK_PHY_DASH | 2885 IWX_CSR_HW_IF_CONFIG_REG_MSK_PHY_TYPE | 2886 IWX_CSR_HW_IF_CONFIG_REG_BIT_RADIO_SI | 2887 IWX_CSR_HW_IF_CONFIG_REG_BIT_MAC_SI; 2888 2889 val = IWX_READ(sc, IWX_CSR_HW_IF_CONFIG_REG); 2890 val &= ~mask; 2891 val |= reg_val; 2892 IWX_WRITE(sc, IWX_CSR_HW_IF_CONFIG_REG, val); 2893 } 2894 2895 static int 2896 iwx_nic_rx_init(struct iwx_softc *sc) 2897 { 2898 IWX_WRITE_1(sc, IWX_CSR_INT_COALESCING, IWX_HOST_INT_TIMEOUT_DEF); 2899 2900 /* 2901 * We don't configure the RFH; the firmware will do that. 2902 * Rx descriptors are set when firmware sends an ALIVE interrupt. 2903 */ 2904 return 0; 2905 } 2906 2907 static int 2908 iwx_nic_init(struct iwx_softc *sc) 2909 { 2910 int err; 2911 2912 iwx_apm_init(sc); 2913 if (sc->sc_device_family < IWX_DEVICE_FAMILY_AX210) 2914 iwx_nic_config(sc); 2915 2916 err = iwx_nic_rx_init(sc); 2917 if (err) 2918 return err; 2919 2920 IWX_SETBITS(sc, IWX_CSR_MAC_SHADOW_REG_CTRL, 0x800fffff); 2921 2922 return 0; 2923 } 2924 2925 /* Map ieee80211_edca_ac categories to firmware Tx FIFO. */ 2926 const uint8_t iwx_ac_to_tx_fifo[] = { 2927 IWX_GEN2_EDCA_TX_FIFO_BE, 2928 IWX_GEN2_EDCA_TX_FIFO_BK, 2929 IWX_GEN2_EDCA_TX_FIFO_VI, 2930 IWX_GEN2_EDCA_TX_FIFO_VO, 2931 }; 2932 2933 static int 2934 iwx_enable_txq(struct iwx_softc *sc, int sta_id, int qid, int tid, 2935 int num_slots) 2936 { 2937 struct iwx_rx_packet *pkt; 2938 struct iwx_tx_queue_cfg_rsp *resp; 2939 struct iwx_tx_queue_cfg_cmd cmd_v0; 2940 struct iwx_scd_queue_cfg_cmd cmd_v3; 2941 struct iwx_host_cmd hcmd = { 2942 .flags = IWX_CMD_WANT_RESP, 2943 .resp_pkt_len = sizeof(*pkt) + sizeof(*resp), 2944 }; 2945 struct iwx_tx_ring *ring = &sc->txq[qid]; 2946 int err, fwqid, cmd_ver; 2947 uint32_t wr_idx; 2948 size_t resp_len; 2949 2950 DPRINTF(("%s: tid=%i\n", __func__, tid)); 2951 DPRINTF(("%s: qid=%i\n", __func__, qid)); 2952 iwx_reset_tx_ring(sc, ring); 2953 2954 cmd_ver = iwx_lookup_cmd_ver(sc, IWX_DATA_PATH_GROUP, 2955 IWX_SCD_QUEUE_CONFIG_CMD); 2956 if (cmd_ver == 0 || cmd_ver == IWX_FW_CMD_VER_UNKNOWN) { 2957 memset(&cmd_v0, 0, sizeof(cmd_v0)); 2958 cmd_v0.sta_id = sta_id; 2959 cmd_v0.tid = tid; 2960 cmd_v0.flags = htole16(IWX_TX_QUEUE_CFG_ENABLE_QUEUE); 2961 cmd_v0.cb_size = htole32(IWX_TFD_QUEUE_CB_SIZE(num_slots)); 2962 cmd_v0.byte_cnt_addr = htole64(ring->bc_tbl.paddr); 2963 cmd_v0.tfdq_addr = htole64(ring->desc_dma.paddr); 2964 hcmd.id = IWX_SCD_QUEUE_CFG; 2965 hcmd.data[0] = &cmd_v0; 2966 hcmd.len[0] = sizeof(cmd_v0); 2967 } else if (cmd_ver == 3) { 2968 memset(&cmd_v3, 0, sizeof(cmd_v3)); 2969 cmd_v3.operation = htole32(IWX_SCD_QUEUE_ADD); 2970 cmd_v3.u.add.tfdq_dram_addr = htole64(ring->desc_dma.paddr); 2971 cmd_v3.u.add.bc_dram_addr = htole64(ring->bc_tbl.paddr); 2972 cmd_v3.u.add.cb_size = htole32(IWX_TFD_QUEUE_CB_SIZE(num_slots)); 2973 cmd_v3.u.add.flags = htole32(0); 2974 cmd_v3.u.add.sta_mask = htole32(1 << sta_id); 2975 cmd_v3.u.add.tid = tid; 2976 hcmd.id = IWX_WIDE_ID(IWX_DATA_PATH_GROUP, 2977 IWX_SCD_QUEUE_CONFIG_CMD); 2978 hcmd.data[0] = &cmd_v3; 2979 hcmd.len[0] = sizeof(cmd_v3); 2980 } else { 2981 printf("%s: unsupported SCD_QUEUE_CFG command version %d\n", 2982 DEVNAME(sc), cmd_ver); 2983 return ENOTSUP; 2984 } 2985 2986 err = iwx_send_cmd(sc, &hcmd); 2987 if (err) 2988 return err; 2989 2990 pkt = hcmd.resp_pkt; 2991 if (!pkt || (pkt->hdr.flags & IWX_CMD_FAILED_MSK)) { 2992 err = EIO; 2993 goto out; 2994 } 2995 2996 resp_len = iwx_rx_packet_payload_len(pkt); 2997 if (resp_len != sizeof(*resp)) { 2998 err = EIO; 2999 goto out; 3000 } 3001 3002 resp = (void *)pkt->data; 3003 fwqid = le16toh(resp->queue_number); 3004 wr_idx = le16toh(resp->write_pointer); 3005 3006 /* Unlike iwlwifi, we do not support dynamic queue ID assignment. */ 3007 if (fwqid != qid) { 3008 DPRINTF(("%s: === fwqid != qid\n", __func__)); 3009 err = EIO; 3010 goto out; 3011 } 3012 3013 if (wr_idx != ring->cur_hw) { 3014 DPRINTF(("%s: === (wr_idx != ring->cur_hw)\n", __func__)); 3015 err = EIO; 3016 goto out; 3017 } 3018 3019 sc->qenablemsk |= (1 << qid); 3020 ring->tid = tid; 3021 out: 3022 iwx_free_resp(sc, &hcmd); 3023 return err; 3024 } 3025 3026 static int 3027 iwx_disable_txq(struct iwx_softc *sc, int sta_id, int qid, uint8_t tid) 3028 { 3029 struct iwx_rx_packet *pkt; 3030 struct iwx_tx_queue_cfg_rsp *resp; 3031 struct iwx_tx_queue_cfg_cmd cmd_v0; 3032 struct iwx_scd_queue_cfg_cmd cmd_v3; 3033 struct iwx_host_cmd hcmd = { 3034 .flags = IWX_CMD_WANT_RESP, 3035 .resp_pkt_len = sizeof(*pkt) + sizeof(*resp), 3036 }; 3037 struct iwx_tx_ring *ring = &sc->txq[qid]; 3038 int err, cmd_ver; 3039 3040 cmd_ver = iwx_lookup_cmd_ver(sc, IWX_DATA_PATH_GROUP, 3041 IWX_SCD_QUEUE_CONFIG_CMD); 3042 if (cmd_ver == 0 || cmd_ver == IWX_FW_CMD_VER_UNKNOWN) { 3043 memset(&cmd_v0, 0, sizeof(cmd_v0)); 3044 cmd_v0.sta_id = sta_id; 3045 cmd_v0.tid = tid; 3046 cmd_v0.flags = htole16(0); /* clear "queue enabled" flag */ 3047 cmd_v0.cb_size = htole32(0); 3048 cmd_v0.byte_cnt_addr = htole64(0); 3049 cmd_v0.tfdq_addr = htole64(0); 3050 hcmd.id = IWX_SCD_QUEUE_CFG; 3051 hcmd.data[0] = &cmd_v0; 3052 hcmd.len[0] = sizeof(cmd_v0); 3053 } else if (cmd_ver == 3) { 3054 memset(&cmd_v3, 0, sizeof(cmd_v3)); 3055 cmd_v3.operation = htole32(IWX_SCD_QUEUE_REMOVE); 3056 cmd_v3.u.remove.sta_mask = htole32(1 << sta_id); 3057 cmd_v3.u.remove.tid = tid; 3058 hcmd.id = IWX_WIDE_ID(IWX_DATA_PATH_GROUP, 3059 IWX_SCD_QUEUE_CONFIG_CMD); 3060 hcmd.data[0] = &cmd_v3; 3061 hcmd.len[0] = sizeof(cmd_v3); 3062 } else { 3063 printf("%s: unsupported SCD_QUEUE_CFG command version %d\n", 3064 DEVNAME(sc), cmd_ver); 3065 return ENOTSUP; 3066 } 3067 3068 err = iwx_send_cmd(sc, &hcmd); 3069 if (err) 3070 return err; 3071 3072 pkt = hcmd.resp_pkt; 3073 if (!pkt || (pkt->hdr.flags & IWX_CMD_FAILED_MSK)) { 3074 err = EIO; 3075 goto out; 3076 } 3077 3078 sc->qenablemsk &= ~(1 << qid); 3079 iwx_reset_tx_ring(sc, ring); 3080 out: 3081 iwx_free_resp(sc, &hcmd); 3082 return err; 3083 } 3084 3085 static void 3086 iwx_post_alive(struct iwx_softc *sc) 3087 { 3088 int txcmd_ver; 3089 3090 iwx_ict_reset(sc); 3091 3092 txcmd_ver = iwx_lookup_notif_ver(sc, IWX_LONG_GROUP, IWX_TX_CMD) ; 3093 if (txcmd_ver != IWX_FW_CMD_VER_UNKNOWN && txcmd_ver > 6) 3094 sc->sc_rate_n_flags_version = 2; 3095 else 3096 sc->sc_rate_n_flags_version = 1; 3097 3098 txcmd_ver = iwx_lookup_cmd_ver(sc, IWX_LONG_GROUP, IWX_TX_CMD); 3099 } 3100 3101 static int 3102 iwx_schedule_session_protection(struct iwx_softc *sc, struct iwx_node *in, 3103 uint32_t duration_tu) 3104 { 3105 3106 struct iwx_session_prot_cmd cmd = { 3107 .id_and_color = htole32(IWX_FW_CMD_ID_AND_COLOR(in->in_id, 3108 in->in_color)), 3109 .action = htole32(IWX_FW_CTXT_ACTION_ADD), 3110 .conf_id = htole32(IWX_SESSION_PROTECT_CONF_ASSOC), 3111 .duration_tu = htole32(duration_tu), 3112 }; 3113 uint32_t cmd_id; 3114 int err; 3115 3116 cmd_id = iwx_cmd_id(IWX_SESSION_PROTECTION_CMD, IWX_MAC_CONF_GROUP, 0); 3117 err = iwx_send_cmd_pdu(sc, cmd_id, 0, sizeof(cmd), &cmd); 3118 if (!err) 3119 sc->sc_flags |= IWX_FLAG_TE_ACTIVE; 3120 return err; 3121 } 3122 3123 static void 3124 iwx_unprotect_session(struct iwx_softc *sc, struct iwx_node *in) 3125 { 3126 struct iwx_session_prot_cmd cmd = { 3127 .id_and_color = htole32(IWX_FW_CMD_ID_AND_COLOR(in->in_id, 3128 in->in_color)), 3129 .action = htole32(IWX_FW_CTXT_ACTION_REMOVE), 3130 .conf_id = htole32(IWX_SESSION_PROTECT_CONF_ASSOC), 3131 .duration_tu = 0, 3132 }; 3133 uint32_t cmd_id; 3134 3135 /* Do nothing if the time event has already ended. */ 3136 if ((sc->sc_flags & IWX_FLAG_TE_ACTIVE) == 0) 3137 return; 3138 3139 cmd_id = iwx_cmd_id(IWX_SESSION_PROTECTION_CMD, IWX_MAC_CONF_GROUP, 0); 3140 if (iwx_send_cmd_pdu(sc, cmd_id, 0, sizeof(cmd), &cmd) == 0) 3141 sc->sc_flags &= ~IWX_FLAG_TE_ACTIVE; 3142 } 3143 3144 /* 3145 * NVM read access and content parsing. We do not support 3146 * external NVM or writing NVM. 3147 */ 3148 3149 static uint8_t 3150 iwx_fw_valid_tx_ant(struct iwx_softc *sc) 3151 { 3152 uint8_t tx_ant; 3153 3154 tx_ant = ((sc->sc_fw_phy_config & IWX_FW_PHY_CFG_TX_CHAIN) 3155 >> IWX_FW_PHY_CFG_TX_CHAIN_POS); 3156 3157 if (sc->sc_nvm.valid_tx_ant) 3158 tx_ant &= sc->sc_nvm.valid_tx_ant; 3159 3160 return tx_ant; 3161 } 3162 3163 static uint8_t 3164 iwx_fw_valid_rx_ant(struct iwx_softc *sc) 3165 { 3166 uint8_t rx_ant; 3167 3168 rx_ant = ((sc->sc_fw_phy_config & IWX_FW_PHY_CFG_RX_CHAIN) 3169 >> IWX_FW_PHY_CFG_RX_CHAIN_POS); 3170 3171 if (sc->sc_nvm.valid_rx_ant) 3172 rx_ant &= sc->sc_nvm.valid_rx_ant; 3173 3174 return rx_ant; 3175 } 3176 3177 static void 3178 iwx_init_channel_map(struct ieee80211com *ic, int maxchans, int *nchans, 3179 struct ieee80211_channel chans[]) 3180 { 3181 struct iwx_softc *sc = ic->ic_softc; 3182 struct iwx_nvm_data *data = &sc->sc_nvm; 3183 uint8_t bands[IEEE80211_MODE_BYTES]; 3184 const uint8_t *nvm_channels; 3185 uint32_t ch_flags; 3186 int ch_idx, nchan; 3187 3188 if (sc->sc_uhb_supported) { 3189 nchan = nitems(iwx_nvm_channels_uhb); 3190 nvm_channels = iwx_nvm_channels_uhb; 3191 } else { 3192 nchan = nitems(iwx_nvm_channels_8000); 3193 nvm_channels = iwx_nvm_channels_8000; 3194 } 3195 3196 /* 2.4Ghz; 1-13: 11b/g channels. */ 3197 if (!data->sku_cap_band_24GHz_enable) 3198 goto band_5; 3199 3200 memset(bands, 0, sizeof(bands)); 3201 setbit(bands, IEEE80211_MODE_11B); 3202 setbit(bands, IEEE80211_MODE_11G); 3203 setbit(bands, IEEE80211_MODE_11NG); 3204 for (ch_idx = 0; 3205 ch_idx < IWX_NUM_2GHZ_CHANNELS && ch_idx < nchan; 3206 ch_idx++) { 3207 3208 uint32_t nflags = 0; 3209 int cflags = 0; 3210 3211 if (sc->sc_rsp_vers == IWX_FBSD_RSP_V4) { 3212 ch_flags = le32_to_cpup( 3213 sc->sc_rsp_info.rsp_v4.regulatory.channel_profile + ch_idx); 3214 } else { 3215 ch_flags = le16_to_cpup( 3216 sc->sc_rsp_info.rsp_v3.regulatory.channel_profile + ch_idx); 3217 } 3218 if ((ch_flags & IWX_NVM_CHANNEL_VALID) == 0) 3219 continue; 3220 3221 if ((ch_flags & IWX_NVM_CHANNEL_40MHZ) != 0) 3222 cflags |= NET80211_CBW_FLAG_HT40; 3223 3224 /* XXX-BZ nflags RADAR/DFS/INDOOR */ 3225 3226 /* error = */ ieee80211_add_channel_cbw(chans, maxchans, nchans, 3227 nvm_channels[ch_idx], 3228 ieee80211_ieee2mhz(nvm_channels[ch_idx], IEEE80211_CHAN_B), 3229 /* max_power IWL_DEFAULT_MAX_TX_POWER */ 22, 3230 nflags, bands, cflags); 3231 } 3232 3233 band_5: 3234 /* 5Ghz */ 3235 if (!data->sku_cap_band_52GHz_enable) 3236 goto band_6; 3237 3238 3239 memset(bands, 0, sizeof(bands)); 3240 setbit(bands, IEEE80211_MODE_11A); 3241 setbit(bands, IEEE80211_MODE_11NA); 3242 setbit(bands, IEEE80211_MODE_VHT_5GHZ); 3243 3244 for (ch_idx = IWX_NUM_2GHZ_CHANNELS; 3245 ch_idx < (IWX_NUM_2GHZ_CHANNELS + IWX_NUM_5GHZ_CHANNELS) && ch_idx < nchan; 3246 ch_idx++) { 3247 uint32_t nflags = 0; 3248 int cflags = 0; 3249 3250 if (sc->sc_rsp_vers == IWX_FBSD_RSP_V4) 3251 ch_flags = le32_to_cpup( 3252 sc->sc_rsp_info.rsp_v4.regulatory.channel_profile + ch_idx); 3253 else 3254 ch_flags = le16_to_cpup( 3255 sc->sc_rsp_info.rsp_v3.regulatory.channel_profile + ch_idx); 3256 3257 if ((ch_flags & IWX_NVM_CHANNEL_VALID) == 0) 3258 continue; 3259 3260 if ((ch_flags & IWX_NVM_CHANNEL_40MHZ) != 0) 3261 cflags |= NET80211_CBW_FLAG_HT40; 3262 if ((ch_flags & IWX_NVM_CHANNEL_80MHZ) != 0) 3263 cflags |= NET80211_CBW_FLAG_VHT80; 3264 if ((ch_flags & IWX_NVM_CHANNEL_160MHZ) != 0) 3265 cflags |= NET80211_CBW_FLAG_VHT160; 3266 3267 /* XXX-BZ nflags RADAR/DFS/INDOOR */ 3268 3269 /* error = */ ieee80211_add_channel_cbw(chans, maxchans, nchans, 3270 nvm_channels[ch_idx], 3271 ieee80211_ieee2mhz(nvm_channels[ch_idx], IEEE80211_CHAN_A), 3272 /* max_power IWL_DEFAULT_MAX_TX_POWER */ 22, 3273 nflags, bands, cflags); 3274 } 3275 band_6: 3276 /* 6GHz one day ... */ 3277 return; 3278 } 3279 3280 static int 3281 iwx_mimo_enabled(struct iwx_softc *sc) 3282 { 3283 3284 return !sc->sc_nvm.sku_cap_mimo_disable; 3285 } 3286 3287 static void 3288 iwx_init_reorder_buffer(struct iwx_reorder_buffer *reorder_buf, 3289 uint16_t ssn, uint16_t buf_size) 3290 { 3291 reorder_buf->head_sn = ssn; 3292 reorder_buf->num_stored = 0; 3293 reorder_buf->buf_size = buf_size; 3294 reorder_buf->last_amsdu = 0; 3295 reorder_buf->last_sub_index = 0; 3296 reorder_buf->removed = 0; 3297 reorder_buf->valid = 0; 3298 reorder_buf->consec_oldsn_drops = 0; 3299 reorder_buf->consec_oldsn_ampdu_gp2 = 0; 3300 reorder_buf->consec_oldsn_prev_drop = 0; 3301 } 3302 3303 static void 3304 iwx_clear_reorder_buffer(struct iwx_softc *sc, struct iwx_rxba_data *rxba) 3305 { 3306 struct iwx_reorder_buffer *reorder_buf = &rxba->reorder_buf; 3307 3308 reorder_buf->removed = 1; 3309 rxba->baid = IWX_RX_REORDER_DATA_INVALID_BAID; 3310 } 3311 3312 #define IWX_MAX_RX_BA_SESSIONS 16 3313 3314 static struct iwx_rxba_data * 3315 iwx_find_rxba_data(struct iwx_softc *sc, uint8_t tid) 3316 { 3317 int i; 3318 3319 for (i = 0; i < nitems(sc->sc_rxba_data); i++) { 3320 if (sc->sc_rxba_data[i].baid == 3321 IWX_RX_REORDER_DATA_INVALID_BAID) 3322 continue; 3323 if (sc->sc_rxba_data[i].tid == tid) 3324 return &sc->sc_rxba_data[i]; 3325 } 3326 3327 return NULL; 3328 } 3329 3330 static int 3331 iwx_sta_rx_agg_baid_cfg_cmd(struct iwx_softc *sc, struct ieee80211_node *ni, 3332 uint8_t tid, uint16_t ssn, uint16_t winsize, int timeout_val, int start, 3333 uint8_t *baid) 3334 { 3335 struct iwx_rx_baid_cfg_cmd cmd; 3336 uint32_t new_baid = 0; 3337 int err; 3338 3339 IWX_ASSERT_LOCKED(sc); 3340 3341 memset(&cmd, 0, sizeof(cmd)); 3342 3343 if (start) { 3344 cmd.action = IWX_RX_BAID_ACTION_ADD; 3345 cmd.alloc.sta_id_mask = htole32(1 << IWX_STATION_ID); 3346 cmd.alloc.tid = tid; 3347 cmd.alloc.ssn = htole16(ssn); 3348 cmd.alloc.win_size = htole16(winsize); 3349 } else { 3350 struct iwx_rxba_data *rxba; 3351 3352 rxba = iwx_find_rxba_data(sc, tid); 3353 if (rxba == NULL) 3354 return ENOENT; 3355 *baid = rxba->baid; 3356 3357 cmd.action = IWX_RX_BAID_ACTION_REMOVE; 3358 if (iwx_lookup_cmd_ver(sc, IWX_DATA_PATH_GROUP, 3359 IWX_RX_BAID_ALLOCATION_CONFIG_CMD) == 1) { 3360 cmd.remove_v1.baid = rxba->baid; 3361 } else { 3362 cmd.remove.sta_id_mask = htole32(1 << IWX_STATION_ID); 3363 cmd.remove.tid = tid; 3364 } 3365 } 3366 3367 err = iwx_send_cmd_pdu_status(sc, IWX_WIDE_ID(IWX_DATA_PATH_GROUP, 3368 IWX_RX_BAID_ALLOCATION_CONFIG_CMD), sizeof(cmd), &cmd, &new_baid); 3369 if (err) 3370 return err; 3371 3372 if (start) { 3373 if (new_baid >= nitems(sc->sc_rxba_data)) 3374 return ERANGE; 3375 *baid = new_baid; 3376 } 3377 3378 return 0; 3379 } 3380 3381 static void 3382 iwx_sta_rx_agg(struct iwx_softc *sc, struct ieee80211_node *ni, uint8_t tid, 3383 uint16_t ssn, uint16_t winsize, int timeout_val, int start) 3384 { 3385 int err; 3386 struct iwx_rxba_data *rxba = NULL; 3387 uint8_t baid = 0; 3388 3389 if (start && sc->sc_rx_ba_sessions >= IWX_MAX_RX_BA_SESSIONS) { 3390 return; 3391 } 3392 3393 if (isset(sc->sc_enabled_capa, IWX_UCODE_TLV_CAPA_BAID_ML_SUPPORT)) { 3394 err = iwx_sta_rx_agg_baid_cfg_cmd(sc, ni, tid, ssn, winsize, 3395 timeout_val, start, &baid); 3396 } else { 3397 panic("sta_rx_agg unsupported hw"); 3398 } 3399 if (err) { 3400 DPRINTF(("%s: iwx_sta_rx_agg_sta err=%i\n", __func__, err)); 3401 return; 3402 } else 3403 DPRINTF(("%s: iwx_sta_rx_agg_sta success\n", __func__)); 3404 3405 rxba = &sc->sc_rxba_data[baid]; 3406 3407 /* Deaggregation is done in hardware. */ 3408 if (start) { 3409 if (rxba->baid != IWX_RX_REORDER_DATA_INVALID_BAID) { 3410 return; 3411 } 3412 rxba->sta_id = IWX_STATION_ID; 3413 rxba->tid = tid; 3414 rxba->baid = baid; 3415 rxba->timeout = timeout_val; 3416 getmicrouptime(&rxba->last_rx); 3417 iwx_init_reorder_buffer(&rxba->reorder_buf, ssn, 3418 winsize); 3419 if (timeout_val != 0) { 3420 DPRINTF(("%s: timeout_val != 0\n", __func__)); 3421 return; 3422 } 3423 } else 3424 iwx_clear_reorder_buffer(sc, rxba); 3425 3426 if (start) { 3427 sc->sc_rx_ba_sessions++; 3428 } else if (sc->sc_rx_ba_sessions > 0) 3429 sc->sc_rx_ba_sessions--; 3430 } 3431 3432 /** 3433 * @brief Allocate an A-MPDU / aggregation session for the given node and TID. 3434 * 3435 * This allocates a TX queue specifically for that TID. 3436 * 3437 * Note that this routine currently doesn't return any status/errors, 3438 * so the caller can't know if the aggregation session was setup or not. 3439 */ 3440 static void 3441 iwx_sta_tx_agg_start(struct iwx_softc *sc, struct ieee80211_node *ni, 3442 uint8_t tid) 3443 { 3444 int err, qid; 3445 3446 qid = sc->aggqid[tid]; 3447 if (qid == 0) { 3448 /* Firmware should pick the next unused Tx queue. */ 3449 qid = fls(sc->qenablemsk); 3450 } 3451 3452 DPRINTF(("%s: qid=%i\n", __func__, qid)); 3453 3454 /* 3455 * Simply enable the queue. 3456 * Firmware handles Tx Ba session setup and teardown. 3457 */ 3458 if ((sc->qenablemsk & (1 << qid)) == 0) { 3459 if (!iwx_nic_lock(sc)) { 3460 return; 3461 } 3462 err = iwx_enable_txq(sc, IWX_STATION_ID, qid, tid, 3463 IWX_TX_RING_COUNT); 3464 iwx_nic_unlock(sc); 3465 if (err) { 3466 printf("%s: could not enable Tx queue %d " 3467 "(error %d)\n", DEVNAME(sc), qid, err); 3468 return; 3469 } 3470 } 3471 ni->ni_tx_ampdu[tid].txa_flags = IEEE80211_AGGR_RUNNING; 3472 DPRINTF(("%s: will set sc->aggqid[%i]=%i\n", __func__, tid, qid)); 3473 sc->aggqid[tid] = qid; 3474 } 3475 3476 static void 3477 iwx_ba_rx_task(void *arg, int npending __unused) 3478 { 3479 struct iwx_softc *sc = arg; 3480 struct ieee80211com *ic = &sc->sc_ic; 3481 struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); 3482 struct ieee80211_node *ni = vap->iv_bss; 3483 int tid; 3484 3485 IWX_LOCK(sc); 3486 for (tid = 0; tid < IWX_MAX_TID_COUNT; tid++) { 3487 if (sc->sc_flags & IWX_FLAG_SHUTDOWN) 3488 break; 3489 if (sc->ba_rx.start_tidmask & (1 << tid)) { 3490 struct iwx_rx_ba *ba = &sc->ni_rx_ba[tid]; 3491 DPRINTF(("%s: ba->ba_flags=%x\n", __func__, 3492 ba->ba_flags)); 3493 if (ba->ba_flags == IWX_BA_DONE) { 3494 DPRINTF(("%s: ampdu for tid %i already added\n", 3495 __func__, tid)); 3496 break; 3497 } 3498 3499 DPRINTF(("%s: ampdu rx start for tid %i\n", __func__, 3500 tid)); 3501 iwx_sta_rx_agg(sc, ni, tid, ba->ba_winstart, 3502 ba->ba_winsize, ba->ba_timeout_val, 1); 3503 sc->ba_rx.start_tidmask &= ~(1 << tid); 3504 ba->ba_flags = IWX_BA_DONE; 3505 } else if (sc->ba_rx.stop_tidmask & (1 << tid)) { 3506 iwx_sta_rx_agg(sc, ni, tid, 0, 0, 0, 0); 3507 sc->ba_rx.stop_tidmask &= ~(1 << tid); 3508 } 3509 } 3510 IWX_UNLOCK(sc); 3511 } 3512 3513 /** 3514 * @brief Task called to setup a deferred block-ack session. 3515 * 3516 * This sets up any/all pending blockack sessions as defined 3517 * in sc->ba_tx.start_tidmask. 3518 * 3519 * Note: the call to iwx_sta_tx_agg_start() isn't being error checked. 3520 */ 3521 static void 3522 iwx_ba_tx_task(void *arg, int npending __unused) 3523 { 3524 struct iwx_softc *sc = arg; 3525 struct ieee80211com *ic = &sc->sc_ic; 3526 struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); 3527 struct ieee80211_node *ni = vap->iv_bss; 3528 uint32_t started_mask = 0; 3529 int tid; 3530 3531 IWX_LOCK(sc); 3532 for (tid = 0; tid < IWX_MAX_TID_COUNT; tid++) { 3533 const struct ieee80211_tx_ampdu *tap; 3534 3535 if (sc->sc_flags & IWX_FLAG_SHUTDOWN) 3536 break; 3537 tap = &ni->ni_tx_ampdu[tid]; 3538 if (IEEE80211_AMPDU_RUNNING(tap)) 3539 break; 3540 if (sc->ba_tx.start_tidmask & (1 << tid)) { 3541 IWX_DPRINTF(sc, IWX_DEBUG_AMPDU_MGMT, 3542 "%s: ampdu tx start for tid %i\n", __func__, tid); 3543 iwx_sta_tx_agg_start(sc, ni, tid); 3544 sc->ba_tx.start_tidmask &= ~(1 << tid); 3545 started_mask |= (1 << tid); 3546 } 3547 } 3548 3549 IWX_UNLOCK(sc); 3550 3551 /* Iterate over the sessions we started; mark them as active */ 3552 for (tid = 0; tid < IWX_MAX_TID_COUNT; tid++) { 3553 if (started_mask & (1 << tid)) { 3554 IWX_DPRINTF(sc, IWX_DEBUG_AMPDU_MGMT, 3555 "%s: informing net80211 to start ampdu on tid %i\n", 3556 __func__, tid); 3557 ieee80211_ampdu_tx_request_active_ext(ni, tid, 1); 3558 } 3559 } 3560 } 3561 3562 static void 3563 iwx_set_mac_addr_from_csr(struct iwx_softc *sc, struct iwx_nvm_data *data) 3564 { 3565 uint32_t mac_addr0, mac_addr1; 3566 3567 memset(data->hw_addr, 0, sizeof(data->hw_addr)); 3568 3569 if (!iwx_nic_lock(sc)) 3570 return; 3571 3572 mac_addr0 = htole32(IWX_READ(sc, IWX_CSR_MAC_ADDR0_STRAP(sc))); 3573 mac_addr1 = htole32(IWX_READ(sc, IWX_CSR_MAC_ADDR1_STRAP(sc))); 3574 3575 iwx_flip_hw_address(mac_addr0, mac_addr1, data->hw_addr); 3576 3577 /* If OEM fused a valid address, use it instead of the one in OTP. */ 3578 if (iwx_is_valid_mac_addr(data->hw_addr)) { 3579 iwx_nic_unlock(sc); 3580 return; 3581 } 3582 3583 mac_addr0 = htole32(IWX_READ(sc, IWX_CSR_MAC_ADDR0_OTP(sc))); 3584 mac_addr1 = htole32(IWX_READ(sc, IWX_CSR_MAC_ADDR1_OTP(sc))); 3585 3586 iwx_flip_hw_address(mac_addr0, mac_addr1, data->hw_addr); 3587 3588 iwx_nic_unlock(sc); 3589 } 3590 3591 static int 3592 iwx_is_valid_mac_addr(const uint8_t *addr) 3593 { 3594 static const uint8_t reserved_mac[] = { 3595 0x02, 0xcc, 0xaa, 0xff, 0xee, 0x00 3596 }; 3597 3598 return (memcmp(reserved_mac, addr, ETHER_ADDR_LEN) != 0 && 3599 memcmp(etherbroadcastaddr, addr, sizeof(etherbroadcastaddr)) != 0 && 3600 memcmp(etheranyaddr, addr, sizeof(etheranyaddr)) != 0 && 3601 !ETHER_IS_MULTICAST(addr)); 3602 } 3603 3604 static void 3605 iwx_flip_hw_address(uint32_t mac_addr0, uint32_t mac_addr1, uint8_t *dest) 3606 { 3607 const uint8_t *hw_addr; 3608 3609 hw_addr = (const uint8_t *)&mac_addr0; 3610 dest[0] = hw_addr[3]; 3611 dest[1] = hw_addr[2]; 3612 dest[2] = hw_addr[1]; 3613 dest[3] = hw_addr[0]; 3614 3615 hw_addr = (const uint8_t *)&mac_addr1; 3616 dest[4] = hw_addr[1]; 3617 dest[5] = hw_addr[0]; 3618 } 3619 3620 static int 3621 iwx_nvm_get(struct iwx_softc *sc) 3622 { 3623 struct iwx_nvm_get_info cmd = {}; 3624 struct iwx_nvm_data *nvm = &sc->sc_nvm; 3625 struct iwx_host_cmd hcmd = { 3626 .flags = IWX_CMD_WANT_RESP | IWX_CMD_SEND_IN_RFKILL, 3627 .data = { &cmd, }, 3628 .len = { sizeof(cmd) }, 3629 .id = IWX_WIDE_ID(IWX_REGULATORY_AND_NVM_GROUP, 3630 IWX_NVM_GET_INFO) 3631 }; 3632 int err = 0; 3633 uint32_t mac_flags; 3634 /* 3635 * All the values in iwx_nvm_get_info_rsp v4 are the same as 3636 * in v3, except for the channel profile part of the 3637 * regulatory. So we can just access the new struct, with the 3638 * exception of the latter. 3639 */ 3640 struct iwx_nvm_get_info_rsp *rsp; 3641 struct iwx_nvm_get_info_rsp_v3 *rsp_v3; 3642 int v4 = isset(sc->sc_ucode_api, IWX_UCODE_TLV_API_REGULATORY_NVM_INFO); 3643 size_t resp_len = v4 ? sizeof(*rsp) : sizeof(*rsp_v3); 3644 3645 hcmd.resp_pkt_len = sizeof(struct iwx_rx_packet) + resp_len; 3646 err = iwx_send_cmd(sc, &hcmd); 3647 if (err) { 3648 printf("%s: failed to send cmd (error %d)", __func__, err); 3649 return err; 3650 } 3651 3652 if (iwx_rx_packet_payload_len(hcmd.resp_pkt) != resp_len) { 3653 printf("%s: iwx_rx_packet_payload_len=%d\n", __func__, 3654 iwx_rx_packet_payload_len(hcmd.resp_pkt)); 3655 printf("%s: resp_len=%zu\n", __func__, resp_len); 3656 err = EIO; 3657 goto out; 3658 } 3659 3660 memset(nvm, 0, sizeof(*nvm)); 3661 3662 iwx_set_mac_addr_from_csr(sc, nvm); 3663 if (!iwx_is_valid_mac_addr(nvm->hw_addr)) { 3664 printf("%s: no valid mac address was found\n", DEVNAME(sc)); 3665 err = EINVAL; 3666 goto out; 3667 } 3668 3669 rsp = (void *)hcmd.resp_pkt->data; 3670 3671 /* Initialize general data */ 3672 nvm->nvm_version = le16toh(rsp->general.nvm_version); 3673 nvm->n_hw_addrs = rsp->general.n_hw_addrs; 3674 3675 /* Initialize MAC sku data */ 3676 mac_flags = le32toh(rsp->mac_sku.mac_sku_flags); 3677 nvm->sku_cap_11ac_enable = 3678 !!(mac_flags & IWX_NVM_MAC_SKU_FLAGS_802_11AC_ENABLED); 3679 nvm->sku_cap_11n_enable = 3680 !!(mac_flags & IWX_NVM_MAC_SKU_FLAGS_802_11N_ENABLED); 3681 nvm->sku_cap_11ax_enable = 3682 !!(mac_flags & IWX_NVM_MAC_SKU_FLAGS_802_11AX_ENABLED); 3683 nvm->sku_cap_band_24GHz_enable = 3684 !!(mac_flags & IWX_NVM_MAC_SKU_FLAGS_BAND_2_4_ENABLED); 3685 nvm->sku_cap_band_52GHz_enable = 3686 !!(mac_flags & IWX_NVM_MAC_SKU_FLAGS_BAND_5_2_ENABLED); 3687 nvm->sku_cap_mimo_disable = 3688 !!(mac_flags & IWX_NVM_MAC_SKU_FLAGS_MIMO_DISABLED); 3689 3690 /* Initialize PHY sku data */ 3691 nvm->valid_tx_ant = (uint8_t)le32toh(rsp->phy_sku.tx_chains); 3692 nvm->valid_rx_ant = (uint8_t)le32toh(rsp->phy_sku.rx_chains); 3693 3694 if (le32toh(rsp->regulatory.lar_enabled) && 3695 isset(sc->sc_enabled_capa, IWX_UCODE_TLV_CAPA_LAR_SUPPORT)) { 3696 nvm->lar_enabled = 1; 3697 } 3698 3699 memcpy(&sc->sc_rsp_info, rsp, resp_len); 3700 if (v4) { 3701 sc->sc_rsp_vers = IWX_FBSD_RSP_V4; 3702 } else { 3703 sc->sc_rsp_vers = IWX_FBSD_RSP_V3; 3704 } 3705 out: 3706 iwx_free_resp(sc, &hcmd); 3707 return err; 3708 } 3709 3710 static int 3711 iwx_load_firmware(struct iwx_softc *sc) 3712 { 3713 struct iwx_fw_sects *fws; 3714 int err; 3715 3716 IWX_ASSERT_LOCKED(sc) 3717 3718 sc->sc_uc.uc_intr = 0; 3719 sc->sc_uc.uc_ok = 0; 3720 3721 fws = &sc->sc_fw.fw_sects[IWX_UCODE_TYPE_REGULAR]; 3722 if (sc->sc_device_family >= IWX_DEVICE_FAMILY_AX210) 3723 err = iwx_ctxt_info_gen3_init(sc, fws); 3724 else 3725 err = iwx_ctxt_info_init(sc, fws); 3726 if (err) { 3727 printf("%s: could not init context info\n", DEVNAME(sc)); 3728 return err; 3729 } 3730 3731 /* wait for the firmware to load */ 3732 err = msleep(&sc->sc_uc, &sc->sc_mtx, 0, "iwxuc", hz); 3733 if (err || !sc->sc_uc.uc_ok) { 3734 printf("%s: firmware upload failed, %d\n", DEVNAME(sc), err); 3735 iwx_ctxt_info_free_paging(sc); 3736 } 3737 3738 iwx_dma_contig_free(&sc->iml_dma); 3739 iwx_ctxt_info_free_fw_img(sc); 3740 3741 if (!sc->sc_uc.uc_ok) 3742 return EINVAL; 3743 3744 return err; 3745 } 3746 3747 static int 3748 iwx_start_fw(struct iwx_softc *sc) 3749 { 3750 int err; 3751 3752 IWX_WRITE(sc, IWX_CSR_INT, ~0); 3753 3754 iwx_disable_interrupts(sc); 3755 3756 /* make sure rfkill handshake bits are cleared */ 3757 IWX_WRITE(sc, IWX_CSR_UCODE_DRV_GP1_CLR, IWX_CSR_UCODE_SW_BIT_RFKILL); 3758 IWX_WRITE(sc, IWX_CSR_UCODE_DRV_GP1_CLR, 3759 IWX_CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED); 3760 3761 /* clear (again), then enable firmware load interrupt */ 3762 IWX_WRITE(sc, IWX_CSR_INT, ~0); 3763 3764 err = iwx_nic_init(sc); 3765 if (err) { 3766 printf("%s: unable to init nic\n", DEVNAME(sc)); 3767 return err; 3768 } 3769 3770 iwx_enable_fwload_interrupt(sc); 3771 3772 return iwx_load_firmware(sc); 3773 } 3774 3775 static int 3776 iwx_pnvm_handle_section(struct iwx_softc *sc, const uint8_t *data, 3777 size_t len) 3778 { 3779 const struct iwx_ucode_tlv *tlv; 3780 uint32_t sha1 = 0; 3781 uint16_t mac_type = 0, rf_id = 0; 3782 uint8_t *pnvm_data = NULL, *tmp; 3783 int hw_match = 0; 3784 uint32_t size = 0; 3785 int err; 3786 3787 while (len >= sizeof(*tlv)) { 3788 uint32_t tlv_len, tlv_type; 3789 3790 len -= sizeof(*tlv); 3791 tlv = (const void *)data; 3792 3793 tlv_len = le32toh(tlv->length); 3794 tlv_type = le32toh(tlv->type); 3795 3796 if (len < tlv_len) { 3797 printf("%s: invalid TLV len: %zd/%u\n", 3798 DEVNAME(sc), len, tlv_len); 3799 err = EINVAL; 3800 goto out; 3801 } 3802 3803 data += sizeof(*tlv); 3804 3805 switch (tlv_type) { 3806 case IWX_UCODE_TLV_PNVM_VERSION: 3807 if (tlv_len < sizeof(uint32_t)) 3808 break; 3809 3810 sha1 = le32_to_cpup((const uint32_t *)data); 3811 break; 3812 case IWX_UCODE_TLV_HW_TYPE: 3813 if (tlv_len < 2 * sizeof(uint16_t)) 3814 break; 3815 3816 if (hw_match) 3817 break; 3818 3819 mac_type = le16_to_cpup((const uint16_t *)data); 3820 rf_id = le16_to_cpup((const uint16_t *)(data + 3821 sizeof(uint16_t))); 3822 3823 if (mac_type == IWX_CSR_HW_REV_TYPE(sc->sc_hw_rev) && 3824 rf_id == IWX_CSR_HW_RFID_TYPE(sc->sc_hw_rf_id)) 3825 hw_match = 1; 3826 break; 3827 case IWX_UCODE_TLV_SEC_RT: { 3828 const struct iwx_pnvm_section *section; 3829 uint32_t data_len; 3830 3831 section = (const void *)data; 3832 data_len = tlv_len - sizeof(*section); 3833 3834 /* TODO: remove, this is a deprecated separator */ 3835 if (le32_to_cpup((const uint32_t *)data) == 0xddddeeee) 3836 break; 3837 3838 tmp = malloc(size + data_len, M_DEVBUF, 3839 M_WAITOK | M_ZERO); 3840 if (tmp == NULL) { 3841 err = ENOMEM; 3842 goto out; 3843 } 3844 // XXX:misha pnvm_data is NULL and size is 0 at first pass 3845 memcpy(tmp, pnvm_data, size); 3846 memcpy(tmp + size, section->data, data_len); 3847 free(pnvm_data, M_DEVBUF); 3848 pnvm_data = tmp; 3849 size += data_len; 3850 break; 3851 } 3852 case IWX_UCODE_TLV_PNVM_SKU: 3853 /* New PNVM section started, stop parsing. */ 3854 goto done; 3855 default: 3856 break; 3857 } 3858 3859 if (roundup(tlv_len, 4) > len) 3860 break; 3861 len -= roundup(tlv_len, 4); 3862 data += roundup(tlv_len, 4); 3863 } 3864 done: 3865 if (!hw_match || size == 0) { 3866 err = ENOENT; 3867 goto out; 3868 } 3869 3870 err = iwx_dma_contig_alloc(sc->sc_dmat, &sc->pnvm_dma, size, 1); 3871 if (err) { 3872 printf("%s: could not allocate DMA memory for PNVM\n", 3873 DEVNAME(sc)); 3874 err = ENOMEM; 3875 goto out; 3876 } 3877 memcpy(sc->pnvm_dma.vaddr, pnvm_data, size); 3878 iwx_ctxt_info_gen3_set_pnvm(sc); 3879 sc->sc_pnvm_ver = sha1; 3880 out: 3881 free(pnvm_data, M_DEVBUF); 3882 return err; 3883 } 3884 3885 static int 3886 iwx_pnvm_parse(struct iwx_softc *sc, const uint8_t *data, size_t len) 3887 { 3888 const struct iwx_ucode_tlv *tlv; 3889 3890 while (len >= sizeof(*tlv)) { 3891 uint32_t tlv_len, tlv_type; 3892 3893 len -= sizeof(*tlv); 3894 tlv = (const void *)data; 3895 3896 tlv_len = le32toh(tlv->length); 3897 tlv_type = le32toh(tlv->type); 3898 3899 if (len < tlv_len || roundup(tlv_len, 4) > len) 3900 return EINVAL; 3901 3902 if (tlv_type == IWX_UCODE_TLV_PNVM_SKU) { 3903 const struct iwx_sku_id *sku_id = 3904 (const void *)(data + sizeof(*tlv)); 3905 3906 data += sizeof(*tlv) + roundup(tlv_len, 4); 3907 len -= roundup(tlv_len, 4); 3908 3909 if (sc->sc_sku_id[0] == le32toh(sku_id->data[0]) && 3910 sc->sc_sku_id[1] == le32toh(sku_id->data[1]) && 3911 sc->sc_sku_id[2] == le32toh(sku_id->data[2]) && 3912 iwx_pnvm_handle_section(sc, data, len) == 0) 3913 return 0; 3914 } else { 3915 data += sizeof(*tlv) + roundup(tlv_len, 4); 3916 len -= roundup(tlv_len, 4); 3917 } 3918 } 3919 3920 return ENOENT; 3921 } 3922 3923 /* Make AX210 firmware loading context point at PNVM image in DMA memory. */ 3924 static void 3925 iwx_ctxt_info_gen3_set_pnvm(struct iwx_softc *sc) 3926 { 3927 struct iwx_prph_scratch *prph_scratch; 3928 struct iwx_prph_scratch_ctrl_cfg *prph_sc_ctrl; 3929 3930 prph_scratch = sc->prph_scratch_dma.vaddr; 3931 prph_sc_ctrl = &prph_scratch->ctrl_cfg; 3932 3933 prph_sc_ctrl->pnvm_cfg.pnvm_base_addr = htole64(sc->pnvm_dma.paddr); 3934 prph_sc_ctrl->pnvm_cfg.pnvm_size = htole32(sc->pnvm_dma.size); 3935 3936 bus_dmamap_sync(sc->sc_dmat, sc->pnvm_dma.map, BUS_DMASYNC_PREWRITE); 3937 } 3938 3939 /* 3940 * Load platform-NVM (non-volatile-memory) data from the filesystem. 3941 * This data apparently contains regulatory information and affects device 3942 * channel configuration. 3943 * The SKU of AX210 devices tells us which PNVM file section is needed. 3944 * Pre-AX210 devices store NVM data onboard. 3945 */ 3946 static int 3947 iwx_load_pnvm(struct iwx_softc *sc) 3948 { 3949 const int wait_flags = IWX_PNVM_COMPLETE; 3950 int err = 0; 3951 const struct firmware *pnvm; 3952 3953 if (sc->sc_sku_id[0] == 0 && 3954 sc->sc_sku_id[1] == 0 && 3955 sc->sc_sku_id[2] == 0) 3956 return 0; 3957 3958 if (sc->sc_pnvm_name) { 3959 if (sc->pnvm_dma.vaddr == NULL) { 3960 IWX_UNLOCK(sc); 3961 pnvm = firmware_get(sc->sc_pnvm_name); 3962 if (pnvm == NULL) { 3963 printf("%s: could not read %s (error %d)\n", 3964 DEVNAME(sc), sc->sc_pnvm_name, err); 3965 IWX_LOCK(sc); 3966 return EINVAL; 3967 } 3968 sc->sc_pnvm = pnvm; 3969 3970 err = iwx_pnvm_parse(sc, pnvm->data, pnvm->datasize); 3971 IWX_LOCK(sc); 3972 if (err && err != ENOENT) { 3973 return EINVAL; 3974 } 3975 } else 3976 iwx_ctxt_info_gen3_set_pnvm(sc); 3977 } 3978 3979 if (!iwx_nic_lock(sc)) { 3980 return EBUSY; 3981 } 3982 3983 /* 3984 * If we don't have a platform NVM file simply ask firmware 3985 * to proceed without it. 3986 */ 3987 3988 iwx_write_umac_prph(sc, IWX_UREG_DOORBELL_TO_ISR6, 3989 IWX_UREG_DOORBELL_TO_ISR6_PNVM); 3990 3991 /* Wait for the pnvm complete notification from firmware. */ 3992 while ((sc->sc_init_complete & wait_flags) != wait_flags) { 3993 err = msleep(&sc->sc_init_complete, &sc->sc_mtx, 0, "iwxinit", 2 * hz); 3994 if (err) 3995 break; 3996 } 3997 3998 iwx_nic_unlock(sc); 3999 4000 return err; 4001 } 4002 4003 static int 4004 iwx_send_tx_ant_cfg(struct iwx_softc *sc, uint8_t valid_tx_ant) 4005 { 4006 struct iwx_tx_ant_cfg_cmd tx_ant_cmd = { 4007 .valid = htole32(valid_tx_ant), 4008 }; 4009 4010 return iwx_send_cmd_pdu(sc, IWX_TX_ANT_CONFIGURATION_CMD, 4011 0, sizeof(tx_ant_cmd), &tx_ant_cmd); 4012 } 4013 4014 static int 4015 iwx_send_phy_cfg_cmd(struct iwx_softc *sc) 4016 { 4017 struct iwx_phy_cfg_cmd phy_cfg_cmd; 4018 4019 phy_cfg_cmd.phy_cfg = htole32(sc->sc_fw_phy_config); 4020 phy_cfg_cmd.calib_control.event_trigger = 4021 sc->sc_default_calib[IWX_UCODE_TYPE_REGULAR].event_trigger; 4022 phy_cfg_cmd.calib_control.flow_trigger = 4023 sc->sc_default_calib[IWX_UCODE_TYPE_REGULAR].flow_trigger; 4024 4025 return iwx_send_cmd_pdu(sc, IWX_PHY_CONFIGURATION_CMD, 0, 4026 sizeof(phy_cfg_cmd), &phy_cfg_cmd); 4027 } 4028 4029 static int 4030 iwx_send_dqa_cmd(struct iwx_softc *sc) 4031 { 4032 struct iwx_dqa_enable_cmd dqa_cmd = { 4033 .cmd_queue = htole32(IWX_DQA_CMD_QUEUE), 4034 }; 4035 uint32_t cmd_id; 4036 4037 cmd_id = iwx_cmd_id(IWX_DQA_ENABLE_CMD, IWX_DATA_PATH_GROUP, 0); 4038 return iwx_send_cmd_pdu(sc, cmd_id, 0, sizeof(dqa_cmd), &dqa_cmd); 4039 } 4040 4041 static int 4042 iwx_load_ucode_wait_alive(struct iwx_softc *sc) 4043 { 4044 int err; 4045 4046 IWX_UNLOCK(sc); 4047 err = iwx_read_firmware(sc); 4048 IWX_LOCK(sc); 4049 if (err) 4050 return err; 4051 4052 err = iwx_start_fw(sc); 4053 if (err) 4054 return err; 4055 4056 if (sc->sc_device_family >= IWX_DEVICE_FAMILY_AX210) { 4057 err = iwx_load_pnvm(sc); 4058 if (err) 4059 return err; 4060 } 4061 4062 iwx_post_alive(sc); 4063 4064 return 0; 4065 } 4066 4067 static int 4068 iwx_run_init_mvm_ucode(struct iwx_softc *sc, int readnvm) 4069 { 4070 const int wait_flags = IWX_INIT_COMPLETE; 4071 struct iwx_nvm_access_complete_cmd nvm_complete = {}; 4072 struct iwx_init_extended_cfg_cmd init_cfg = { 4073 .init_flags = htole32(IWX_INIT_NVM), 4074 }; 4075 4076 int err; 4077 4078 if ((sc->sc_flags & IWX_FLAG_RFKILL) && !readnvm) { 4079 printf("%s: radio is disabled by hardware switch\n", 4080 DEVNAME(sc)); 4081 return EPERM; 4082 } 4083 4084 sc->sc_init_complete = 0; 4085 err = iwx_load_ucode_wait_alive(sc); 4086 if (err) { 4087 IWX_DPRINTF(sc, IWX_DEBUG_FIRMWARE_TLV, 4088 "%s: failed to load init firmware\n", DEVNAME(sc)); 4089 return err; 4090 } else { 4091 IWX_DPRINTF(sc, IWX_DEBUG_FIRMWARE_TLV, 4092 "%s: successfully loaded init firmware\n", __func__); 4093 } 4094 4095 /* 4096 * Send init config command to mark that we are sending NVM 4097 * access commands 4098 */ 4099 err = iwx_send_cmd_pdu(sc, IWX_WIDE_ID(IWX_SYSTEM_GROUP, 4100 IWX_INIT_EXTENDED_CFG_CMD), 0, sizeof(init_cfg), &init_cfg); 4101 if (err) { 4102 printf("%s: IWX_INIT_EXTENDED_CFG_CMD error=%d\n", __func__, 4103 err); 4104 return err; 4105 } 4106 4107 err = iwx_send_cmd_pdu(sc, IWX_WIDE_ID(IWX_REGULATORY_AND_NVM_GROUP, 4108 IWX_NVM_ACCESS_COMPLETE), 0, sizeof(nvm_complete), &nvm_complete); 4109 if (err) { 4110 return err; 4111 } 4112 4113 /* Wait for the init complete notification from the firmware. */ 4114 while ((sc->sc_init_complete & wait_flags) != wait_flags) { 4115 err = msleep(&sc->sc_init_complete, &sc->sc_mtx, 0, "iwxinit", 2 * hz); 4116 if (err) { 4117 DPRINTF(("%s: will return err=%d\n", __func__, err)); 4118 return err; 4119 } else { 4120 DPRINTF(("%s: sc_init_complete == IWX_INIT_COMPLETE\n", 4121 __func__)); 4122 } 4123 } 4124 4125 if (readnvm) { 4126 err = iwx_nvm_get(sc); 4127 DPRINTF(("%s: err=%d\n", __func__, err)); 4128 if (err) { 4129 printf("%s: failed to read nvm (error %d)\n", 4130 DEVNAME(sc), err); 4131 return err; 4132 } else { 4133 DPRINTF(("%s: successfully read nvm\n", DEVNAME(sc))); 4134 } 4135 IEEE80211_ADDR_COPY(sc->sc_ic.ic_macaddr, sc->sc_nvm.hw_addr); 4136 } 4137 return 0; 4138 } 4139 4140 static int 4141 iwx_config_ltr(struct iwx_softc *sc) 4142 { 4143 struct iwx_ltr_config_cmd cmd = { 4144 .flags = htole32(IWX_LTR_CFG_FLAG_FEATURE_ENABLE), 4145 }; 4146 4147 if (!sc->sc_ltr_enabled) 4148 return 0; 4149 4150 return iwx_send_cmd_pdu(sc, IWX_LTR_CONFIG, 0, sizeof(cmd), &cmd); 4151 } 4152 4153 static void 4154 iwx_update_rx_desc(struct iwx_softc *sc, struct iwx_rx_ring *ring, int idx, 4155 bus_dma_segment_t *seg) 4156 { 4157 struct iwx_rx_data *data = &ring->data[idx]; 4158 4159 if (sc->sc_device_family >= IWX_DEVICE_FAMILY_AX210) { 4160 struct iwx_rx_transfer_desc *desc = ring->desc; 4161 desc[idx].rbid = htole16(idx & 0xffff); 4162 desc[idx].addr = htole64((*seg).ds_addr); 4163 bus_dmamap_sync(ring->data_dmat, data->map, 4164 BUS_DMASYNC_PREWRITE); 4165 } else { 4166 ((uint64_t *)ring->desc)[idx] = 4167 htole64((*seg).ds_addr); 4168 bus_dmamap_sync(ring->data_dmat, data->map, 4169 BUS_DMASYNC_PREWRITE); 4170 } 4171 } 4172 4173 static int 4174 iwx_rx_addbuf(struct iwx_softc *sc, int size, int idx) 4175 { 4176 struct iwx_rx_ring *ring = &sc->rxq; 4177 struct iwx_rx_data *data = &ring->data[idx]; 4178 struct mbuf *m; 4179 int err; 4180 int fatal = 0; 4181 bus_dma_segment_t seg; 4182 int nsegs; 4183 4184 m = m_getjcl(M_NOWAIT, MT_DATA, M_PKTHDR, IWX_RBUF_SIZE); 4185 if (m == NULL) 4186 return ENOBUFS; 4187 4188 if (data->m != NULL) { 4189 bus_dmamap_unload(ring->data_dmat, data->map); 4190 fatal = 1; 4191 } 4192 4193 m->m_len = m->m_pkthdr.len = m->m_ext.ext_size; 4194 err = bus_dmamap_load_mbuf_sg(ring->data_dmat, data->map, m, &seg, 4195 &nsegs, BUS_DMA_NOWAIT); 4196 if (err) { 4197 /* XXX */ 4198 if (fatal) 4199 panic("could not load RX mbuf"); 4200 m_freem(m); 4201 return err; 4202 } 4203 data->m = m; 4204 bus_dmamap_sync(ring->data_dmat, data->map, BUS_DMASYNC_PREREAD); 4205 4206 /* Update RX descriptor. */ 4207 iwx_update_rx_desc(sc, ring, idx, &seg); 4208 return 0; 4209 } 4210 4211 static int 4212 iwx_rxmq_get_signal_strength(struct iwx_softc *sc, 4213 struct iwx_rx_mpdu_desc *desc) 4214 { 4215 int energy_a, energy_b; 4216 4217 if (sc->sc_device_family >= IWX_DEVICE_FAMILY_AX210) { 4218 energy_a = desc->v3.energy_a; 4219 energy_b = desc->v3.energy_b; 4220 } else { 4221 energy_a = desc->v1.energy_a; 4222 energy_b = desc->v1.energy_b; 4223 } 4224 energy_a = energy_a ? -energy_a : -256; 4225 energy_b = energy_b ? -energy_b : -256; 4226 return MAX(energy_a, energy_b); 4227 } 4228 4229 static int 4230 iwx_rxmq_get_chains(struct iwx_softc *sc, 4231 struct iwx_rx_mpdu_desc *desc) 4232 { 4233 4234 if (sc->sc_device_family >= IWX_DEVICE_FAMILY_AX210) 4235 return ((desc->v3.rate_n_flags & IWX_RATE_MCS_ANT_AB_MSK) >> 4236 IWX_RATE_MCS_ANT_POS); 4237 else 4238 return ((desc->v1.rate_n_flags & IWX_RATE_MCS_ANT_AB_MSK) >> 4239 IWX_RATE_MCS_ANT_POS); 4240 } 4241 4242 static void 4243 iwx_rx_rx_phy_cmd(struct iwx_softc *sc, struct iwx_rx_packet *pkt, 4244 struct iwx_rx_data *data) 4245 { 4246 struct iwx_rx_phy_info *phy_info = (void *)pkt->data; 4247 struct iwx_cmd_header *cmd_hdr = &pkt->hdr; 4248 int qid = cmd_hdr->qid; 4249 struct iwx_tx_ring *ring = &sc->txq[qid]; 4250 4251 bus_dmamap_sync(ring->data_dmat, data->map, BUS_DMASYNC_PREREAD); 4252 memcpy(&sc->sc_last_phy_info, phy_info, sizeof(sc->sc_last_phy_info)); 4253 } 4254 4255 /* 4256 * Retrieve the average noise (in dBm) among receivers. 4257 */ 4258 static int 4259 iwx_get_noise(const struct iwx_statistics_rx_non_phy *stats) 4260 { 4261 int i, total, nbant, noise; 4262 4263 total = nbant = noise = 0; 4264 for (i = 0; i < 3; i++) { 4265 noise = le32toh(stats->beacon_silence_rssi[i]) & 0xff; 4266 if (noise) { 4267 total += noise; 4268 nbant++; 4269 } 4270 } 4271 4272 /* There should be at least one antenna but check anyway. */ 4273 return (nbant == 0) ? -127 : (total / nbant) - 107; 4274 } 4275 4276 #if 0 4277 int 4278 iwx_ccmp_decap(struct iwx_softc *sc, struct mbuf *m, struct ieee80211_node *ni, 4279 struct ieee80211_rxinfo *rxi) 4280 { 4281 struct ieee80211com *ic = &sc->sc_ic; 4282 struct ieee80211_key *k; 4283 struct ieee80211_frame *wh; 4284 uint64_t pn, *prsc; 4285 uint8_t *ivp; 4286 uint8_t tid; 4287 int hdrlen, hasqos; 4288 4289 wh = mtod(m, struct ieee80211_frame *); 4290 hdrlen = ieee80211_get_hdrlen(wh); 4291 ivp = (uint8_t *)wh + hdrlen; 4292 4293 /* find key for decryption */ 4294 k = ieee80211_get_rxkey(ic, m, ni); 4295 if (k == NULL || k->k_cipher != IEEE80211_CIPHER_CCMP) 4296 return 1; 4297 4298 /* Check that ExtIV bit is be set. */ 4299 if (!(ivp[3] & IEEE80211_WEP_EXTIV)) 4300 return 1; 4301 4302 hasqos = ieee80211_has_qos(wh); 4303 tid = hasqos ? ieee80211_get_qos(wh) & IEEE80211_QOS_TID : 0; 4304 prsc = &k->k_rsc[tid]; 4305 4306 /* Extract the 48-bit PN from the CCMP header. */ 4307 pn = (uint64_t)ivp[0] | 4308 (uint64_t)ivp[1] << 8 | 4309 (uint64_t)ivp[4] << 16 | 4310 (uint64_t)ivp[5] << 24 | 4311 (uint64_t)ivp[6] << 32 | 4312 (uint64_t)ivp[7] << 40; 4313 if (rxi->rxi_flags & IEEE80211_RXI_HWDEC_SAME_PN) { 4314 if (pn < *prsc) { 4315 ic->ic_stats.is_ccmp_replays++; 4316 return 1; 4317 } 4318 } else if (pn <= *prsc) { 4319 ic->ic_stats.is_ccmp_replays++; 4320 return 1; 4321 } 4322 /* Last seen packet number is updated in ieee80211_inputm(). */ 4323 4324 /* 4325 * Some firmware versions strip the MIC, and some don't. It is not 4326 * clear which of the capability flags could tell us what to expect. 4327 * For now, keep things simple and just leave the MIC in place if 4328 * it is present. 4329 * 4330 * The IV will be stripped by ieee80211_inputm(). 4331 */ 4332 return 0; 4333 } 4334 #endif 4335 4336 static int 4337 iwx_rx_hwdecrypt(struct iwx_softc *sc, struct mbuf *m, uint32_t rx_pkt_status) 4338 { 4339 struct ieee80211_frame *wh; 4340 int ret = 0; 4341 uint8_t type, subtype; 4342 4343 wh = mtod(m, struct ieee80211_frame *); 4344 4345 type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK; 4346 if (type == IEEE80211_FC0_TYPE_CTL) { 4347 return 0; 4348 } 4349 4350 subtype = wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK; 4351 if (IEEE80211_QOS_HAS_SEQ(wh) && (subtype & IEEE80211_FC0_SUBTYPE_NODATA)) { 4352 return 0; 4353 } 4354 4355 4356 if (((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) != 4357 IEEE80211_FC0_TYPE_CTL) 4358 && (wh->i_fc[1] & IEEE80211_FC1_PROTECTED)) { 4359 if ((rx_pkt_status & IWX_RX_MPDU_RES_STATUS_SEC_ENC_MSK) != 4360 IWX_RX_MPDU_RES_STATUS_SEC_CCM_ENC) { 4361 DPRINTF(("%s: not IWX_RX_MPDU_RES_STATUS_SEC_CCM_ENC\n", __func__)); 4362 ret = 1; 4363 goto out; 4364 } 4365 /* Check whether decryption was successful or not. */ 4366 if ((rx_pkt_status & 4367 (IWX_RX_MPDU_RES_STATUS_DEC_DONE | 4368 IWX_RX_MPDU_RES_STATUS_MIC_OK)) != 4369 (IWX_RX_MPDU_RES_STATUS_DEC_DONE | 4370 IWX_RX_MPDU_RES_STATUS_MIC_OK)) { 4371 DPRINTF(("%s: not IWX_RX_MPDU_RES_STATUS_MIC_OK\n", __func__)); 4372 ret = 1; 4373 goto out; 4374 } 4375 } 4376 out: 4377 return ret; 4378 } 4379 4380 static void 4381 iwx_rx_frame(struct iwx_softc *sc, struct mbuf *m, int chanidx, 4382 uint32_t rx_pkt_status, int is_shortpre, int rate_n_flags, 4383 uint32_t device_timestamp, uint8_t rssi) 4384 { 4385 struct ieee80211com *ic = &sc->sc_ic; 4386 struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); 4387 struct ieee80211_frame *wh; 4388 struct ieee80211_node *ni; 4389 4390 /* 4391 * We need to turn the hardware provided channel index into a channel 4392 * and then find it in our ic_channels array 4393 */ 4394 if (chanidx < 0 || chanidx >= nitems(ic->ic_channels)) { 4395 /* 4396 * OpenBSD points this at the ibss chan, which it defaults to 4397 * channel 1 and then never touches again. Skip a step. 4398 */ 4399 printf("iwx: %s:%d controlling chanidx to 1 (%d)\n", __func__, __LINE__, chanidx); 4400 chanidx = 1; 4401 } 4402 4403 int channel = chanidx; 4404 for (int i = 0; i < ic->ic_nchans; i++) { 4405 if (ic->ic_channels[i].ic_ieee == channel) { 4406 chanidx = i; 4407 } 4408 } 4409 ic->ic_curchan = &ic->ic_channels[chanidx]; 4410 4411 wh = mtod(m, struct ieee80211_frame *); 4412 ni = ieee80211_find_rxnode(ic, (struct ieee80211_frame_min *)wh); 4413 4414 #if 0 /* XXX hw decrypt */ 4415 if ((rxi->rxi_flags & IEEE80211_RXI_HWDEC) && 4416 iwx_ccmp_decap(sc, m, ni, rxi) != 0) { 4417 m_freem(m); 4418 ieee80211_release_node(ic, ni); 4419 return; 4420 } 4421 #endif 4422 if (ieee80211_radiotap_active_vap(vap)) { 4423 struct iwx_rx_radiotap_header *tap = &sc->sc_rxtap; 4424 uint16_t chan_flags; 4425 int have_legacy_rate = 1; 4426 uint8_t mcs, rate; 4427 4428 tap->wr_flags = 0; 4429 if (is_shortpre) 4430 tap->wr_flags |= IEEE80211_RADIOTAP_F_SHORTPRE; 4431 tap->wr_chan_freq = 4432 htole16(ic->ic_channels[chanidx].ic_freq); 4433 chan_flags = ic->ic_channels[chanidx].ic_flags; 4434 #if 0 4435 if (ic->ic_curmode != IEEE80211_MODE_11N && 4436 ic->ic_curmode != IEEE80211_MODE_11AC) { 4437 chan_flags &= ~IEEE80211_CHAN_HT; 4438 chan_flags &= ~IEEE80211_CHAN_40MHZ; 4439 } 4440 if (ic->ic_curmode != IEEE80211_MODE_11AC) 4441 chan_flags &= ~IEEE80211_CHAN_VHT; 4442 #else 4443 chan_flags &= ~IEEE80211_CHAN_HT; 4444 #endif 4445 tap->wr_chan_flags = htole16(chan_flags); 4446 tap->wr_dbm_antsignal = rssi; 4447 tap->wr_dbm_antnoise = (int8_t)sc->sc_noise; 4448 tap->wr_tsft = device_timestamp; 4449 4450 if (sc->sc_rate_n_flags_version >= 2) { 4451 uint32_t mod_type = (rate_n_flags & 4452 IWX_RATE_MCS_MOD_TYPE_MSK); 4453 const struct ieee80211_rateset *rs = NULL; 4454 uint32_t ridx; 4455 have_legacy_rate = (mod_type == IWX_RATE_MCS_CCK_MSK || 4456 mod_type == IWX_RATE_MCS_LEGACY_OFDM_MSK); 4457 mcs = (rate_n_flags & IWX_RATE_HT_MCS_CODE_MSK); 4458 ridx = (rate_n_flags & IWX_RATE_LEGACY_RATE_MSK); 4459 if (mod_type == IWX_RATE_MCS_CCK_MSK) 4460 rs = &ieee80211_std_rateset_11b; 4461 else if (mod_type == IWX_RATE_MCS_LEGACY_OFDM_MSK) 4462 rs = &ieee80211_std_rateset_11a; 4463 if (rs && ridx < rs->rs_nrates) { 4464 rate = (rs->rs_rates[ridx] & 4465 IEEE80211_RATE_VAL); 4466 } else 4467 rate = 0; 4468 } else { 4469 have_legacy_rate = ((rate_n_flags & 4470 (IWX_RATE_MCS_HT_MSK_V1 | 4471 IWX_RATE_MCS_VHT_MSK_V1)) == 0); 4472 mcs = (rate_n_flags & 4473 (IWX_RATE_HT_MCS_RATE_CODE_MSK_V1 | 4474 IWX_RATE_HT_MCS_NSS_MSK_V1)); 4475 rate = (rate_n_flags & IWX_RATE_LEGACY_RATE_MSK_V1); 4476 } 4477 if (!have_legacy_rate) { 4478 tap->wr_rate = (0x80 | mcs); 4479 } else { 4480 switch (rate) { 4481 /* CCK rates. */ 4482 case 10: tap->wr_rate = 2; break; 4483 case 20: tap->wr_rate = 4; break; 4484 case 55: tap->wr_rate = 11; break; 4485 case 110: tap->wr_rate = 22; break; 4486 /* OFDM rates. */ 4487 case 0xd: tap->wr_rate = 12; break; 4488 case 0xf: tap->wr_rate = 18; break; 4489 case 0x5: tap->wr_rate = 24; break; 4490 case 0x7: tap->wr_rate = 36; break; 4491 case 0x9: tap->wr_rate = 48; break; 4492 case 0xb: tap->wr_rate = 72; break; 4493 case 0x1: tap->wr_rate = 96; break; 4494 case 0x3: tap->wr_rate = 108; break; 4495 /* Unknown rate: should not happen. */ 4496 default: tap->wr_rate = 0; 4497 } 4498 // XXX hack - this needs rebased with the new rate stuff anyway 4499 tap->wr_rate = rate; 4500 } 4501 } 4502 4503 IWX_UNLOCK(sc); 4504 if (ni == NULL) { 4505 if (ieee80211_input_mimo_all(ic, m) == -1) 4506 printf("%s:%d input_all returned -1\n", __func__, __LINE__); 4507 } else { 4508 4509 if (ieee80211_input_mimo(ni, m) == -1) 4510 printf("%s:%d input_all returned -1\n", __func__, __LINE__); 4511 ieee80211_free_node(ni); 4512 } 4513 IWX_LOCK(sc); 4514 } 4515 4516 static void 4517 iwx_rx_mpdu_mq(struct iwx_softc *sc, struct mbuf *m, void *pktdata, 4518 size_t maxlen) 4519 { 4520 struct ieee80211com *ic = &sc->sc_ic; 4521 struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); 4522 struct ieee80211_node *ni = vap->iv_bss; 4523 struct ieee80211_key *k; 4524 struct ieee80211_rx_stats rxs; 4525 struct iwx_rx_mpdu_desc *desc; 4526 uint32_t len, hdrlen, rate_n_flags, device_timestamp; 4527 int rssi; 4528 uint8_t chanidx; 4529 uint16_t phy_info; 4530 size_t desc_size; 4531 int pad = 0; 4532 4533 if (sc->sc_device_family >= IWX_DEVICE_FAMILY_AX210) 4534 desc_size = sizeof(*desc); 4535 else 4536 desc_size = IWX_RX_DESC_SIZE_V1; 4537 4538 if (maxlen < desc_size) { 4539 m_freem(m); 4540 return; /* drop */ 4541 } 4542 4543 desc = (struct iwx_rx_mpdu_desc *)pktdata; 4544 4545 if (!(desc->status & htole16(IWX_RX_MPDU_RES_STATUS_CRC_OK)) || 4546 !(desc->status & htole16(IWX_RX_MPDU_RES_STATUS_OVERRUN_OK))) { 4547 printf("%s: Bad CRC or FIFO: 0x%08X\n", __func__, desc->status); 4548 m_freem(m); 4549 return; /* drop */ 4550 } 4551 4552 len = le16toh(desc->mpdu_len); 4553 if (ic->ic_opmode == IEEE80211_M_MONITOR) { 4554 /* Allow control frames in monitor mode. */ 4555 if (len < sizeof(struct ieee80211_frame_cts)) { 4556 m_freem(m); 4557 return; 4558 } 4559 4560 } else if (len < sizeof(struct ieee80211_frame)) { 4561 m_freem(m); 4562 return; 4563 } 4564 if (len > maxlen - desc_size) { 4565 m_freem(m); 4566 return; 4567 } 4568 4569 // TODO: arithmetic on a pointer to void is a GNU extension 4570 m->m_data = (char *)pktdata + desc_size; 4571 m->m_pkthdr.len = m->m_len = len; 4572 4573 /* Account for padding following the frame header. */ 4574 if (desc->mac_flags2 & IWX_RX_MPDU_MFLG2_PAD) { 4575 struct ieee80211_frame *wh = mtod(m, struct ieee80211_frame *); 4576 int type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK; 4577 if (type == IEEE80211_FC0_TYPE_CTL) { 4578 switch (wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK) { 4579 case IEEE80211_FC0_SUBTYPE_CTS: 4580 hdrlen = sizeof(struct ieee80211_frame_cts); 4581 break; 4582 case IEEE80211_FC0_SUBTYPE_ACK: 4583 hdrlen = sizeof(struct ieee80211_frame_ack); 4584 break; 4585 default: 4586 hdrlen = sizeof(struct ieee80211_frame_min); 4587 break; 4588 } 4589 } else 4590 hdrlen = ieee80211_hdrsize(wh); 4591 4592 if ((le16toh(desc->status) & 4593 IWX_RX_MPDU_RES_STATUS_SEC_ENC_MSK) == 4594 IWX_RX_MPDU_RES_STATUS_SEC_CCM_ENC) { 4595 // CCMP header length 4596 hdrlen += 8; 4597 } 4598 4599 memmove(m->m_data + 2, m->m_data, hdrlen); 4600 m_adj(m, 2); 4601 4602 } 4603 4604 if ((le16toh(desc->status) & 4605 IWX_RX_MPDU_RES_STATUS_SEC_ENC_MSK) == 4606 IWX_RX_MPDU_RES_STATUS_SEC_CCM_ENC) { 4607 pad = 1; 4608 } 4609 4610 /* If it's a HT node then perform re-order processing */ 4611 if (ni->ni_flags & IEEE80211_NODE_HT) 4612 m->m_flags |= M_AMPDU; 4613 4614 /* 4615 * Hardware de-aggregates A-MSDUs and copies the same MAC header 4616 * in place for each subframe. But it leaves the 'A-MSDU present' 4617 * bit set in the frame header. We need to clear this bit ourselves. 4618 * (XXX This workaround is not required on AX200/AX201 devices that 4619 * have been tested by me, but it's unclear when this problem was 4620 * fixed in the hardware. It definitely affects the 9k generation. 4621 * Leaving this in place for now since some 9k/AX200 hybrids seem 4622 * to exist that we may eventually add support for.) 4623 * 4624 * And we must allow the same CCMP PN for subframes following the 4625 * first subframe. Otherwise they would be discarded as replays. 4626 */ 4627 if (desc->mac_flags2 & IWX_RX_MPDU_MFLG2_AMSDU) { 4628 struct ieee80211_frame *wh = mtod(m, struct ieee80211_frame *); 4629 uint8_t subframe_idx = (desc->amsdu_info & 4630 IWX_RX_MPDU_AMSDU_SUBFRAME_IDX_MASK); 4631 uint8_t *qos; 4632 4633 rxs.c_pktflags |= IEEE80211_RX_F_AMSDU; 4634 if (subframe_idx > 0) 4635 rxs.c_pktflags |= IEEE80211_RX_F_AMSDU_MORE; 4636 4637 /* XXX should keep driver statistics about this */ 4638 IWX_DPRINTF(sc, IWX_DEBUG_AMPDU_MGMT, 4639 "%s: === IWX_RX_MPDU_MFLG2_AMSDU\n", __func__); 4640 4641 qos = ieee80211_getqos(wh); 4642 qos[0] &= ~IEEE80211_QOS_AMSDU; 4643 } 4644 4645 /* 4646 * Verify decryption before duplicate detection. The latter uses 4647 * the TID supplied in QoS frame headers and this TID is implicitly 4648 * verified as part of the CCMP nonce. 4649 */ 4650 k = ieee80211_crypto_get_txkey(ni, m); 4651 if (k != NULL && 4652 (k->wk_cipher->ic_cipher == IEEE80211_CIPHER_AES_CCM) && 4653 iwx_rx_hwdecrypt(sc, m, le16toh(desc->status)/*, &rxi*/)) { 4654 DPRINTF(("%s: iwx_rx_hwdecrypt failed\n", __func__)); 4655 m_freem(m); 4656 return; 4657 } 4658 4659 if (sc->sc_device_family >= IWX_DEVICE_FAMILY_AX210) { 4660 rate_n_flags = le32toh(desc->v3.rate_n_flags); 4661 chanidx = desc->v3.channel; 4662 device_timestamp = le32toh(desc->v3.gp2_on_air_rise); 4663 } else { 4664 rate_n_flags = le32toh(desc->v1.rate_n_flags); 4665 chanidx = desc->v1.channel; 4666 device_timestamp = le32toh(desc->v1.gp2_on_air_rise); 4667 } 4668 4669 phy_info = le16toh(desc->phy_info); 4670 4671 rssi = iwx_rxmq_get_signal_strength(sc, desc); 4672 rssi = (0 - IWX_MIN_DBM) + rssi; /* normalize */ 4673 rssi = MIN(rssi, (IWX_MAX_DBM - IWX_MIN_DBM)); /* clip to max. 100% */ 4674 4675 memset(&rxs, 0, sizeof(rxs)); 4676 rxs.r_flags |= IEEE80211_R_IEEE | IEEE80211_R_FREQ; 4677 rxs.r_flags |= IEEE80211_R_BAND; 4678 rxs.r_flags |= IEEE80211_R_NF | IEEE80211_R_RSSI; 4679 rxs.r_flags |= IEEE80211_R_TSF32 | IEEE80211_R_TSF_START; 4680 4681 rxs.c_ieee = chanidx; 4682 rxs.c_freq = ieee80211_ieee2mhz(rxs.c_ieee, 4683 chanidx <= 14 ? IEEE80211_CHAN_2GHZ : IEEE80211_CHAN_5GHZ); 4684 rxs.c_band = chanidx <= 14 ? IEEE80211_CHAN_2GHZ : IEEE80211_CHAN_5GHZ; 4685 rxs.c_rx_tsf = device_timestamp; 4686 rxs.c_chain = iwx_rxmq_get_chains(sc, desc); 4687 if (rxs.c_chain != 0) 4688 rxs.r_flags |= IEEE80211_R_C_CHAIN; 4689 4690 /* rssi is in 1/2db units */ 4691 rxs.c_rssi = rssi * 2; 4692 rxs.c_nf = sc->sc_noise; 4693 4694 if (pad) { 4695 rxs.c_pktflags |= IEEE80211_RX_F_DECRYPTED; 4696 rxs.c_pktflags |= IEEE80211_RX_F_IV_STRIP; 4697 } 4698 4699 if (ieee80211_add_rx_params(m, &rxs) == 0) { 4700 printf("%s: ieee80211_add_rx_params failed\n", __func__); 4701 return; 4702 } 4703 4704 ieee80211_add_rx_params(m, &rxs); 4705 4706 #if 0 4707 if (iwx_rx_reorder(sc, m, chanidx, desc, 4708 (phy_info & IWX_RX_MPDU_PHY_SHORT_PREAMBLE), 4709 rate_n_flags, device_timestamp, &rxi, ml)) 4710 return; 4711 #endif 4712 4713 if (pad) { 4714 #define TRIM 8 4715 struct ieee80211_frame *wh = mtod(m, struct ieee80211_frame *); 4716 hdrlen = ieee80211_hdrsize(wh); 4717 memmove(m->m_data + TRIM, m->m_data, hdrlen); 4718 m_adj(m, TRIM); 4719 #undef TRIM 4720 } 4721 4722 iwx_rx_frame(sc, m, chanidx, le16toh(desc->status), 4723 (phy_info & IWX_RX_MPDU_PHY_SHORT_PREAMBLE), 4724 rate_n_flags, device_timestamp, rssi); 4725 } 4726 4727 static void 4728 iwx_clear_tx_desc(struct iwx_softc *sc, struct iwx_tx_ring *ring, int idx) 4729 { 4730 struct iwx_tfh_tfd *desc = &ring->desc[idx]; 4731 uint8_t num_tbs = le16toh(desc->num_tbs) & 0x1f; 4732 int i; 4733 4734 /* First TB is never cleared - it is bidirectional DMA data. */ 4735 for (i = 1; i < num_tbs; i++) { 4736 struct iwx_tfh_tb *tb = &desc->tbs[i]; 4737 memset(tb, 0, sizeof(*tb)); 4738 } 4739 desc->num_tbs = htole16(1); 4740 4741 bus_dmamap_sync(ring->desc_dma.tag, ring->desc_dma.map, 4742 BUS_DMASYNC_PREWRITE); 4743 } 4744 4745 static void 4746 iwx_txd_done(struct iwx_softc *sc, struct iwx_tx_ring *ring, 4747 struct iwx_tx_data *txd) 4748 { 4749 bus_dmamap_sync(ring->data_dmat, txd->map, BUS_DMASYNC_POSTWRITE); 4750 bus_dmamap_unload(ring->data_dmat, txd->map); 4751 4752 ieee80211_tx_complete(&txd->in->in_ni, txd->m, 0); 4753 txd->m = NULL; 4754 txd->in = NULL; 4755 } 4756 4757 static void 4758 iwx_txq_advance(struct iwx_softc *sc, struct iwx_tx_ring *ring, uint16_t idx) 4759 { 4760 struct iwx_tx_data *txd; 4761 4762 while (ring->tail_hw != idx) { 4763 txd = &ring->data[ring->tail]; 4764 if (txd->m != NULL) { 4765 iwx_clear_tx_desc(sc, ring, ring->tail); 4766 iwx_tx_update_byte_tbl(sc, ring, ring->tail, 0, 0); 4767 iwx_txd_done(sc, ring, txd); 4768 ring->queued--; 4769 if (ring->queued < 0) 4770 panic("caught negative queue count"); 4771 } 4772 ring->tail = (ring->tail + 1) % IWX_TX_RING_COUNT; 4773 ring->tail_hw = (ring->tail_hw + 1) % sc->max_tfd_queue_size; 4774 } 4775 } 4776 4777 static void 4778 iwx_rx_tx_cmd(struct iwx_softc *sc, struct iwx_rx_packet *pkt, 4779 struct iwx_rx_data *data) 4780 { 4781 struct ieee80211com *ic = &sc->sc_ic; 4782 struct ifnet *ifp = IC2IFP(ic); 4783 struct iwx_cmd_header *cmd_hdr = &pkt->hdr; 4784 int qid = cmd_hdr->qid, status, txfail; 4785 struct iwx_tx_ring *ring = &sc->txq[qid]; 4786 struct iwx_tx_resp *tx_resp = (void *)pkt->data; 4787 uint32_t ssn; 4788 uint32_t len = iwx_rx_packet_len(pkt); 4789 int idx = cmd_hdr->idx; 4790 struct iwx_tx_data *txd = &ring->data[idx]; 4791 struct mbuf *m = txd->m; 4792 4793 bus_dmamap_sync(ring->data_dmat, data->map, BUS_DMASYNC_POSTREAD); 4794 4795 /* Sanity checks. */ 4796 if (sizeof(*tx_resp) > len) 4797 return; 4798 if (qid < IWX_FIRST_AGG_TX_QUEUE && tx_resp->frame_count > 1) 4799 return; 4800 if (qid >= IWX_FIRST_AGG_TX_QUEUE && sizeof(*tx_resp) + sizeof(ssn) + 4801 tx_resp->frame_count * sizeof(tx_resp->status) > len) 4802 return; 4803 4804 sc->sc_tx_timer[qid] = 0; 4805 4806 if (tx_resp->frame_count > 1) /* A-MPDU */ 4807 return; 4808 4809 status = le16toh(tx_resp->status.status) & IWX_TX_STATUS_MSK; 4810 txfail = (status != IWX_TX_STATUS_SUCCESS && 4811 status != IWX_TX_STATUS_DIRECT_DONE); 4812 4813 #ifdef __not_yet__ 4814 /* TODO: Replace accounting below with ieee80211_tx_complete() */ 4815 ieee80211_tx_complete(&in->in_ni, m, txfail); 4816 #else 4817 if (txfail) 4818 if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); 4819 else { 4820 if_inc_counter(ifp, IFCOUNTER_OBYTES, m->m_pkthdr.len); 4821 if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1); 4822 if (m->m_flags & M_MCAST) 4823 if_inc_counter(ifp, IFCOUNTER_OMCASTS, 1); 4824 } 4825 #endif 4826 /* 4827 * On hardware supported by iwx(4) the SSN counter corresponds 4828 * to a Tx ring index rather than a sequence number. 4829 * Frames up to this index (non-inclusive) can now be freed. 4830 */ 4831 memcpy(&ssn, &tx_resp->status + tx_resp->frame_count, sizeof(ssn)); 4832 ssn = le32toh(ssn); 4833 if (ssn < sc->max_tfd_queue_size) { 4834 iwx_txq_advance(sc, ring, ssn); 4835 iwx_clear_oactive(sc, ring); 4836 } 4837 } 4838 4839 static void 4840 iwx_clear_oactive(struct iwx_softc *sc, struct iwx_tx_ring *ring) 4841 { 4842 IWX_ASSERT_LOCKED(sc); 4843 4844 if (ring->queued < iwx_lomark) { 4845 sc->qfullmsk &= ~(1 << ring->qid); 4846 if (sc->qfullmsk == 0 /* && ifq_is_oactive(&ifp->if_snd) */) { 4847 /* 4848 * Well, we're in interrupt context, but then again 4849 * I guess net80211 does all sorts of stunts in 4850 * interrupt context, so maybe this is no biggie. 4851 */ 4852 iwx_start(sc); 4853 } 4854 } 4855 } 4856 4857 static void 4858 iwx_rx_compressed_ba(struct iwx_softc *sc, struct iwx_rx_packet *pkt) 4859 { 4860 struct iwx_compressed_ba_notif *ba_res = (void *)pkt->data; 4861 struct ieee80211com *ic = &sc->sc_ic; 4862 struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); 4863 struct iwx_node *in = IWX_NODE(vap->iv_bss); 4864 struct ieee80211_node *ni = &in->in_ni; 4865 struct iwx_tx_ring *ring; 4866 uint16_t i, tfd_cnt, ra_tid_cnt, idx; 4867 int qid; 4868 4869 // if (ic->ic_state != IEEE80211_S_RUN) 4870 // return; 4871 4872 if (iwx_rx_packet_payload_len(pkt) < sizeof(*ba_res)) 4873 return; 4874 4875 if (ba_res->sta_id != IWX_STATION_ID) 4876 return; 4877 4878 in = (void *)ni; 4879 4880 tfd_cnt = le16toh(ba_res->tfd_cnt); 4881 ra_tid_cnt = le16toh(ba_res->ra_tid_cnt); 4882 if (!tfd_cnt || iwx_rx_packet_payload_len(pkt) < (sizeof(*ba_res) + 4883 sizeof(ba_res->ra_tid[0]) * ra_tid_cnt + 4884 sizeof(ba_res->tfd[0]) * tfd_cnt)) 4885 return; 4886 4887 for (i = 0; i < tfd_cnt; i++) { 4888 struct iwx_compressed_ba_tfd *ba_tfd = &ba_res->tfd[i]; 4889 uint8_t tid; 4890 4891 tid = ba_tfd->tid; 4892 if (tid >= nitems(sc->aggqid)) 4893 continue; 4894 4895 qid = sc->aggqid[tid]; 4896 if (qid != htole16(ba_tfd->q_num)) 4897 continue; 4898 4899 ring = &sc->txq[qid]; 4900 4901 #if 0 4902 ba = &ni->ni_tx_ba[tid]; 4903 if (ba->ba_state != IEEE80211_BA_AGREED) 4904 continue; 4905 #endif 4906 idx = le16toh(ba_tfd->tfd_index); 4907 sc->sc_tx_timer[qid] = 0; 4908 iwx_txq_advance(sc, ring, idx); 4909 iwx_clear_oactive(sc, ring); 4910 } 4911 } 4912 4913 static void 4914 iwx_rx_bmiss(struct iwx_softc *sc, struct iwx_rx_packet *pkt, 4915 struct iwx_rx_data *data) 4916 { 4917 struct ieee80211com *ic = &sc->sc_ic; 4918 struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); 4919 struct iwx_missed_beacons_notif *mbn = (void *)pkt->data; 4920 uint32_t missed; 4921 4922 if ((ic->ic_opmode != IEEE80211_M_STA) || 4923 (vap->iv_state != IEEE80211_S_RUN)) 4924 return; 4925 4926 bus_dmamap_sync(sc->rxq.data_dmat, data->map, 4927 BUS_DMASYNC_POSTREAD); 4928 4929 IWX_DPRINTF(sc, IWX_DEBUG_BEACON, 4930 "%s: mac_id=%u, cmslrx=%u, cmb=%u, neb=%d, nrb=%u\n", 4931 __func__, 4932 le32toh(mbn->mac_id), 4933 le32toh(mbn->consec_missed_beacons_since_last_rx), 4934 le32toh(mbn->consec_missed_beacons), 4935 le32toh(mbn->num_expected_beacons), 4936 le32toh(mbn->num_recvd_beacons)); 4937 4938 missed = le32toh(mbn->consec_missed_beacons_since_last_rx); 4939 if (missed > vap->iv_bmissthreshold) { 4940 ieee80211_beacon_miss(ic); 4941 } 4942 } 4943 4944 static int 4945 iwx_binding_cmd(struct iwx_softc *sc, struct iwx_node *in, uint32_t action) 4946 { 4947 struct iwx_binding_cmd cmd; 4948 struct ieee80211com *ic = &sc->sc_ic; 4949 struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); 4950 struct iwx_vap *ivp = IWX_VAP(vap); 4951 struct iwx_phy_ctxt *phyctxt = ivp->phy_ctxt; 4952 uint32_t mac_id = IWX_FW_CMD_ID_AND_COLOR(in->in_id, in->in_color); 4953 int i, err, active = (sc->sc_flags & IWX_FLAG_BINDING_ACTIVE); 4954 uint32_t status; 4955 4956 if (action == IWX_FW_CTXT_ACTION_ADD && active) 4957 panic("binding already added"); 4958 if (action == IWX_FW_CTXT_ACTION_REMOVE && !active) 4959 panic("binding already removed"); 4960 4961 if (phyctxt == NULL) /* XXX race with iwx_stop() */ 4962 return EINVAL; 4963 4964 memset(&cmd, 0, sizeof(cmd)); 4965 4966 cmd.id_and_color 4967 = htole32(IWX_FW_CMD_ID_AND_COLOR(phyctxt->id, phyctxt->color)); 4968 cmd.action = htole32(action); 4969 cmd.phy = htole32(IWX_FW_CMD_ID_AND_COLOR(phyctxt->id, phyctxt->color)); 4970 4971 cmd.macs[0] = htole32(mac_id); 4972 for (i = 1; i < IWX_MAX_MACS_IN_BINDING; i++) 4973 cmd.macs[i] = htole32(IWX_FW_CTXT_INVALID); 4974 4975 if (IEEE80211_IS_CHAN_2GHZ(phyctxt->channel) || 4976 !isset(sc->sc_enabled_capa, IWX_UCODE_TLV_CAPA_CDB_SUPPORT)) 4977 cmd.lmac_id = htole32(IWX_LMAC_24G_INDEX); 4978 else 4979 cmd.lmac_id = htole32(IWX_LMAC_5G_INDEX); 4980 4981 status = 0; 4982 err = iwx_send_cmd_pdu_status(sc, IWX_BINDING_CONTEXT_CMD, sizeof(cmd), 4983 &cmd, &status); 4984 if (err == 0 && status != 0) 4985 err = EIO; 4986 4987 return err; 4988 } 4989 4990 static uint8_t 4991 iwx_get_vht_ctrl_pos(struct ieee80211com *ic, struct ieee80211_channel *chan) 4992 { 4993 int ctlchan = ieee80211_chan2ieee(ic, chan); 4994 int midpoint = chan->ic_vht_ch_freq1; 4995 4996 /* 4997 * The FW is expected to check the control channel position only 4998 * when in HT/VHT and the channel width is not 20MHz. Return 4999 * this value as the default one: 5000 */ 5001 uint8_t pos = IWX_PHY_VHT_CTRL_POS_1_BELOW; 5002 5003 switch (ctlchan - midpoint) { 5004 case -6: 5005 pos = IWX_PHY_VHT_CTRL_POS_2_BELOW; 5006 break; 5007 case -2: 5008 pos = IWX_PHY_VHT_CTRL_POS_1_BELOW; 5009 break; 5010 case 2: 5011 pos = IWX_PHY_VHT_CTRL_POS_1_ABOVE; 5012 break; 5013 case 6: 5014 pos = IWX_PHY_VHT_CTRL_POS_2_ABOVE; 5015 break; 5016 default: 5017 break; 5018 } 5019 5020 return pos; 5021 } 5022 5023 static int 5024 iwx_phy_ctxt_cmd_uhb_v3_v4(struct iwx_softc *sc, struct iwx_phy_ctxt *ctxt, 5025 uint8_t chains_static, uint8_t chains_dynamic, uint32_t action, uint8_t sco, 5026 uint8_t vht_chan_width, int cmdver) 5027 { 5028 struct ieee80211com *ic = &sc->sc_ic; 5029 struct iwx_phy_context_cmd_uhb cmd; 5030 uint8_t active_cnt, idle_cnt; 5031 struct ieee80211_channel *chan = ctxt->channel; 5032 5033 memset(&cmd, 0, sizeof(cmd)); 5034 cmd.id_and_color = htole32(IWX_FW_CMD_ID_AND_COLOR(ctxt->id, 5035 ctxt->color)); 5036 cmd.action = htole32(action); 5037 5038 if (IEEE80211_IS_CHAN_2GHZ(chan) || 5039 !isset(sc->sc_enabled_capa, IWX_UCODE_TLV_CAPA_CDB_SUPPORT)) 5040 cmd.lmac_id = htole32(IWX_LMAC_24G_INDEX); 5041 else 5042 cmd.lmac_id = htole32(IWX_LMAC_5G_INDEX); 5043 5044 cmd.ci.band = IEEE80211_IS_CHAN_2GHZ(chan) ? 5045 IWX_PHY_BAND_24 : IWX_PHY_BAND_5; 5046 cmd.ci.channel = htole32(ieee80211_chan2ieee(ic, chan)); 5047 5048 if (IEEE80211_IS_CHAN_VHT80(chan)) { 5049 cmd.ci.ctrl_pos = iwx_get_vht_ctrl_pos(ic, chan); 5050 cmd.ci.width = IWX_PHY_VHT_CHANNEL_MODE80; 5051 } else if (IEEE80211_IS_CHAN_HT40(chan)) { 5052 cmd.ci.width = IWX_PHY_VHT_CHANNEL_MODE40; 5053 if (IEEE80211_IS_CHAN_HT40D(chan)) 5054 cmd.ci.ctrl_pos = IWX_PHY_VHT_CTRL_POS_1_ABOVE; 5055 else 5056 cmd.ci.ctrl_pos = IWX_PHY_VHT_CTRL_POS_1_BELOW; 5057 } else { 5058 cmd.ci.width = IWX_PHY_VHT_CHANNEL_MODE20; 5059 cmd.ci.ctrl_pos = IWX_PHY_VHT_CTRL_POS_1_BELOW; 5060 } 5061 5062 if (cmdver < 4 && iwx_lookup_cmd_ver(sc, IWX_DATA_PATH_GROUP, 5063 IWX_RLC_CONFIG_CMD) != 2) { 5064 idle_cnt = chains_static; 5065 active_cnt = chains_dynamic; 5066 cmd.rxchain_info = htole32(iwx_fw_valid_rx_ant(sc) << 5067 IWX_PHY_RX_CHAIN_VALID_POS); 5068 cmd.rxchain_info |= htole32(idle_cnt << 5069 IWX_PHY_RX_CHAIN_CNT_POS); 5070 cmd.rxchain_info |= htole32(active_cnt << 5071 IWX_PHY_RX_CHAIN_MIMO_CNT_POS); 5072 } 5073 5074 return iwx_send_cmd_pdu(sc, IWX_PHY_CONTEXT_CMD, 0, sizeof(cmd), &cmd); 5075 } 5076 5077 #if 0 5078 int 5079 iwx_phy_ctxt_cmd_v3_v4(struct iwx_softc *sc, struct iwx_phy_ctxt *ctxt, 5080 uint8_t chains_static, uint8_t chains_dynamic, uint32_t action, uint8_t sco, 5081 uint8_t vht_chan_width, int cmdver) 5082 { 5083 struct ieee80211com *ic = &sc->sc_ic; 5084 struct iwx_phy_context_cmd cmd; 5085 uint8_t active_cnt, idle_cnt; 5086 struct ieee80211_channel *chan = ctxt->channel; 5087 5088 memset(&cmd, 0, sizeof(cmd)); 5089 cmd.id_and_color = htole32(IWX_FW_CMD_ID_AND_COLOR(ctxt->id, 5090 ctxt->color)); 5091 cmd.action = htole32(action); 5092 5093 if (IEEE80211_IS_CHAN_2GHZ(ctxt->channel) || 5094 !isset(sc->sc_enabled_capa, IWX_UCODE_TLV_CAPA_CDB_SUPPORT)) 5095 cmd.lmac_id = htole32(IWX_LMAC_24G_INDEX); 5096 else 5097 cmd.lmac_id = htole32(IWX_LMAC_5G_INDEX); 5098 5099 cmd.ci.band = IEEE80211_IS_CHAN_2GHZ(chan) ? 5100 IWX_PHY_BAND_24 : IWX_PHY_BAND_5; 5101 cmd.ci.channel = ieee80211_chan2ieee(ic, chan); 5102 if (vht_chan_width == IEEE80211_VHTOP0_CHAN_WIDTH_80) { 5103 cmd.ci.ctrl_pos = iwx_get_vht_ctrl_pos(ic, chan); 5104 cmd.ci.width = IWX_PHY_VHT_CHANNEL_MODE80; 5105 } else if (chan->ic_flags & IEEE80211_CHAN_40MHZ) { 5106 if (sco == IEEE80211_HTOP0_SCO_SCA) { 5107 /* secondary chan above -> control chan below */ 5108 cmd.ci.ctrl_pos = IWX_PHY_VHT_CTRL_POS_1_BELOW; 5109 cmd.ci.width = IWX_PHY_VHT_CHANNEL_MODE40; 5110 } else if (sco == IEEE80211_HTOP0_SCO_SCB) { 5111 /* secondary chan below -> control chan above */ 5112 cmd.ci.ctrl_pos = IWX_PHY_VHT_CTRL_POS_1_ABOVE; 5113 cmd.ci.width = IWX_PHY_VHT_CHANNEL_MODE40; 5114 } else { 5115 cmd.ci.width = IWX_PHY_VHT_CHANNEL_MODE20; 5116 cmd.ci.ctrl_pos = IWX_PHY_VHT_CTRL_POS_1_BELOW; 5117 } 5118 } else { 5119 cmd.ci.width = IWX_PHY_VHT_CHANNEL_MODE20; 5120 cmd.ci.ctrl_pos = IWX_PHY_VHT_CTRL_POS_1_BELOW; 5121 } 5122 5123 if (cmdver < 4 && iwx_lookup_cmd_ver(sc, IWX_DATA_PATH_GROUP, 5124 IWX_RLC_CONFIG_CMD) != 2) { 5125 idle_cnt = chains_static; 5126 active_cnt = chains_dynamic; 5127 cmd.rxchain_info = htole32(iwx_fw_valid_rx_ant(sc) << 5128 IWX_PHY_RX_CHAIN_VALID_POS); 5129 cmd.rxchain_info |= htole32(idle_cnt << 5130 IWX_PHY_RX_CHAIN_CNT_POS); 5131 cmd.rxchain_info |= htole32(active_cnt << 5132 IWX_PHY_RX_CHAIN_MIMO_CNT_POS); 5133 } 5134 5135 return iwx_send_cmd_pdu(sc, IWX_PHY_CONTEXT_CMD, 0, sizeof(cmd), &cmd); 5136 } 5137 #endif 5138 5139 static int 5140 iwx_phy_ctxt_cmd(struct iwx_softc *sc, struct iwx_phy_ctxt *ctxt, 5141 uint8_t chains_static, uint8_t chains_dynamic, uint32_t action, 5142 uint32_t apply_time, uint8_t sco, uint8_t vht_chan_width) 5143 { 5144 int cmdver; 5145 5146 cmdver = iwx_lookup_cmd_ver(sc, IWX_LONG_GROUP, IWX_PHY_CONTEXT_CMD); 5147 if (cmdver != 3 && cmdver != 4) { 5148 printf("%s: firmware does not support phy-context-cmd v3/v4\n", 5149 DEVNAME(sc)); 5150 return ENOTSUP; 5151 } 5152 5153 /* 5154 * Intel increased the size of the fw_channel_info struct and neglected 5155 * to bump the phy_context_cmd struct, which contains an fw_channel_info 5156 * member in the middle. 5157 * To keep things simple we use a separate function to handle the larger 5158 * variant of the phy context command. 5159 */ 5160 if (isset(sc->sc_enabled_capa, IWX_UCODE_TLV_CAPA_ULTRA_HB_CHANNELS)) { 5161 return iwx_phy_ctxt_cmd_uhb_v3_v4(sc, ctxt, chains_static, 5162 chains_dynamic, action, sco, vht_chan_width, cmdver); 5163 } else 5164 panic("Unsupported old hardware contact thj@"); 5165 5166 #if 0 5167 return iwx_phy_ctxt_cmd_v3_v4(sc, ctxt, chains_static, chains_dynamic, 5168 action, sco, vht_chan_width, cmdver); 5169 #endif 5170 } 5171 5172 static int 5173 iwx_send_cmd(struct iwx_softc *sc, struct iwx_host_cmd *hcmd) 5174 { 5175 struct iwx_tx_ring *ring = &sc->txq[IWX_DQA_CMD_QUEUE]; 5176 struct iwx_tfh_tfd *desc; 5177 struct iwx_tx_data *txdata; 5178 struct iwx_device_cmd *cmd; 5179 struct mbuf *m; 5180 bus_addr_t paddr; 5181 uint64_t addr; 5182 int err = 0, i, paylen, off/*, s*/; 5183 int idx, code, async, group_id; 5184 size_t hdrlen, datasz; 5185 uint8_t *data; 5186 int generation = sc->sc_generation; 5187 bus_dma_segment_t seg[10]; 5188 int nsegs; 5189 5190 code = hcmd->id; 5191 async = hcmd->flags & IWX_CMD_ASYNC; 5192 idx = ring->cur; 5193 5194 for (i = 0, paylen = 0; i < nitems(hcmd->len); i++) { 5195 paylen += hcmd->len[i]; 5196 } 5197 5198 /* If this command waits for a response, allocate response buffer. */ 5199 hcmd->resp_pkt = NULL; 5200 if (hcmd->flags & IWX_CMD_WANT_RESP) { 5201 uint8_t *resp_buf; 5202 KASSERT(!async, ("async command want response")); 5203 KASSERT(hcmd->resp_pkt_len >= sizeof(struct iwx_rx_packet), 5204 ("wrong pkt len 1")); 5205 KASSERT(hcmd->resp_pkt_len <= IWX_CMD_RESP_MAX, 5206 ("wrong pkt len 2")); 5207 if (sc->sc_cmd_resp_pkt[idx] != NULL) 5208 return ENOSPC; 5209 resp_buf = malloc(hcmd->resp_pkt_len, M_DEVBUF, 5210 M_NOWAIT | M_ZERO); 5211 if (resp_buf == NULL) 5212 return ENOMEM; 5213 sc->sc_cmd_resp_pkt[idx] = resp_buf; 5214 sc->sc_cmd_resp_len[idx] = hcmd->resp_pkt_len; 5215 } else { 5216 sc->sc_cmd_resp_pkt[idx] = NULL; 5217 } 5218 5219 desc = &ring->desc[idx]; 5220 txdata = &ring->data[idx]; 5221 5222 /* 5223 * XXX Intel inside (tm) 5224 * Firmware API versions >= 50 reject old-style commands in 5225 * group 0 with a "BAD_COMMAND" firmware error. We must pretend 5226 * that such commands were in the LONG_GROUP instead in order 5227 * for firmware to accept them. 5228 */ 5229 if (iwx_cmd_groupid(code) == 0) { 5230 code = IWX_WIDE_ID(IWX_LONG_GROUP, code); 5231 txdata->flags |= IWX_TXDATA_FLAG_CMD_IS_NARROW; 5232 } else 5233 txdata->flags &= ~IWX_TXDATA_FLAG_CMD_IS_NARROW; 5234 5235 group_id = iwx_cmd_groupid(code); 5236 5237 hdrlen = sizeof(cmd->hdr_wide); 5238 datasz = sizeof(cmd->data_wide); 5239 5240 if (paylen > datasz) { 5241 /* Command is too large to fit in pre-allocated space. */ 5242 size_t totlen = hdrlen + paylen; 5243 if (paylen > IWX_MAX_CMD_PAYLOAD_SIZE) { 5244 printf("%s: firmware command too long (%zd bytes)\n", 5245 DEVNAME(sc), totlen); 5246 err = EINVAL; 5247 goto out; 5248 } 5249 if (totlen > IWX_RBUF_SIZE) 5250 panic("totlen > IWX_RBUF_SIZE"); 5251 m = m_getjcl(M_NOWAIT, MT_DATA, M_PKTHDR, IWX_RBUF_SIZE); 5252 if (m == NULL) { 5253 printf("%s: could not get fw cmd mbuf (%i bytes)\n", 5254 DEVNAME(sc), IWX_RBUF_SIZE); 5255 err = ENOMEM; 5256 goto out; 5257 } 5258 m->m_len = m->m_pkthdr.len = m->m_ext.ext_size; 5259 err = bus_dmamap_load_mbuf_sg(ring->data_dmat, txdata->map, m, 5260 seg, &nsegs, BUS_DMA_NOWAIT); 5261 if (nsegs > 20) 5262 panic("nsegs > 20"); 5263 DPRINTF(("%s: nsegs=%i\n", __func__, nsegs)); 5264 if (err) { 5265 printf("%s: could not load fw cmd mbuf (%zd bytes)\n", 5266 DEVNAME(sc), totlen); 5267 m_freem(m); 5268 goto out; 5269 } 5270 txdata->m = m; /* mbuf will be freed in iwx_cmd_done() */ 5271 cmd = mtod(m, struct iwx_device_cmd *); 5272 paddr = seg[0].ds_addr; 5273 } else { 5274 cmd = &ring->cmd[idx]; 5275 paddr = txdata->cmd_paddr; 5276 } 5277 5278 memset(cmd, 0, sizeof(*cmd)); 5279 cmd->hdr_wide.opcode = iwx_cmd_opcode(code); 5280 cmd->hdr_wide.group_id = group_id; 5281 cmd->hdr_wide.qid = ring->qid; 5282 cmd->hdr_wide.idx = idx; 5283 cmd->hdr_wide.length = htole16(paylen); 5284 cmd->hdr_wide.version = iwx_cmd_version(code); 5285 data = cmd->data_wide; 5286 5287 for (i = 0, off = 0; i < nitems(hcmd->data); i++) { 5288 if (hcmd->len[i] == 0) 5289 continue; 5290 memcpy(data + off, hcmd->data[i], hcmd->len[i]); 5291 off += hcmd->len[i]; 5292 } 5293 KASSERT(off == paylen, ("off %d != paylen %d", off, paylen)); 5294 5295 desc->tbs[0].tb_len = htole16(MIN(hdrlen + paylen, IWX_FIRST_TB_SIZE)); 5296 addr = htole64(paddr); 5297 memcpy(&desc->tbs[0].addr, &addr, sizeof(addr)); 5298 if (hdrlen + paylen > IWX_FIRST_TB_SIZE) { 5299 DPRINTF(("%s: hdrlen=%zu paylen=%d\n", __func__, hdrlen, 5300 paylen)); 5301 desc->tbs[1].tb_len = htole16(hdrlen + paylen - 5302 IWX_FIRST_TB_SIZE); 5303 addr = htole64(paddr + IWX_FIRST_TB_SIZE); 5304 memcpy(&desc->tbs[1].addr, &addr, sizeof(addr)); 5305 desc->num_tbs = htole16(2); 5306 } else 5307 desc->num_tbs = htole16(1); 5308 5309 if (paylen > datasz) { 5310 bus_dmamap_sync(ring->data_dmat, txdata->map, 5311 BUS_DMASYNC_PREWRITE); 5312 } else { 5313 bus_dmamap_sync(ring->cmd_dma.tag, ring->cmd_dma.map, 5314 BUS_DMASYNC_PREWRITE); 5315 } 5316 bus_dmamap_sync(ring->desc_dma.tag, ring->desc_dma.map, 5317 BUS_DMASYNC_PREWRITE); 5318 5319 /* Kick command ring. */ 5320 ring->queued++; 5321 ring->cur = (ring->cur + 1) % IWX_TX_RING_COUNT; 5322 ring->cur_hw = (ring->cur_hw + 1) % sc->max_tfd_queue_size; 5323 DPRINTF(("%s: ring->cur_hw=%i\n", __func__, ring->cur_hw)); 5324 IWX_WRITE(sc, IWX_HBUS_TARG_WRPTR, ring->qid << 16 | ring->cur_hw); 5325 5326 if (!async) { 5327 err = msleep(desc, &sc->sc_mtx, PCATCH, "iwxcmd", hz); 5328 if (err == 0) { 5329 /* if hardware is no longer up, return error */ 5330 if (generation != sc->sc_generation) { 5331 err = ENXIO; 5332 goto out; 5333 } 5334 5335 /* Response buffer will be freed in iwx_free_resp(). */ 5336 hcmd->resp_pkt = (void *)sc->sc_cmd_resp_pkt[idx]; 5337 sc->sc_cmd_resp_pkt[idx] = NULL; 5338 } else if (generation == sc->sc_generation) { 5339 free(sc->sc_cmd_resp_pkt[idx], M_DEVBUF); 5340 sc->sc_cmd_resp_pkt[idx] = NULL; 5341 } 5342 } 5343 out: 5344 return err; 5345 } 5346 5347 static int 5348 iwx_send_cmd_pdu(struct iwx_softc *sc, uint32_t id, uint32_t flags, 5349 uint16_t len, const void *data) 5350 { 5351 struct iwx_host_cmd cmd = { 5352 .id = id, 5353 .len = { len, }, 5354 .data = { data, }, 5355 .flags = flags, 5356 }; 5357 5358 return iwx_send_cmd(sc, &cmd); 5359 } 5360 5361 static int 5362 iwx_send_cmd_status(struct iwx_softc *sc, struct iwx_host_cmd *cmd, 5363 uint32_t *status) 5364 { 5365 struct iwx_rx_packet *pkt; 5366 struct iwx_cmd_response *resp; 5367 int err, resp_len; 5368 5369 KASSERT(((cmd->flags & IWX_CMD_WANT_RESP) == 0), ("IWX_CMD_WANT_RESP")); 5370 cmd->flags |= IWX_CMD_WANT_RESP; 5371 cmd->resp_pkt_len = sizeof(*pkt) + sizeof(*resp); 5372 5373 err = iwx_send_cmd(sc, cmd); 5374 if (err) 5375 return err; 5376 5377 pkt = cmd->resp_pkt; 5378 if (pkt == NULL || (pkt->hdr.flags & IWX_CMD_FAILED_MSK)) 5379 return EIO; 5380 5381 resp_len = iwx_rx_packet_payload_len(pkt); 5382 if (resp_len != sizeof(*resp)) { 5383 iwx_free_resp(sc, cmd); 5384 return EIO; 5385 } 5386 5387 resp = (void *)pkt->data; 5388 *status = le32toh(resp->status); 5389 iwx_free_resp(sc, cmd); 5390 return err; 5391 } 5392 5393 static int 5394 iwx_send_cmd_pdu_status(struct iwx_softc *sc, uint32_t id, uint16_t len, 5395 const void *data, uint32_t *status) 5396 { 5397 struct iwx_host_cmd cmd = { 5398 .id = id, 5399 .len = { len, }, 5400 .data = { data, }, 5401 }; 5402 5403 return iwx_send_cmd_status(sc, &cmd, status); 5404 } 5405 5406 static void 5407 iwx_free_resp(struct iwx_softc *sc, struct iwx_host_cmd *hcmd) 5408 { 5409 KASSERT((hcmd->flags & (IWX_CMD_WANT_RESP)) == IWX_CMD_WANT_RESP, 5410 ("hcmd flags !IWX_CMD_WANT_RESP")); 5411 free(hcmd->resp_pkt, M_DEVBUF); 5412 hcmd->resp_pkt = NULL; 5413 } 5414 5415 static void 5416 iwx_cmd_done(struct iwx_softc *sc, int qid, int idx, int code) 5417 { 5418 struct iwx_tx_ring *ring = &sc->txq[IWX_DQA_CMD_QUEUE]; 5419 struct iwx_tx_data *data; 5420 5421 if (qid != IWX_DQA_CMD_QUEUE) { 5422 return; /* Not a command ack. */ 5423 } 5424 5425 data = &ring->data[idx]; 5426 5427 if (data->m != NULL) { 5428 bus_dmamap_sync(ring->data_dmat, data->map, 5429 BUS_DMASYNC_POSTWRITE); 5430 bus_dmamap_unload(ring->data_dmat, data->map); 5431 m_freem(data->m); 5432 data->m = NULL; 5433 } 5434 wakeup(&ring->desc[idx]); 5435 5436 DPRINTF(("%s: command 0x%x done\n", __func__, code)); 5437 if (ring->queued == 0) { 5438 DPRINTF(("%s: unexpected firmware response to command 0x%x\n", 5439 DEVNAME(sc), code)); 5440 } else if (ring->queued > 0) 5441 ring->queued--; 5442 } 5443 5444 static uint32_t 5445 iwx_fw_rateidx_ofdm(uint8_t rval) 5446 { 5447 /* Firmware expects indices which match our 11a rate set. */ 5448 const struct ieee80211_rateset *rs = &ieee80211_std_rateset_11a; 5449 int i; 5450 5451 for (i = 0; i < rs->rs_nrates; i++) { 5452 if ((rs->rs_rates[i] & IEEE80211_RATE_VAL) == rval) 5453 return i; 5454 } 5455 5456 return 0; 5457 } 5458 5459 static uint32_t 5460 iwx_fw_rateidx_cck(uint8_t rval) 5461 { 5462 /* Firmware expects indices which match our 11b rate set. */ 5463 const struct ieee80211_rateset *rs = &ieee80211_std_rateset_11b; 5464 int i; 5465 5466 for (i = 0; i < rs->rs_nrates; i++) { 5467 if ((rs->rs_rates[i] & IEEE80211_RATE_VAL) == rval) 5468 return i; 5469 } 5470 5471 return 0; 5472 } 5473 5474 static int 5475 iwx_min_basic_rate(struct ieee80211com *ic) 5476 { 5477 struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); 5478 struct ieee80211_node *ni = vap->iv_bss; 5479 struct ieee80211_rateset *rs = &ni->ni_rates; 5480 struct ieee80211_channel *c = ni->ni_chan; 5481 int i, min, rval; 5482 5483 min = -1; 5484 5485 if (c == IEEE80211_CHAN_ANYC) { 5486 printf("%s: channel is IEEE80211_CHAN_ANYC\n", __func__); 5487 return -1; 5488 } 5489 5490 for (i = 0; i < rs->rs_nrates; i++) { 5491 if ((rs->rs_rates[i] & IEEE80211_RATE_BASIC) == 0) 5492 continue; 5493 rval = (rs->rs_rates[i] & IEEE80211_RATE_VAL); 5494 if (min == -1) 5495 min = rval; 5496 else if (rval < min) 5497 min = rval; 5498 } 5499 5500 /* Default to 1 Mbit/s on 2GHz and 6 Mbit/s on 5GHz. */ 5501 if (min == -1) 5502 min = IEEE80211_IS_CHAN_2GHZ(c) ? 2 : 12; 5503 5504 return min; 5505 } 5506 5507 /* 5508 * Determine the Tx command flags and Tx rate+flags to use. 5509 * Return the selected Tx rate. 5510 */ 5511 static const struct iwx_rate * 5512 iwx_tx_fill_cmd(struct iwx_softc *sc, struct iwx_node *in, 5513 struct ieee80211_frame *wh, uint16_t *flags, uint32_t *rate_n_flags, 5514 struct mbuf *m) 5515 { 5516 struct ieee80211com *ic = &sc->sc_ic; 5517 struct ieee80211_node *ni = &in->in_ni; 5518 struct ieee80211_rateset *rs = &ni->ni_rates; 5519 const struct iwx_rate *rinfo = NULL; 5520 int type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK; 5521 int ridx = iwx_min_basic_rate(ic); 5522 int min_ridx, rate_flags; 5523 uint8_t rval; 5524 5525 /* We're in the process of clearing the node, no channel already */ 5526 if (ridx == -1) 5527 return NULL; 5528 5529 min_ridx = iwx_rval2ridx(ridx); 5530 5531 *flags = 0; 5532 5533 if (IEEE80211_IS_MULTICAST(wh->i_addr1) || 5534 type != IEEE80211_FC0_TYPE_DATA) { 5535 /* for non-data, use the lowest supported rate */ 5536 ridx = min_ridx; 5537 *flags |= IWX_TX_FLAGS_CMD_RATE; 5538 } else if (ni->ni_flags & IEEE80211_NODE_VHT) { 5539 /* TODO: VHT - the ridx / rate array doesn't have VHT rates yet */ 5540 ridx = iwx_min_basic_rate(ic); 5541 } else if (ni->ni_flags & IEEE80211_NODE_HT) { 5542 ridx = iwx_mcs2ridx[ieee80211_node_get_txrate_dot11rate(ni) 5543 & ~IEEE80211_RATE_MCS]; 5544 } else { 5545 rval = (rs->rs_rates[ieee80211_node_get_txrate_dot11rate(ni)] 5546 & IEEE80211_RATE_VAL); 5547 ridx = iwx_rval2ridx(rval); 5548 if (ridx < min_ridx) 5549 ridx = min_ridx; 5550 } 5551 5552 if (m->m_flags & M_EAPOL) 5553 *flags |= IWX_TX_FLAGS_HIGH_PRI; 5554 5555 rinfo = &iwx_rates[ridx]; 5556 5557 /* 5558 * Do not fill rate_n_flags if firmware controls the Tx rate. 5559 * For data frames we rely on Tx rate scaling in firmware by default. 5560 */ 5561 if ((*flags & IWX_TX_FLAGS_CMD_RATE) == 0) { 5562 *rate_n_flags = 0; 5563 return rinfo; 5564 } 5565 5566 /* 5567 * Forcing a CCK/OFDM legacy rate is important for management frames. 5568 * Association will only succeed if we do this correctly. 5569 */ 5570 5571 IWX_DPRINTF(sc, IWX_DEBUG_TXRATE,"%s%d:: min_ridx=%i\n", __func__, __LINE__, min_ridx); 5572 IWX_DPRINTF(sc, IWX_DEBUG_TXRATE, "%s:%d: ridx=%i\n", __func__, __LINE__, ridx); 5573 rate_flags = IWX_RATE_MCS_ANT_A_MSK; 5574 if (IWX_RIDX_IS_CCK(ridx)) { 5575 if (sc->sc_rate_n_flags_version >= 2) 5576 rate_flags |= IWX_RATE_MCS_CCK_MSK; 5577 else 5578 rate_flags |= IWX_RATE_MCS_CCK_MSK_V1; 5579 } else if (sc->sc_rate_n_flags_version >= 2) 5580 rate_flags |= IWX_RATE_MCS_LEGACY_OFDM_MSK; 5581 5582 rval = (rs->rs_rates[ieee80211_node_get_txrate_dot11rate(ni)] 5583 & IEEE80211_RATE_VAL); 5584 IWX_DPRINTF(sc, IWX_DEBUG_TXRATE, "%s:%d: rval=%i dot11 %d\n", __func__, __LINE__, 5585 rval, rs->rs_rates[ieee80211_node_get_txrate_dot11rate(ni)]); 5586 5587 if (sc->sc_rate_n_flags_version >= 2) { 5588 if (rate_flags & IWX_RATE_MCS_LEGACY_OFDM_MSK) { 5589 rate_flags |= (iwx_fw_rateidx_ofdm(rval) & 5590 IWX_RATE_LEGACY_RATE_MSK); 5591 } else { 5592 rate_flags |= (iwx_fw_rateidx_cck(rval) & 5593 IWX_RATE_LEGACY_RATE_MSK); 5594 } 5595 } else 5596 rate_flags |= rinfo->plcp; 5597 5598 *rate_n_flags = rate_flags; 5599 IWX_DPRINTF(sc, IWX_DEBUG_TXRATE, "%s:%d flags=0x%x\n", 5600 __func__, __LINE__,*flags); 5601 IWX_DPRINTF(sc, IWX_DEBUG_TXRATE, "%s:%d rate_n_flags=0x%x\n", 5602 __func__, __LINE__, *rate_n_flags); 5603 5604 if (sc->sc_debug & IWX_DEBUG_TXRATE) 5605 print_ratenflags(__func__, __LINE__, 5606 *rate_n_flags, sc->sc_rate_n_flags_version); 5607 5608 return rinfo; 5609 } 5610 5611 static void 5612 iwx_tx_update_byte_tbl(struct iwx_softc *sc, struct iwx_tx_ring *txq, 5613 int idx, uint16_t byte_cnt, uint16_t num_tbs) 5614 { 5615 uint8_t filled_tfd_size, num_fetch_chunks; 5616 uint16_t len = byte_cnt; 5617 uint16_t bc_ent; 5618 5619 filled_tfd_size = offsetof(struct iwx_tfh_tfd, tbs) + 5620 num_tbs * sizeof(struct iwx_tfh_tb); 5621 /* 5622 * filled_tfd_size contains the number of filled bytes in the TFD. 5623 * Dividing it by 64 will give the number of chunks to fetch 5624 * to SRAM- 0 for one chunk, 1 for 2 and so on. 5625 * If, for example, TFD contains only 3 TBs then 32 bytes 5626 * of the TFD are used, and only one chunk of 64 bytes should 5627 * be fetched 5628 */ 5629 num_fetch_chunks = howmany(filled_tfd_size, 64) - 1; 5630 5631 if (sc->sc_device_family >= IWX_DEVICE_FAMILY_AX210) { 5632 struct iwx_gen3_bc_tbl_entry *scd_bc_tbl = txq->bc_tbl.vaddr; 5633 /* Starting from AX210, the HW expects bytes */ 5634 bc_ent = htole16(len | (num_fetch_chunks << 14)); 5635 scd_bc_tbl[idx].tfd_offset = bc_ent; 5636 } else { 5637 struct iwx_agn_scd_bc_tbl *scd_bc_tbl = txq->bc_tbl.vaddr; 5638 /* Before AX210, the HW expects DW */ 5639 len = howmany(len, 4); 5640 bc_ent = htole16(len | (num_fetch_chunks << 12)); 5641 scd_bc_tbl->tfd_offset[idx] = bc_ent; 5642 } 5643 5644 bus_dmamap_sync(sc->sc_dmat, txq->bc_tbl.map, BUS_DMASYNC_PREWRITE); 5645 } 5646 5647 static int 5648 iwx_tx(struct iwx_softc *sc, struct mbuf *m, struct ieee80211_node *ni) 5649 { 5650 struct ieee80211com *ic = &sc->sc_ic; 5651 struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); 5652 struct iwx_node *in = (void *)ni; 5653 struct iwx_tx_ring *ring; 5654 struct iwx_tx_data *data; 5655 struct iwx_tfh_tfd *desc; 5656 struct iwx_device_cmd *cmd; 5657 struct ieee80211_frame *wh; 5658 struct ieee80211_key *k = NULL; 5659 const struct iwx_rate *rinfo; 5660 uint64_t paddr; 5661 u_int hdrlen; 5662 uint32_t rate_n_flags; 5663 uint16_t num_tbs, flags, offload_assist = 0; 5664 int i, totlen, err, pad, qid; 5665 #define IWM_MAX_SCATTER 20 5666 bus_dma_segment_t *seg, segs[IWM_MAX_SCATTER]; 5667 int nsegs; 5668 struct mbuf *m1; 5669 size_t txcmd_size; 5670 5671 IWX_ASSERT_LOCKED(sc); 5672 5673 wh = mtod(m, struct ieee80211_frame *); 5674 hdrlen = ieee80211_anyhdrsize(wh); 5675 5676 qid = sc->first_data_qid; 5677 5678 /* Put QoS frames on the data queue which maps to their TID. */ 5679 if (IEEE80211_QOS_HAS_SEQ(wh)) { 5680 uint16_t qos = ieee80211_gettid(wh); 5681 uint8_t tid = qos & IEEE80211_QOS_TID; 5682 struct ieee80211_tx_ampdu *tap = &ni->ni_tx_ampdu[tid]; 5683 5684 /* 5685 * Note: we're currently putting all frames into one queue 5686 * except for A-MPDU queues. We should be able to choose 5687 * other WME queues but first we need to verify they've been 5688 * correctly setup for data. 5689 */ 5690 5691 /* 5692 * Only QoS data goes into an A-MPDU queue; 5693 * don't add QoS null, the other data types, etc. 5694 */ 5695 if (IEEE80211_AMPDU_RUNNING(tap) && 5696 IEEE80211_IS_QOSDATA(wh) && 5697 !IEEE80211_IS_MULTICAST(wh->i_addr1) && 5698 sc->aggqid[tid] != 0) { 5699 qid = sc->aggqid[tid]; 5700 } 5701 } 5702 5703 ring = &sc->txq[qid]; 5704 desc = &ring->desc[ring->cur]; 5705 memset(desc, 0, sizeof(*desc)); 5706 data = &ring->data[ring->cur]; 5707 5708 cmd = &ring->cmd[ring->cur]; 5709 cmd->hdr.code = IWX_TX_CMD; 5710 cmd->hdr.flags = 0; 5711 cmd->hdr.qid = ring->qid; 5712 cmd->hdr.idx = ring->cur; 5713 5714 rinfo = iwx_tx_fill_cmd(sc, in, wh, &flags, &rate_n_flags, m); 5715 if (rinfo == NULL) 5716 return EINVAL; 5717 5718 /* Offloaded sequence number assignment; non-AMPDU case */ 5719 if ((m->m_flags & M_AMPDU_MPDU) == 0) 5720 ieee80211_output_seqno_assign(ni, -1, m); 5721 5722 /* Radiotap */ 5723 if (ieee80211_radiotap_active_vap(vap)) { 5724 struct iwx_tx_radiotap_header *tap = &sc->sc_txtap; 5725 5726 tap->wt_flags = 0; 5727 tap->wt_chan_freq = htole16(ni->ni_chan->ic_freq); 5728 tap->wt_chan_flags = htole16(ni->ni_chan->ic_flags); 5729 tap->wt_rate = rinfo->rate; 5730 if (k != NULL) 5731 tap->wt_flags |= IEEE80211_RADIOTAP_F_WEP; 5732 ieee80211_radiotap_tx(vap, m); 5733 } 5734 5735 /* Encrypt - CCMP via direct HW path, TKIP/WEP indirected openbsd-style for now */ 5736 if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) { 5737 k = ieee80211_crypto_get_txkey(ni, m); 5738 if (k == NULL) { 5739 printf("%s: k is NULL!\n", __func__); 5740 m_freem(m); 5741 return (ENOBUFS); 5742 } else if (k->wk_cipher->ic_cipher == IEEE80211_CIPHER_AES_CCM) { 5743 k->wk_keytsc++; 5744 } else { 5745 k->wk_cipher->ic_encap(k, m); 5746 5747 /* 802.11 headers may have moved */ 5748 wh = mtod(m, struct ieee80211_frame *); 5749 flags |= IWX_TX_FLAGS_ENCRYPT_DIS; 5750 } 5751 } else 5752 flags |= IWX_TX_FLAGS_ENCRYPT_DIS; 5753 5754 totlen = m->m_pkthdr.len; 5755 5756 if (hdrlen & 3) { 5757 /* First segment length must be a multiple of 4. */ 5758 pad = 4 - (hdrlen & 3); 5759 offload_assist |= IWX_TX_CMD_OFFLD_PAD; 5760 } else 5761 pad = 0; 5762 5763 if (sc->sc_device_family >= IWX_DEVICE_FAMILY_AX210) { 5764 struct iwx_tx_cmd_gen3 *tx = (void *)cmd->data; 5765 memset(tx, 0, sizeof(*tx)); 5766 tx->len = htole16(totlen); 5767 tx->offload_assist = htole32(offload_assist); 5768 tx->flags = htole16(flags); 5769 tx->rate_n_flags = htole32(rate_n_flags); 5770 memcpy(tx->hdr, wh, hdrlen); 5771 txcmd_size = sizeof(*tx); 5772 } else { 5773 struct iwx_tx_cmd_gen2 *tx = (void *)cmd->data; 5774 memset(tx, 0, sizeof(*tx)); 5775 tx->len = htole16(totlen); 5776 tx->offload_assist = htole16(offload_assist); 5777 tx->flags = htole32(flags); 5778 tx->rate_n_flags = htole32(rate_n_flags); 5779 memcpy(tx->hdr, wh, hdrlen); 5780 txcmd_size = sizeof(*tx); 5781 } 5782 5783 /* Trim 802.11 header. */ 5784 m_adj(m, hdrlen); 5785 5786 err = bus_dmamap_load_mbuf_sg(ring->data_dmat, data->map, m, segs, 5787 &nsegs, BUS_DMA_NOWAIT); 5788 if (err && err != EFBIG) { 5789 printf("%s: can't map mbuf (error %d)\n", DEVNAME(sc), err); 5790 m_freem(m); 5791 return err; 5792 } 5793 if (err) { 5794 /* Too many DMA segments, linearize mbuf. */ 5795 m1 = m_collapse(m, M_NOWAIT, IWM_MAX_SCATTER - 2); 5796 if (m1 == NULL) { 5797 printf("%s: could not defrag mbufs\n", __func__); 5798 m_freem(m); 5799 return (ENOBUFS); 5800 } 5801 m = m1; 5802 err = bus_dmamap_load_mbuf_sg(ring->data_dmat, data->map, m, 5803 segs, &nsegs, BUS_DMA_NOWAIT); 5804 if (err) { 5805 printf("%s: can't map mbuf (error %d)\n", __func__, 5806 err); 5807 m_freem(m); 5808 return (err); 5809 } 5810 } 5811 data->m = m; 5812 data->in = in; 5813 5814 /* Fill TX descriptor. */ 5815 num_tbs = 2 + nsegs; 5816 desc->num_tbs = htole16(num_tbs); 5817 5818 desc->tbs[0].tb_len = htole16(IWX_FIRST_TB_SIZE); 5819 paddr = htole64(data->cmd_paddr); 5820 memcpy(&desc->tbs[0].addr, &paddr, sizeof(paddr)); 5821 if (data->cmd_paddr >> 32 != (data->cmd_paddr + le32toh(desc->tbs[0].tb_len)) >> 32) 5822 DPRINTF(("%s: TB0 crosses 32bit boundary\n", __func__)); 5823 desc->tbs[1].tb_len = htole16(sizeof(struct iwx_cmd_header) + 5824 txcmd_size + hdrlen + pad - IWX_FIRST_TB_SIZE); 5825 paddr = htole64(data->cmd_paddr + IWX_FIRST_TB_SIZE); 5826 memcpy(&desc->tbs[1].addr, &paddr, sizeof(paddr)); 5827 5828 if (data->cmd_paddr >> 32 != (data->cmd_paddr + le32toh(desc->tbs[1].tb_len)) >> 32) 5829 DPRINTF(("%s: TB1 crosses 32bit boundary\n", __func__)); 5830 5831 /* Other DMA segments are for data payload. */ 5832 for (i = 0; i < nsegs; i++) { 5833 seg = &segs[i]; 5834 desc->tbs[i + 2].tb_len = htole16(seg->ds_len); 5835 paddr = htole64(seg->ds_addr); 5836 memcpy(&desc->tbs[i + 2].addr, &paddr, sizeof(paddr)); 5837 if (data->cmd_paddr >> 32 != (data->cmd_paddr + le32toh(desc->tbs[i + 2].tb_len)) >> 32) 5838 DPRINTF(("%s: TB%d crosses 32bit boundary\n", __func__, i + 2)); 5839 } 5840 5841 bus_dmamap_sync(ring->data_dmat, data->map, BUS_DMASYNC_PREWRITE); 5842 bus_dmamap_sync(ring->cmd_dma.tag, ring->cmd_dma.map, 5843 BUS_DMASYNC_PREWRITE); 5844 bus_dmamap_sync(ring->desc_dma.tag, ring->desc_dma.map, 5845 BUS_DMASYNC_PREWRITE); 5846 5847 iwx_tx_update_byte_tbl(sc, ring, ring->cur, totlen, num_tbs); 5848 5849 /* Kick TX ring. */ 5850 ring->cur = (ring->cur + 1) % IWX_TX_RING_COUNT; 5851 ring->cur_hw = (ring->cur_hw + 1) % sc->max_tfd_queue_size; 5852 IWX_WRITE(sc, IWX_HBUS_TARG_WRPTR, ring->qid << 16 | ring->cur_hw); 5853 5854 /* Mark TX ring as full if we reach a certain threshold. */ 5855 if (++ring->queued > iwx_himark) { 5856 sc->qfullmsk |= 1 << ring->qid; 5857 } 5858 5859 sc->sc_tx_timer[ring->qid] = 15; 5860 5861 return 0; 5862 } 5863 5864 static int 5865 iwx_flush_sta_tids(struct iwx_softc *sc, int sta_id, uint16_t tids) 5866 { 5867 struct iwx_rx_packet *pkt; 5868 struct iwx_tx_path_flush_cmd_rsp *resp; 5869 struct iwx_tx_path_flush_cmd flush_cmd = { 5870 .sta_id = htole32(sta_id), 5871 .tid_mask = htole16(tids), 5872 }; 5873 struct iwx_host_cmd hcmd = { 5874 .id = IWX_TXPATH_FLUSH, 5875 .len = { sizeof(flush_cmd), }, 5876 .data = { &flush_cmd, }, 5877 .flags = IWX_CMD_WANT_RESP, 5878 .resp_pkt_len = sizeof(*pkt) + sizeof(*resp), 5879 }; 5880 int err, resp_len, i, num_flushed_queues; 5881 5882 err = iwx_send_cmd(sc, &hcmd); 5883 if (err) 5884 return err; 5885 5886 pkt = hcmd.resp_pkt; 5887 if (!pkt || (pkt->hdr.flags & IWX_CMD_FAILED_MSK)) { 5888 err = EIO; 5889 goto out; 5890 } 5891 5892 resp_len = iwx_rx_packet_payload_len(pkt); 5893 /* Some firmware versions don't provide a response. */ 5894 if (resp_len == 0) 5895 goto out; 5896 else if (resp_len != sizeof(*resp)) { 5897 err = EIO; 5898 goto out; 5899 } 5900 5901 resp = (void *)pkt->data; 5902 5903 if (le16toh(resp->sta_id) != sta_id) { 5904 err = EIO; 5905 goto out; 5906 } 5907 5908 num_flushed_queues = le16toh(resp->num_flushed_queues); 5909 if (num_flushed_queues > IWX_TX_FLUSH_QUEUE_RSP) { 5910 err = EIO; 5911 goto out; 5912 } 5913 5914 for (i = 0; i < num_flushed_queues; i++) { 5915 struct iwx_flush_queue_info *queue_info = &resp->queues[i]; 5916 uint16_t tid = le16toh(queue_info->tid); 5917 uint16_t read_after = le16toh(queue_info->read_after_flush); 5918 uint16_t qid = le16toh(queue_info->queue_num); 5919 struct iwx_tx_ring *txq; 5920 5921 if (qid >= nitems(sc->txq)) 5922 continue; 5923 5924 txq = &sc->txq[qid]; 5925 if (tid != txq->tid) 5926 continue; 5927 5928 iwx_txq_advance(sc, txq, read_after); 5929 } 5930 out: 5931 iwx_free_resp(sc, &hcmd); 5932 return err; 5933 } 5934 5935 #define IWX_FLUSH_WAIT_MS 2000 5936 5937 static int 5938 iwx_drain_sta(struct iwx_softc *sc, struct iwx_node* in, int drain) 5939 { 5940 struct iwx_add_sta_cmd cmd; 5941 int err; 5942 uint32_t status; 5943 5944 memset(&cmd, 0, sizeof(cmd)); 5945 cmd.mac_id_n_color = htole32(IWX_FW_CMD_ID_AND_COLOR(in->in_id, 5946 in->in_color)); 5947 cmd.sta_id = IWX_STATION_ID; 5948 cmd.add_modify = IWX_STA_MODE_MODIFY; 5949 cmd.station_flags = drain ? htole32(IWX_STA_FLG_DRAIN_FLOW) : 0; 5950 cmd.station_flags_msk = htole32(IWX_STA_FLG_DRAIN_FLOW); 5951 5952 status = IWX_ADD_STA_SUCCESS; 5953 err = iwx_send_cmd_pdu_status(sc, IWX_ADD_STA, 5954 sizeof(cmd), &cmd, &status); 5955 if (err) { 5956 printf("%s: could not update sta (error %d)\n", 5957 DEVNAME(sc), err); 5958 return err; 5959 } 5960 5961 switch (status & IWX_ADD_STA_STATUS_MASK) { 5962 case IWX_ADD_STA_SUCCESS: 5963 break; 5964 default: 5965 err = EIO; 5966 printf("%s: Couldn't %s draining for station\n", 5967 DEVNAME(sc), drain ? "enable" : "disable"); 5968 break; 5969 } 5970 5971 return err; 5972 } 5973 5974 static int 5975 iwx_flush_sta(struct iwx_softc *sc, struct iwx_node *in) 5976 { 5977 int err; 5978 5979 IWX_ASSERT_LOCKED(sc); 5980 5981 sc->sc_flags |= IWX_FLAG_TXFLUSH; 5982 5983 err = iwx_drain_sta(sc, in, 1); 5984 if (err) 5985 goto done; 5986 5987 err = iwx_flush_sta_tids(sc, IWX_STATION_ID, 0xffff); 5988 if (err) { 5989 printf("%s: could not flush Tx path (error %d)\n", 5990 DEVNAME(sc), err); 5991 goto done; 5992 } 5993 5994 /* 5995 * XXX-THJ: iwx_wait_tx_queues_empty was here, but it was a nope in the 5996 * fc drive rand has has been replaced in OpenBSD. 5997 */ 5998 5999 err = iwx_drain_sta(sc, in, 0); 6000 done: 6001 sc->sc_flags &= ~IWX_FLAG_TXFLUSH; 6002 return err; 6003 } 6004 6005 #define IWX_POWER_KEEP_ALIVE_PERIOD_SEC 25 6006 6007 static int 6008 iwx_beacon_filter_send_cmd(struct iwx_softc *sc, 6009 struct iwx_beacon_filter_cmd *cmd) 6010 { 6011 return iwx_send_cmd_pdu(sc, IWX_REPLY_BEACON_FILTERING_CMD, 6012 0, sizeof(struct iwx_beacon_filter_cmd), cmd); 6013 } 6014 6015 static int 6016 iwx_update_beacon_abort(struct iwx_softc *sc, struct iwx_node *in, int enable) 6017 { 6018 struct iwx_beacon_filter_cmd cmd = { 6019 IWX_BF_CMD_CONFIG_DEFAULTS, 6020 .bf_enable_beacon_filter = htole32(1), 6021 .ba_enable_beacon_abort = htole32(enable), 6022 }; 6023 6024 if (!sc->sc_bf.bf_enabled) 6025 return 0; 6026 6027 sc->sc_bf.ba_enabled = enable; 6028 return iwx_beacon_filter_send_cmd(sc, &cmd); 6029 } 6030 6031 static void 6032 iwx_power_build_cmd(struct iwx_softc *sc, struct iwx_node *in, 6033 struct iwx_mac_power_cmd *cmd) 6034 { 6035 struct ieee80211com *ic = &sc->sc_ic; 6036 struct ieee80211_node *ni = &in->in_ni; 6037 struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); 6038 int dtim_period, dtim_msec, keep_alive; 6039 6040 cmd->id_and_color = htole32(IWX_FW_CMD_ID_AND_COLOR(in->in_id, 6041 in->in_color)); 6042 if (vap->iv_dtim_period) 6043 dtim_period = vap->iv_dtim_period; 6044 else 6045 dtim_period = 1; 6046 6047 /* 6048 * Regardless of power management state the driver must set 6049 * keep alive period. FW will use it for sending keep alive NDPs 6050 * immediately after association. Check that keep alive period 6051 * is at least 3 * DTIM. 6052 */ 6053 dtim_msec = dtim_period * ni->ni_intval; 6054 keep_alive = MAX(3 * dtim_msec, 1000 * IWX_POWER_KEEP_ALIVE_PERIOD_SEC); 6055 keep_alive = roundup(keep_alive, 1000) / 1000; 6056 cmd->keep_alive_seconds = htole16(keep_alive); 6057 6058 if (ic->ic_opmode != IEEE80211_M_MONITOR) 6059 cmd->flags = htole16(IWX_POWER_FLAGS_POWER_SAVE_ENA_MSK); 6060 } 6061 6062 static int 6063 iwx_power_mac_update_mode(struct iwx_softc *sc, struct iwx_node *in) 6064 { 6065 int err; 6066 int ba_enable; 6067 struct iwx_mac_power_cmd cmd; 6068 6069 memset(&cmd, 0, sizeof(cmd)); 6070 6071 iwx_power_build_cmd(sc, in, &cmd); 6072 6073 err = iwx_send_cmd_pdu(sc, IWX_MAC_PM_POWER_TABLE, 0, 6074 sizeof(cmd), &cmd); 6075 if (err != 0) 6076 return err; 6077 6078 ba_enable = !!(cmd.flags & 6079 htole16(IWX_POWER_FLAGS_POWER_MANAGEMENT_ENA_MSK)); 6080 return iwx_update_beacon_abort(sc, in, ba_enable); 6081 } 6082 6083 static int 6084 iwx_power_update_device(struct iwx_softc *sc) 6085 { 6086 struct iwx_device_power_cmd cmd = { }; 6087 struct ieee80211com *ic = &sc->sc_ic; 6088 6089 if (ic->ic_opmode != IEEE80211_M_MONITOR) 6090 cmd.flags = htole16(IWX_DEVICE_POWER_FLAGS_POWER_SAVE_ENA_MSK); 6091 6092 return iwx_send_cmd_pdu(sc, 6093 IWX_POWER_TABLE_CMD, 0, sizeof(cmd), &cmd); 6094 } 6095 #if 0 6096 static int 6097 iwx_enable_beacon_filter(struct iwx_softc *sc, struct iwx_node *in) 6098 { 6099 struct iwx_beacon_filter_cmd cmd = { 6100 IWX_BF_CMD_CONFIG_DEFAULTS, 6101 .bf_enable_beacon_filter = htole32(1), 6102 .ba_enable_beacon_abort = htole32(sc->sc_bf.ba_enabled), 6103 }; 6104 int err; 6105 6106 err = iwx_beacon_filter_send_cmd(sc, &cmd); 6107 if (err == 0) 6108 sc->sc_bf.bf_enabled = 1; 6109 6110 return err; 6111 } 6112 #endif 6113 static int 6114 iwx_disable_beacon_filter(struct iwx_softc *sc) 6115 { 6116 struct iwx_beacon_filter_cmd cmd; 6117 int err; 6118 6119 memset(&cmd, 0, sizeof(cmd)); 6120 6121 err = iwx_beacon_filter_send_cmd(sc, &cmd); 6122 if (err == 0) 6123 sc->sc_bf.bf_enabled = 0; 6124 6125 return err; 6126 } 6127 6128 static int 6129 iwx_add_sta_cmd(struct iwx_softc *sc, struct iwx_node *in, int update) 6130 { 6131 struct iwx_add_sta_cmd add_sta_cmd; 6132 int err, i; 6133 uint32_t status, aggsize; 6134 const uint32_t max_aggsize = (IWX_STA_FLG_MAX_AGG_SIZE_64K >> 6135 IWX_STA_FLG_MAX_AGG_SIZE_SHIFT); 6136 struct ieee80211com *ic = &sc->sc_ic; 6137 struct ieee80211_node *ni = &in->in_ni; 6138 struct ieee80211_htrateset *htrs = &ni->ni_htrates; 6139 6140 if (!update && (sc->sc_flags & IWX_FLAG_STA_ACTIVE)) 6141 panic("STA already added"); 6142 6143 memset(&add_sta_cmd, 0, sizeof(add_sta_cmd)); 6144 6145 if (ic->ic_opmode == IEEE80211_M_MONITOR) { 6146 add_sta_cmd.sta_id = IWX_MONITOR_STA_ID; 6147 add_sta_cmd.station_type = IWX_STA_GENERAL_PURPOSE; 6148 } else { 6149 add_sta_cmd.sta_id = IWX_STATION_ID; 6150 add_sta_cmd.station_type = IWX_STA_LINK; 6151 } 6152 add_sta_cmd.mac_id_n_color 6153 = htole32(IWX_FW_CMD_ID_AND_COLOR(in->in_id, in->in_color)); 6154 if (!update) { 6155 if (ic->ic_opmode == IEEE80211_M_MONITOR) 6156 IEEE80211_ADDR_COPY(&add_sta_cmd.addr, 6157 etheranyaddr); 6158 else 6159 IEEE80211_ADDR_COPY(&add_sta_cmd.addr, 6160 in->in_macaddr); 6161 } 6162 DPRINTF(("%s: add_sta_cmd.addr=%s\n", __func__, 6163 ether_sprintf(add_sta_cmd.addr))); 6164 add_sta_cmd.add_modify = update ? 1 : 0; 6165 add_sta_cmd.station_flags_msk 6166 |= htole32(IWX_STA_FLG_FAT_EN_MSK | IWX_STA_FLG_MIMO_EN_MSK); 6167 6168 if (in->in_ni.ni_flags & IEEE80211_NODE_HT) { 6169 add_sta_cmd.station_flags_msk 6170 |= htole32(IWX_STA_FLG_MAX_AGG_SIZE_MSK | 6171 IWX_STA_FLG_AGG_MPDU_DENS_MSK); 6172 6173 if (iwx_mimo_enabled(sc)) { 6174 if (ni->ni_flags & IEEE80211_NODE_VHT) { 6175 add_sta_cmd.station_flags |= 6176 htole32(IWX_STA_FLG_MIMO_EN_MIMO2); 6177 } else { 6178 int hasmimo = 0; 6179 for (i = 0; i < htrs->rs_nrates; i++) { 6180 if (htrs->rs_rates[i] > 7) { 6181 hasmimo = 1; 6182 break; 6183 } 6184 } 6185 if (hasmimo) { 6186 add_sta_cmd.station_flags |= 6187 htole32(IWX_STA_FLG_MIMO_EN_MIMO2); 6188 } 6189 } 6190 } 6191 6192 if (ni->ni_flags & IEEE80211_NODE_HT && 6193 IEEE80211_IS_CHAN_HT40(ni->ni_chan)) { 6194 add_sta_cmd.station_flags |= htole32( 6195 IWX_STA_FLG_FAT_EN_40MHZ); 6196 } 6197 6198 6199 if (ni->ni_flags & IEEE80211_NODE_VHT) { 6200 if (IEEE80211_IS_CHAN_VHT80(ni->ni_chan)) { 6201 add_sta_cmd.station_flags |= htole32( 6202 IWX_STA_FLG_FAT_EN_80MHZ); 6203 } 6204 // XXX-misha: TODO get real ampdu size 6205 aggsize = max_aggsize; 6206 } else { 6207 aggsize = _IEEE80211_MASKSHIFT(le16toh(ni->ni_htparam), 6208 IEEE80211_HTCAP_MAXRXAMPDU); 6209 } 6210 6211 if (aggsize > max_aggsize) 6212 aggsize = max_aggsize; 6213 add_sta_cmd.station_flags |= htole32((aggsize << 6214 IWX_STA_FLG_MAX_AGG_SIZE_SHIFT) & 6215 IWX_STA_FLG_MAX_AGG_SIZE_MSK); 6216 6217 switch (_IEEE80211_MASKSHIFT(le16toh(ni->ni_htparam), 6218 IEEE80211_HTCAP_MPDUDENSITY)) { 6219 case IEEE80211_HTCAP_MPDUDENSITY_2: 6220 add_sta_cmd.station_flags 6221 |= htole32(IWX_STA_FLG_AGG_MPDU_DENS_2US); 6222 break; 6223 case IEEE80211_HTCAP_MPDUDENSITY_4: 6224 add_sta_cmd.station_flags 6225 |= htole32(IWX_STA_FLG_AGG_MPDU_DENS_4US); 6226 break; 6227 case IEEE80211_HTCAP_MPDUDENSITY_8: 6228 add_sta_cmd.station_flags 6229 |= htole32(IWX_STA_FLG_AGG_MPDU_DENS_8US); 6230 break; 6231 case IEEE80211_HTCAP_MPDUDENSITY_16: 6232 add_sta_cmd.station_flags 6233 |= htole32(IWX_STA_FLG_AGG_MPDU_DENS_16US); 6234 break; 6235 default: 6236 break; 6237 } 6238 } 6239 6240 status = IWX_ADD_STA_SUCCESS; 6241 err = iwx_send_cmd_pdu_status(sc, IWX_ADD_STA, sizeof(add_sta_cmd), 6242 &add_sta_cmd, &status); 6243 if (!err && (status & IWX_ADD_STA_STATUS_MASK) != IWX_ADD_STA_SUCCESS) 6244 err = EIO; 6245 6246 return err; 6247 } 6248 6249 static int 6250 iwx_rm_sta_cmd(struct iwx_softc *sc, struct iwx_node *in) 6251 { 6252 struct ieee80211com *ic = &sc->sc_ic; 6253 struct iwx_rm_sta_cmd rm_sta_cmd; 6254 int err; 6255 6256 if ((sc->sc_flags & IWX_FLAG_STA_ACTIVE) == 0) 6257 panic("sta already removed"); 6258 6259 memset(&rm_sta_cmd, 0, sizeof(rm_sta_cmd)); 6260 if (ic->ic_opmode == IEEE80211_M_MONITOR) 6261 rm_sta_cmd.sta_id = IWX_MONITOR_STA_ID; 6262 else 6263 rm_sta_cmd.sta_id = IWX_STATION_ID; 6264 6265 err = iwx_send_cmd_pdu(sc, IWX_REMOVE_STA, 0, sizeof(rm_sta_cmd), 6266 &rm_sta_cmd); 6267 6268 return err; 6269 } 6270 6271 static int 6272 iwx_rm_sta(struct iwx_softc *sc, struct iwx_node *in) 6273 { 6274 int err, i, cmd_ver; 6275 6276 err = iwx_flush_sta(sc, in); 6277 if (err) { 6278 printf("%s: could not flush Tx path (error %d)\n", 6279 DEVNAME(sc), err); 6280 return err; 6281 } 6282 6283 /* 6284 * New SCD_QUEUE_CONFIG API requires explicit queue removal 6285 * before a station gets removed. 6286 */ 6287 cmd_ver = iwx_lookup_cmd_ver(sc, IWX_DATA_PATH_GROUP, 6288 IWX_SCD_QUEUE_CONFIG_CMD); 6289 if (cmd_ver != 0 && cmd_ver != IWX_FW_CMD_VER_UNKNOWN) { 6290 err = iwx_disable_mgmt_queue(sc); 6291 if (err) 6292 return err; 6293 for (i = IWX_FIRST_AGG_TX_QUEUE; 6294 i < IWX_LAST_AGG_TX_QUEUE; i++) { 6295 struct iwx_tx_ring *ring = &sc->txq[i]; 6296 if ((sc->qenablemsk & (1 << i)) == 0) 6297 continue; 6298 err = iwx_disable_txq(sc, IWX_STATION_ID, 6299 ring->qid, ring->tid); 6300 if (err) { 6301 printf("%s: could not disable Tx queue %d " 6302 "(error %d)\n", DEVNAME(sc), ring->qid, 6303 err); 6304 return err; 6305 } 6306 } 6307 } 6308 6309 err = iwx_rm_sta_cmd(sc, in); 6310 if (err) { 6311 printf("%s: could not remove STA (error %d)\n", 6312 DEVNAME(sc), err); 6313 return err; 6314 } 6315 6316 in->in_flags = 0; 6317 6318 sc->sc_rx_ba_sessions = 0; 6319 sc->ba_rx.start_tidmask = 0; 6320 sc->ba_rx.stop_tidmask = 0; 6321 memset(sc->aggqid, 0, sizeof(sc->aggqid)); 6322 sc->ba_tx.start_tidmask = 0; 6323 sc->ba_tx.stop_tidmask = 0; 6324 for (i = IWX_FIRST_AGG_TX_QUEUE; i < IWX_LAST_AGG_TX_QUEUE; i++) 6325 sc->qenablemsk &= ~(1 << i); 6326 6327 #if 0 6328 for (i = 0; i < IEEE80211_NUM_TID; i++) { 6329 struct ieee80211_tx_ba *ba = &ni->ni_tx_ba[i]; 6330 if (ba->ba_state != IEEE80211_BA_AGREED) 6331 continue; 6332 ieee80211_delba_request(ic, ni, 0, 1, i); 6333 } 6334 #endif 6335 /* Clear ampdu rx state (GOS-1525) */ 6336 for (i = 0; i < IWX_MAX_TID_COUNT; i++) { 6337 struct iwx_rx_ba *ba = &sc->ni_rx_ba[i]; 6338 ba->ba_flags = 0; 6339 } 6340 6341 return 0; 6342 } 6343 6344 static uint8_t 6345 iwx_umac_scan_fill_channels(struct iwx_softc *sc, 6346 struct iwx_scan_channel_cfg_umac *chan, size_t chan_nitems, 6347 int n_ssids, uint32_t channel_cfg_flags) 6348 { 6349 struct ieee80211com *ic = &sc->sc_ic; 6350 struct ieee80211_scan_state *ss = ic->ic_scan; 6351 struct ieee80211_channel *c; 6352 uint8_t nchan; 6353 int j; 6354 6355 for (nchan = j = 0; 6356 j < ss->ss_last && 6357 nchan < sc->sc_capa_n_scan_channels; 6358 j++) { 6359 uint8_t channel_num; 6360 6361 c = ss->ss_chans[j]; 6362 channel_num = ieee80211_mhz2ieee(c->ic_freq, 0); 6363 if (isset(sc->sc_ucode_api, 6364 IWX_UCODE_TLV_API_SCAN_EXT_CHAN_VER)) { 6365 chan->v2.channel_num = channel_num; 6366 if (IEEE80211_IS_CHAN_2GHZ(c)) 6367 chan->v2.band = IWX_PHY_BAND_24; 6368 else 6369 chan->v2.band = IWX_PHY_BAND_5; 6370 chan->v2.iter_count = 1; 6371 chan->v2.iter_interval = 0; 6372 } else { 6373 chan->v1.channel_num = channel_num; 6374 chan->v1.iter_count = 1; 6375 chan->v1.iter_interval = htole16(0); 6376 } 6377 chan->flags |= htole32(channel_cfg_flags); 6378 chan++; 6379 nchan++; 6380 } 6381 6382 return nchan; 6383 } 6384 6385 static int 6386 iwx_fill_probe_req(struct iwx_softc *sc, struct iwx_scan_probe_req *preq) 6387 { 6388 struct ieee80211com *ic = &sc->sc_ic; 6389 struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); 6390 struct ieee80211_frame *wh = (struct ieee80211_frame *)preq->buf; 6391 struct ieee80211_rateset *rs; 6392 size_t remain = sizeof(preq->buf); 6393 uint8_t *frm, *pos; 6394 6395 memset(preq, 0, sizeof(*preq)); 6396 6397 if (remain < sizeof(*wh) + 2) 6398 return ENOBUFS; 6399 6400 /* 6401 * Build a probe request frame. Most of the following code is a 6402 * copy & paste of what is done in net80211. 6403 */ 6404 wh->i_fc[0] = IEEE80211_FC0_VERSION_0 | IEEE80211_FC0_TYPE_MGT | 6405 IEEE80211_FC0_SUBTYPE_PROBE_REQ; 6406 wh->i_fc[1] = IEEE80211_FC1_DIR_NODS; 6407 IEEE80211_ADDR_COPY(wh->i_addr1, etherbroadcastaddr); 6408 IEEE80211_ADDR_COPY(wh->i_addr2, vap ? vap->iv_myaddr : ic->ic_macaddr); 6409 IEEE80211_ADDR_COPY(wh->i_addr3, etherbroadcastaddr); 6410 *(uint16_t *)&wh->i_dur[0] = 0; /* filled by HW */ 6411 *(uint16_t *)&wh->i_seq[0] = 0; /* filled by HW */ 6412 6413 frm = (uint8_t *)(wh + 1); 6414 *frm++ = IEEE80211_ELEMID_SSID; 6415 *frm++ = 0; 6416 /* hardware inserts SSID */ 6417 6418 /* Tell the firmware where the MAC header is. */ 6419 preq->mac_header.offset = 0; 6420 preq->mac_header.len = htole16(frm - (uint8_t *)wh); 6421 remain -= frm - (uint8_t *)wh; 6422 6423 /* Fill in 2GHz IEs and tell firmware where they are. */ 6424 rs = &ic->ic_sup_rates[IEEE80211_MODE_11G]; 6425 if (rs->rs_nrates > IEEE80211_RATE_SIZE) { 6426 if (remain < 4 + rs->rs_nrates) 6427 return ENOBUFS; 6428 } else if (remain < 2 + rs->rs_nrates) 6429 return ENOBUFS; 6430 preq->band_data[0].offset = htole16(frm - (uint8_t *)wh); 6431 pos = frm; 6432 frm = ieee80211_add_rates(frm, rs); 6433 if (rs->rs_nrates > IEEE80211_RATE_SIZE) 6434 frm = ieee80211_add_xrates(frm, rs); 6435 remain -= frm - pos; 6436 6437 if (isset(sc->sc_enabled_capa, 6438 IWX_UCODE_TLV_CAPA_DS_PARAM_SET_IE_SUPPORT)) { 6439 if (remain < 3) 6440 return ENOBUFS; 6441 *frm++ = IEEE80211_ELEMID_DSPARMS; 6442 *frm++ = 1; 6443 *frm++ = 0; 6444 remain -= 3; 6445 } 6446 preq->band_data[0].len = htole16(frm - pos); 6447 6448 if (sc->sc_nvm.sku_cap_band_52GHz_enable) { 6449 /* Fill in 5GHz IEs. */ 6450 rs = &ic->ic_sup_rates[IEEE80211_MODE_11A]; 6451 if (rs->rs_nrates > IEEE80211_RATE_SIZE) { 6452 if (remain < 4 + rs->rs_nrates) 6453 return ENOBUFS; 6454 } else if (remain < 2 + rs->rs_nrates) 6455 return ENOBUFS; 6456 preq->band_data[1].offset = htole16(frm - (uint8_t *)wh); 6457 pos = frm; 6458 frm = ieee80211_add_rates(frm, rs); 6459 if (rs->rs_nrates > IEEE80211_RATE_SIZE) 6460 frm = ieee80211_add_xrates(frm, rs); 6461 preq->band_data[1].len = htole16(frm - pos); 6462 remain -= frm - pos; 6463 if (vap->iv_vht_flags & IEEE80211_FVHT_VHT) { 6464 if (remain < 14) 6465 return ENOBUFS; 6466 frm = ieee80211_add_vhtcap(frm, vap->iv_bss); 6467 remain -= frm - pos; 6468 preq->band_data[1].len = htole16(frm - pos); 6469 } 6470 } 6471 6472 /* Send 11n IEs on both 2GHz and 5GHz bands. */ 6473 preq->common_data.offset = htole16(frm - (uint8_t *)wh); 6474 pos = frm; 6475 if (vap->iv_flags_ht & IEEE80211_FHT_HT) { 6476 if (remain < 28) 6477 return ENOBUFS; 6478 frm = ieee80211_add_htcap(frm, vap->iv_bss); 6479 /* XXX add WME info? */ 6480 remain -= frm - pos; 6481 } 6482 6483 preq->common_data.len = htole16(frm - pos); 6484 6485 return 0; 6486 } 6487 6488 static int 6489 iwx_config_umac_scan_reduced(struct iwx_softc *sc) 6490 { 6491 struct iwx_scan_config scan_cfg; 6492 struct iwx_host_cmd hcmd = { 6493 .id = iwx_cmd_id(IWX_SCAN_CFG_CMD, IWX_LONG_GROUP, 0), 6494 .len[0] = sizeof(scan_cfg), 6495 .data[0] = &scan_cfg, 6496 .flags = 0, 6497 }; 6498 int cmdver; 6499 6500 if (!isset(sc->sc_ucode_api, IWX_UCODE_TLV_API_REDUCED_SCAN_CONFIG)) { 6501 printf("%s: firmware does not support reduced scan config\n", 6502 DEVNAME(sc)); 6503 return ENOTSUP; 6504 } 6505 6506 memset(&scan_cfg, 0, sizeof(scan_cfg)); 6507 6508 /* 6509 * SCAN_CFG version >= 5 implies that the broadcast 6510 * STA ID field is deprecated. 6511 */ 6512 cmdver = iwx_lookup_cmd_ver(sc, IWX_LONG_GROUP, IWX_SCAN_CFG_CMD); 6513 if (cmdver == IWX_FW_CMD_VER_UNKNOWN || cmdver < 5) 6514 scan_cfg.bcast_sta_id = 0xff; 6515 6516 scan_cfg.tx_chains = htole32(iwx_fw_valid_tx_ant(sc)); 6517 scan_cfg.rx_chains = htole32(iwx_fw_valid_rx_ant(sc)); 6518 6519 return iwx_send_cmd(sc, &hcmd); 6520 } 6521 6522 static uint16_t 6523 iwx_scan_umac_flags_v2(struct iwx_softc *sc, int bgscan) 6524 { 6525 struct ieee80211com *ic = &sc->sc_ic; 6526 struct ieee80211_scan_state *ss = ic->ic_scan; 6527 uint16_t flags = 0; 6528 6529 if (ss->ss_nssid == 0) { 6530 DPRINTF(("%s: Passive scan started\n", __func__)); 6531 flags |= IWX_UMAC_SCAN_GEN_FLAGS_V2_FORCE_PASSIVE; 6532 } 6533 6534 flags |= IWX_UMAC_SCAN_GEN_FLAGS_V2_PASS_ALL; 6535 flags |= IWX_UMAC_SCAN_GEN_FLAGS_V2_NTFY_ITER_COMPLETE; 6536 flags |= IWX_UMAC_SCAN_GEN_FLAGS_V2_ADAPTIVE_DWELL; 6537 6538 return flags; 6539 } 6540 6541 #define IWX_SCAN_DWELL_ACTIVE 10 6542 #define IWX_SCAN_DWELL_PASSIVE 110 6543 6544 /* adaptive dwell max budget time [TU] for full scan */ 6545 #define IWX_SCAN_ADWELL_MAX_BUDGET_FULL_SCAN 300 6546 /* adaptive dwell max budget time [TU] for directed scan */ 6547 #define IWX_SCAN_ADWELL_MAX_BUDGET_DIRECTED_SCAN 100 6548 /* adaptive dwell default high band APs number */ 6549 #define IWX_SCAN_ADWELL_DEFAULT_HB_N_APS 8 6550 /* adaptive dwell default low band APs number */ 6551 #define IWX_SCAN_ADWELL_DEFAULT_LB_N_APS 2 6552 /* adaptive dwell default APs number in social channels (1, 6, 11) */ 6553 #define IWX_SCAN_ADWELL_DEFAULT_N_APS_SOCIAL 10 6554 /* adaptive dwell number of APs override for p2p friendly GO channels */ 6555 #define IWX_SCAN_ADWELL_N_APS_GO_FRIENDLY 10 6556 /* adaptive dwell number of APs override for social channels */ 6557 #define IWX_SCAN_ADWELL_N_APS_SOCIAL_CHS 2 6558 6559 static void 6560 iwx_scan_umac_dwell_v10(struct iwx_softc *sc, 6561 struct iwx_scan_general_params_v10 *general_params, int bgscan) 6562 { 6563 uint32_t suspend_time, max_out_time; 6564 uint8_t active_dwell, passive_dwell; 6565 6566 active_dwell = IWX_SCAN_DWELL_ACTIVE; 6567 passive_dwell = IWX_SCAN_DWELL_PASSIVE; 6568 6569 general_params->adwell_default_social_chn = 6570 IWX_SCAN_ADWELL_DEFAULT_N_APS_SOCIAL; 6571 general_params->adwell_default_2g = IWX_SCAN_ADWELL_DEFAULT_LB_N_APS; 6572 general_params->adwell_default_5g = IWX_SCAN_ADWELL_DEFAULT_HB_N_APS; 6573 6574 if (bgscan) 6575 general_params->adwell_max_budget = 6576 htole16(IWX_SCAN_ADWELL_MAX_BUDGET_DIRECTED_SCAN); 6577 else 6578 general_params->adwell_max_budget = 6579 htole16(IWX_SCAN_ADWELL_MAX_BUDGET_FULL_SCAN); 6580 6581 general_params->scan_priority = htole32(IWX_SCAN_PRIORITY_EXT_6); 6582 if (bgscan) { 6583 max_out_time = htole32(120); 6584 suspend_time = htole32(120); 6585 } else { 6586 max_out_time = htole32(0); 6587 suspend_time = htole32(0); 6588 } 6589 general_params->max_out_of_time[IWX_SCAN_LB_LMAC_IDX] = 6590 htole32(max_out_time); 6591 general_params->suspend_time[IWX_SCAN_LB_LMAC_IDX] = 6592 htole32(suspend_time); 6593 general_params->max_out_of_time[IWX_SCAN_HB_LMAC_IDX] = 6594 htole32(max_out_time); 6595 general_params->suspend_time[IWX_SCAN_HB_LMAC_IDX] = 6596 htole32(suspend_time); 6597 6598 general_params->active_dwell[IWX_SCAN_LB_LMAC_IDX] = active_dwell; 6599 general_params->passive_dwell[IWX_SCAN_LB_LMAC_IDX] = passive_dwell; 6600 general_params->active_dwell[IWX_SCAN_HB_LMAC_IDX] = active_dwell; 6601 general_params->passive_dwell[IWX_SCAN_HB_LMAC_IDX] = passive_dwell; 6602 } 6603 6604 static void 6605 iwx_scan_umac_fill_general_p_v10(struct iwx_softc *sc, 6606 struct iwx_scan_general_params_v10 *gp, uint16_t gen_flags, int bgscan) 6607 { 6608 iwx_scan_umac_dwell_v10(sc, gp, bgscan); 6609 6610 gp->flags = htole16(gen_flags); 6611 6612 if (gen_flags & IWX_UMAC_SCAN_GEN_FLAGS_V2_FRAGMENTED_LMAC1) 6613 gp->num_of_fragments[IWX_SCAN_LB_LMAC_IDX] = 3; 6614 if (gen_flags & IWX_UMAC_SCAN_GEN_FLAGS_V2_FRAGMENTED_LMAC2) 6615 gp->num_of_fragments[IWX_SCAN_HB_LMAC_IDX] = 3; 6616 6617 gp->scan_start_mac_id = 0; 6618 } 6619 6620 static void 6621 iwx_scan_umac_fill_ch_p_v6(struct iwx_softc *sc, 6622 struct iwx_scan_channel_params_v6 *cp, uint32_t channel_cfg_flags, 6623 int n_ssid) 6624 { 6625 cp->flags = IWX_SCAN_CHANNEL_FLAG_ENABLE_CHAN_ORDER; 6626 6627 cp->count = iwx_umac_scan_fill_channels(sc, cp->channel_config, 6628 nitems(cp->channel_config), n_ssid, channel_cfg_flags); 6629 6630 cp->n_aps_override[0] = IWX_SCAN_ADWELL_N_APS_GO_FRIENDLY; 6631 cp->n_aps_override[1] = IWX_SCAN_ADWELL_N_APS_SOCIAL_CHS; 6632 } 6633 6634 static int 6635 iwx_umac_scan_v14(struct iwx_softc *sc, int bgscan) 6636 { 6637 struct ieee80211com *ic = &sc->sc_ic; 6638 struct ieee80211_scan_state *ss = ic->ic_scan; 6639 struct iwx_host_cmd hcmd = { 6640 .id = iwx_cmd_id(IWX_SCAN_REQ_UMAC, IWX_LONG_GROUP, 0), 6641 .len = { 0, }, 6642 .data = { NULL, }, 6643 .flags = 0, 6644 }; 6645 struct iwx_scan_req_umac_v14 *cmd = &sc->sc_umac_v14_cmd; 6646 struct iwx_scan_req_params_v14 *scan_p; 6647 int err, async = bgscan, n_ssid = 0; 6648 uint16_t gen_flags; 6649 uint32_t bitmap_ssid = 0; 6650 6651 IWX_ASSERT_LOCKED(sc); 6652 6653 bzero(cmd, sizeof(struct iwx_scan_req_umac_v14)); 6654 6655 scan_p = &cmd->scan_params; 6656 6657 cmd->ooc_priority = htole32(IWX_SCAN_PRIORITY_EXT_6); 6658 cmd->uid = htole32(0); 6659 6660 gen_flags = iwx_scan_umac_flags_v2(sc, bgscan); 6661 iwx_scan_umac_fill_general_p_v10(sc, &scan_p->general_params, 6662 gen_flags, bgscan); 6663 6664 scan_p->periodic_params.schedule[0].interval = htole16(0); 6665 scan_p->periodic_params.schedule[0].iter_count = 1; 6666 6667 err = iwx_fill_probe_req(sc, &scan_p->probe_params.preq); 6668 if (err) { 6669 printf("%s: iwx_fill_probe_req failed (error %d)\n", __func__, 6670 err); 6671 return err; 6672 } 6673 6674 for (int i=0; i < ss->ss_nssid; i++) { 6675 scan_p->probe_params.direct_scan[i].id = IEEE80211_ELEMID_SSID; 6676 scan_p->probe_params.direct_scan[i].len = 6677 MIN(ss->ss_ssid[i].len, IEEE80211_NWID_LEN); 6678 DPRINTF(("%s: Active scan started for ssid ", __func__)); 6679 memcpy(scan_p->probe_params.direct_scan[i].ssid, 6680 ss->ss_ssid[i].ssid, ss->ss_ssid[i].len); 6681 n_ssid++; 6682 bitmap_ssid |= (1 << i); 6683 } 6684 DPRINTF(("%s: bitmap_ssid=0x%x\n", __func__, bitmap_ssid)); 6685 6686 iwx_scan_umac_fill_ch_p_v6(sc, &scan_p->channel_params, bitmap_ssid, 6687 n_ssid); 6688 6689 hcmd.len[0] = sizeof(*cmd); 6690 hcmd.data[0] = (void *)cmd; 6691 hcmd.flags |= async ? IWX_CMD_ASYNC : 0; 6692 6693 err = iwx_send_cmd(sc, &hcmd); 6694 return err; 6695 } 6696 6697 static void 6698 iwx_mcc_update(struct iwx_softc *sc, struct iwx_mcc_chub_notif *notif) 6699 { 6700 char alpha2[3]; 6701 6702 snprintf(alpha2, sizeof(alpha2), "%c%c", 6703 (le16toh(notif->mcc) & 0xff00) >> 8, le16toh(notif->mcc) & 0xff); 6704 6705 IWX_DPRINTF(sc, IWX_DEBUG_FW, "%s: firmware has detected regulatory domain '%s' " 6706 "(0x%x)\n", DEVNAME(sc), alpha2, le16toh(notif->mcc)); 6707 6708 /* TODO: Schedule a task to send MCC_UPDATE_CMD? */ 6709 } 6710 6711 uint8_t 6712 iwx_ridx2rate(struct ieee80211_rateset *rs, int ridx) 6713 { 6714 int i; 6715 uint8_t rval; 6716 6717 for (i = 0; i < rs->rs_nrates; i++) { 6718 rval = (rs->rs_rates[i] & IEEE80211_RATE_VAL); 6719 if (rval == iwx_rates[ridx].rate) 6720 return rs->rs_rates[i]; 6721 } 6722 6723 return 0; 6724 } 6725 6726 static int 6727 iwx_rval2ridx(int rval) 6728 { 6729 int ridx; 6730 6731 for (ridx = 0; ridx < nitems(iwx_rates); ridx++) { 6732 if (iwx_rates[ridx].plcp == IWX_RATE_INVM_PLCP) 6733 continue; 6734 if (rval == iwx_rates[ridx].rate) 6735 break; 6736 } 6737 6738 return ridx; 6739 } 6740 6741 static void 6742 iwx_ack_rates(struct iwx_softc *sc, struct iwx_node *in, int *cck_rates, 6743 int *ofdm_rates) 6744 { 6745 struct ieee80211_node *ni = &in->in_ni; 6746 struct ieee80211_rateset *rs = &ni->ni_rates; 6747 int lowest_present_ofdm = -1; 6748 int lowest_present_cck = -1; 6749 uint8_t cck = 0; 6750 uint8_t ofdm = 0; 6751 int i; 6752 6753 if (ni->ni_chan == IEEE80211_CHAN_ANYC || 6754 IEEE80211_IS_CHAN_2GHZ(ni->ni_chan)) { 6755 for (i = IWX_FIRST_CCK_RATE; i < IWX_FIRST_OFDM_RATE; i++) { 6756 if ((iwx_ridx2rate(rs, i) & IEEE80211_RATE_BASIC) == 0) 6757 continue; 6758 cck |= (1 << i); 6759 if (lowest_present_cck == -1 || lowest_present_cck > i) 6760 lowest_present_cck = i; 6761 } 6762 } 6763 for (i = IWX_FIRST_OFDM_RATE; i <= IWX_LAST_NON_HT_RATE; i++) { 6764 if ((iwx_ridx2rate(rs, i) & IEEE80211_RATE_BASIC) == 0) 6765 continue; 6766 ofdm |= (1 << (i - IWX_FIRST_OFDM_RATE)); 6767 if (lowest_present_ofdm == -1 || lowest_present_ofdm > i) 6768 lowest_present_ofdm = i; 6769 } 6770 6771 /* 6772 * Now we've got the basic rates as bitmaps in the ofdm and cck 6773 * variables. This isn't sufficient though, as there might not 6774 * be all the right rates in the bitmap. E.g. if the only basic 6775 * rates are 5.5 Mbps and 11 Mbps, we still need to add 1 Mbps 6776 * and 6 Mbps because the 802.11-2007 standard says in 9.6: 6777 * 6778 * [...] a STA responding to a received frame shall transmit 6779 * its Control Response frame [...] at the highest rate in the 6780 * BSSBasicRateSet parameter that is less than or equal to the 6781 * rate of the immediately previous frame in the frame exchange 6782 * sequence ([...]) and that is of the same modulation class 6783 * ([...]) as the received frame. If no rate contained in the 6784 * BSSBasicRateSet parameter meets these conditions, then the 6785 * control frame sent in response to a received frame shall be 6786 * transmitted at the highest mandatory rate of the PHY that is 6787 * less than or equal to the rate of the received frame, and 6788 * that is of the same modulation class as the received frame. 6789 * 6790 * As a consequence, we need to add all mandatory rates that are 6791 * lower than all of the basic rates to these bitmaps. 6792 */ 6793 6794 if (IWX_RATE_24M_INDEX < lowest_present_ofdm) 6795 ofdm |= IWX_RATE_BIT_MSK(24) >> IWX_FIRST_OFDM_RATE; 6796 if (IWX_RATE_12M_INDEX < lowest_present_ofdm) 6797 ofdm |= IWX_RATE_BIT_MSK(12) >> IWX_FIRST_OFDM_RATE; 6798 /* 6M already there or needed so always add */ 6799 ofdm |= IWX_RATE_BIT_MSK(6) >> IWX_FIRST_OFDM_RATE; 6800 6801 /* 6802 * CCK is a bit more complex with DSSS vs. HR/DSSS vs. ERP. 6803 * Note, however: 6804 * - if no CCK rates are basic, it must be ERP since there must 6805 * be some basic rates at all, so they're OFDM => ERP PHY 6806 * (or we're in 5 GHz, and the cck bitmap will never be used) 6807 * - if 11M is a basic rate, it must be ERP as well, so add 5.5M 6808 * - if 5.5M is basic, 1M and 2M are mandatory 6809 * - if 2M is basic, 1M is mandatory 6810 * - if 1M is basic, that's the only valid ACK rate. 6811 * As a consequence, it's not as complicated as it sounds, just add 6812 * any lower rates to the ACK rate bitmap. 6813 */ 6814 if (IWX_RATE_11M_INDEX < lowest_present_cck) 6815 cck |= IWX_RATE_BIT_MSK(11) >> IWX_FIRST_CCK_RATE; 6816 if (IWX_RATE_5M_INDEX < lowest_present_cck) 6817 cck |= IWX_RATE_BIT_MSK(5) >> IWX_FIRST_CCK_RATE; 6818 if (IWX_RATE_2M_INDEX < lowest_present_cck) 6819 cck |= IWX_RATE_BIT_MSK(2) >> IWX_FIRST_CCK_RATE; 6820 /* 1M already there or needed so always add */ 6821 cck |= IWX_RATE_BIT_MSK(1) >> IWX_FIRST_CCK_RATE; 6822 6823 *cck_rates = cck; 6824 *ofdm_rates = ofdm; 6825 } 6826 6827 static void 6828 iwx_mac_ctxt_cmd_common(struct iwx_softc *sc, struct iwx_node *in, 6829 struct iwx_mac_ctx_cmd *cmd, uint32_t action) 6830 { 6831 #define IWX_EXP2(x) ((1 << (x)) - 1) /* CWmin = 2^ECWmin - 1 */ 6832 struct ieee80211com *ic = &sc->sc_ic; 6833 struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); 6834 struct ieee80211_node *ni = vap->iv_bss; 6835 int cck_ack_rates, ofdm_ack_rates; 6836 6837 cmd->id_and_color = htole32(IWX_FW_CMD_ID_AND_COLOR(in->in_id, 6838 in->in_color)); 6839 cmd->action = htole32(action); 6840 6841 if (action == IWX_FW_CTXT_ACTION_REMOVE) 6842 return; 6843 6844 if (ic->ic_opmode == IEEE80211_M_MONITOR) 6845 cmd->mac_type = htole32(IWX_FW_MAC_TYPE_LISTENER); 6846 else if (ic->ic_opmode == IEEE80211_M_STA) 6847 cmd->mac_type = htole32(IWX_FW_MAC_TYPE_BSS_STA); 6848 else 6849 panic("unsupported operating mode %d", ic->ic_opmode); 6850 cmd->tsf_id = htole32(IWX_TSF_ID_A); 6851 6852 IEEE80211_ADDR_COPY(cmd->node_addr, vap->iv_myaddr); 6853 DPRINTF(("%s: cmd->node_addr=%s\n", __func__, 6854 ether_sprintf(cmd->node_addr))); 6855 if (ic->ic_opmode == IEEE80211_M_MONITOR) { 6856 IEEE80211_ADDR_COPY(cmd->bssid_addr, etherbroadcastaddr); 6857 return; 6858 } 6859 6860 IEEE80211_ADDR_COPY(cmd->bssid_addr, in->in_macaddr); 6861 DPRINTF(("%s: cmd->bssid_addr=%s\n", __func__, 6862 ether_sprintf(cmd->bssid_addr))); 6863 iwx_ack_rates(sc, in, &cck_ack_rates, &ofdm_ack_rates); 6864 cmd->cck_rates = htole32(cck_ack_rates); 6865 cmd->ofdm_rates = htole32(ofdm_ack_rates); 6866 6867 cmd->cck_short_preamble 6868 = htole32((ic->ic_flags & IEEE80211_F_SHPREAMBLE) 6869 ? IWX_MAC_FLG_SHORT_PREAMBLE : 0); 6870 cmd->short_slot 6871 = htole32((ic->ic_flags & IEEE80211_F_SHSLOT) 6872 ? IWX_MAC_FLG_SHORT_SLOT : 0); 6873 6874 struct chanAccParams chp; 6875 ieee80211_wme_vap_getparams(vap, &chp); 6876 6877 for (int i = 0; i < WME_NUM_AC; i++) { 6878 int txf = iwx_ac_to_tx_fifo[i]; 6879 cmd->ac[txf].cw_min = IWX_EXP2(chp.cap_wmeParams[i].wmep_logcwmin); 6880 cmd->ac[txf].cw_max = IWX_EXP2(chp.cap_wmeParams[i].wmep_logcwmax); 6881 cmd->ac[txf].aifsn = chp.cap_wmeParams[i].wmep_aifsn; 6882 cmd->ac[txf].fifos_mask = (1 << txf); 6883 cmd->ac[txf].edca_txop = chp.cap_wmeParams[i].wmep_txopLimit; 6884 6885 cmd->ac[txf].edca_txop = htole16(chp.cap_wmeParams[i].wmep_txopLimit * 32); 6886 } 6887 6888 if (ni->ni_flags & IEEE80211_NODE_QOS) { 6889 DPRINTF(("%s: === IEEE80211_NODE_QOS\n", __func__)); 6890 cmd->qos_flags |= htole32(IWX_MAC_QOS_FLG_UPDATE_EDCA); 6891 } 6892 6893 if (ni->ni_flags & IEEE80211_NODE_HT) { 6894 switch (vap->iv_curhtprotmode) { 6895 case IEEE80211_HTINFO_OPMODE_PURE: 6896 break; 6897 case IEEE80211_HTINFO_OPMODE_PROTOPT: 6898 case IEEE80211_HTINFO_OPMODE_MIXED: 6899 cmd->protection_flags |= 6900 htole32(IWX_MAC_PROT_FLG_HT_PROT | 6901 IWX_MAC_PROT_FLG_FAT_PROT); 6902 break; 6903 case IEEE80211_HTINFO_OPMODE_HT20PR: 6904 if (in->in_phyctxt && 6905 (in->in_phyctxt->sco == IEEE80211_HTINFO_2NDCHAN_ABOVE || 6906 in->in_phyctxt->sco == IEEE80211_HTINFO_2NDCHAN_BELOW)) { 6907 cmd->protection_flags |= 6908 htole32(IWX_MAC_PROT_FLG_HT_PROT | 6909 IWX_MAC_PROT_FLG_FAT_PROT); 6910 } 6911 break; 6912 default: 6913 break; 6914 } 6915 cmd->qos_flags |= htole32(IWX_MAC_QOS_FLG_TGN); 6916 DPRINTF(("%s: === IWX_MAC_QOS_FLG_TGN\n", __func__)); 6917 } 6918 6919 if (ic->ic_flags & IEEE80211_F_USEPROT) 6920 cmd->protection_flags |= htole32(IWX_MAC_PROT_FLG_TGG_PROTECT); 6921 cmd->filter_flags = htole32(IWX_MAC_FILTER_ACCEPT_GRP); 6922 #undef IWX_EXP2 6923 } 6924 6925 static void 6926 iwx_mac_ctxt_cmd_fill_sta(struct iwx_softc *sc, struct iwx_node *in, 6927 struct iwx_mac_data_sta *sta, int assoc) 6928 { 6929 struct ieee80211_node *ni = &in->in_ni; 6930 struct ieee80211com *ic = &sc->sc_ic; 6931 struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); 6932 uint32_t dtim_off; 6933 uint64_t tsf; 6934 int dtim_period; 6935 6936 dtim_off = ni->ni_dtim_count * ni->ni_intval * IEEE80211_DUR_TU; 6937 tsf = le64toh(ni->ni_tstamp.tsf); 6938 dtim_period = vap->iv_dtim_period; 6939 6940 sta->is_assoc = htole32(assoc); 6941 6942 if (assoc) { 6943 sta->dtim_time = htole32(tsf + dtim_off); 6944 sta->dtim_tsf = htole64(tsf + dtim_off); 6945 // XXX: unset in iwm 6946 sta->assoc_beacon_arrive_time = 0; 6947 } 6948 sta->bi = htole32(ni->ni_intval); 6949 sta->dtim_interval = htole32(ni->ni_intval * dtim_period); 6950 sta->data_policy = htole32(0); 6951 sta->listen_interval = htole32(10); 6952 sta->assoc_id = htole32(ni->ni_associd); 6953 } 6954 6955 static int 6956 iwx_mac_ctxt_cmd(struct iwx_softc *sc, struct iwx_node *in, uint32_t action, 6957 int assoc) 6958 { 6959 struct ieee80211com *ic = &sc->sc_ic; 6960 struct ieee80211_node *ni = &in->in_ni; 6961 struct iwx_mac_ctx_cmd cmd; 6962 int active = (sc->sc_flags & IWX_FLAG_MAC_ACTIVE); 6963 6964 if (action == IWX_FW_CTXT_ACTION_ADD && active) 6965 panic("MAC already added"); 6966 if (action == IWX_FW_CTXT_ACTION_REMOVE && !active) 6967 panic("MAC already removed"); 6968 6969 memset(&cmd, 0, sizeof(cmd)); 6970 6971 iwx_mac_ctxt_cmd_common(sc, in, &cmd, action); 6972 6973 if (action == IWX_FW_CTXT_ACTION_REMOVE) { 6974 return iwx_send_cmd_pdu(sc, IWX_MAC_CONTEXT_CMD, 0, 6975 sizeof(cmd), &cmd); 6976 } 6977 6978 if (ic->ic_opmode == IEEE80211_M_MONITOR) { 6979 cmd.filter_flags |= htole32(IWX_MAC_FILTER_IN_PROMISC | 6980 IWX_MAC_FILTER_IN_CONTROL_AND_MGMT | 6981 IWX_MAC_FILTER_ACCEPT_GRP | 6982 IWX_MAC_FILTER_IN_BEACON | 6983 IWX_MAC_FILTER_IN_PROBE_REQUEST | 6984 IWX_MAC_FILTER_IN_CRC32); 6985 // XXX: dtim period is in vap 6986 } else if (!assoc || !ni->ni_associd /*|| !ni->ni_dtimperiod*/) { 6987 /* 6988 * Allow beacons to pass through as long as we are not 6989 * associated or we do not have dtim period information. 6990 */ 6991 cmd.filter_flags |= htole32(IWX_MAC_FILTER_IN_BEACON); 6992 } 6993 iwx_mac_ctxt_cmd_fill_sta(sc, in, &cmd.sta, assoc); 6994 return iwx_send_cmd_pdu(sc, IWX_MAC_CONTEXT_CMD, 0, sizeof(cmd), &cmd); 6995 } 6996 6997 static int 6998 iwx_clear_statistics(struct iwx_softc *sc) 6999 { 7000 struct iwx_statistics_cmd scmd = { 7001 .flags = htole32(IWX_STATISTICS_FLG_CLEAR) 7002 }; 7003 struct iwx_host_cmd cmd = { 7004 .id = IWX_STATISTICS_CMD, 7005 .len[0] = sizeof(scmd), 7006 .data[0] = &scmd, 7007 .flags = IWX_CMD_WANT_RESP, 7008 .resp_pkt_len = sizeof(struct iwx_notif_statistics), 7009 }; 7010 int err; 7011 7012 err = iwx_send_cmd(sc, &cmd); 7013 if (err) 7014 return err; 7015 7016 iwx_free_resp(sc, &cmd); 7017 return 0; 7018 } 7019 7020 static int 7021 iwx_scan(struct iwx_softc *sc) 7022 { 7023 int err; 7024 err = iwx_umac_scan_v14(sc, 0); 7025 7026 if (err) { 7027 printf("%s: could not initiate scan\n", DEVNAME(sc)); 7028 return err; 7029 } 7030 return 0; 7031 } 7032 7033 static int 7034 iwx_bgscan(struct ieee80211com *ic) 7035 { 7036 struct iwx_softc *sc = ic->ic_softc; 7037 int err; 7038 7039 err = iwx_umac_scan_v14(sc, 1); 7040 if (err) { 7041 printf("%s: could not initiate scan\n", DEVNAME(sc)); 7042 return err; 7043 } 7044 return 0; 7045 } 7046 7047 static int 7048 iwx_enable_mgmt_queue(struct iwx_softc *sc) 7049 { 7050 int err; 7051 7052 sc->first_data_qid = IWX_DQA_CMD_QUEUE + 1; 7053 7054 /* 7055 * Non-QoS frames use the "MGMT" TID and queue. 7056 * Other TIDs and data queues are reserved for QoS data frames. 7057 */ 7058 err = iwx_enable_txq(sc, IWX_STATION_ID, sc->first_data_qid, 7059 IWX_MGMT_TID, IWX_TX_RING_COUNT); 7060 if (err) { 7061 printf("%s: could not enable Tx queue %d (error %d)\n", 7062 DEVNAME(sc), sc->first_data_qid, err); 7063 return err; 7064 } 7065 7066 return 0; 7067 } 7068 7069 static int 7070 iwx_disable_mgmt_queue(struct iwx_softc *sc) 7071 { 7072 int err, cmd_ver; 7073 7074 /* Explicit removal is only required with old SCD_QUEUE_CFG command. */ 7075 cmd_ver = iwx_lookup_cmd_ver(sc, IWX_DATA_PATH_GROUP, 7076 IWX_SCD_QUEUE_CONFIG_CMD); 7077 if (cmd_ver == 0 || cmd_ver == IWX_FW_CMD_VER_UNKNOWN) 7078 return 0; 7079 7080 sc->first_data_qid = IWX_DQA_CMD_QUEUE + 1; 7081 7082 err = iwx_disable_txq(sc, IWX_STATION_ID, sc->first_data_qid, 7083 IWX_MGMT_TID); 7084 if (err) { 7085 printf("%s: could not disable Tx queue %d (error %d)\n", 7086 DEVNAME(sc), sc->first_data_qid, err); 7087 return err; 7088 } 7089 7090 return 0; 7091 } 7092 7093 static int 7094 iwx_rs_rval2idx(uint8_t rval) 7095 { 7096 /* Firmware expects indices which match our 11g rate set. */ 7097 const struct ieee80211_rateset *rs = &ieee80211_std_rateset_11g; 7098 int i; 7099 7100 for (i = 0; i < rs->rs_nrates; i++) { 7101 if ((rs->rs_rates[i] & IEEE80211_RATE_VAL) == rval) 7102 return i; 7103 } 7104 7105 return -1; 7106 } 7107 7108 static uint16_t 7109 iwx_rs_ht_rates(struct iwx_softc *sc, struct ieee80211_node *ni, int rsidx) 7110 { 7111 uint16_t htrates = 0; 7112 struct ieee80211_htrateset *htrs = &ni->ni_htrates; 7113 int i; 7114 7115 if (rsidx == IEEE80211_HT_RATESET_SISO) { 7116 for (i = 0; i < htrs->rs_nrates; i++) { 7117 if (htrs->rs_rates[i] <= 7) 7118 htrates |= (1 << htrs->rs_rates[i]); 7119 } 7120 } else if (rsidx == IEEE80211_HT_RATESET_MIMO2) { 7121 for (i = 0; i < htrs->rs_nrates; i++) { 7122 if (htrs->rs_rates[i] > 7 && htrs->rs_rates[i] <= 15) 7123 htrates |= (1 << (htrs->rs_rates[i] - 8)); 7124 } 7125 } else 7126 panic(("iwx_rs_ht_rates")); 7127 7128 IWX_DPRINTF(sc, IWX_DEBUG_TXRATE, 7129 "%s:%d rsidx=%i htrates=0x%x\n", __func__, __LINE__, rsidx, htrates); 7130 7131 return htrates; 7132 } 7133 7134 uint16_t 7135 iwx_rs_vht_rates(struct iwx_softc *sc, struct ieee80211_node *ni, int num_ss) 7136 { 7137 uint16_t rx_mcs; 7138 int max_mcs = -1; 7139 #define IEEE80211_VHT_MCS_FOR_SS_MASK(n) (0x3 << (2*((n)-1))) 7140 #define IEEE80211_VHT_MCS_FOR_SS_SHIFT(n) (2*((n)-1)) 7141 rx_mcs = (ni->ni_vht_mcsinfo.tx_mcs_map & 7142 IEEE80211_VHT_MCS_FOR_SS_MASK(num_ss)) >> 7143 IEEE80211_VHT_MCS_FOR_SS_SHIFT(num_ss); 7144 7145 switch (rx_mcs) { 7146 case IEEE80211_VHT_MCS_NOT_SUPPORTED: 7147 break; 7148 case IEEE80211_VHT_MCS_SUPPORT_0_7: 7149 max_mcs = 7; 7150 break; 7151 case IEEE80211_VHT_MCS_SUPPORT_0_8: 7152 max_mcs = 8; 7153 break; 7154 case IEEE80211_VHT_MCS_SUPPORT_0_9: 7155 /* Disable VHT MCS 9 for 20MHz-only stations. */ 7156 if ((ni->ni_htcap & IEEE80211_HTCAP_CHWIDTH40) == 0) 7157 max_mcs = 8; 7158 else 7159 max_mcs = 9; 7160 break; 7161 default: 7162 /* Should not happen; Values above cover the possible range. */ 7163 panic("invalid VHT Rx MCS value %u", rx_mcs); 7164 } 7165 7166 return ((1 << (max_mcs + 1)) - 1); 7167 } 7168 7169 static int 7170 iwx_rs_init_v3(struct iwx_softc *sc, struct iwx_node *in) 7171 { 7172 #if 1 7173 panic("iwx: Trying to init rate set on untested version"); 7174 #else 7175 struct ieee80211_node *ni = &in->in_ni; 7176 struct ieee80211_rateset *rs = &ni->ni_rates; 7177 struct iwx_tlc_config_cmd_v3 cfg_cmd; 7178 uint32_t cmd_id; 7179 int i; 7180 size_t cmd_size = sizeof(cfg_cmd); 7181 7182 memset(&cfg_cmd, 0, sizeof(cfg_cmd)); 7183 7184 for (i = 0; i < rs->rs_nrates; i++) { 7185 uint8_t rval = rs->rs_rates[i] & IEEE80211_RATE_VAL; 7186 int idx = iwx_rs_rval2idx(rval); 7187 if (idx == -1) 7188 return EINVAL; 7189 cfg_cmd.non_ht_rates |= (1 << idx); 7190 } 7191 7192 if (ni->ni_flags & IEEE80211_NODE_VHT) { 7193 cfg_cmd.mode = IWX_TLC_MNG_MODE_VHT; 7194 cfg_cmd.ht_rates[IWX_TLC_NSS_1][IWX_TLC_MCS_PER_BW_80] = 7195 htole16(iwx_rs_vht_rates(sc, ni, 1)); 7196 cfg_cmd.ht_rates[IWX_TLC_NSS_2][IWX_TLC_MCS_PER_BW_80] = 7197 htole16(iwx_rs_vht_rates(sc, ni, 2)); 7198 } else if (ni->ni_flags & IEEE80211_NODE_HT) { 7199 cfg_cmd.mode = IWX_TLC_MNG_MODE_HT; 7200 cfg_cmd.ht_rates[IWX_TLC_NSS_1][IWX_TLC_MCS_PER_BW_80] = 7201 htole16(iwx_rs_ht_rates(sc, ni, 7202 IEEE80211_HT_RATESET_SISO)); 7203 cfg_cmd.ht_rates[IWX_TLC_NSS_2][IWX_TLC_MCS_PER_BW_80] = 7204 htole16(iwx_rs_ht_rates(sc, ni, 7205 IEEE80211_HT_RATESET_MIMO2)); 7206 } else 7207 cfg_cmd.mode = IWX_TLC_MNG_MODE_NON_HT; 7208 7209 cfg_cmd.sta_id = IWX_STATION_ID; 7210 if (in->in_phyctxt->vht_chan_width == IEEE80211_VHTOP0_CHAN_WIDTH_80) 7211 cfg_cmd.max_ch_width = IWX_TLC_MNG_CH_WIDTH_80MHZ; 7212 else if (in->in_phyctxt->sco == IEEE80211_HTOP0_SCO_SCA || 7213 in->in_phyctxt->sco == IEEE80211_HTOP0_SCO_SCB) 7214 cfg_cmd.max_ch_width = IWX_TLC_MNG_CH_WIDTH_40MHZ; 7215 else 7216 cfg_cmd.max_ch_width = IWX_TLC_MNG_CH_WIDTH_20MHZ; 7217 cfg_cmd.chains = IWX_TLC_MNG_CHAIN_A_MSK | IWX_TLC_MNG_CHAIN_B_MSK; 7218 if (ni->ni_flags & IEEE80211_NODE_VHT) 7219 cfg_cmd.max_mpdu_len = htole16(3895); 7220 else 7221 cfg_cmd.max_mpdu_len = htole16(3839); 7222 if (ni->ni_flags & IEEE80211_NODE_HT) { 7223 if (ieee80211_node_supports_ht_sgi20(ni)) { 7224 cfg_cmd.sgi_ch_width_supp |= (1 << 7225 IWX_TLC_MNG_CH_WIDTH_20MHZ); 7226 } 7227 if (ieee80211_node_supports_ht_sgi40(ni)) { 7228 cfg_cmd.sgi_ch_width_supp |= (1 << 7229 IWX_TLC_MNG_CH_WIDTH_40MHZ); 7230 } 7231 } 7232 if ((ni->ni_flags & IEEE80211_NODE_VHT) && 7233 ieee80211_node_supports_vht_sgi80(ni)) 7234 cfg_cmd.sgi_ch_width_supp |= (1 << IWX_TLC_MNG_CH_WIDTH_80MHZ); 7235 7236 cmd_id = iwx_cmd_id(IWX_TLC_MNG_CONFIG_CMD, IWX_DATA_PATH_GROUP, 0); 7237 return iwx_send_cmd_pdu(sc, cmd_id, IWX_CMD_ASYNC, cmd_size, &cfg_cmd); 7238 #endif 7239 } 7240 7241 static int 7242 iwx_rs_init_v4(struct iwx_softc *sc, struct iwx_node *in) 7243 { 7244 struct ieee80211_node *ni = &in->in_ni; 7245 struct ieee80211_rateset *rs = &ni->ni_rates; 7246 struct ieee80211_htrateset *htrs = &ni->ni_htrates; 7247 struct iwx_tlc_config_cmd_v4 cfg_cmd; 7248 uint32_t cmd_id; 7249 int i; 7250 int sgi80 = 0; 7251 size_t cmd_size = sizeof(cfg_cmd); 7252 7253 memset(&cfg_cmd, 0, sizeof(cfg_cmd)); 7254 7255 for (i = 0; i < rs->rs_nrates; i++) { 7256 uint8_t rval = rs->rs_rates[i] & IEEE80211_RATE_VAL; 7257 int idx = iwx_rs_rval2idx(rval); 7258 if (idx == -1) 7259 return EINVAL; 7260 cfg_cmd.non_ht_rates |= (1 << idx); 7261 } 7262 for (i = 0; i < htrs->rs_nrates; i++) { 7263 DPRINTF(("%s: htrate=%i\n", __func__, htrs->rs_rates[i])); 7264 } 7265 7266 if (ni->ni_flags & IEEE80211_NODE_VHT) { 7267 cfg_cmd.mode = IWX_TLC_MNG_MODE_VHT; 7268 cfg_cmd.ht_rates[IWX_TLC_NSS_1][IWX_TLC_MCS_PER_BW_80] = 7269 htole16(iwx_rs_vht_rates(sc, ni, 1)); 7270 cfg_cmd.ht_rates[IWX_TLC_NSS_2][IWX_TLC_MCS_PER_BW_80] = 7271 htole16(iwx_rs_vht_rates(sc, ni, 2)); 7272 7273 IWX_DPRINTF(sc, IWX_DEBUG_TXRATE, "%s:%d SISO=0x%x\n", 7274 __func__, __LINE__, 7275 cfg_cmd.ht_rates[IWX_TLC_NSS_1][IWX_TLC_MCS_PER_BW_80]); 7276 IWX_DPRINTF(sc, IWX_DEBUG_TXRATE, "%s:%d MIMO2=0x%x\n", 7277 __func__, __LINE__, 7278 cfg_cmd.ht_rates[IWX_TLC_NSS_2][IWX_TLC_MCS_PER_BW_80]); 7279 } else if (ni->ni_flags & IEEE80211_NODE_HT) { 7280 cfg_cmd.mode = IWX_TLC_MNG_MODE_HT; 7281 cfg_cmd.ht_rates[IWX_TLC_NSS_1][IWX_TLC_MCS_PER_BW_80] = 7282 htole16(iwx_rs_ht_rates(sc, ni, 7283 IEEE80211_HT_RATESET_SISO)); 7284 cfg_cmd.ht_rates[IWX_TLC_NSS_2][IWX_TLC_MCS_PER_BW_80] = 7285 htole16(iwx_rs_ht_rates(sc, ni, 7286 IEEE80211_HT_RATESET_MIMO2)); 7287 7288 IWX_DPRINTF(sc, IWX_DEBUG_TXRATE, "%s:%d SISO=0x%x\n", 7289 __func__, __LINE__, 7290 cfg_cmd.ht_rates[IWX_TLC_NSS_1][IWX_TLC_MCS_PER_BW_80]); 7291 IWX_DPRINTF(sc, IWX_DEBUG_TXRATE, "%s:%d MIMO2=0x%x\n", 7292 __func__, __LINE__, 7293 cfg_cmd.ht_rates[IWX_TLC_NSS_2][IWX_TLC_MCS_PER_BW_80]); 7294 } else 7295 cfg_cmd.mode = IWX_TLC_MNG_MODE_NON_HT; 7296 7297 cfg_cmd.sta_id = IWX_STATION_ID; 7298 #if 0 7299 if (in->in_phyctxt->vht_chan_width == IEEE80211_VHTOP0_CHAN_WIDTH_80) 7300 cfg_cmd.max_ch_width = IWX_TLC_MNG_CH_WIDTH_80MHZ; 7301 else if (in->in_phyctxt->sco == IEEE80211_HTOP0_SCO_SCA || 7302 in->in_phyctxt->sco == IEEE80211_HTOP0_SCO_SCB) 7303 cfg_cmd.max_ch_width = IWX_TLC_MNG_CH_WIDTH_40MHZ; 7304 else 7305 cfg_cmd.max_ch_width = IWX_TLC_MNG_CH_WIDTH_20MHZ; 7306 #endif 7307 if (IEEE80211_IS_CHAN_VHT80(in->in_ni.ni_chan)) { 7308 cfg_cmd.max_ch_width = IWX_TLC_MNG_CH_WIDTH_80MHZ; 7309 } else if (IEEE80211_IS_CHAN_HT40(in->in_ni.ni_chan)) { 7310 cfg_cmd.max_ch_width = IWX_TLC_MNG_CH_WIDTH_40MHZ; 7311 } else { 7312 cfg_cmd.max_ch_width = IWX_TLC_MNG_CH_WIDTH_20MHZ; 7313 } 7314 7315 cfg_cmd.chains = IWX_TLC_MNG_CHAIN_A_MSK | IWX_TLC_MNG_CHAIN_B_MSK; 7316 if (ni->ni_flags & IEEE80211_NODE_VHT) 7317 cfg_cmd.max_mpdu_len = htole16(3895); 7318 else 7319 cfg_cmd.max_mpdu_len = htole16(3839); 7320 if (ni->ni_flags & IEEE80211_NODE_HT) { 7321 if (ni->ni_htcap & IEEE80211_HTCAP_SHORTGI20) { 7322 cfg_cmd.sgi_ch_width_supp |= (1 << 7323 IWX_TLC_MNG_CH_WIDTH_20MHZ); 7324 } 7325 if (ni->ni_htcap & IEEE80211_HTCAP_SHORTGI40) { 7326 cfg_cmd.sgi_ch_width_supp |= (1 << 7327 IWX_TLC_MNG_CH_WIDTH_40MHZ); 7328 } 7329 } 7330 sgi80 = _IEEE80211_MASKSHIFT(ni->ni_vhtcap, 7331 IEEE80211_VHTCAP_SHORT_GI_80); 7332 if ((ni->ni_flags & IEEE80211_NODE_VHT) && sgi80) { 7333 cfg_cmd.sgi_ch_width_supp |= (1 << IWX_TLC_MNG_CH_WIDTH_80MHZ); 7334 } 7335 7336 cmd_id = iwx_cmd_id(IWX_TLC_MNG_CONFIG_CMD, IWX_DATA_PATH_GROUP, 0); 7337 return iwx_send_cmd_pdu(sc, cmd_id, IWX_CMD_ASYNC, cmd_size, &cfg_cmd); 7338 } 7339 7340 static int 7341 iwx_rs_init(struct iwx_softc *sc, struct iwx_node *in) 7342 { 7343 int cmd_ver; 7344 7345 cmd_ver = iwx_lookup_cmd_ver(sc, IWX_DATA_PATH_GROUP, 7346 IWX_TLC_MNG_CONFIG_CMD); 7347 if (cmd_ver == 4) 7348 return iwx_rs_init_v4(sc, in); 7349 else 7350 return iwx_rs_init_v3(sc, in); 7351 } 7352 7353 7354 /** 7355 * @brief Turn the given TX rate control notification into an ieee80211_node_txrate 7356 * 7357 * This populates the given txrate node with the TX rate control notification. 7358 * 7359 * @param sc driver softc 7360 * @param notif firmware notification 7361 * @param ni ieee80211_node update 7362 * @returns true if updated, false if not 7363 */ 7364 static bool 7365 iwx_rs_update_node_txrate(struct iwx_softc *sc, 7366 const struct iwx_tlc_update_notif *notif, struct ieee80211_node *ni) 7367 { 7368 struct ieee80211com *ic = &sc->sc_ic; 7369 /* XXX TODO: create an inline function in if_iwxreg.h? */ 7370 static int cck_idx_to_rate[] = { 2, 4, 11, 22, 2, 2, 2, 2 }; 7371 static int ofdm_idx_to_rate[] = { 12, 18, 24, 36, 48, 72, 96, 108 }; 7372 7373 uint32_t rate_n_flags; 7374 uint32_t type; 7375 7376 /* Extract the rate and command version */ 7377 rate_n_flags = le32toh(notif->rate); 7378 7379 if (sc->sc_rate_n_flags_version != 2) { 7380 net80211_ic_printf(ic, 7381 "%s: unsupported rate_n_flags version (%d)\n", 7382 __func__, 7383 sc->sc_rate_n_flags_version); 7384 return (false); 7385 } 7386 7387 if (sc->sc_debug & IWX_DEBUG_TXRATE) 7388 print_ratenflags(__func__, __LINE__, 7389 rate_n_flags, sc->sc_rate_n_flags_version); 7390 7391 type = (rate_n_flags & IWX_RATE_MCS_MOD_TYPE_MSK); 7392 switch (type) { 7393 case IWX_RATE_MCS_CCK_MSK: 7394 ieee80211_node_set_txrate_dot11rate(ni, 7395 cck_idx_to_rate[rate_n_flags & IWX_RATE_LEGACY_RATE_MSK]); 7396 return (true); 7397 case IWX_RATE_MCS_LEGACY_OFDM_MSK: 7398 ieee80211_node_set_txrate_dot11rate(ni, 7399 ofdm_idx_to_rate[rate_n_flags & IWX_RATE_LEGACY_RATE_MSK]); 7400 return (true); 7401 case IWX_RATE_MCS_HT_MSK: 7402 /* 7403 * TODO: the current API doesn't include channel width 7404 * and other flags, so we can't accurately store them yet! 7405 * 7406 * channel width: (flags & IWX_RATE_MCS_CHAN_WIDTH_MSK) 7407 * >> IWX_RATE_MCS_CHAN_WIDTH_POS) 7408 * LDPC: (flags & (1 << 16)) 7409 */ 7410 ieee80211_node_set_txrate_ht_mcsrate(ni, 7411 IWX_RATE_HT_MCS_INDEX(rate_n_flags)); 7412 return (true); 7413 case IWX_RATE_MCS_VHT_MSK: 7414 /* TODO: same comment on channel width, etc above */ 7415 ieee80211_node_set_txrate_vht_rate(ni, 7416 IWX_RATE_VHT_MCS_CODE(rate_n_flags), 7417 IWX_RATE_VHT_MCS_NSS(rate_n_flags)); 7418 return (true); 7419 default: 7420 net80211_ic_printf(ic, 7421 "%s: unsupported chosen rate type in " 7422 "IWX_RATE_MCS_MOD_TYPE (%d)\n", __func__, 7423 type >> IWX_RATE_MCS_MOD_TYPE_POS); 7424 return (false); 7425 } 7426 7427 /* Default: if we get here, we didn't successfully update anything */ 7428 return (false); 7429 } 7430 7431 /** 7432 * @brief Process a firmware rate control update and update net80211. 7433 * 7434 * Since firmware is doing rate control, this just needs to update 7435 * the txrate in the ieee80211_node entry. 7436 */ 7437 static void 7438 iwx_rs_update(struct iwx_softc *sc, struct iwx_tlc_update_notif *notif) 7439 { 7440 struct ieee80211com *ic = &sc->sc_ic; 7441 struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); 7442 /* XXX TODO: get a node ref! */ 7443 struct ieee80211_node *ni = (void *)vap->iv_bss; 7444 7445 /* 7446 * For now the iwx driver only supports a single vdev with a single 7447 * node; it doesn't yet support ibss/hostap/multiple vdevs. 7448 */ 7449 if (notif->sta_id != IWX_STATION_ID || 7450 (le32toh(notif->flags) & IWX_TLC_NOTIF_FLAG_RATE) == 0) 7451 return; 7452 7453 iwx_rs_update_node_txrate(sc, notif, ni); 7454 } 7455 7456 static int 7457 iwx_phy_send_rlc(struct iwx_softc *sc, struct iwx_phy_ctxt *phyctxt, 7458 uint8_t chains_static, uint8_t chains_dynamic) 7459 { 7460 struct iwx_rlc_config_cmd cmd; 7461 uint32_t cmd_id; 7462 uint8_t active_cnt, idle_cnt; 7463 7464 memset(&cmd, 0, sizeof(cmd)); 7465 7466 idle_cnt = chains_static; 7467 active_cnt = chains_dynamic; 7468 7469 cmd.phy_id = htole32(phyctxt->id); 7470 cmd.rlc.rx_chain_info = htole32(iwx_fw_valid_rx_ant(sc) << 7471 IWX_PHY_RX_CHAIN_VALID_POS); 7472 cmd.rlc.rx_chain_info |= htole32(idle_cnt << IWX_PHY_RX_CHAIN_CNT_POS); 7473 cmd.rlc.rx_chain_info |= htole32(active_cnt << 7474 IWX_PHY_RX_CHAIN_MIMO_CNT_POS); 7475 7476 cmd_id = iwx_cmd_id(IWX_RLC_CONFIG_CMD, IWX_DATA_PATH_GROUP, 2); 7477 return iwx_send_cmd_pdu(sc, cmd_id, 0, sizeof(cmd), &cmd); 7478 } 7479 7480 static int 7481 iwx_phy_ctxt_update(struct iwx_softc *sc, struct iwx_phy_ctxt *phyctxt, 7482 struct ieee80211_channel *chan, uint8_t chains_static, 7483 uint8_t chains_dynamic, uint32_t apply_time, uint8_t sco, 7484 uint8_t vht_chan_width) 7485 { 7486 uint16_t band_flags = (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_5GHZ); 7487 int err; 7488 7489 if (chan == IEEE80211_CHAN_ANYC) { 7490 printf("%s: GOS-3833: IEEE80211_CHAN_ANYC triggered\n", 7491 DEVNAME(sc)); 7492 return EIO; 7493 } 7494 7495 if (isset(sc->sc_enabled_capa, 7496 IWX_UCODE_TLV_CAPA_BINDING_CDB_SUPPORT) && 7497 (phyctxt->channel->ic_flags & band_flags) != 7498 (chan->ic_flags & band_flags)) { 7499 err = iwx_phy_ctxt_cmd(sc, phyctxt, chains_static, 7500 chains_dynamic, IWX_FW_CTXT_ACTION_REMOVE, apply_time, sco, 7501 vht_chan_width); 7502 if (err) { 7503 printf("%s: could not remove PHY context " 7504 "(error %d)\n", DEVNAME(sc), err); 7505 return err; 7506 } 7507 phyctxt->channel = chan; 7508 err = iwx_phy_ctxt_cmd(sc, phyctxt, chains_static, 7509 chains_dynamic, IWX_FW_CTXT_ACTION_ADD, apply_time, sco, 7510 vht_chan_width); 7511 if (err) { 7512 printf("%s: could not add PHY context " 7513 "(error %d)\n", DEVNAME(sc), err); 7514 return err; 7515 } 7516 } else { 7517 phyctxt->channel = chan; 7518 err = iwx_phy_ctxt_cmd(sc, phyctxt, chains_static, 7519 chains_dynamic, IWX_FW_CTXT_ACTION_MODIFY, apply_time, sco, 7520 vht_chan_width); 7521 if (err) { 7522 printf("%s: could not update PHY context (error %d)\n", 7523 DEVNAME(sc), err); 7524 return err; 7525 } 7526 } 7527 7528 phyctxt->sco = sco; 7529 phyctxt->vht_chan_width = vht_chan_width; 7530 7531 DPRINTF(("%s: phyctxt->channel->ic_ieee=%d\n", __func__, 7532 phyctxt->channel->ic_ieee)); 7533 DPRINTF(("%s: phyctxt->sco=%d\n", __func__, phyctxt->sco)); 7534 DPRINTF(("%s: phyctxt->vht_chan_width=%d\n", __func__, 7535 phyctxt->vht_chan_width)); 7536 7537 if (iwx_lookup_cmd_ver(sc, IWX_DATA_PATH_GROUP, 7538 IWX_RLC_CONFIG_CMD) == 2) 7539 return iwx_phy_send_rlc(sc, phyctxt, 7540 chains_static, chains_dynamic); 7541 7542 return 0; 7543 } 7544 7545 static int 7546 iwx_auth(struct ieee80211vap *vap, struct iwx_softc *sc) 7547 { 7548 struct ieee80211com *ic = &sc->sc_ic; 7549 struct iwx_node *in; 7550 struct iwx_vap *ivp = IWX_VAP(vap); 7551 struct ieee80211_node *ni; 7552 uint32_t duration; 7553 int generation = sc->sc_generation, err; 7554 7555 IWX_ASSERT_LOCKED(sc); 7556 7557 ni = ieee80211_ref_node(vap->iv_bss); 7558 in = IWX_NODE(ni); 7559 7560 if (ic->ic_opmode == IEEE80211_M_MONITOR) { 7561 err = iwx_phy_ctxt_update(sc, &sc->sc_phyctxt[0], 7562 ic->ic_bsschan, 1, 1, 0, IEEE80211_HTOP0_SCO_SCN, 7563 IEEE80211_VHTOP0_CHAN_WIDTH_HT); 7564 if (err) 7565 return err; 7566 } else { 7567 err = iwx_phy_ctxt_update(sc, &sc->sc_phyctxt[0], 7568 in->in_ni.ni_chan, 1, 1, 0, IEEE80211_HTOP0_SCO_SCN, 7569 IEEE80211_VHTOP0_CHAN_WIDTH_HT); 7570 if (err) 7571 return err; 7572 } 7573 ivp->phy_ctxt = &sc->sc_phyctxt[0]; 7574 IEEE80211_ADDR_COPY(in->in_macaddr, in->in_ni.ni_macaddr); 7575 DPRINTF(("%s: in-in_macaddr=%s\n", __func__, 7576 ether_sprintf(in->in_macaddr))); 7577 7578 err = iwx_mac_ctxt_cmd(sc, in, IWX_FW_CTXT_ACTION_ADD, 0); 7579 if (err) { 7580 printf("%s: could not add MAC context (error %d)\n", 7581 DEVNAME(sc), err); 7582 return err; 7583 } 7584 sc->sc_flags |= IWX_FLAG_MAC_ACTIVE; 7585 7586 err = iwx_binding_cmd(sc, in, IWX_FW_CTXT_ACTION_ADD); 7587 if (err) { 7588 printf("%s: could not add binding (error %d)\n", 7589 DEVNAME(sc), err); 7590 goto rm_mac_ctxt; 7591 } 7592 sc->sc_flags |= IWX_FLAG_BINDING_ACTIVE; 7593 7594 err = iwx_add_sta_cmd(sc, in, 0); 7595 if (err) { 7596 printf("%s: could not add sta (error %d)\n", 7597 DEVNAME(sc), err); 7598 goto rm_binding; 7599 } 7600 sc->sc_flags |= IWX_FLAG_STA_ACTIVE; 7601 7602 if (ic->ic_opmode == IEEE80211_M_MONITOR) { 7603 err = iwx_enable_txq(sc, IWX_MONITOR_STA_ID, 7604 IWX_DQA_INJECT_MONITOR_QUEUE, IWX_MGMT_TID, 7605 IWX_TX_RING_COUNT); 7606 if (err) 7607 goto rm_sta; 7608 return 0; 7609 } 7610 7611 err = iwx_enable_mgmt_queue(sc); 7612 if (err) 7613 goto rm_sta; 7614 7615 err = iwx_clear_statistics(sc); 7616 if (err) 7617 goto rm_mgmt_queue; 7618 7619 /* 7620 * Prevent the FW from wandering off channel during association 7621 * by "protecting" the session with a time event. 7622 */ 7623 if (in->in_ni.ni_intval) 7624 duration = in->in_ni.ni_intval * 9; 7625 else 7626 duration = 900; 7627 return iwx_schedule_session_protection(sc, in, duration); 7628 7629 rm_mgmt_queue: 7630 if (generation == sc->sc_generation) 7631 iwx_disable_mgmt_queue(sc); 7632 rm_sta: 7633 if (generation == sc->sc_generation) { 7634 iwx_rm_sta_cmd(sc, in); 7635 sc->sc_flags &= ~IWX_FLAG_STA_ACTIVE; 7636 } 7637 rm_binding: 7638 if (generation == sc->sc_generation) { 7639 iwx_binding_cmd(sc, in, IWX_FW_CTXT_ACTION_REMOVE); 7640 sc->sc_flags &= ~IWX_FLAG_BINDING_ACTIVE; 7641 } 7642 rm_mac_ctxt: 7643 if (generation == sc->sc_generation) { 7644 iwx_mac_ctxt_cmd(sc, in, IWX_FW_CTXT_ACTION_REMOVE, 0); 7645 sc->sc_flags &= ~IWX_FLAG_MAC_ACTIVE; 7646 } 7647 return err; 7648 } 7649 7650 static int 7651 iwx_deauth(struct iwx_softc *sc) 7652 { 7653 struct ieee80211com *ic = &sc->sc_ic; 7654 struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); 7655 struct iwx_node *in = IWX_NODE(vap->iv_bss); 7656 int err; 7657 7658 IWX_ASSERT_LOCKED(sc); 7659 7660 iwx_unprotect_session(sc, in); 7661 7662 if (sc->sc_flags & IWX_FLAG_STA_ACTIVE) { 7663 err = iwx_rm_sta(sc, in); 7664 if (err) 7665 return err; 7666 sc->sc_flags &= ~IWX_FLAG_STA_ACTIVE; 7667 } 7668 7669 if (sc->sc_flags & IWX_FLAG_BINDING_ACTIVE) { 7670 err = iwx_binding_cmd(sc, in, IWX_FW_CTXT_ACTION_REMOVE); 7671 if (err) { 7672 printf("%s: could not remove binding (error %d)\n", 7673 DEVNAME(sc), err); 7674 return err; 7675 } 7676 sc->sc_flags &= ~IWX_FLAG_BINDING_ACTIVE; 7677 } 7678 7679 DPRINTF(("%s: IWX_FLAG_MAC_ACTIVE=%d\n", __func__, sc->sc_flags & 7680 IWX_FLAG_MAC_ACTIVE)); 7681 if (sc->sc_flags & IWX_FLAG_MAC_ACTIVE) { 7682 err = iwx_mac_ctxt_cmd(sc, in, IWX_FW_CTXT_ACTION_REMOVE, 0); 7683 if (err) { 7684 printf("%s: could not remove MAC context (error %d)\n", 7685 DEVNAME(sc), err); 7686 return err; 7687 } 7688 sc->sc_flags &= ~IWX_FLAG_MAC_ACTIVE; 7689 } 7690 7691 /* Move unused PHY context to a default channel. */ 7692 //TODO uncommented in obsd, but stays on the way of auth->auth 7693 err = iwx_phy_ctxt_update(sc, &sc->sc_phyctxt[0], 7694 &ic->ic_channels[1], 1, 1, 0, IEEE80211_HTOP0_SCO_SCN, 7695 IEEE80211_VHTOP0_CHAN_WIDTH_HT); 7696 if (err) 7697 return err; 7698 7699 return 0; 7700 } 7701 7702 static int 7703 iwx_run(struct ieee80211vap *vap, struct iwx_softc *sc) 7704 { 7705 struct ieee80211com *ic = &sc->sc_ic; 7706 struct iwx_node *in = IWX_NODE(vap->iv_bss); 7707 struct ieee80211_node *ni = &in->in_ni; 7708 struct iwx_vap *ivp = IWX_VAP(vap); 7709 int err; 7710 7711 IWX_ASSERT_LOCKED(sc); 7712 7713 if (ni->ni_flags & IEEE80211_NODE_HT) { 7714 uint8_t chains = iwx_mimo_enabled(sc) ? 2 : 1; 7715 uint8_t sco, vht_chan_width; 7716 sco = IEEE80211_HTOP0_SCO_SCN; 7717 if ((ni->ni_flags & IEEE80211_NODE_VHT) && 7718 IEEE80211_IS_CHAN_VHT80(ni->ni_chan)) 7719 vht_chan_width = IEEE80211_VHTOP0_CHAN_WIDTH_80; 7720 else 7721 vht_chan_width = IEEE80211_VHTOP0_CHAN_WIDTH_HT; 7722 err = iwx_phy_ctxt_update(sc, ivp->phy_ctxt, 7723 ivp->phy_ctxt->channel, chains, chains, 7724 0, sco, vht_chan_width); 7725 if (err) { 7726 printf("%s: failed to update PHY\n", DEVNAME(sc)); 7727 return err; 7728 } 7729 } 7730 7731 /* Update STA again to apply HT and VHT settings. */ 7732 err = iwx_add_sta_cmd(sc, in, 1); 7733 if (err) { 7734 printf("%s: could not update STA (error %d)\n", 7735 DEVNAME(sc), err); 7736 return err; 7737 } 7738 7739 /* We have now been assigned an associd by the AP. */ 7740 err = iwx_mac_ctxt_cmd(sc, in, IWX_FW_CTXT_ACTION_MODIFY, 1); 7741 if (err) { 7742 printf("%s: failed to update MAC\n", DEVNAME(sc)); 7743 return err; 7744 } 7745 7746 err = iwx_sf_config(sc, IWX_SF_FULL_ON); 7747 if (err) { 7748 printf("%s: could not set sf full on (error %d)\n", 7749 DEVNAME(sc), err); 7750 return err; 7751 } 7752 7753 err = iwx_allow_mcast(sc); 7754 if (err) { 7755 printf("%s: could not allow mcast (error %d)\n", 7756 DEVNAME(sc), err); 7757 return err; 7758 } 7759 7760 err = iwx_power_update_device(sc); 7761 if (err) { 7762 printf("%s: could not send power command (error %d)\n", 7763 DEVNAME(sc), err); 7764 return err; 7765 } 7766 #ifdef notyet 7767 /* 7768 * Disabled for now. Default beacon filter settings 7769 * prevent net80211 from getting ERP and HT protection 7770 * updates from beacons. 7771 */ 7772 err = iwx_enable_beacon_filter(sc, in); 7773 if (err) { 7774 printf("%s: could not enable beacon filter\n", 7775 DEVNAME(sc)); 7776 return err; 7777 } 7778 #endif 7779 err = iwx_power_mac_update_mode(sc, in); 7780 if (err) { 7781 printf("%s: could not update MAC power (error %d)\n", 7782 DEVNAME(sc), err); 7783 return err; 7784 } 7785 7786 if (ic->ic_opmode == IEEE80211_M_MONITOR) 7787 return 0; 7788 7789 err = iwx_rs_init(sc, in); 7790 if (err) { 7791 printf("%s: could not init rate scaling (error %d)\n", 7792 DEVNAME(sc), err); 7793 return err; 7794 } 7795 7796 return 0; 7797 } 7798 7799 static int 7800 iwx_run_stop(struct iwx_softc *sc) 7801 { 7802 struct ieee80211com *ic = &sc->sc_ic; 7803 struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); 7804 struct iwx_node *in = IWX_NODE(vap->iv_bss); 7805 struct ieee80211_node *ni = &in->in_ni; 7806 int err, i; 7807 7808 IWX_ASSERT_LOCKED(sc); 7809 7810 err = iwx_flush_sta(sc, in); 7811 if (err) { 7812 printf("%s: could not flush Tx path (error %d)\n", 7813 DEVNAME(sc), err); 7814 return err; 7815 } 7816 7817 /* 7818 * Stop Rx BA sessions now. We cannot rely on the BA task 7819 * for this when moving out of RUN state since it runs in a 7820 * separate thread. 7821 * Note that in->in_ni (struct ieee80211_node) already represents 7822 * our new access point in case we are roaming between APs. 7823 * This means we cannot rely on struct ieee802111_node to tell 7824 * us which BA sessions exist. 7825 */ 7826 // TODO agg 7827 for (i = 0; i < nitems(sc->sc_rxba_data); i++) { 7828 struct iwx_rxba_data *rxba = &sc->sc_rxba_data[i]; 7829 if (rxba->baid == IWX_RX_REORDER_DATA_INVALID_BAID) 7830 continue; 7831 iwx_sta_rx_agg(sc, ni, rxba->tid, 0, 0, 0, 0); 7832 } 7833 7834 err = iwx_sf_config(sc, IWX_SF_INIT_OFF); 7835 if (err) 7836 return err; 7837 7838 err = iwx_disable_beacon_filter(sc); 7839 if (err) { 7840 printf("%s: could not disable beacon filter (error %d)\n", 7841 DEVNAME(sc), err); 7842 return err; 7843 } 7844 7845 /* Mark station as disassociated. */ 7846 err = iwx_mac_ctxt_cmd(sc, in, IWX_FW_CTXT_ACTION_MODIFY, 0); 7847 if (err) { 7848 printf("%s: failed to update MAC\n", DEVNAME(sc)); 7849 return err; 7850 } 7851 7852 return 0; 7853 } 7854 7855 static struct ieee80211_node * 7856 iwx_node_alloc(struct ieee80211vap *vap, const uint8_t mac[IEEE80211_ADDR_LEN]) 7857 { 7858 return malloc(sizeof (struct iwx_node), M_80211_NODE, 7859 M_NOWAIT | M_ZERO); 7860 } 7861 7862 #if 0 7863 int 7864 iwx_set_key(struct ieee80211com *ic, struct ieee80211_node *ni, 7865 struct ieee80211_key *k) 7866 { 7867 struct iwx_softc *sc = ic->ic_softc; 7868 struct iwx_node *in = (void *)ni; 7869 struct iwx_setkey_task_arg *a; 7870 int err; 7871 7872 if (k->k_cipher != IEEE80211_CIPHER_CCMP) { 7873 /* Fallback to software crypto for other ciphers. */ 7874 err = ieee80211_set_key(ic, ni, k); 7875 if (!err && in != NULL && (k->k_flags & IEEE80211_KEY_GROUP)) 7876 in->in_flags |= IWX_NODE_FLAG_HAVE_GROUP_KEY; 7877 return err; 7878 } 7879 7880 if (sc->setkey_nkeys >= nitems(sc->setkey_arg)) 7881 return ENOSPC; 7882 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); 7890 return EBUSY; 7891 } 7892 7893 int 7894 iwx_add_sta_key(struct iwx_softc *sc, int sta_id, struct ieee80211_node *ni, 7895 struct ieee80211_key *k) 7896 { 7897 struct ieee80211com *ic = &sc->sc_ic; 7898 struct iwx_node *in = (void *)ni; 7899 struct iwx_add_sta_key_cmd cmd; 7900 uint32_t status; 7901 const int want_keymask = (IWX_NODE_FLAG_HAVE_PAIRWISE_KEY | 7902 IWX_NODE_FLAG_HAVE_GROUP_KEY); 7903 int err; 7904 7905 /* 7906 * Keys are stored in 'ni' so 'k' is valid if 'ni' is valid. 7907 * Currently we only implement station mode where 'ni' is always 7908 * ic->ic_bss so there is no need to validate arguments beyond this: 7909 */ 7910 KASSERT(ni == ic->ic_bss); 7911 7912 memset(&cmd, 0, sizeof(cmd)); 7913 7914 cmd.common.key_flags = htole16(IWX_STA_KEY_FLG_CCM | 7915 IWX_STA_KEY_FLG_WEP_KEY_MAP | 7916 ((k->k_id << IWX_STA_KEY_FLG_KEYID_POS) & 7917 IWX_STA_KEY_FLG_KEYID_MSK)); 7918 if (k->k_flags & IEEE80211_KEY_GROUP) { 7919 cmd.common.key_offset = 1; 7920 cmd.common.key_flags |= htole16(IWX_STA_KEY_MULTICAST); 7921 } else 7922 cmd.common.key_offset = 0; 7923 7924 memcpy(cmd.common.key, k->k_key, MIN(sizeof(cmd.common.key), k->k_len)); 7925 cmd.common.sta_id = sta_id; 7926 7927 cmd.transmit_seq_cnt = htole64(k->k_tsc); 7928 7929 status = IWX_ADD_STA_SUCCESS; 7930 err = iwx_send_cmd_pdu_status(sc, IWX_ADD_STA_KEY, sizeof(cmd), &cmd, 7931 &status); 7932 if (sc->sc_flags & IWX_FLAG_SHUTDOWN) 7933 return ECANCELED; 7934 if (!err && (status & IWX_ADD_STA_STATUS_MASK) != IWX_ADD_STA_SUCCESS) 7935 err = EIO; 7936 if (err) { 7937 IEEE80211_SEND_MGMT(ic, ni, IEEE80211_FC0_SUBTYPE_DEAUTH, 7938 IEEE80211_REASON_AUTH_LEAVE); 7939 ieee80211_new_state(ic, IEEE80211_S_SCAN, -1); 7940 return err; 7941 } 7942 7943 if (k->k_flags & IEEE80211_KEY_GROUP) 7944 in->in_flags |= IWX_NODE_FLAG_HAVE_GROUP_KEY; 7945 else 7946 in->in_flags |= IWX_NODE_FLAG_HAVE_PAIRWISE_KEY; 7947 7948 if ((in->in_flags & want_keymask) == want_keymask) { 7949 DPRINTF(("marking port %s valid\n", 7950 ether_sprintf(ni->ni_macaddr))); 7951 ni->ni_port_valid = 1; 7952 ieee80211_set_link_state(ic, LINK_STATE_UP); 7953 } 7954 7955 return 0; 7956 } 7957 7958 void 7959 iwx_setkey_task(void *arg) 7960 { 7961 struct iwx_softc *sc = arg; 7962 struct iwx_setkey_task_arg *a; 7963 int err = 0, s = splnet(); 7964 7965 while (sc->setkey_nkeys > 0) { 7966 if (err || (sc->sc_flags & IWX_FLAG_SHUTDOWN)) 7967 break; 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--; 7976 } 7977 7978 refcnt_rele_wake(&sc->task_refs); 7979 splx(s); 7980 } 7981 7982 void 7983 iwx_delete_key(struct ieee80211com *ic, struct ieee80211_node *ni, 7984 struct ieee80211_key *k) 7985 { 7986 struct iwx_softc *sc = ic->ic_softc; 7987 struct iwx_add_sta_key_cmd cmd; 7988 7989 if (k->k_cipher != IEEE80211_CIPHER_CCMP) { 7990 /* Fallback to software crypto for other ciphers. */ 7991 ieee80211_delete_key(ic, ni, k); 7992 return; 7993 } 7994 7995 if ((sc->sc_flags & IWX_FLAG_STA_ACTIVE) == 0) 7996 return; 7997 7998 memset(&cmd, 0, sizeof(cmd)); 7999 8000 cmd.common.key_flags = htole16(IWX_STA_KEY_NOT_VALID | 8001 IWX_STA_KEY_FLG_NO_ENC | IWX_STA_KEY_FLG_WEP_KEY_MAP | 8002 ((k->k_id << IWX_STA_KEY_FLG_KEYID_POS) & 8003 IWX_STA_KEY_FLG_KEYID_MSK)); 8004 memcpy(cmd.common.key, k->k_key, MIN(sizeof(cmd.common.key), k->k_len)); 8005 if (k->k_flags & IEEE80211_KEY_GROUP) 8006 cmd.common.key_offset = 1; 8007 else 8008 cmd.common.key_offset = 0; 8009 cmd.common.sta_id = IWX_STATION_ID; 8010 8011 iwx_send_cmd_pdu(sc, IWX_ADD_STA_KEY, IWX_CMD_ASYNC, sizeof(cmd), &cmd); 8012 } 8013 #endif 8014 8015 static int 8016 iwx_newstate_sub(struct ieee80211vap *vap, enum ieee80211_state nstate) 8017 { 8018 struct ieee80211com *ic = vap->iv_ic; 8019 struct iwx_softc *sc = ic->ic_softc; 8020 enum ieee80211_state ostate = vap->iv_state; 8021 int err = 0; 8022 8023 IWX_LOCK(sc); 8024 8025 if (nstate <= ostate || nstate > IEEE80211_S_RUN) { 8026 switch (ostate) { 8027 case IEEE80211_S_RUN: 8028 err = iwx_run_stop(sc); 8029 if (err) 8030 goto out; 8031 /* FALLTHROUGH */ 8032 case IEEE80211_S_ASSOC: 8033 case IEEE80211_S_AUTH: 8034 if (nstate <= IEEE80211_S_AUTH) { 8035 err = iwx_deauth(sc); 8036 if (err) 8037 goto out; 8038 } 8039 /* FALLTHROUGH */ 8040 case IEEE80211_S_SCAN: 8041 case IEEE80211_S_INIT: 8042 default: 8043 break; 8044 } 8045 // 8046 // /* Die now if iwx_stop() was called while we were sleeping. */ 8047 // if (sc->sc_flags & IWX_FLAG_SHUTDOWN) { 8048 // refcnt_rele_wake(&sc->task_refs); 8049 // splx(s); 8050 // return; 8051 // } 8052 } 8053 8054 switch (nstate) { 8055 case IEEE80211_S_INIT: 8056 break; 8057 8058 case IEEE80211_S_SCAN: 8059 break; 8060 8061 case IEEE80211_S_AUTH: 8062 err = iwx_auth(vap, sc); 8063 break; 8064 8065 case IEEE80211_S_ASSOC: 8066 break; 8067 8068 case IEEE80211_S_RUN: 8069 err = iwx_run(vap, sc); 8070 break; 8071 default: 8072 break; 8073 } 8074 8075 out: 8076 IWX_UNLOCK(sc); 8077 8078 return (err); 8079 } 8080 8081 static int 8082 iwx_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) 8083 { 8084 struct iwx_vap *ivp = IWX_VAP(vap); 8085 struct ieee80211com *ic = vap->iv_ic; 8086 enum ieee80211_state ostate = vap->iv_state; 8087 int err; 8088 8089 /* 8090 * Prevent attempts to transition towards the same state, unless 8091 * we are scanning in which case a SCAN -> SCAN transition 8092 * triggers another scan iteration. And AUTH -> AUTH is needed 8093 * to support band-steering. 8094 */ 8095 if (ostate == nstate && nstate != IEEE80211_S_SCAN && 8096 nstate != IEEE80211_S_AUTH) 8097 return 0; 8098 IEEE80211_UNLOCK(ic); 8099 err = iwx_newstate_sub(vap, nstate); 8100 IEEE80211_LOCK(ic); 8101 if (err == 0) 8102 err = ivp->iv_newstate(vap, nstate, arg); 8103 8104 return (err); 8105 } 8106 8107 static void 8108 iwx_endscan(struct iwx_softc *sc) 8109 { 8110 struct ieee80211com *ic = &sc->sc_ic; 8111 struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); 8112 8113 if ((sc->sc_flags & (IWX_FLAG_SCANNING | IWX_FLAG_BGSCAN)) == 0) 8114 return; 8115 8116 sc->sc_flags &= ~(IWX_FLAG_SCANNING | IWX_FLAG_BGSCAN); 8117 8118 ieee80211_scan_done(TAILQ_FIRST(&ic->ic_vaps)); 8119 wakeup(&vap->iv_state); /* wake up iwx_newstate */ 8120 } 8121 8122 /* 8123 * Aging and idle timeouts for the different possible scenarios 8124 * in default configuration 8125 */ 8126 static const uint32_t 8127 iwx_sf_full_timeout_def[IWX_SF_NUM_SCENARIO][IWX_SF_NUM_TIMEOUT_TYPES] = { 8128 { 8129 htole32(IWX_SF_SINGLE_UNICAST_AGING_TIMER_DEF), 8130 htole32(IWX_SF_SINGLE_UNICAST_IDLE_TIMER_DEF) 8131 }, 8132 { 8133 htole32(IWX_SF_AGG_UNICAST_AGING_TIMER_DEF), 8134 htole32(IWX_SF_AGG_UNICAST_IDLE_TIMER_DEF) 8135 }, 8136 { 8137 htole32(IWX_SF_MCAST_AGING_TIMER_DEF), 8138 htole32(IWX_SF_MCAST_IDLE_TIMER_DEF) 8139 }, 8140 { 8141 htole32(IWX_SF_BA_AGING_TIMER_DEF), 8142 htole32(IWX_SF_BA_IDLE_TIMER_DEF) 8143 }, 8144 { 8145 htole32(IWX_SF_TX_RE_AGING_TIMER_DEF), 8146 htole32(IWX_SF_TX_RE_IDLE_TIMER_DEF) 8147 }, 8148 }; 8149 8150 /* 8151 * Aging and idle timeouts for the different possible scenarios 8152 * in single BSS MAC configuration. 8153 */ 8154 static const uint32_t 8155 iwx_sf_full_timeout[IWX_SF_NUM_SCENARIO][IWX_SF_NUM_TIMEOUT_TYPES] = { 8156 { 8157 htole32(IWX_SF_SINGLE_UNICAST_AGING_TIMER), 8158 htole32(IWX_SF_SINGLE_UNICAST_IDLE_TIMER) 8159 }, 8160 { 8161 htole32(IWX_SF_AGG_UNICAST_AGING_TIMER), 8162 htole32(IWX_SF_AGG_UNICAST_IDLE_TIMER) 8163 }, 8164 { 8165 htole32(IWX_SF_MCAST_AGING_TIMER), 8166 htole32(IWX_SF_MCAST_IDLE_TIMER) 8167 }, 8168 { 8169 htole32(IWX_SF_BA_AGING_TIMER), 8170 htole32(IWX_SF_BA_IDLE_TIMER) 8171 }, 8172 { 8173 htole32(IWX_SF_TX_RE_AGING_TIMER), 8174 htole32(IWX_SF_TX_RE_IDLE_TIMER) 8175 }, 8176 }; 8177 8178 static void 8179 iwx_fill_sf_command(struct iwx_softc *sc, struct iwx_sf_cfg_cmd *sf_cmd, 8180 struct ieee80211_node *ni) 8181 { 8182 int i, j, watermark; 8183 8184 sf_cmd->watermark[IWX_SF_LONG_DELAY_ON] = htole32(IWX_SF_W_MARK_SCAN); 8185 8186 /* 8187 * If we are in association flow - check antenna configuration 8188 * capabilities of the AP station, and choose the watermark accordingly. 8189 */ 8190 if (ni) { 8191 if (ni->ni_flags & IEEE80211_NODE_HT) { 8192 struct ieee80211_htrateset *htrs = &ni->ni_htrates; 8193 int hasmimo = 0; 8194 for (i = 0; i < htrs->rs_nrates; i++) { 8195 if (htrs->rs_rates[i] > 7) { 8196 hasmimo = 1; 8197 break; 8198 } 8199 } 8200 if (hasmimo) 8201 watermark = IWX_SF_W_MARK_MIMO2; 8202 else 8203 watermark = IWX_SF_W_MARK_SISO; 8204 } else { 8205 watermark = IWX_SF_W_MARK_LEGACY; 8206 } 8207 /* default watermark value for unassociated mode. */ 8208 } else { 8209 watermark = IWX_SF_W_MARK_MIMO2; 8210 } 8211 sf_cmd->watermark[IWX_SF_FULL_ON] = htole32(watermark); 8212 8213 for (i = 0; i < IWX_SF_NUM_SCENARIO; i++) { 8214 for (j = 0; j < IWX_SF_NUM_TIMEOUT_TYPES; j++) { 8215 sf_cmd->long_delay_timeouts[i][j] = 8216 htole32(IWX_SF_LONG_DELAY_AGING_TIMER); 8217 } 8218 } 8219 8220 if (ni) { 8221 memcpy(sf_cmd->full_on_timeouts, iwx_sf_full_timeout, 8222 sizeof(iwx_sf_full_timeout)); 8223 } else { 8224 memcpy(sf_cmd->full_on_timeouts, iwx_sf_full_timeout_def, 8225 sizeof(iwx_sf_full_timeout_def)); 8226 } 8227 8228 } 8229 8230 static int 8231 iwx_sf_config(struct iwx_softc *sc, int new_state) 8232 { 8233 struct ieee80211com *ic = &sc->sc_ic; 8234 struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); 8235 struct ieee80211_node *ni = vap->iv_bss; 8236 struct iwx_sf_cfg_cmd sf_cmd = { 8237 .state = htole32(new_state), 8238 }; 8239 int err = 0; 8240 8241 switch (new_state) { 8242 case IWX_SF_UNINIT: 8243 case IWX_SF_INIT_OFF: 8244 iwx_fill_sf_command(sc, &sf_cmd, NULL); 8245 break; 8246 case IWX_SF_FULL_ON: 8247 iwx_fill_sf_command(sc, &sf_cmd, ni); 8248 break; 8249 default: 8250 return EINVAL; 8251 } 8252 8253 err = iwx_send_cmd_pdu(sc, IWX_REPLY_SF_CFG_CMD, IWX_CMD_ASYNC, 8254 sizeof(sf_cmd), &sf_cmd); 8255 return err; 8256 } 8257 8258 static int 8259 iwx_send_bt_init_conf(struct iwx_softc *sc) 8260 { 8261 struct iwx_bt_coex_cmd bt_cmd; 8262 8263 bzero(&bt_cmd, sizeof(struct iwx_bt_coex_cmd)); 8264 8265 bt_cmd.mode = htole32(IWX_BT_COEX_NW); 8266 bt_cmd.enabled_modules |= BT_COEX_SYNC2SCO_ENABLED; 8267 bt_cmd.enabled_modules |= BT_COEX_HIGH_BAND_RET; 8268 8269 8270 return iwx_send_cmd_pdu(sc, IWX_BT_CONFIG, 0, sizeof(bt_cmd), 8271 &bt_cmd); 8272 } 8273 8274 static int 8275 iwx_send_soc_conf(struct iwx_softc *sc) 8276 { 8277 struct iwx_soc_configuration_cmd cmd; 8278 int err; 8279 uint32_t cmd_id, flags = 0; 8280 8281 memset(&cmd, 0, sizeof(cmd)); 8282 8283 /* 8284 * In VER_1 of this command, the discrete value is considered 8285 * an integer; In VER_2, it's a bitmask. Since we have only 2 8286 * values in VER_1, this is backwards-compatible with VER_2, 8287 * as long as we don't set any other flag bits. 8288 */ 8289 if (!sc->sc_integrated) { /* VER_1 */ 8290 flags = IWX_SOC_CONFIG_CMD_FLAGS_DISCRETE; 8291 } else { /* VER_2 */ 8292 uint8_t scan_cmd_ver; 8293 if (sc->sc_ltr_delay != IWX_SOC_FLAGS_LTR_APPLY_DELAY_NONE) 8294 flags |= (sc->sc_ltr_delay & 8295 IWX_SOC_FLAGS_LTR_APPLY_DELAY_MASK); 8296 scan_cmd_ver = iwx_lookup_cmd_ver(sc, IWX_LONG_GROUP, 8297 IWX_SCAN_REQ_UMAC); 8298 if (scan_cmd_ver != IWX_FW_CMD_VER_UNKNOWN && 8299 scan_cmd_ver >= 2 && sc->sc_low_latency_xtal) 8300 flags |= IWX_SOC_CONFIG_CMD_FLAGS_LOW_LATENCY; 8301 } 8302 cmd.flags = htole32(flags); 8303 8304 cmd.latency = htole32(sc->sc_xtal_latency); 8305 8306 cmd_id = iwx_cmd_id(IWX_SOC_CONFIGURATION_CMD, IWX_SYSTEM_GROUP, 0); 8307 err = iwx_send_cmd_pdu(sc, cmd_id, 0, sizeof(cmd), &cmd); 8308 if (err) 8309 printf("%s: failed to set soc latency: %d\n", DEVNAME(sc), err); 8310 return err; 8311 } 8312 8313 static int 8314 iwx_send_update_mcc_cmd(struct iwx_softc *sc, const char *alpha2) 8315 { 8316 struct iwx_mcc_update_cmd mcc_cmd; 8317 struct iwx_host_cmd hcmd = { 8318 .id = IWX_MCC_UPDATE_CMD, 8319 .flags = IWX_CMD_WANT_RESP, 8320 .data = { &mcc_cmd }, 8321 }; 8322 struct iwx_rx_packet *pkt; 8323 struct iwx_mcc_update_resp *resp; 8324 size_t resp_len; 8325 int err; 8326 8327 memset(&mcc_cmd, 0, sizeof(mcc_cmd)); 8328 mcc_cmd.mcc = htole16(alpha2[0] << 8 | alpha2[1]); 8329 if (isset(sc->sc_ucode_api, IWX_UCODE_TLV_API_WIFI_MCC_UPDATE) || 8330 isset(sc->sc_enabled_capa, IWX_UCODE_TLV_CAPA_LAR_MULTI_MCC)) 8331 mcc_cmd.source_id = IWX_MCC_SOURCE_GET_CURRENT; 8332 else 8333 mcc_cmd.source_id = IWX_MCC_SOURCE_OLD_FW; 8334 8335 hcmd.len[0] = sizeof(struct iwx_mcc_update_cmd); 8336 hcmd.resp_pkt_len = IWX_CMD_RESP_MAX; 8337 8338 err = iwx_send_cmd(sc, &hcmd); 8339 if (err) 8340 return err; 8341 8342 pkt = hcmd.resp_pkt; 8343 if (!pkt || (pkt->hdr.flags & IWX_CMD_FAILED_MSK)) { 8344 err = EIO; 8345 goto out; 8346 } 8347 8348 resp_len = iwx_rx_packet_payload_len(pkt); 8349 if (resp_len < sizeof(*resp)) { 8350 err = EIO; 8351 goto out; 8352 } 8353 8354 resp = (void *)pkt->data; 8355 if (resp_len != sizeof(*resp) + 8356 resp->n_channels * sizeof(resp->channels[0])) { 8357 err = EIO; 8358 goto out; 8359 } 8360 8361 DPRINTF(("MCC status=0x%x mcc=0x%x cap=0x%x time=0x%x geo_info=0x%x source_id=0x%d n_channels=%u\n", 8362 resp->status, resp->mcc, resp->cap, resp->time, resp->geo_info, resp->source_id, resp->n_channels)); 8363 8364 out: 8365 iwx_free_resp(sc, &hcmd); 8366 8367 return err; 8368 } 8369 8370 static int 8371 iwx_send_temp_report_ths_cmd(struct iwx_softc *sc) 8372 { 8373 struct iwx_temp_report_ths_cmd cmd; 8374 int err; 8375 8376 /* 8377 * In order to give responsibility for critical-temperature-kill 8378 * and TX backoff to FW we need to send an empty temperature 8379 * reporting command at init time. 8380 */ 8381 memset(&cmd, 0, sizeof(cmd)); 8382 8383 err = iwx_send_cmd_pdu(sc, 8384 IWX_WIDE_ID(IWX_PHY_OPS_GROUP, IWX_TEMP_REPORTING_THRESHOLDS_CMD), 8385 0, sizeof(cmd), &cmd); 8386 if (err) 8387 printf("%s: TEMP_REPORT_THS_CMD command failed (error %d)\n", 8388 DEVNAME(sc), err); 8389 8390 return err; 8391 } 8392 8393 static int 8394 iwx_init_hw(struct iwx_softc *sc) 8395 { 8396 struct ieee80211com *ic = &sc->sc_ic; 8397 int err = 0, i; 8398 8399 err = iwx_run_init_mvm_ucode(sc, 0); 8400 if (err) 8401 return err; 8402 8403 if (!iwx_nic_lock(sc)) 8404 return EBUSY; 8405 8406 err = iwx_send_tx_ant_cfg(sc, iwx_fw_valid_tx_ant(sc)); 8407 if (err) { 8408 printf("%s: could not init tx ant config (error %d)\n", 8409 DEVNAME(sc), err); 8410 goto err; 8411 } 8412 8413 if (sc->sc_tx_with_siso_diversity) { 8414 err = iwx_send_phy_cfg_cmd(sc); 8415 if (err) { 8416 printf("%s: could not send phy config (error %d)\n", 8417 DEVNAME(sc), err); 8418 goto err; 8419 } 8420 } 8421 8422 err = iwx_send_bt_init_conf(sc); 8423 if (err) { 8424 printf("%s: could not init bt coex (error %d)\n", 8425 DEVNAME(sc), err); 8426 return err; 8427 } 8428 8429 err = iwx_send_soc_conf(sc); 8430 if (err) { 8431 printf("%s: iwx_send_soc_conf failed\n", __func__); 8432 return err; 8433 } 8434 8435 if (isset(sc->sc_enabled_capa, IWX_UCODE_TLV_CAPA_DQA_SUPPORT)) { 8436 printf("%s: === IWX_UCODE_TLV_CAPA_DQA_SUPPORT\n", __func__); 8437 err = iwx_send_dqa_cmd(sc); 8438 if (err) { 8439 printf("%s: IWX_UCODE_TLV_CAPA_DQA_SUPPORT " 8440 "failed (error %d)\n", __func__, err); 8441 return err; 8442 } 8443 } 8444 // TODO phyctxt 8445 for (i = 0; i < IWX_NUM_PHY_CTX; i++) { 8446 /* 8447 * The channel used here isn't relevant as it's 8448 * going to be overwritten in the other flows. 8449 * For now use the first channel we have. 8450 */ 8451 sc->sc_phyctxt[i].id = i; 8452 sc->sc_phyctxt[i].channel = &ic->ic_channels[1]; 8453 err = iwx_phy_ctxt_cmd(sc, &sc->sc_phyctxt[i], 1, 1, 8454 IWX_FW_CTXT_ACTION_ADD, 0, 0, 0); 8455 if (err) { 8456 printf("%s: could not add phy context %d (error %d)\n", 8457 DEVNAME(sc), i, err); 8458 goto err; 8459 } 8460 if (iwx_lookup_cmd_ver(sc, IWX_DATA_PATH_GROUP, 8461 IWX_RLC_CONFIG_CMD) == 2) { 8462 err = iwx_phy_send_rlc(sc, &sc->sc_phyctxt[i], 1, 1); 8463 if (err) { 8464 printf("%s: could not configure RLC for PHY " 8465 "%d (error %d)\n", DEVNAME(sc), i, err); 8466 goto err; 8467 } 8468 } 8469 } 8470 8471 err = iwx_config_ltr(sc); 8472 if (err) { 8473 printf("%s: PCIe LTR configuration failed (error %d)\n", 8474 DEVNAME(sc), err); 8475 } 8476 8477 if (isset(sc->sc_enabled_capa, IWX_UCODE_TLV_CAPA_CT_KILL_BY_FW)) { 8478 err = iwx_send_temp_report_ths_cmd(sc); 8479 if (err) { 8480 printf("%s: iwx_send_temp_report_ths_cmd failed\n", 8481 __func__); 8482 goto err; 8483 } 8484 } 8485 8486 err = iwx_power_update_device(sc); 8487 if (err) { 8488 printf("%s: could not send power command (error %d)\n", 8489 DEVNAME(sc), err); 8490 goto err; 8491 } 8492 8493 if (sc->sc_nvm.lar_enabled) { 8494 err = iwx_send_update_mcc_cmd(sc, "ZZ"); 8495 if (err) { 8496 printf("%s: could not init LAR (error %d)\n", 8497 DEVNAME(sc), err); 8498 goto err; 8499 } 8500 } 8501 8502 err = iwx_config_umac_scan_reduced(sc); 8503 if (err) { 8504 printf("%s: could not configure scan (error %d)\n", 8505 DEVNAME(sc), err); 8506 goto err; 8507 } 8508 8509 err = iwx_disable_beacon_filter(sc); 8510 if (err) { 8511 printf("%s: could not disable beacon filter (error %d)\n", 8512 DEVNAME(sc), err); 8513 goto err; 8514 } 8515 8516 err: 8517 iwx_nic_unlock(sc); 8518 return err; 8519 } 8520 8521 /* Allow multicast from our BSSID. */ 8522 static int 8523 iwx_allow_mcast(struct iwx_softc *sc) 8524 { 8525 struct ieee80211com *ic = &sc->sc_ic; 8526 struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); 8527 struct iwx_node *in = IWX_NODE(vap->iv_bss); 8528 struct iwx_mcast_filter_cmd *cmd; 8529 size_t size; 8530 int err; 8531 8532 size = roundup(sizeof(*cmd), 4); 8533 cmd = malloc(size, M_DEVBUF, M_NOWAIT | M_ZERO); 8534 if (cmd == NULL) 8535 return ENOMEM; 8536 cmd->filter_own = 1; 8537 cmd->port_id = 0; 8538 cmd->count = 0; 8539 cmd->pass_all = 1; 8540 IEEE80211_ADDR_COPY(cmd->bssid, in->in_macaddr); 8541 8542 err = iwx_send_cmd_pdu(sc, IWX_MCAST_FILTER_CMD, 8543 0, size, cmd); 8544 free(cmd, M_DEVBUF); 8545 return err; 8546 } 8547 8548 static int 8549 iwx_init(struct iwx_softc *sc) 8550 { 8551 int err, generation; 8552 generation = ++sc->sc_generation; 8553 iwx_preinit(sc); 8554 8555 err = iwx_start_hw(sc); 8556 if (err) { 8557 printf("%s: iwx_start_hw failed\n", __func__); 8558 return err; 8559 } 8560 8561 err = iwx_init_hw(sc); 8562 if (err) { 8563 if (generation == sc->sc_generation) 8564 iwx_stop_device(sc); 8565 printf("%s: iwx_init_hw failed (error %d)\n", __func__, err); 8566 return err; 8567 } 8568 8569 sc->sc_flags |= IWX_FLAG_HW_INITED; 8570 callout_reset(&sc->watchdog_to, hz, iwx_watchdog, sc); 8571 8572 return 0; 8573 } 8574 8575 static void 8576 iwx_start(struct iwx_softc *sc) 8577 { 8578 struct ieee80211_node *ni; 8579 struct mbuf *m; 8580 8581 IWX_ASSERT_LOCKED(sc); 8582 8583 while (sc->qfullmsk == 0 && (m = mbufq_dequeue(&sc->sc_snd)) != NULL) { 8584 ni = (struct ieee80211_node *)m->m_pkthdr.rcvif; 8585 if (iwx_tx(sc, m, ni) != 0) { 8586 if_inc_counter(ni->ni_vap->iv_ifp, IFCOUNTER_OERRORS, 1); 8587 continue; 8588 } 8589 } 8590 } 8591 8592 static void 8593 iwx_stop(struct iwx_softc *sc) 8594 { 8595 struct ieee80211com *ic = &sc->sc_ic; 8596 struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); 8597 struct iwx_vap *ivp = IWX_VAP(vap); 8598 8599 iwx_stop_device(sc); 8600 8601 /* Reset soft state. */ 8602 sc->sc_generation++; 8603 ivp->phy_ctxt = NULL; 8604 8605 sc->sc_flags &= ~(IWX_FLAG_SCANNING | IWX_FLAG_BGSCAN); 8606 sc->sc_flags &= ~IWX_FLAG_MAC_ACTIVE; 8607 sc->sc_flags &= ~IWX_FLAG_BINDING_ACTIVE; 8608 sc->sc_flags &= ~IWX_FLAG_STA_ACTIVE; 8609 sc->sc_flags &= ~IWX_FLAG_TE_ACTIVE; 8610 sc->sc_flags &= ~IWX_FLAG_HW_ERR; 8611 sc->sc_flags &= ~IWX_FLAG_SHUTDOWN; 8612 sc->sc_flags &= ~IWX_FLAG_TXFLUSH; 8613 8614 sc->sc_rx_ba_sessions = 0; 8615 sc->ba_rx.start_tidmask = 0; 8616 sc->ba_rx.stop_tidmask = 0; 8617 memset(sc->aggqid, 0, sizeof(sc->aggqid)); 8618 sc->ba_tx.start_tidmask = 0; 8619 sc->ba_tx.stop_tidmask = 0; 8620 } 8621 8622 static void 8623 iwx_watchdog(void *arg) 8624 { 8625 struct iwx_softc *sc = arg; 8626 struct ieee80211com *ic = &sc->sc_ic; 8627 int i; 8628 8629 /* 8630 * We maintain a separate timer for each Tx queue because 8631 * Tx aggregation queues can get "stuck" while other queues 8632 * keep working. The Linux driver uses a similar workaround. 8633 */ 8634 for (i = 0; i < nitems(sc->sc_tx_timer); i++) { 8635 if (sc->sc_tx_timer[i] > 0) { 8636 if (--sc->sc_tx_timer[i] == 0) { 8637 printf("%s: device timeout\n", DEVNAME(sc)); 8638 8639 iwx_nic_error(sc); 8640 iwx_dump_driver_status(sc); 8641 ieee80211_restart_all(ic); 8642 return; 8643 } 8644 } 8645 } 8646 callout_reset(&sc->watchdog_to, hz, iwx_watchdog, sc); 8647 } 8648 8649 /* 8650 * Note: This structure is read from the device with IO accesses, 8651 * and the reading already does the endian conversion. As it is 8652 * read with uint32_t-sized accesses, any members with a different size 8653 * need to be ordered correctly though! 8654 */ 8655 struct iwx_error_event_table { 8656 uint32_t valid; /* (nonzero) valid, (0) log is empty */ 8657 uint32_t error_id; /* type of error */ 8658 uint32_t trm_hw_status0; /* TRM HW status */ 8659 uint32_t trm_hw_status1; /* TRM HW status */ 8660 uint32_t blink2; /* branch link */ 8661 uint32_t ilink1; /* interrupt link */ 8662 uint32_t ilink2; /* interrupt link */ 8663 uint32_t data1; /* error-specific data */ 8664 uint32_t data2; /* error-specific data */ 8665 uint32_t data3; /* error-specific data */ 8666 uint32_t bcon_time; /* beacon timer */ 8667 uint32_t tsf_low; /* network timestamp function timer */ 8668 uint32_t tsf_hi; /* network timestamp function timer */ 8669 uint32_t gp1; /* GP1 timer register */ 8670 uint32_t gp2; /* GP2 timer register */ 8671 uint32_t fw_rev_type; /* firmware revision type */ 8672 uint32_t major; /* uCode version major */ 8673 uint32_t minor; /* uCode version minor */ 8674 uint32_t hw_ver; /* HW Silicon version */ 8675 uint32_t brd_ver; /* HW board version */ 8676 uint32_t log_pc; /* log program counter */ 8677 uint32_t frame_ptr; /* frame pointer */ 8678 uint32_t stack_ptr; /* stack pointer */ 8679 uint32_t hcmd; /* last host command header */ 8680 uint32_t isr0; /* isr status register LMPM_NIC_ISR0: 8681 * rxtx_flag */ 8682 uint32_t isr1; /* isr status register LMPM_NIC_ISR1: 8683 * host_flag */ 8684 uint32_t isr2; /* isr status register LMPM_NIC_ISR2: 8685 * enc_flag */ 8686 uint32_t isr3; /* isr status register LMPM_NIC_ISR3: 8687 * time_flag */ 8688 uint32_t isr4; /* isr status register LMPM_NIC_ISR4: 8689 * wico interrupt */ 8690 uint32_t last_cmd_id; /* last HCMD id handled by the firmware */ 8691 uint32_t wait_event; /* wait event() caller address */ 8692 uint32_t l2p_control; /* L2pControlField */ 8693 uint32_t l2p_duration; /* L2pDurationField */ 8694 uint32_t l2p_mhvalid; /* L2pMhValidBits */ 8695 uint32_t l2p_addr_match; /* L2pAddrMatchStat */ 8696 uint32_t lmpm_pmg_sel; /* indicate which clocks are turned on 8697 * (LMPM_PMG_SEL) */ 8698 uint32_t u_timestamp; /* indicate when the date and time of the 8699 * compilation */ 8700 uint32_t flow_handler; /* FH read/write pointers, RX credit */ 8701 } __packed /* LOG_ERROR_TABLE_API_S_VER_3 */; 8702 8703 /* 8704 * UMAC error struct - relevant starting from family 8000 chip. 8705 * Note: This structure is read from the device with IO accesses, 8706 * and the reading already does the endian conversion. As it is 8707 * read with u32-sized accesses, any members with a different size 8708 * need to be ordered correctly though! 8709 */ 8710 struct iwx_umac_error_event_table { 8711 uint32_t valid; /* (nonzero) valid, (0) log is empty */ 8712 uint32_t error_id; /* type of error */ 8713 uint32_t blink1; /* branch link */ 8714 uint32_t blink2; /* branch link */ 8715 uint32_t ilink1; /* interrupt link */ 8716 uint32_t ilink2; /* interrupt link */ 8717 uint32_t data1; /* error-specific data */ 8718 uint32_t data2; /* error-specific data */ 8719 uint32_t data3; /* error-specific data */ 8720 uint32_t umac_major; 8721 uint32_t umac_minor; 8722 uint32_t frame_pointer; /* core register 27*/ 8723 uint32_t stack_pointer; /* core register 28 */ 8724 uint32_t cmd_header; /* latest host cmd sent to UMAC */ 8725 uint32_t nic_isr_pref; /* ISR status register */ 8726 } __packed; 8727 8728 #define ERROR_START_OFFSET (1 * sizeof(uint32_t)) 8729 #define ERROR_ELEM_SIZE (7 * sizeof(uint32_t)) 8730 8731 static void 8732 iwx_nic_umac_error(struct iwx_softc *sc) 8733 { 8734 struct iwx_umac_error_event_table table; 8735 uint32_t base; 8736 8737 base = sc->sc_uc.uc_umac_error_event_table; 8738 8739 if (base < 0x400000) { 8740 printf("%s: Invalid error log pointer 0x%08x\n", 8741 DEVNAME(sc), base); 8742 return; 8743 } 8744 8745 if (iwx_read_mem(sc, base, &table, sizeof(table)/sizeof(uint32_t))) { 8746 printf("%s: reading errlog failed\n", DEVNAME(sc)); 8747 return; 8748 } 8749 8750 if (ERROR_START_OFFSET <= table.valid * ERROR_ELEM_SIZE) { 8751 printf("%s: Start UMAC Error Log Dump:\n", DEVNAME(sc)); 8752 printf("%s: Status: 0x%x, count: %d\n", DEVNAME(sc), 8753 sc->sc_flags, table.valid); 8754 } 8755 8756 printf("%s: 0x%08X | %s\n", DEVNAME(sc), table.error_id, 8757 iwx_desc_lookup(table.error_id)); 8758 printf("%s: 0x%08X | umac branchlink1\n", DEVNAME(sc), table.blink1); 8759 printf("%s: 0x%08X | umac branchlink2\n", DEVNAME(sc), table.blink2); 8760 printf("%s: 0x%08X | umac interruptlink1\n", DEVNAME(sc), table.ilink1); 8761 printf("%s: 0x%08X | umac interruptlink2\n", DEVNAME(sc), table.ilink2); 8762 printf("%s: 0x%08X | umac data1\n", DEVNAME(sc), table.data1); 8763 printf("%s: 0x%08X | umac data2\n", DEVNAME(sc), table.data2); 8764 printf("%s: 0x%08X | umac data3\n", DEVNAME(sc), table.data3); 8765 printf("%s: 0x%08X | umac major\n", DEVNAME(sc), table.umac_major); 8766 printf("%s: 0x%08X | umac minor\n", DEVNAME(sc), table.umac_minor); 8767 printf("%s: 0x%08X | frame pointer\n", DEVNAME(sc), 8768 table.frame_pointer); 8769 printf("%s: 0x%08X | stack pointer\n", DEVNAME(sc), 8770 table.stack_pointer); 8771 printf("%s: 0x%08X | last host cmd\n", DEVNAME(sc), table.cmd_header); 8772 printf("%s: 0x%08X | isr status reg\n", DEVNAME(sc), 8773 table.nic_isr_pref); 8774 } 8775 8776 #define IWX_FW_SYSASSERT_CPU_MASK 0xf0000000 8777 static struct { 8778 const char *name; 8779 uint8_t num; 8780 } advanced_lookup[] = { 8781 { "NMI_INTERRUPT_WDG", 0x34 }, 8782 { "SYSASSERT", 0x35 }, 8783 { "UCODE_VERSION_MISMATCH", 0x37 }, 8784 { "BAD_COMMAND", 0x38 }, 8785 { "BAD_COMMAND", 0x39 }, 8786 { "NMI_INTERRUPT_DATA_ACTION_PT", 0x3C }, 8787 { "FATAL_ERROR", 0x3D }, 8788 { "NMI_TRM_HW_ERR", 0x46 }, 8789 { "NMI_INTERRUPT_TRM", 0x4C }, 8790 { "NMI_INTERRUPT_BREAK_POINT", 0x54 }, 8791 { "NMI_INTERRUPT_WDG_RXF_FULL", 0x5C }, 8792 { "NMI_INTERRUPT_WDG_NO_RBD_RXF_FULL", 0x64 }, 8793 { "NMI_INTERRUPT_HOST", 0x66 }, 8794 { "NMI_INTERRUPT_LMAC_FATAL", 0x70 }, 8795 { "NMI_INTERRUPT_UMAC_FATAL", 0x71 }, 8796 { "NMI_INTERRUPT_OTHER_LMAC_FATAL", 0x73 }, 8797 { "NMI_INTERRUPT_ACTION_PT", 0x7C }, 8798 { "NMI_INTERRUPT_UNKNOWN", 0x84 }, 8799 { "NMI_INTERRUPT_INST_ACTION_PT", 0x86 }, 8800 { "ADVANCED_SYSASSERT", 0 }, 8801 }; 8802 8803 static const char * 8804 iwx_desc_lookup(uint32_t num) 8805 { 8806 int i; 8807 8808 for (i = 0; i < nitems(advanced_lookup) - 1; i++) 8809 if (advanced_lookup[i].num == 8810 (num & ~IWX_FW_SYSASSERT_CPU_MASK)) 8811 return advanced_lookup[i].name; 8812 8813 /* No entry matches 'num', so it is the last: ADVANCED_SYSASSERT */ 8814 return advanced_lookup[i].name; 8815 } 8816 8817 /* 8818 * Support for dumping the error log seemed like a good idea ... 8819 * but it's mostly hex junk and the only sensible thing is the 8820 * hw/ucode revision (which we know anyway). Since it's here, 8821 * I'll just leave it in, just in case e.g. the Intel guys want to 8822 * help us decipher some "ADVANCED_SYSASSERT" later. 8823 */ 8824 static void 8825 iwx_nic_error(struct iwx_softc *sc) 8826 { 8827 struct iwx_error_event_table table; 8828 uint32_t base; 8829 8830 printf("%s: dumping device error log\n", DEVNAME(sc)); 8831 printf("%s: GOS-3758: 1\n", __func__); 8832 base = sc->sc_uc.uc_lmac_error_event_table[0]; 8833 printf("%s: GOS-3758: 2\n", __func__); 8834 if (base < 0x400000) { 8835 printf("%s: Invalid error log pointer 0x%08x\n", 8836 DEVNAME(sc), base); 8837 return; 8838 } 8839 8840 printf("%s: GOS-3758: 3\n", __func__); 8841 if (iwx_read_mem(sc, base, &table, sizeof(table)/sizeof(uint32_t))) { 8842 printf("%s: reading errlog failed\n", DEVNAME(sc)); 8843 return; 8844 } 8845 8846 printf("%s: GOS-3758: 4\n", __func__); 8847 if (!table.valid) { 8848 printf("%s: errlog not found, skipping\n", DEVNAME(sc)); 8849 return; 8850 } 8851 8852 printf("%s: GOS-3758: 5\n", __func__); 8853 if (ERROR_START_OFFSET <= table.valid * ERROR_ELEM_SIZE) { 8854 printf("%s: Start Error Log Dump:\n", DEVNAME(sc)); 8855 printf("%s: Status: 0x%x, count: %d\n", DEVNAME(sc), 8856 sc->sc_flags, table.valid); 8857 } 8858 8859 printf("%s: GOS-3758: 6\n", __func__); 8860 printf("%s: 0x%08X | %-28s\n", DEVNAME(sc), table.error_id, 8861 iwx_desc_lookup(table.error_id)); 8862 printf("%s: %08X | trm_hw_status0\n", DEVNAME(sc), 8863 table.trm_hw_status0); 8864 printf("%s: %08X | trm_hw_status1\n", DEVNAME(sc), 8865 table.trm_hw_status1); 8866 printf("%s: %08X | branchlink2\n", DEVNAME(sc), table.blink2); 8867 printf("%s: %08X | interruptlink1\n", DEVNAME(sc), table.ilink1); 8868 printf("%s: %08X | interruptlink2\n", DEVNAME(sc), table.ilink2); 8869 printf("%s: %08X | data1\n", DEVNAME(sc), table.data1); 8870 printf("%s: %08X | data2\n", DEVNAME(sc), table.data2); 8871 printf("%s: %08X | data3\n", DEVNAME(sc), table.data3); 8872 printf("%s: %08X | beacon time\n", DEVNAME(sc), table.bcon_time); 8873 printf("%s: %08X | tsf low\n", DEVNAME(sc), table.tsf_low); 8874 printf("%s: %08X | tsf hi\n", DEVNAME(sc), table.tsf_hi); 8875 printf("%s: %08X | time gp1\n", DEVNAME(sc), table.gp1); 8876 printf("%s: %08X | time gp2\n", DEVNAME(sc), table.gp2); 8877 printf("%s: %08X | uCode revision type\n", DEVNAME(sc), 8878 table.fw_rev_type); 8879 printf("%s: %08X | uCode version major\n", DEVNAME(sc), 8880 table.major); 8881 printf("%s: %08X | uCode version minor\n", DEVNAME(sc), 8882 table.minor); 8883 printf("%s: %08X | hw version\n", DEVNAME(sc), table.hw_ver); 8884 printf("%s: %08X | board version\n", DEVNAME(sc), table.brd_ver); 8885 printf("%s: %08X | hcmd\n", DEVNAME(sc), table.hcmd); 8886 printf("%s: %08X | isr0\n", DEVNAME(sc), table.isr0); 8887 printf("%s: %08X | isr1\n", DEVNAME(sc), table.isr1); 8888 printf("%s: %08X | isr2\n", DEVNAME(sc), table.isr2); 8889 printf("%s: %08X | isr3\n", DEVNAME(sc), table.isr3); 8890 printf("%s: %08X | isr4\n", DEVNAME(sc), table.isr4); 8891 printf("%s: %08X | last cmd Id\n", DEVNAME(sc), table.last_cmd_id); 8892 printf("%s: %08X | wait_event\n", DEVNAME(sc), table.wait_event); 8893 printf("%s: %08X | l2p_control\n", DEVNAME(sc), table.l2p_control); 8894 printf("%s: %08X | l2p_duration\n", DEVNAME(sc), table.l2p_duration); 8895 printf("%s: %08X | l2p_mhvalid\n", DEVNAME(sc), table.l2p_mhvalid); 8896 printf("%s: %08X | l2p_addr_match\n", DEVNAME(sc), table.l2p_addr_match); 8897 printf("%s: %08X | lmpm_pmg_sel\n", DEVNAME(sc), table.lmpm_pmg_sel); 8898 printf("%s: %08X | timestamp\n", DEVNAME(sc), table.u_timestamp); 8899 printf("%s: %08X | flow_handler\n", DEVNAME(sc), table.flow_handler); 8900 8901 if (sc->sc_uc.uc_umac_error_event_table) 8902 iwx_nic_umac_error(sc); 8903 } 8904 8905 static void 8906 iwx_dump_driver_status(struct iwx_softc *sc) 8907 { 8908 struct ieee80211com *ic = &sc->sc_ic; 8909 struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); 8910 enum ieee80211_state state = vap->iv_state; 8911 int i; 8912 8913 printf("driver status:\n"); 8914 for (i = 0; i < nitems(sc->txq); i++) { 8915 struct iwx_tx_ring *ring = &sc->txq[i]; 8916 printf(" tx ring %2d: qid=%-2d cur=%-3d " 8917 "cur_hw=%-3d queued=%-3d\n", 8918 i, ring->qid, ring->cur, ring->cur_hw, 8919 ring->queued); 8920 } 8921 printf(" rx ring: cur=%d\n", sc->rxq.cur); 8922 printf(" 802.11 state %s\n", ieee80211_state_name[state]); 8923 } 8924 8925 #define SYNC_RESP_STRUCT(_var_, _pkt_) \ 8926 do { \ 8927 bus_dmamap_sync(sc->rxq.data_dmat, data->map, BUS_DMASYNC_POSTREAD); \ 8928 _var_ = (void *)((_pkt_)+1); \ 8929 } while (/*CONSTCOND*/0) 8930 8931 static int 8932 iwx_rx_pkt_valid(struct iwx_rx_packet *pkt) 8933 { 8934 int qid, idx, code; 8935 8936 qid = pkt->hdr.qid & ~0x80; 8937 idx = pkt->hdr.idx; 8938 code = IWX_WIDE_ID(pkt->hdr.flags, pkt->hdr.code); 8939 8940 return (!(qid == 0 && idx == 0 && code == 0) && 8941 pkt->len_n_flags != htole32(IWX_FH_RSCSR_FRAME_INVALID)); 8942 } 8943 8944 static void 8945 iwx_rx_pkt(struct iwx_softc *sc, struct iwx_rx_data *data, struct mbuf *ml) 8946 { 8947 struct ieee80211com *ic = &sc->sc_ic; 8948 struct iwx_rx_packet *pkt, *nextpkt; 8949 uint32_t offset = 0, nextoff = 0, nmpdu = 0, len; 8950 struct mbuf *m0, *m; 8951 const size_t minsz = sizeof(pkt->len_n_flags) + sizeof(pkt->hdr); 8952 int qid, idx, code, handled = 1; 8953 8954 m0 = data->m; 8955 while (m0 && offset + minsz < IWX_RBUF_SIZE) { 8956 pkt = (struct iwx_rx_packet *)(m0->m_data + offset); 8957 qid = pkt->hdr.qid; 8958 idx = pkt->hdr.idx; 8959 code = IWX_WIDE_ID(pkt->hdr.flags, pkt->hdr.code); 8960 8961 if (!iwx_rx_pkt_valid(pkt)) 8962 break; 8963 8964 /* 8965 * XXX Intel inside (tm) 8966 * Any commands in the LONG_GROUP could actually be in the 8967 * LEGACY group. Firmware API versions >= 50 reject commands 8968 * in group 0, forcing us to use this hack. 8969 */ 8970 if (iwx_cmd_groupid(code) == IWX_LONG_GROUP) { 8971 struct iwx_tx_ring *ring = &sc->txq[qid]; 8972 struct iwx_tx_data *txdata = &ring->data[idx]; 8973 if (txdata->flags & IWX_TXDATA_FLAG_CMD_IS_NARROW) 8974 code = iwx_cmd_opcode(code); 8975 } 8976 8977 len = sizeof(pkt->len_n_flags) + iwx_rx_packet_len(pkt); 8978 if (len < minsz || len > (IWX_RBUF_SIZE - offset)) 8979 break; 8980 8981 // TODO ??? 8982 if (code == IWX_REPLY_RX_MPDU_CMD && ++nmpdu == 1) { 8983 /* Take mbuf m0 off the RX ring. */ 8984 if (iwx_rx_addbuf(sc, IWX_RBUF_SIZE, sc->rxq.cur)) { 8985 break; 8986 } 8987 KASSERT((data->m != m0), ("%s: data->m != m0", __func__)); 8988 } 8989 8990 switch (code) { 8991 case IWX_REPLY_RX_PHY_CMD: 8992 /* XXX-THJ: I've not managed to hit this path in testing */ 8993 iwx_rx_rx_phy_cmd(sc, pkt, data); 8994 break; 8995 8996 case IWX_REPLY_RX_MPDU_CMD: { 8997 size_t maxlen = IWX_RBUF_SIZE - offset - minsz; 8998 nextoff = offset + 8999 roundup(len, IWX_FH_RSCSR_FRAME_ALIGN); 9000 nextpkt = (struct iwx_rx_packet *) 9001 (m0->m_data + nextoff); 9002 /* AX210 devices ship only one packet per Rx buffer. */ 9003 if (sc->sc_device_family >= IWX_DEVICE_FAMILY_AX210 || 9004 nextoff + minsz >= IWX_RBUF_SIZE || 9005 !iwx_rx_pkt_valid(nextpkt)) { 9006 /* No need to copy last frame in buffer. */ 9007 if (offset > 0) 9008 m_adj(m0, offset); 9009 iwx_rx_mpdu_mq(sc, m0, pkt->data, maxlen); 9010 m0 = NULL; /* stack owns m0 now; abort loop */ 9011 } else { 9012 /* 9013 * Create an mbuf which points to the current 9014 * packet. Always copy from offset zero to 9015 * preserve m_pkthdr. 9016 */ 9017 m = m_copym(m0, 0, M_COPYALL, M_NOWAIT); 9018 if (m == NULL) { 9019 m_freem(m0); 9020 m0 = NULL; 9021 break; 9022 } 9023 m_adj(m, offset); 9024 iwx_rx_mpdu_mq(sc, m, pkt->data, maxlen); 9025 } 9026 break; 9027 } 9028 9029 // case IWX_BAR_FRAME_RELEASE: 9030 // iwx_rx_bar_frame_release(sc, pkt, ml); 9031 // break; 9032 // 9033 case IWX_TX_CMD: 9034 iwx_rx_tx_cmd(sc, pkt, data); 9035 break; 9036 9037 case IWX_BA_NOTIF: 9038 iwx_rx_compressed_ba(sc, pkt); 9039 break; 9040 9041 case IWX_MISSED_BEACONS_NOTIFICATION: 9042 IWX_DPRINTF(sc, IWX_DEBUG_BEACON, 9043 "%s: IWX_MISSED_BEACONS_NOTIFICATION\n", 9044 __func__); 9045 iwx_rx_bmiss(sc, pkt, data); 9046 break; 9047 9048 case IWX_MFUART_LOAD_NOTIFICATION: 9049 break; 9050 9051 case IWX_ALIVE: { 9052 struct iwx_alive_resp_v4 *resp4; 9053 struct iwx_alive_resp_v5 *resp5; 9054 struct iwx_alive_resp_v6 *resp6; 9055 9056 DPRINTF(("%s: firmware alive\n", __func__)); 9057 sc->sc_uc.uc_ok = 0; 9058 9059 /* 9060 * For v5 and above, we can check the version, for older 9061 * versions we need to check the size. 9062 */ 9063 if (iwx_lookup_notif_ver(sc, IWX_LEGACY_GROUP, 9064 IWX_ALIVE) == 6) { 9065 SYNC_RESP_STRUCT(resp6, pkt); 9066 if (iwx_rx_packet_payload_len(pkt) != 9067 sizeof(*resp6)) { 9068 sc->sc_uc.uc_intr = 1; 9069 wakeup(&sc->sc_uc); 9070 break; 9071 } 9072 sc->sc_uc.uc_lmac_error_event_table[0] = le32toh( 9073 resp6->lmac_data[0].dbg_ptrs.error_event_table_ptr); 9074 sc->sc_uc.uc_lmac_error_event_table[1] = le32toh( 9075 resp6->lmac_data[1].dbg_ptrs.error_event_table_ptr); 9076 sc->sc_uc.uc_log_event_table = le32toh( 9077 resp6->lmac_data[0].dbg_ptrs.log_event_table_ptr); 9078 sc->sc_uc.uc_umac_error_event_table = le32toh( 9079 resp6->umac_data.dbg_ptrs.error_info_addr); 9080 sc->sc_sku_id[0] = 9081 le32toh(resp6->sku_id.data[0]); 9082 sc->sc_sku_id[1] = 9083 le32toh(resp6->sku_id.data[1]); 9084 sc->sc_sku_id[2] = 9085 le32toh(resp6->sku_id.data[2]); 9086 if (resp6->status == IWX_ALIVE_STATUS_OK) { 9087 sc->sc_uc.uc_ok = 1; 9088 } 9089 } else if (iwx_lookup_notif_ver(sc, IWX_LEGACY_GROUP, 9090 IWX_ALIVE) == 5) { 9091 SYNC_RESP_STRUCT(resp5, pkt); 9092 if (iwx_rx_packet_payload_len(pkt) != 9093 sizeof(*resp5)) { 9094 sc->sc_uc.uc_intr = 1; 9095 wakeup(&sc->sc_uc); 9096 break; 9097 } 9098 sc->sc_uc.uc_lmac_error_event_table[0] = le32toh( 9099 resp5->lmac_data[0].dbg_ptrs.error_event_table_ptr); 9100 sc->sc_uc.uc_lmac_error_event_table[1] = le32toh( 9101 resp5->lmac_data[1].dbg_ptrs.error_event_table_ptr); 9102 sc->sc_uc.uc_log_event_table = le32toh( 9103 resp5->lmac_data[0].dbg_ptrs.log_event_table_ptr); 9104 sc->sc_uc.uc_umac_error_event_table = le32toh( 9105 resp5->umac_data.dbg_ptrs.error_info_addr); 9106 sc->sc_sku_id[0] = 9107 le32toh(resp5->sku_id.data[0]); 9108 sc->sc_sku_id[1] = 9109 le32toh(resp5->sku_id.data[1]); 9110 sc->sc_sku_id[2] = 9111 le32toh(resp5->sku_id.data[2]); 9112 if (resp5->status == IWX_ALIVE_STATUS_OK) 9113 sc->sc_uc.uc_ok = 1; 9114 } else if (iwx_rx_packet_payload_len(pkt) == sizeof(*resp4)) { 9115 SYNC_RESP_STRUCT(resp4, pkt); 9116 sc->sc_uc.uc_lmac_error_event_table[0] = le32toh( 9117 resp4->lmac_data[0].dbg_ptrs.error_event_table_ptr); 9118 sc->sc_uc.uc_lmac_error_event_table[1] = le32toh( 9119 resp4->lmac_data[1].dbg_ptrs.error_event_table_ptr); 9120 sc->sc_uc.uc_log_event_table = le32toh( 9121 resp4->lmac_data[0].dbg_ptrs.log_event_table_ptr); 9122 sc->sc_uc.uc_umac_error_event_table = le32toh( 9123 resp4->umac_data.dbg_ptrs.error_info_addr); 9124 if (resp4->status == IWX_ALIVE_STATUS_OK) 9125 sc->sc_uc.uc_ok = 1; 9126 } else 9127 printf("unknown payload version"); 9128 9129 sc->sc_uc.uc_intr = 1; 9130 wakeup(&sc->sc_uc); 9131 break; 9132 } 9133 9134 case IWX_STATISTICS_NOTIFICATION: { 9135 struct iwx_notif_statistics *stats; 9136 SYNC_RESP_STRUCT(stats, pkt); 9137 memcpy(&sc->sc_stats, stats, sizeof(sc->sc_stats)); 9138 sc->sc_noise = iwx_get_noise(&stats->rx.general); 9139 break; 9140 } 9141 9142 case IWX_DTS_MEASUREMENT_NOTIFICATION: 9143 case IWX_WIDE_ID(IWX_PHY_OPS_GROUP, 9144 IWX_DTS_MEASUREMENT_NOTIF_WIDE): 9145 case IWX_WIDE_ID(IWX_PHY_OPS_GROUP, 9146 IWX_TEMP_REPORTING_THRESHOLDS_CMD): 9147 break; 9148 9149 case IWX_WIDE_ID(IWX_PHY_OPS_GROUP, 9150 IWX_CT_KILL_NOTIFICATION): { 9151 struct iwx_ct_kill_notif *notif; 9152 SYNC_RESP_STRUCT(notif, pkt); 9153 printf("%s: device at critical temperature (%u degC), " 9154 "stopping device\n", 9155 DEVNAME(sc), le16toh(notif->temperature)); 9156 sc->sc_flags |= IWX_FLAG_HW_ERR; 9157 ieee80211_restart_all(ic); 9158 break; 9159 } 9160 9161 case IWX_WIDE_ID(IWX_DATA_PATH_GROUP, 9162 IWX_SCD_QUEUE_CONFIG_CMD): 9163 case IWX_WIDE_ID(IWX_DATA_PATH_GROUP, 9164 IWX_RX_BAID_ALLOCATION_CONFIG_CMD): 9165 case IWX_WIDE_ID(IWX_MAC_CONF_GROUP, 9166 IWX_SESSION_PROTECTION_CMD): 9167 case IWX_WIDE_ID(IWX_REGULATORY_AND_NVM_GROUP, 9168 IWX_NVM_GET_INFO): 9169 case IWX_ADD_STA_KEY: 9170 case IWX_PHY_CONFIGURATION_CMD: 9171 case IWX_TX_ANT_CONFIGURATION_CMD: 9172 case IWX_ADD_STA: 9173 case IWX_MAC_CONTEXT_CMD: 9174 case IWX_REPLY_SF_CFG_CMD: 9175 case IWX_POWER_TABLE_CMD: 9176 case IWX_LTR_CONFIG: 9177 case IWX_PHY_CONTEXT_CMD: 9178 case IWX_BINDING_CONTEXT_CMD: 9179 case IWX_WIDE_ID(IWX_LONG_GROUP, IWX_SCAN_CFG_CMD): 9180 case IWX_WIDE_ID(IWX_LONG_GROUP, IWX_SCAN_REQ_UMAC): 9181 case IWX_WIDE_ID(IWX_LONG_GROUP, IWX_SCAN_ABORT_UMAC): 9182 case IWX_REPLY_BEACON_FILTERING_CMD: 9183 case IWX_MAC_PM_POWER_TABLE: 9184 case IWX_TIME_QUOTA_CMD: 9185 case IWX_REMOVE_STA: 9186 case IWX_TXPATH_FLUSH: 9187 case IWX_BT_CONFIG: 9188 case IWX_MCC_UPDATE_CMD: 9189 case IWX_TIME_EVENT_CMD: 9190 case IWX_STATISTICS_CMD: 9191 case IWX_SCD_QUEUE_CFG: { 9192 size_t pkt_len; 9193 9194 if (sc->sc_cmd_resp_pkt[idx] == NULL) 9195 break; 9196 9197 bus_dmamap_sync(sc->rxq.data_dmat, data->map, 9198 BUS_DMASYNC_POSTREAD); 9199 9200 pkt_len = sizeof(pkt->len_n_flags) + 9201 iwx_rx_packet_len(pkt); 9202 9203 if ((pkt->hdr.flags & IWX_CMD_FAILED_MSK) || 9204 pkt_len < sizeof(*pkt) || 9205 pkt_len > sc->sc_cmd_resp_len[idx]) { 9206 free(sc->sc_cmd_resp_pkt[idx], M_DEVBUF); 9207 sc->sc_cmd_resp_pkt[idx] = NULL; 9208 break; 9209 } 9210 9211 bus_dmamap_sync(sc->rxq.data_dmat, data->map, 9212 BUS_DMASYNC_POSTREAD); 9213 memcpy(sc->sc_cmd_resp_pkt[idx], pkt, pkt_len); 9214 break; 9215 } 9216 9217 case IWX_INIT_COMPLETE_NOTIF: 9218 sc->sc_init_complete |= IWX_INIT_COMPLETE; 9219 wakeup(&sc->sc_init_complete); 9220 break; 9221 9222 case IWX_SCAN_COMPLETE_UMAC: { 9223 DPRINTF(("%s: >>> IWX_SCAN_COMPLETE_UMAC\n", __func__)); 9224 struct iwx_umac_scan_complete *notif __attribute__((unused)); 9225 SYNC_RESP_STRUCT(notif, pkt); 9226 DPRINTF(("%s: scan complete notif->status=%d\n", __func__, 9227 notif->status)); 9228 ieee80211_runtask(&sc->sc_ic, &sc->sc_es_task); 9229 iwx_endscan(sc); 9230 break; 9231 } 9232 9233 case IWX_SCAN_ITERATION_COMPLETE_UMAC: { 9234 DPRINTF(("%s: >>> IWX_SCAN_ITERATION_COMPLETE_UMAC\n", 9235 __func__)); 9236 struct iwx_umac_scan_iter_complete_notif *notif __attribute__((unused)); 9237 SYNC_RESP_STRUCT(notif, pkt); 9238 DPRINTF(("%s: iter scan complete notif->status=%d\n", __func__, 9239 notif->status)); 9240 iwx_endscan(sc); 9241 break; 9242 } 9243 9244 case IWX_MCC_CHUB_UPDATE_CMD: { 9245 struct iwx_mcc_chub_notif *notif; 9246 SYNC_RESP_STRUCT(notif, pkt); 9247 iwx_mcc_update(sc, notif); 9248 break; 9249 } 9250 9251 case IWX_REPLY_ERROR: { 9252 struct iwx_error_resp *resp; 9253 SYNC_RESP_STRUCT(resp, pkt); 9254 printf("%s: firmware error 0x%x, cmd 0x%x\n", 9255 DEVNAME(sc), le32toh(resp->error_type), 9256 resp->cmd_id); 9257 break; 9258 } 9259 9260 case IWX_TIME_EVENT_NOTIFICATION: { 9261 struct iwx_time_event_notif *notif; 9262 uint32_t action; 9263 SYNC_RESP_STRUCT(notif, pkt); 9264 9265 if (sc->sc_time_event_uid != le32toh(notif->unique_id)) 9266 break; 9267 action = le32toh(notif->action); 9268 if (action & IWX_TE_V2_NOTIF_HOST_EVENT_END) 9269 sc->sc_flags &= ~IWX_FLAG_TE_ACTIVE; 9270 break; 9271 } 9272 9273 case IWX_WIDE_ID(IWX_MAC_CONF_GROUP, 9274 IWX_SESSION_PROTECTION_NOTIF): { 9275 struct iwx_session_prot_notif *notif; 9276 uint32_t status, start, conf_id; 9277 9278 SYNC_RESP_STRUCT(notif, pkt); 9279 9280 status = le32toh(notif->status); 9281 start = le32toh(notif->start); 9282 conf_id = le32toh(notif->conf_id); 9283 /* Check for end of successful PROTECT_CONF_ASSOC. */ 9284 if (status == 1 && start == 0 && 9285 conf_id == IWX_SESSION_PROTECT_CONF_ASSOC) 9286 sc->sc_flags &= ~IWX_FLAG_TE_ACTIVE; 9287 break; 9288 } 9289 9290 case IWX_WIDE_ID(IWX_SYSTEM_GROUP, 9291 IWX_FSEQ_VER_MISMATCH_NOTIFICATION): 9292 break; 9293 9294 /* 9295 * Firmware versions 21 and 22 generate some DEBUG_LOG_MSG 9296 * messages. Just ignore them for now. 9297 */ 9298 case IWX_DEBUG_LOG_MSG: 9299 break; 9300 9301 case IWX_MCAST_FILTER_CMD: 9302 break; 9303 9304 case IWX_WIDE_ID(IWX_DATA_PATH_GROUP, IWX_DQA_ENABLE_CMD): 9305 break; 9306 9307 case IWX_WIDE_ID(IWX_SYSTEM_GROUP, IWX_SOC_CONFIGURATION_CMD): 9308 break; 9309 9310 case IWX_WIDE_ID(IWX_SYSTEM_GROUP, IWX_INIT_EXTENDED_CFG_CMD): 9311 break; 9312 9313 case IWX_WIDE_ID(IWX_REGULATORY_AND_NVM_GROUP, 9314 IWX_NVM_ACCESS_COMPLETE): 9315 break; 9316 9317 case IWX_WIDE_ID(IWX_DATA_PATH_GROUP, IWX_RX_NO_DATA_NOTIF): 9318 break; /* happens in monitor mode; ignore for now */ 9319 9320 case IWX_WIDE_ID(IWX_DATA_PATH_GROUP, IWX_TLC_MNG_CONFIG_CMD): 9321 break; 9322 9323 case IWX_WIDE_ID(IWX_DATA_PATH_GROUP, 9324 IWX_TLC_MNG_UPDATE_NOTIF): { 9325 struct iwx_tlc_update_notif *notif; 9326 SYNC_RESP_STRUCT(notif, pkt); 9327 (void)notif; 9328 if (iwx_rx_packet_payload_len(pkt) == sizeof(*notif)) 9329 iwx_rs_update(sc, notif); 9330 break; 9331 } 9332 9333 case IWX_WIDE_ID(IWX_DATA_PATH_GROUP, IWX_RLC_CONFIG_CMD): 9334 break; 9335 9336 /* undocumented notification from iwx-ty-a0-gf-a0-77 image */ 9337 case IWX_WIDE_ID(IWX_DATA_PATH_GROUP, 0xf8): 9338 break; 9339 9340 case IWX_WIDE_ID(IWX_REGULATORY_AND_NVM_GROUP, 9341 IWX_PNVM_INIT_COMPLETE): 9342 DPRINTF(("%s: IWX_PNVM_INIT_COMPLETE\n", __func__)); 9343 sc->sc_init_complete |= IWX_PNVM_COMPLETE; 9344 wakeup(&sc->sc_init_complete); 9345 break; 9346 9347 default: 9348 handled = 0; 9349 /* XXX wulf: Get rid of bluetooth-related spam */ 9350 if ((code == 0xc2 && pkt->len_n_flags == 0x0000000c) || 9351 (code == 0xce && pkt->len_n_flags == 0x2000002c)) 9352 break; 9353 printf("%s: unhandled firmware response 0x%x/0x%x " 9354 "rx ring %d[%d]\n", 9355 DEVNAME(sc), code, pkt->len_n_flags, 9356 (qid & ~0x80), idx); 9357 break; 9358 } 9359 9360 /* 9361 * uCode sets bit 0x80 when it originates the notification, 9362 * i.e. when the notification is not a direct response to a 9363 * command sent by the driver. 9364 * For example, uCode issues IWX_REPLY_RX when it sends a 9365 * received frame to the driver. 9366 */ 9367 if (handled && !(qid & (1 << 7))) { 9368 iwx_cmd_done(sc, qid, idx, code); 9369 } 9370 9371 offset += roundup(len, IWX_FH_RSCSR_FRAME_ALIGN); 9372 9373 /* AX210 devices ship only one packet per Rx buffer. */ 9374 if (sc->sc_device_family >= IWX_DEVICE_FAMILY_AX210) 9375 break; 9376 } 9377 9378 if (m0 && m0 != data->m) 9379 m_freem(m0); 9380 } 9381 9382 static void 9383 iwx_notif_intr(struct iwx_softc *sc) 9384 { 9385 struct mbuf m; 9386 uint16_t hw; 9387 9388 bus_dmamap_sync(sc->rxq.stat_dma.tag, sc->rxq.stat_dma.map, 9389 BUS_DMASYNC_POSTREAD); 9390 9391 if (sc->sc_device_family >= IWX_DEVICE_FAMILY_AX210) { 9392 uint16_t *status = sc->rxq.stat_dma.vaddr; 9393 hw = le16toh(*status) & 0xfff; 9394 } else 9395 hw = le16toh(sc->rxq.stat->closed_rb_num) & 0xfff; 9396 hw &= (IWX_RX_MQ_RING_COUNT - 1); 9397 while (sc->rxq.cur != hw) { 9398 struct iwx_rx_data *data = &sc->rxq.data[sc->rxq.cur]; 9399 9400 bus_dmamap_sync(sc->rxq.data_dmat, data->map, 9401 BUS_DMASYNC_POSTREAD); 9402 9403 iwx_rx_pkt(sc, data, &m); 9404 sc->rxq.cur = (sc->rxq.cur + 1) % IWX_RX_MQ_RING_COUNT; 9405 } 9406 9407 /* 9408 * Tell the firmware what we have processed. 9409 * Seems like the hardware gets upset unless we align the write by 8?? 9410 */ 9411 hw = (hw == 0) ? IWX_RX_MQ_RING_COUNT - 1 : hw - 1; 9412 IWX_WRITE(sc, IWX_RFH_Q0_FRBDCB_WIDX_TRG, hw & ~7); 9413 } 9414 9415 #if 0 9416 int 9417 iwx_intr(void *arg) 9418 { 9419 struct iwx_softc *sc = arg; 9420 struct ieee80211com *ic = &sc->sc_ic; 9421 struct ifnet *ifp = IC2IFP(ic); 9422 int r1, r2, rv = 0; 9423 9424 IWX_WRITE(sc, IWX_CSR_INT_MASK, 0); 9425 9426 if (sc->sc_flags & IWX_FLAG_USE_ICT) { 9427 uint32_t *ict = sc->ict_dma.vaddr; 9428 int tmp; 9429 9430 tmp = htole32(ict[sc->ict_cur]); 9431 if (!tmp) 9432 goto out_ena; 9433 9434 /* 9435 * ok, there was something. keep plowing until we have all. 9436 */ 9437 r1 = r2 = 0; 9438 while (tmp) { 9439 r1 |= tmp; 9440 ict[sc->ict_cur] = 0; 9441 sc->ict_cur = (sc->ict_cur+1) % IWX_ICT_COUNT; 9442 tmp = htole32(ict[sc->ict_cur]); 9443 } 9444 9445 /* this is where the fun begins. don't ask */ 9446 if (r1 == 0xffffffff) 9447 r1 = 0; 9448 9449 /* i am not expected to understand this */ 9450 if (r1 & 0xc0000) 9451 r1 |= 0x8000; 9452 r1 = (0xff & r1) | ((0xff00 & r1) << 16); 9453 } else { 9454 r1 = IWX_READ(sc, IWX_CSR_INT); 9455 if (r1 == 0xffffffff || (r1 & 0xfffffff0) == 0xa5a5a5a0) 9456 goto out; 9457 r2 = IWX_READ(sc, IWX_CSR_FH_INT_STATUS); 9458 } 9459 if (r1 == 0 && r2 == 0) { 9460 goto out_ena; 9461 } 9462 9463 IWX_WRITE(sc, IWX_CSR_INT, r1 | ~sc->sc_intmask); 9464 9465 if (r1 & IWX_CSR_INT_BIT_ALIVE) { 9466 #if 0 9467 int i; 9468 /* Firmware has now configured the RFH. */ 9469 for (i = 0; i < IWX_RX_MQ_RING_COUNT; i++) 9470 iwx_update_rx_desc(sc, &sc->rxq, i); 9471 #endif 9472 IWX_WRITE(sc, IWX_RFH_Q0_FRBDCB_WIDX_TRG, 8); 9473 } 9474 9475 9476 if (r1 & IWX_CSR_INT_BIT_RF_KILL) { 9477 iwx_check_rfkill(sc); 9478 rv = 1; 9479 goto out_ena; 9480 } 9481 9482 if (r1 & IWX_CSR_INT_BIT_SW_ERR) { 9483 if (ifp->if_flags & IFF_DEBUG) { 9484 iwx_nic_error(sc); 9485 iwx_dump_driver_status(sc); 9486 } 9487 printf("%s: fatal firmware error\n", DEVNAME(sc)); 9488 ieee80211_restart_all(ic); 9489 rv = 1; 9490 goto out; 9491 9492 } 9493 9494 if (r1 & IWX_CSR_INT_BIT_HW_ERR) { 9495 printf("%s: hardware error, stopping device \n", DEVNAME(sc)); 9496 iwx_stop(sc); 9497 rv = 1; 9498 goto out; 9499 } 9500 9501 /* firmware chunk loaded */ 9502 if (r1 & IWX_CSR_INT_BIT_FH_TX) { 9503 IWX_WRITE(sc, IWX_CSR_FH_INT_STATUS, IWX_CSR_FH_INT_TX_MASK); 9504 9505 sc->sc_fw_chunk_done = 1; 9506 wakeup(&sc->sc_fw); 9507 } 9508 9509 if (r1 & (IWX_CSR_INT_BIT_FH_RX | IWX_CSR_INT_BIT_SW_RX | 9510 IWX_CSR_INT_BIT_RX_PERIODIC)) { 9511 if (r1 & (IWX_CSR_INT_BIT_FH_RX | IWX_CSR_INT_BIT_SW_RX)) { 9512 IWX_WRITE(sc, IWX_CSR_FH_INT_STATUS, IWX_CSR_FH_INT_RX_MASK); 9513 } 9514 if (r1 & IWX_CSR_INT_BIT_RX_PERIODIC) { 9515 IWX_WRITE(sc, IWX_CSR_INT, IWX_CSR_INT_BIT_RX_PERIODIC); 9516 } 9517 9518 /* Disable periodic interrupt; we use it as just a one-shot. */ 9519 IWX_WRITE_1(sc, IWX_CSR_INT_PERIODIC_REG, IWX_CSR_INT_PERIODIC_DIS); 9520 9521 /* 9522 * Enable periodic interrupt in 8 msec only if we received 9523 * real RX interrupt (instead of just periodic int), to catch 9524 * any dangling Rx interrupt. If it was just the periodic 9525 * interrupt, there was no dangling Rx activity, and no need 9526 * to extend the periodic interrupt; one-shot is enough. 9527 */ 9528 if (r1 & (IWX_CSR_INT_BIT_FH_RX | IWX_CSR_INT_BIT_SW_RX)) 9529 IWX_WRITE_1(sc, IWX_CSR_INT_PERIODIC_REG, 9530 IWX_CSR_INT_PERIODIC_ENA); 9531 9532 iwx_notif_intr(sc); 9533 } 9534 9535 rv = 1; 9536 9537 out_ena: 9538 iwx_restore_interrupts(sc); 9539 out: 9540 return rv; 9541 } 9542 #endif 9543 9544 static void 9545 iwx_intr_msix(void *arg) 9546 { 9547 struct iwx_softc *sc = arg; 9548 struct ieee80211com *ic = &sc->sc_ic; 9549 uint32_t inta_fh, inta_hw; 9550 int vector = 0; 9551 9552 IWX_LOCK(sc); 9553 9554 inta_fh = IWX_READ(sc, IWX_CSR_MSIX_FH_INT_CAUSES_AD); 9555 inta_hw = IWX_READ(sc, IWX_CSR_MSIX_HW_INT_CAUSES_AD); 9556 IWX_WRITE(sc, IWX_CSR_MSIX_FH_INT_CAUSES_AD, inta_fh); 9557 IWX_WRITE(sc, IWX_CSR_MSIX_HW_INT_CAUSES_AD, inta_hw); 9558 inta_fh &= sc->sc_fh_mask; 9559 inta_hw &= sc->sc_hw_mask; 9560 9561 if (inta_fh & IWX_MSIX_FH_INT_CAUSES_Q0 || 9562 inta_fh & IWX_MSIX_FH_INT_CAUSES_Q1) { 9563 iwx_notif_intr(sc); 9564 } 9565 9566 /* firmware chunk loaded */ 9567 if (inta_fh & IWX_MSIX_FH_INT_CAUSES_D2S_CH0_NUM) { 9568 sc->sc_fw_chunk_done = 1; 9569 wakeup(&sc->sc_fw); 9570 } 9571 9572 if ((inta_fh & IWX_MSIX_FH_INT_CAUSES_FH_ERR) || 9573 (inta_hw & IWX_MSIX_HW_INT_CAUSES_REG_SW_ERR) || 9574 (inta_hw & IWX_MSIX_HW_INT_CAUSES_REG_SW_ERR_V2)) { 9575 if (sc->sc_debug) { 9576 iwx_nic_error(sc); 9577 iwx_dump_driver_status(sc); 9578 } 9579 printf("%s: fatal firmware error\n", DEVNAME(sc)); 9580 ieee80211_restart_all(ic); 9581 goto out; 9582 } 9583 9584 if (inta_hw & IWX_MSIX_HW_INT_CAUSES_REG_RF_KILL) { 9585 iwx_check_rfkill(sc); 9586 } 9587 9588 if (inta_hw & IWX_MSIX_HW_INT_CAUSES_REG_HW_ERR) { 9589 printf("%s: hardware error, stopping device \n", DEVNAME(sc)); 9590 sc->sc_flags |= IWX_FLAG_HW_ERR; 9591 iwx_stop(sc); 9592 goto out; 9593 } 9594 9595 if (inta_hw & IWX_MSIX_HW_INT_CAUSES_REG_ALIVE) { 9596 IWX_DPRINTF(sc, IWX_DEBUG_TRACE, 9597 "%s:%d WARNING: Skipping rx desc update\n", 9598 __func__, __LINE__); 9599 #if 0 9600 /* 9601 * XXX-THJ: we don't have the dma segment handy. This is hacked 9602 * out in the fc release, return to it if we ever get this 9603 * warning. 9604 */ 9605 /* Firmware has now configured the RFH. */ 9606 for (int i = 0; i < IWX_RX_MQ_RING_COUNT; i++) 9607 iwx_update_rx_desc(sc, &sc->rxq, i); 9608 #endif 9609 IWX_WRITE(sc, IWX_RFH_Q0_FRBDCB_WIDX_TRG, 8); 9610 } 9611 9612 /* 9613 * Before sending the interrupt the HW disables it to prevent 9614 * a nested interrupt. This is done by writing 1 to the corresponding 9615 * bit in the mask register. After handling the interrupt, it should be 9616 * re-enabled by clearing this bit. This register is defined as 9617 * write 1 clear (W1C) register, meaning that it's being clear 9618 * by writing 1 to the bit. 9619 */ 9620 IWX_WRITE(sc, IWX_CSR_MSIX_AUTOMASK_ST_AD, 1 << vector); 9621 out: 9622 IWX_UNLOCK(sc); 9623 return; 9624 } 9625 9626 /* 9627 * The device info table below contains device-specific config overrides. 9628 * The most important parameter derived from this table is the name of the 9629 * firmware image to load. 9630 * 9631 * The Linux iwlwifi driver uses an "old" and a "new" device info table. 9632 * The "old" table matches devices based on PCI vendor/product IDs only. 9633 * The "new" table extends this with various device parameters derived 9634 * from MAC type, and RF type. 9635 * 9636 * In iwlwifi "old" and "new" tables share the same array, where "old" 9637 * entries contain dummy values for data defined only for "new" entries. 9638 * As of 2022, Linux developers are still in the process of moving entries 9639 * from "old" to "new" style and it looks like this effort has stalled in 9640 * in some work-in-progress state for quite a while. Linux commits moving 9641 * entries from "old" to "new" have at times been reverted due to regressions. 9642 * Part of this complexity comes from iwlwifi supporting both iwm(4) and iwx(4) 9643 * devices in the same driver. 9644 * 9645 * Our table below contains mostly "new" entries declared in iwlwifi 9646 * with the _IWL_DEV_INFO() macro (with a leading underscore). 9647 * Other devices are matched based on PCI vendor/product ID as usual, 9648 * unless matching specific PCI subsystem vendor/product IDs is required. 9649 * 9650 * Some "old"-style entries are required to identify the firmware image to use. 9651 * Others might be used to print a specific marketing name into Linux dmesg, 9652 * but we can't be sure whether the corresponding devices would be matched 9653 * correctly in the absence of their entries. So we include them just in case. 9654 */ 9655 9656 struct iwx_dev_info { 9657 uint16_t device; 9658 uint16_t subdevice; 9659 uint16_t mac_type; 9660 uint16_t rf_type; 9661 uint8_t mac_step; 9662 uint8_t rf_id; 9663 uint8_t no_160; 9664 uint8_t cores; 9665 uint8_t cdb; 9666 uint8_t jacket; 9667 const struct iwx_device_cfg *cfg; 9668 }; 9669 9670 #define _IWX_DEV_INFO(_device, _subdevice, _mac_type, _mac_step, _rf_type, \ 9671 _rf_id, _no_160, _cores, _cdb, _jacket, _cfg) \ 9672 { .device = (_device), .subdevice = (_subdevice), .cfg = &(_cfg), \ 9673 .mac_type = _mac_type, .rf_type = _rf_type, \ 9674 .no_160 = _no_160, .cores = _cores, .rf_id = _rf_id, \ 9675 .mac_step = _mac_step, .cdb = _cdb, .jacket = _jacket } 9676 9677 #define IWX_DEV_INFO(_device, _subdevice, _cfg) \ 9678 _IWX_DEV_INFO(_device, _subdevice, IWX_CFG_ANY, IWX_CFG_ANY, \ 9679 IWX_CFG_ANY, IWX_CFG_ANY, IWX_CFG_ANY, IWX_CFG_ANY, \ 9680 IWX_CFG_ANY, IWX_CFG_ANY, _cfg) 9681 9682 /* 9683 * When adding entries to this table keep in mind that entries must 9684 * be listed in the same order as in the Linux driver. Code walks this 9685 * table backwards and uses the first matching entry it finds. 9686 * Device firmware must be available in fw_update(8). 9687 */ 9688 static const struct iwx_dev_info iwx_dev_info_table[] = { 9689 /* So with HR */ 9690 IWX_DEV_INFO(0x2725, 0x0090, iwx_2ax_cfg_so_gf_a0), 9691 IWX_DEV_INFO(0x2725, 0x0020, iwx_2ax_cfg_ty_gf_a0), 9692 IWX_DEV_INFO(0x2725, 0x2020, iwx_2ax_cfg_ty_gf_a0), 9693 IWX_DEV_INFO(0x2725, 0x0024, iwx_2ax_cfg_ty_gf_a0), 9694 IWX_DEV_INFO(0x2725, 0x0310, iwx_2ax_cfg_ty_gf_a0), 9695 IWX_DEV_INFO(0x2725, 0x0510, iwx_2ax_cfg_ty_gf_a0), 9696 IWX_DEV_INFO(0x2725, 0x0A10, iwx_2ax_cfg_ty_gf_a0), 9697 IWX_DEV_INFO(0x2725, 0xE020, iwx_2ax_cfg_ty_gf_a0), 9698 IWX_DEV_INFO(0x2725, 0xE024, iwx_2ax_cfg_ty_gf_a0), 9699 IWX_DEV_INFO(0x2725, 0x4020, iwx_2ax_cfg_ty_gf_a0), 9700 IWX_DEV_INFO(0x2725, 0x6020, iwx_2ax_cfg_ty_gf_a0), 9701 IWX_DEV_INFO(0x2725, 0x6024, iwx_2ax_cfg_ty_gf_a0), 9702 IWX_DEV_INFO(0x2725, 0x1673, iwx_2ax_cfg_ty_gf_a0), /* killer_1675w */ 9703 IWX_DEV_INFO(0x2725, 0x1674, iwx_2ax_cfg_ty_gf_a0), /* killer_1675x */ 9704 IWX_DEV_INFO(0x51f0, 0x1691, iwx_2ax_cfg_so_gf4_a0), /* killer_1690s */ 9705 IWX_DEV_INFO(0x51f0, 0x1692, iwx_2ax_cfg_so_gf4_a0), /* killer_1690i */ 9706 IWX_DEV_INFO(0x51f1, 0x1691, iwx_2ax_cfg_so_gf4_a0), 9707 IWX_DEV_INFO(0x51f1, 0x1692, iwx_2ax_cfg_so_gf4_a0), 9708 IWX_DEV_INFO(0x54f0, 0x1691, iwx_2ax_cfg_so_gf4_a0), /* killer_1690s */ 9709 IWX_DEV_INFO(0x54f0, 0x1692, iwx_2ax_cfg_so_gf4_a0), /* killer_1690i */ 9710 IWX_DEV_INFO(0x7a70, 0x0090, iwx_2ax_cfg_so_gf_a0_long), 9711 IWX_DEV_INFO(0x7a70, 0x0098, iwx_2ax_cfg_so_gf_a0_long), 9712 IWX_DEV_INFO(0x7a70, 0x00b0, iwx_2ax_cfg_so_gf4_a0_long), 9713 IWX_DEV_INFO(0x7a70, 0x0310, iwx_2ax_cfg_so_gf_a0_long), 9714 IWX_DEV_INFO(0x7a70, 0x0510, iwx_2ax_cfg_so_gf_a0_long), 9715 IWX_DEV_INFO(0x7a70, 0x0a10, iwx_2ax_cfg_so_gf_a0_long), 9716 IWX_DEV_INFO(0x7af0, 0x0090, iwx_2ax_cfg_so_gf_a0), 9717 IWX_DEV_INFO(0x7af0, 0x0098, iwx_2ax_cfg_so_gf_a0), 9718 IWX_DEV_INFO(0x7af0, 0x00b0, iwx_2ax_cfg_so_gf4_a0), 9719 IWX_DEV_INFO(0x7a70, 0x1691, iwx_2ax_cfg_so_gf4_a0), /* killer_1690s */ 9720 IWX_DEV_INFO(0x7a70, 0x1692, iwx_2ax_cfg_so_gf4_a0), /* killer_1690i */ 9721 IWX_DEV_INFO(0x7af0, 0x0310, iwx_2ax_cfg_so_gf_a0), 9722 IWX_DEV_INFO(0x7af0, 0x0510, iwx_2ax_cfg_so_gf_a0), 9723 IWX_DEV_INFO(0x7af0, 0x0a10, iwx_2ax_cfg_so_gf_a0), 9724 IWX_DEV_INFO(0x7f70, 0x1691, iwx_2ax_cfg_so_gf4_a0), /* killer_1690s */ 9725 IWX_DEV_INFO(0x7f70, 0x1692, iwx_2ax_cfg_so_gf4_a0), /* killer_1690i */ 9726 9727 /* So with GF2 */ 9728 IWX_DEV_INFO(0x2726, 0x1671, iwx_2ax_cfg_so_gf_a0), /* killer_1675s */ 9729 IWX_DEV_INFO(0x2726, 0x1672, iwx_2ax_cfg_so_gf_a0), /* killer_1675i */ 9730 IWX_DEV_INFO(0x51f0, 0x1671, iwx_2ax_cfg_so_gf_a0), /* killer_1675s */ 9731 IWX_DEV_INFO(0x51f0, 0x1672, iwx_2ax_cfg_so_gf_a0), /* killer_1675i */ 9732 IWX_DEV_INFO(0x54f0, 0x1671, iwx_2ax_cfg_so_gf_a0), /* killer_1675s */ 9733 IWX_DEV_INFO(0x54f0, 0x1672, iwx_2ax_cfg_so_gf_a0), /* killer_1675i */ 9734 IWX_DEV_INFO(0x7a70, 0x1671, iwx_2ax_cfg_so_gf_a0), /* killer_1675s */ 9735 IWX_DEV_INFO(0x7a70, 0x1672, iwx_2ax_cfg_so_gf_a0), /* killer_1675i */ 9736 IWX_DEV_INFO(0x7af0, 0x1671, iwx_2ax_cfg_so_gf_a0), /* killer_1675s */ 9737 IWX_DEV_INFO(0x7af0, 0x1672, iwx_2ax_cfg_so_gf_a0), /* killer_1675i */ 9738 IWX_DEV_INFO(0x7f70, 0x1671, iwx_2ax_cfg_so_gf_a0), /* killer_1675s */ 9739 IWX_DEV_INFO(0x7f70, 0x1672, iwx_2ax_cfg_so_gf_a0), /* killer_1675i */ 9740 9741 /* Qu with Jf, C step */ 9742 _IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY, 9743 IWX_CFG_MAC_TYPE_QU, IWX_SILICON_C_STEP, 9744 IWX_CFG_RF_TYPE_JF1, IWX_CFG_RF_ID_JF1, 9745 IWX_CFG_160, IWX_CFG_CORES_BT, IWX_CFG_NO_CDB, 9746 IWX_CFG_ANY, iwx_9560_qu_c0_jf_b0_cfg), /* 9461_160 */ 9747 _IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY, 9748 IWX_CFG_MAC_TYPE_QU, IWX_SILICON_C_STEP, 9749 IWX_CFG_RF_TYPE_JF1, IWX_CFG_RF_ID_JF1, 9750 IWX_CFG_NO_160, IWX_CFG_CORES_BT, IWX_CFG_NO_CDB, 9751 IWX_CFG_ANY, iwx_9560_qu_c0_jf_b0_cfg), /* iwl9461 */ 9752 _IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY, 9753 IWX_CFG_MAC_TYPE_QU, IWX_SILICON_C_STEP, 9754 IWX_CFG_RF_TYPE_JF1, IWX_CFG_RF_ID_JF1_DIV, 9755 IWX_CFG_160, IWX_CFG_CORES_BT, IWX_CFG_NO_CDB, 9756 IWX_CFG_ANY, iwx_9560_qu_c0_jf_b0_cfg), /* 9462_160 */ 9757 _IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY, 9758 IWX_CFG_MAC_TYPE_QU, IWX_SILICON_C_STEP, 9759 IWX_CFG_RF_TYPE_JF1, IWX_CFG_RF_ID_JF1_DIV, 9760 IWX_CFG_NO_160, IWX_CFG_CORES_BT, IWX_CFG_NO_CDB, 9761 IWX_CFG_ANY, iwx_9560_qu_c0_jf_b0_cfg), /* 9462 */ 9762 _IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY, 9763 IWX_CFG_MAC_TYPE_QU, IWX_SILICON_C_STEP, 9764 IWX_CFG_RF_TYPE_JF2, IWX_CFG_RF_ID_JF, 9765 IWX_CFG_160, IWX_CFG_CORES_BT, IWX_CFG_NO_CDB, 9766 IWX_CFG_ANY, iwx_9560_qu_c0_jf_b0_cfg), /* 9560_160 */ 9767 _IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY, 9768 IWX_CFG_MAC_TYPE_QU, IWX_SILICON_C_STEP, 9769 IWX_CFG_RF_TYPE_JF2, IWX_CFG_RF_ID_JF, 9770 IWX_CFG_NO_160, IWX_CFG_CORES_BT, IWX_CFG_NO_CDB, 9771 IWX_CFG_ANY, iwx_9560_qu_c0_jf_b0_cfg), /* 9560 */ 9772 _IWX_DEV_INFO(IWX_CFG_ANY, 0x1551, 9773 IWX_CFG_MAC_TYPE_QU, IWX_SILICON_C_STEP, 9774 IWX_CFG_RF_TYPE_JF2, IWX_CFG_RF_ID_JF, 9775 IWX_CFG_160, IWX_CFG_CORES_BT, IWX_CFG_NO_CDB, 9776 IWX_CFG_ANY, 9777 iwx_9560_qu_c0_jf_b0_cfg), /* 9560_killer_1550s */ 9778 _IWX_DEV_INFO(IWX_CFG_ANY, 0x1552, 9779 IWX_CFG_MAC_TYPE_QU, IWX_SILICON_C_STEP, 9780 IWX_CFG_RF_TYPE_JF2, IWX_CFG_RF_ID_JF, 9781 IWX_CFG_NO_160, IWX_CFG_CORES_BT, IWX_CFG_NO_CDB, 9782 IWX_CFG_ANY, 9783 iwx_9560_qu_c0_jf_b0_cfg), /* 9560_killer_1550i */ 9784 9785 /* QuZ with Jf */ 9786 _IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY, 9787 IWX_CFG_MAC_TYPE_QUZ, IWX_CFG_ANY, 9788 IWX_CFG_RF_TYPE_JF2, IWX_CFG_RF_ID_JF, 9789 IWX_CFG_160, IWX_CFG_CORES_BT, IWX_CFG_NO_CDB, 9790 IWX_CFG_ANY, iwx_9560_quz_a0_jf_b0_cfg), /* 9461_160 */ 9791 _IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY, 9792 IWX_CFG_MAC_TYPE_QUZ, IWX_CFG_ANY, 9793 IWX_CFG_RF_TYPE_JF2, IWX_CFG_RF_ID_JF, 9794 IWX_CFG_NO_160, IWX_CFG_CORES_BT, IWX_CFG_NO_CDB, 9795 IWX_CFG_ANY, iwx_9560_quz_a0_jf_b0_cfg), /* 9461 */ 9796 _IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY, 9797 IWX_CFG_MAC_TYPE_QUZ, IWX_CFG_ANY, 9798 IWX_CFG_RF_TYPE_JF1, IWX_CFG_RF_ID_JF1_DIV, 9799 IWX_CFG_160, IWX_CFG_CORES_BT, IWX_CFG_NO_CDB, 9800 IWX_CFG_ANY, iwx_9560_quz_a0_jf_b0_cfg), /* 9462_160 */ 9801 _IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY, 9802 IWX_CFG_MAC_TYPE_QUZ, IWX_CFG_ANY, 9803 IWX_CFG_RF_TYPE_JF1, IWX_CFG_RF_ID_JF1_DIV, 9804 IWX_CFG_NO_160, IWX_CFG_CORES_BT, IWX_CFG_NO_CDB, 9805 IWX_CFG_ANY, iwx_9560_quz_a0_jf_b0_cfg), /* 9462 */ 9806 _IWX_DEV_INFO(IWX_CFG_ANY, 0x1551, 9807 IWX_CFG_MAC_TYPE_QUZ, IWX_CFG_ANY, 9808 IWX_CFG_RF_TYPE_JF2, IWX_CFG_RF_ID_JF, 9809 IWX_CFG_160, IWX_CFG_CORES_BT, IWX_CFG_NO_CDB, 9810 IWX_CFG_ANY, 9811 iwx_9560_quz_a0_jf_b0_cfg), /* killer_1550s */ 9812 _IWX_DEV_INFO(IWX_CFG_ANY, 0x1552, 9813 IWX_CFG_MAC_TYPE_QUZ, IWX_CFG_ANY, 9814 IWX_CFG_RF_TYPE_JF2, IWX_CFG_RF_ID_JF, 9815 IWX_CFG_NO_160, IWX_CFG_CORES_BT, IWX_CFG_NO_CDB, 9816 IWX_CFG_ANY, 9817 iwx_9560_quz_a0_jf_b0_cfg), /* 9560_killer_1550i */ 9818 9819 /* Qu with Hr, B step */ 9820 _IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY, 9821 IWX_CFG_MAC_TYPE_QU, IWX_SILICON_B_STEP, 9822 IWX_CFG_RF_TYPE_HR1, IWX_CFG_ANY, 9823 IWX_CFG_ANY, IWX_CFG_ANY, IWX_CFG_NO_CDB, IWX_CFG_ANY, 9824 iwx_qu_b0_hr1_b0), /* AX101 */ 9825 _IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY, 9826 IWX_CFG_MAC_TYPE_QU, IWX_SILICON_B_STEP, 9827 IWX_CFG_RF_TYPE_HR2, IWX_CFG_ANY, 9828 IWX_CFG_NO_160, IWX_CFG_ANY, IWX_CFG_NO_CDB, IWX_CFG_ANY, 9829 iwx_qu_b0_hr_b0), /* AX203 */ 9830 9831 /* Qu with Hr, C step */ 9832 _IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY, 9833 IWX_CFG_MAC_TYPE_QU, IWX_SILICON_C_STEP, 9834 IWX_CFG_RF_TYPE_HR1, IWX_CFG_ANY, 9835 IWX_CFG_ANY, IWX_CFG_ANY, IWX_CFG_NO_CDB, IWX_CFG_ANY, 9836 iwx_qu_c0_hr1_b0), /* AX101 */ 9837 _IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY, 9838 IWX_CFG_MAC_TYPE_QU, IWX_SILICON_C_STEP, 9839 IWX_CFG_RF_TYPE_HR2, IWX_CFG_ANY, 9840 IWX_CFG_NO_160, IWX_CFG_ANY, IWX_CFG_NO_CDB, IWX_CFG_ANY, 9841 iwx_qu_c0_hr_b0), /* AX203 */ 9842 _IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY, 9843 IWX_CFG_MAC_TYPE_QU, IWX_SILICON_C_STEP, 9844 IWX_CFG_RF_TYPE_HR2, IWX_CFG_ANY, 9845 IWX_CFG_160, IWX_CFG_ANY, IWX_CFG_NO_CDB, IWX_CFG_ANY, 9846 iwx_qu_c0_hr_b0), /* AX201 */ 9847 9848 /* QuZ with Hr */ 9849 _IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY, 9850 IWX_CFG_MAC_TYPE_QUZ, IWX_CFG_ANY, 9851 IWX_CFG_RF_TYPE_HR1, IWX_CFG_ANY, 9852 IWX_CFG_ANY, IWX_CFG_ANY, IWX_CFG_NO_CDB, IWX_CFG_ANY, 9853 iwx_quz_a0_hr1_b0), /* AX101 */ 9854 _IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY, 9855 IWX_CFG_MAC_TYPE_QUZ, IWX_SILICON_B_STEP, 9856 IWX_CFG_RF_TYPE_HR2, IWX_CFG_ANY, 9857 IWX_CFG_NO_160, IWX_CFG_ANY, IWX_CFG_NO_CDB, IWX_CFG_ANY, 9858 iwx_cfg_quz_a0_hr_b0), /* AX203 */ 9859 9860 /* SoF with JF2 */ 9861 _IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY, 9862 IWX_CFG_MAC_TYPE_SOF, IWX_CFG_ANY, 9863 IWX_CFG_RF_TYPE_JF2, IWX_CFG_RF_ID_JF, 9864 IWX_CFG_160, IWX_CFG_CORES_BT, IWX_CFG_NO_CDB, 9865 IWX_CFG_ANY, iwx_2ax_cfg_so_jf_b0), /* 9560_160 */ 9866 _IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY, 9867 IWX_CFG_MAC_TYPE_SOF, IWX_CFG_ANY, 9868 IWX_CFG_RF_TYPE_JF2, IWX_CFG_RF_ID_JF, 9869 IWX_CFG_NO_160, IWX_CFG_CORES_BT, IWX_CFG_NO_CDB, 9870 IWX_CFG_ANY, iwx_2ax_cfg_so_jf_b0), /* 9560 */ 9871 9872 /* SoF with JF */ 9873 _IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY, 9874 IWX_CFG_MAC_TYPE_SOF, IWX_CFG_ANY, 9875 IWX_CFG_RF_TYPE_JF1, IWX_CFG_RF_ID_JF1, 9876 IWX_CFG_160, IWX_CFG_CORES_BT, IWX_CFG_NO_CDB, 9877 IWX_CFG_ANY, iwx_2ax_cfg_so_jf_b0), /* 9461_160 */ 9878 _IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY, 9879 IWX_CFG_MAC_TYPE_SOF, IWX_CFG_ANY, 9880 IWX_CFG_RF_TYPE_JF1, IWX_CFG_RF_ID_JF1_DIV, 9881 IWX_CFG_160, IWX_CFG_CORES_BT, IWX_CFG_NO_CDB, 9882 IWX_CFG_ANY, iwx_2ax_cfg_so_jf_b0), /* 9462_160 */ 9883 _IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY, 9884 IWX_CFG_MAC_TYPE_SOF, IWX_CFG_ANY, 9885 IWX_CFG_RF_TYPE_JF1, IWX_CFG_RF_ID_JF1, 9886 IWX_CFG_NO_160, IWX_CFG_CORES_BT, IWX_CFG_NO_CDB, 9887 IWX_CFG_ANY, iwx_2ax_cfg_so_jf_b0), /* 9461_name */ 9888 _IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY, 9889 IWX_CFG_MAC_TYPE_SOF, IWX_CFG_ANY, 9890 IWX_CFG_RF_TYPE_JF1, IWX_CFG_RF_ID_JF1_DIV, 9891 IWX_CFG_NO_160, IWX_CFG_CORES_BT, IWX_CFG_NO_CDB, 9892 IWX_CFG_ANY, iwx_2ax_cfg_so_jf_b0), /* 9462 */ 9893 9894 /* So with Hr */ 9895 _IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY, 9896 IWX_CFG_MAC_TYPE_SO, IWX_CFG_ANY, 9897 IWX_CFG_RF_TYPE_HR2, IWX_CFG_ANY, 9898 IWX_CFG_NO_160, IWX_CFG_ANY, IWX_CFG_NO_CDB, IWX_CFG_ANY, 9899 iwx_cfg_so_a0_hr_b0), /* AX203 */ 9900 _IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY, 9901 IWX_CFG_MAC_TYPE_SO, IWX_CFG_ANY, 9902 IWX_CFG_RF_TYPE_HR1, IWX_CFG_ANY, 9903 IWX_CFG_160, IWX_CFG_ANY, IWX_CFG_NO_CDB, IWX_CFG_ANY, 9904 iwx_cfg_so_a0_hr_b0), /* ax101 */ 9905 _IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY, 9906 IWX_CFG_MAC_TYPE_SO, IWX_CFG_ANY, 9907 IWX_CFG_RF_TYPE_HR2, IWX_CFG_ANY, 9908 IWX_CFG_160, IWX_CFG_ANY, IWX_CFG_NO_CDB, IWX_CFG_ANY, 9909 iwx_cfg_so_a0_hr_b0), /* ax201 */ 9910 9911 /* So-F with Hr */ 9912 _IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY, 9913 IWX_CFG_MAC_TYPE_SOF, IWX_CFG_ANY, 9914 IWX_CFG_RF_TYPE_HR2, IWX_CFG_ANY, 9915 IWX_CFG_NO_160, IWX_CFG_ANY, IWX_CFG_NO_CDB, IWX_CFG_ANY, 9916 iwx_cfg_so_a0_hr_b0), /* AX203 */ 9917 _IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY, 9918 IWX_CFG_MAC_TYPE_SOF, IWX_CFG_ANY, 9919 IWX_CFG_RF_TYPE_HR1, IWX_CFG_ANY, 9920 IWX_CFG_160, IWX_CFG_ANY, IWX_CFG_NO_CDB, IWX_CFG_ANY, 9921 iwx_cfg_so_a0_hr_b0), /* AX101 */ 9922 _IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY, 9923 IWX_CFG_MAC_TYPE_SOF, IWX_CFG_ANY, 9924 IWX_CFG_RF_TYPE_HR2, IWX_CFG_ANY, 9925 IWX_CFG_160, IWX_CFG_ANY, IWX_CFG_NO_CDB, IWX_CFG_ANY, 9926 iwx_cfg_so_a0_hr_b0), /* AX201 */ 9927 9928 /* So-F with GF */ 9929 _IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY, 9930 IWX_CFG_MAC_TYPE_SOF, IWX_CFG_ANY, 9931 IWX_CFG_RF_TYPE_GF, IWX_CFG_ANY, 9932 IWX_CFG_160, IWX_CFG_ANY, IWX_CFG_NO_CDB, IWX_CFG_ANY, 9933 iwx_2ax_cfg_so_gf_a0), /* AX211 */ 9934 _IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY, 9935 IWX_CFG_MAC_TYPE_SOF, IWX_CFG_ANY, 9936 IWX_CFG_RF_TYPE_GF, IWX_CFG_ANY, 9937 IWX_CFG_160, IWX_CFG_ANY, IWX_CFG_CDB, IWX_CFG_ANY, 9938 iwx_2ax_cfg_so_gf4_a0), /* AX411 */ 9939 9940 /* So with GF */ 9941 _IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY, 9942 IWX_CFG_MAC_TYPE_SO, IWX_CFG_ANY, 9943 IWX_CFG_RF_TYPE_GF, IWX_CFG_ANY, 9944 IWX_CFG_160, IWX_CFG_ANY, IWX_CFG_NO_CDB, IWX_CFG_ANY, 9945 iwx_2ax_cfg_so_gf_a0), /* AX211 */ 9946 _IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY, 9947 IWX_CFG_MAC_TYPE_SO, IWX_CFG_ANY, 9948 IWX_CFG_RF_TYPE_GF, IWX_CFG_ANY, 9949 IWX_CFG_160, IWX_CFG_ANY, IWX_CFG_CDB, IWX_CFG_ANY, 9950 iwx_2ax_cfg_so_gf4_a0), /* AX411 */ 9951 9952 /* So with JF2 */ 9953 _IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY, 9954 IWX_CFG_MAC_TYPE_SO, IWX_CFG_ANY, 9955 IWX_CFG_RF_TYPE_JF2, IWX_CFG_RF_ID_JF, 9956 IWX_CFG_160, IWX_CFG_CORES_BT, IWX_CFG_NO_CDB, 9957 IWX_CFG_ANY, iwx_2ax_cfg_so_jf_b0), /* 9560_160 */ 9958 _IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY, 9959 IWX_CFG_MAC_TYPE_SO, IWX_CFG_ANY, 9960 IWX_CFG_RF_TYPE_JF2, IWX_CFG_RF_ID_JF, 9961 IWX_CFG_NO_160, IWX_CFG_CORES_BT, IWX_CFG_NO_CDB, 9962 IWX_CFG_ANY, iwx_2ax_cfg_so_jf_b0), /* 9560 */ 9963 9964 /* So with JF */ 9965 _IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY, 9966 IWX_CFG_MAC_TYPE_SO, IWX_CFG_ANY, 9967 IWX_CFG_RF_TYPE_JF1, IWX_CFG_RF_ID_JF1, 9968 IWX_CFG_160, IWX_CFG_CORES_BT, IWX_CFG_NO_CDB, 9969 IWX_CFG_ANY, iwx_2ax_cfg_so_jf_b0), /* 9461_160 */ 9970 _IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY, 9971 IWX_CFG_MAC_TYPE_SO, IWX_CFG_ANY, 9972 IWX_CFG_RF_TYPE_JF1, IWX_CFG_RF_ID_JF1_DIV, 9973 IWX_CFG_160, IWX_CFG_CORES_BT, IWX_CFG_NO_CDB, 9974 IWX_CFG_ANY, iwx_2ax_cfg_so_jf_b0), /* 9462_160 */ 9975 _IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY, 9976 IWX_CFG_MAC_TYPE_SO, IWX_CFG_ANY, 9977 IWX_CFG_RF_TYPE_JF1, IWX_CFG_RF_ID_JF1, 9978 IWX_CFG_NO_160, IWX_CFG_CORES_BT, IWX_CFG_NO_CDB, 9979 IWX_CFG_ANY, iwx_2ax_cfg_so_jf_b0), /* iwl9461 */ 9980 _IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY, 9981 IWX_CFG_MAC_TYPE_SO, IWX_CFG_ANY, 9982 IWX_CFG_RF_TYPE_JF1, IWX_CFG_RF_ID_JF1_DIV, 9983 IWX_CFG_NO_160, IWX_CFG_CORES_BT, IWX_CFG_NO_CDB, 9984 IWX_CFG_ANY, iwx_2ax_cfg_so_jf_b0), /* 9462 */ 9985 }; 9986 9987 static int 9988 iwx_preinit(struct iwx_softc *sc) 9989 { 9990 struct ieee80211com *ic = &sc->sc_ic; 9991 int err; 9992 9993 err = iwx_prepare_card_hw(sc); 9994 if (err) { 9995 printf("%s: could not initialize hardware\n", DEVNAME(sc)); 9996 return err; 9997 } 9998 9999 if (sc->attached) { 10000 return 0; 10001 } 10002 10003 err = iwx_start_hw(sc); 10004 if (err) { 10005 printf("%s: could not initialize hardware\n", DEVNAME(sc)); 10006 return err; 10007 } 10008 10009 err = iwx_run_init_mvm_ucode(sc, 1); 10010 iwx_stop_device(sc); 10011 if (err) { 10012 printf("%s: failed to stop device\n", DEVNAME(sc)); 10013 return err; 10014 } 10015 10016 /* Print version info and MAC address on first successful fw load. */ 10017 sc->attached = 1; 10018 if (sc->sc_pnvm_ver) { 10019 printf("%s: hw rev 0x%x, fw %s, pnvm %08x, " 10020 "address %s\n", 10021 DEVNAME(sc), sc->sc_hw_rev & IWX_CSR_HW_REV_TYPE_MSK, 10022 sc->sc_fwver, sc->sc_pnvm_ver, 10023 ether_sprintf(sc->sc_nvm.hw_addr)); 10024 } else { 10025 printf("%s: hw rev 0x%x, fw %s, address %s\n", 10026 DEVNAME(sc), sc->sc_hw_rev & IWX_CSR_HW_REV_TYPE_MSK, 10027 sc->sc_fwver, ether_sprintf(sc->sc_nvm.hw_addr)); 10028 } 10029 10030 /* not all hardware can do 5GHz band */ 10031 if (!sc->sc_nvm.sku_cap_band_52GHz_enable) 10032 memset(&ic->ic_sup_rates[IEEE80211_MODE_11A], 0, 10033 sizeof(ic->ic_sup_rates[IEEE80211_MODE_11A])); 10034 10035 return 0; 10036 } 10037 10038 static void 10039 iwx_attach_hook(void *self) 10040 { 10041 struct iwx_softc *sc = (void *)self; 10042 struct ieee80211com *ic = &sc->sc_ic; 10043 int err; 10044 10045 IWX_LOCK(sc); 10046 err = iwx_preinit(sc); 10047 IWX_UNLOCK(sc); 10048 if (err != 0) 10049 goto out; 10050 10051 iwx_init_channel_map(ic, IEEE80211_CHAN_MAX, &ic->ic_nchans, 10052 ic->ic_channels); 10053 10054 ieee80211_ifattach(ic); 10055 ic->ic_vap_create = iwx_vap_create; 10056 ic->ic_vap_delete = iwx_vap_delete; 10057 ic->ic_raw_xmit = iwx_raw_xmit; 10058 ic->ic_node_alloc = iwx_node_alloc; 10059 ic->ic_scan_start = iwx_scan_start; 10060 ic->ic_scan_end = iwx_scan_end; 10061 ic->ic_update_mcast = iwx_update_mcast; 10062 ic->ic_getradiocaps = iwx_init_channel_map; 10063 10064 ic->ic_set_channel = iwx_set_channel; 10065 ic->ic_scan_curchan = iwx_scan_curchan; 10066 ic->ic_scan_mindwell = iwx_scan_mindwell; 10067 ic->ic_wme.wme_update = iwx_wme_update; 10068 ic->ic_parent = iwx_parent; 10069 ic->ic_transmit = iwx_transmit; 10070 10071 sc->sc_ampdu_rx_start = ic->ic_ampdu_rx_start; 10072 ic->ic_ampdu_rx_start = iwx_ampdu_rx_start; 10073 sc->sc_ampdu_rx_stop = ic->ic_ampdu_rx_stop; 10074 ic->ic_ampdu_rx_stop = iwx_ampdu_rx_stop; 10075 10076 sc->sc_addba_request = ic->ic_addba_request; 10077 ic->ic_addba_request = iwx_addba_request; 10078 sc->sc_addba_response = ic->ic_addba_response; 10079 ic->ic_addba_response = iwx_addba_response; 10080 10081 iwx_radiotap_attach(sc); 10082 ieee80211_announce(ic); 10083 out: 10084 config_intrhook_disestablish(&sc->sc_preinit_hook); 10085 } 10086 10087 const struct iwx_device_cfg * 10088 iwx_find_device_cfg(struct iwx_softc *sc) 10089 { 10090 uint16_t sdev_id, mac_type, rf_type; 10091 uint8_t mac_step, cdb, jacket, rf_id, no_160, cores; 10092 int i; 10093 10094 sdev_id = pci_get_subdevice(sc->sc_dev); 10095 mac_type = IWX_CSR_HW_REV_TYPE(sc->sc_hw_rev); 10096 mac_step = IWX_CSR_HW_REV_STEP(sc->sc_hw_rev << 2); 10097 rf_type = IWX_CSR_HW_RFID_TYPE(sc->sc_hw_rf_id); 10098 cdb = IWX_CSR_HW_RFID_IS_CDB(sc->sc_hw_rf_id); 10099 jacket = IWX_CSR_HW_RFID_IS_JACKET(sc->sc_hw_rf_id); 10100 10101 rf_id = IWX_SUBDEVICE_RF_ID(sdev_id); 10102 no_160 = IWX_SUBDEVICE_NO_160(sdev_id); 10103 cores = IWX_SUBDEVICE_CORES(sdev_id); 10104 10105 for (i = nitems(iwx_dev_info_table) - 1; i >= 0; i--) { 10106 const struct iwx_dev_info *dev_info = &iwx_dev_info_table[i]; 10107 10108 if (dev_info->device != (uint16_t)IWX_CFG_ANY && 10109 dev_info->device != sc->sc_pid) 10110 continue; 10111 10112 if (dev_info->subdevice != (uint16_t)IWX_CFG_ANY && 10113 dev_info->subdevice != sdev_id) 10114 continue; 10115 10116 if (dev_info->mac_type != (uint16_t)IWX_CFG_ANY && 10117 dev_info->mac_type != mac_type) 10118 continue; 10119 10120 if (dev_info->mac_step != (uint8_t)IWX_CFG_ANY && 10121 dev_info->mac_step != mac_step) 10122 continue; 10123 10124 if (dev_info->rf_type != (uint16_t)IWX_CFG_ANY && 10125 dev_info->rf_type != rf_type) 10126 continue; 10127 10128 if (dev_info->cdb != (uint8_t)IWX_CFG_ANY && 10129 dev_info->cdb != cdb) 10130 continue; 10131 10132 if (dev_info->jacket != (uint8_t)IWX_CFG_ANY && 10133 dev_info->jacket != jacket) 10134 continue; 10135 10136 if (dev_info->rf_id != (uint8_t)IWX_CFG_ANY && 10137 dev_info->rf_id != rf_id) 10138 continue; 10139 10140 if (dev_info->no_160 != (uint8_t)IWX_CFG_ANY && 10141 dev_info->no_160 != no_160) 10142 continue; 10143 10144 if (dev_info->cores != (uint8_t)IWX_CFG_ANY && 10145 dev_info->cores != cores) 10146 continue; 10147 10148 return dev_info->cfg; 10149 } 10150 10151 return NULL; 10152 } 10153 10154 static int 10155 iwx_probe(device_t dev) 10156 { 10157 int i; 10158 10159 for (i = 0; i < nitems(iwx_devices); i++) { 10160 if (pci_get_vendor(dev) == PCI_VENDOR_INTEL && 10161 pci_get_device(dev) == iwx_devices[i].device) { 10162 device_set_desc(dev, iwx_devices[i].name); 10163 10164 /* 10165 * Due to significant existing deployments using 10166 * iwlwifi lower the priority of iwx. 10167 * 10168 * This inverts the advice in bus.h where drivers 10169 * supporting newer hardware should return 10170 * BUS_PROBE_DEFAULT and drivers for older devices 10171 * return BUS_PROBE_LOW_PRIORITY. 10172 * 10173 */ 10174 return (BUS_PROBE_LOW_PRIORITY); 10175 } 10176 } 10177 10178 return (ENXIO); 10179 } 10180 10181 static int 10182 iwx_attach(device_t dev) 10183 { 10184 struct iwx_softc *sc = device_get_softc(dev); 10185 struct ieee80211com *ic = &sc->sc_ic; 10186 const struct iwx_device_cfg *cfg; 10187 int err; 10188 int txq_i, i, j; 10189 size_t ctxt_info_size; 10190 int rid; 10191 int count; 10192 int error; 10193 sc->sc_dev = dev; 10194 sc->sc_pid = pci_get_device(dev); 10195 sc->sc_dmat = bus_get_dma_tag(sc->sc_dev); 10196 10197 TASK_INIT(&sc->sc_es_task, 0, iwx_endscan_cb, sc); 10198 IWX_LOCK_INIT(sc); 10199 mbufq_init(&sc->sc_snd, ifqmaxlen); 10200 TASK_INIT(&sc->ba_rx_task, 0, iwx_ba_rx_task, sc); 10201 TASK_INIT(&sc->ba_tx_task, 0, iwx_ba_tx_task, sc); 10202 sc->sc_tq = taskqueue_create("iwm_taskq", M_WAITOK, 10203 taskqueue_thread_enqueue, &sc->sc_tq); 10204 error = taskqueue_start_threads(&sc->sc_tq, 1, 0, "iwm_taskq"); 10205 if (error != 0) { 10206 device_printf(dev, "can't start taskq thread, error %d\n", 10207 error); 10208 return (ENXIO); 10209 } 10210 10211 pci_find_cap(dev, PCIY_EXPRESS, &sc->sc_cap_off); 10212 if (sc->sc_cap_off == 0) { 10213 device_printf(dev, "PCIe capability structure not found!\n"); 10214 return (ENXIO); 10215 } 10216 10217 /* 10218 * We disable the RETRY_TIMEOUT register (0x41) to keep 10219 * PCI Tx retries from interfering with C3 CPU state. 10220 */ 10221 pci_write_config(dev, PCI_CFG_RETRY_TIMEOUT, 0x00, 1); 10222 10223 if (pci_msix_count(dev)) { 10224 sc->sc_msix = 1; 10225 } else { 10226 device_printf(dev, "no MSI-X found\n"); 10227 return (ENXIO); 10228 } 10229 10230 pci_enable_busmaster(dev); 10231 rid = PCIR_BAR(0); 10232 sc->sc_mem = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, 10233 RF_ACTIVE); 10234 if (sc->sc_mem == NULL) { 10235 device_printf(sc->sc_dev, "can't map mem space\n"); 10236 return (ENXIO); 10237 } 10238 sc->sc_st = rman_get_bustag(sc->sc_mem); 10239 sc->sc_sh = rman_get_bushandle(sc->sc_mem); 10240 10241 count = 1; 10242 rid = 0; 10243 if (pci_alloc_msix(dev, &count) == 0) 10244 rid = 1; 10245 DPRINTF(("%s: count=%d\n", __func__, count)); 10246 sc->sc_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, RF_ACTIVE | 10247 (rid != 0 ? 0 : RF_SHAREABLE)); 10248 if (sc->sc_irq == NULL) { 10249 device_printf(dev, "can't map interrupt\n"); 10250 return (ENXIO); 10251 } 10252 error = bus_setup_intr(dev, sc->sc_irq, INTR_TYPE_NET | INTR_MPSAFE, 10253 NULL, iwx_intr_msix, sc, &sc->sc_ih); 10254 if (error != 0) { 10255 device_printf(dev, "can't establish interrupt\n"); 10256 return (ENXIO); 10257 } 10258 10259 /* Clear pending interrupts. */ 10260 IWX_WRITE(sc, IWX_CSR_INT_MASK, 0); 10261 IWX_WRITE(sc, IWX_CSR_INT, ~0); 10262 IWX_WRITE(sc, IWX_CSR_FH_INT_STATUS, ~0); 10263 10264 sc->sc_hw_rev = IWX_READ(sc, IWX_CSR_HW_REV); 10265 DPRINTF(("%s: sc->sc_hw_rev=%d\n", __func__, sc->sc_hw_rev)); 10266 sc->sc_hw_rf_id = IWX_READ(sc, IWX_CSR_HW_RF_ID); 10267 DPRINTF(("%s: sc->sc_hw_rf_id =%d\n", __func__, sc->sc_hw_rf_id)); 10268 10269 /* 10270 * In the 8000 HW family the format of the 4 bytes of CSR_HW_REV have 10271 * changed, and now the revision step also includes bit 0-1 (no more 10272 * "dash" value). To keep hw_rev backwards compatible - we'll store it 10273 * in the old format. 10274 */ 10275 sc->sc_hw_rev = (sc->sc_hw_rev & 0xfff0) | 10276 (IWX_CSR_HW_REV_STEP(sc->sc_hw_rev << 2) << 2); 10277 10278 switch (sc->sc_pid) { 10279 case PCI_PRODUCT_INTEL_WL_22500_1: 10280 sc->sc_fwname = IWX_CC_A_FW; 10281 sc->sc_device_family = IWX_DEVICE_FAMILY_22000; 10282 sc->sc_integrated = 0; 10283 sc->sc_ltr_delay = IWX_SOC_FLAGS_LTR_APPLY_DELAY_NONE; 10284 sc->sc_low_latency_xtal = 0; 10285 sc->sc_xtal_latency = 0; 10286 sc->sc_tx_with_siso_diversity = 0; 10287 sc->sc_uhb_supported = 0; 10288 break; 10289 case PCI_PRODUCT_INTEL_WL_22500_2: 10290 case PCI_PRODUCT_INTEL_WL_22500_5: 10291 /* These devices should be QuZ only. */ 10292 if (sc->sc_hw_rev != IWX_CSR_HW_REV_TYPE_QUZ) { 10293 device_printf(dev, "unsupported AX201 adapter\n"); 10294 return (ENXIO); 10295 } 10296 sc->sc_fwname = IWX_QUZ_A_HR_B_FW; 10297 sc->sc_device_family = IWX_DEVICE_FAMILY_22000; 10298 sc->sc_integrated = 1; 10299 sc->sc_ltr_delay = IWX_SOC_FLAGS_LTR_APPLY_DELAY_200; 10300 sc->sc_low_latency_xtal = 0; 10301 sc->sc_xtal_latency = 500; 10302 sc->sc_tx_with_siso_diversity = 0; 10303 sc->sc_uhb_supported = 0; 10304 break; 10305 case PCI_PRODUCT_INTEL_WL_22500_3: 10306 if (sc->sc_hw_rev == IWX_CSR_HW_REV_TYPE_QU_C0) 10307 sc->sc_fwname = IWX_QU_C_HR_B_FW; 10308 else if (sc->sc_hw_rev == IWX_CSR_HW_REV_TYPE_QUZ) 10309 sc->sc_fwname = IWX_QUZ_A_HR_B_FW; 10310 else 10311 sc->sc_fwname = IWX_QU_B_HR_B_FW; 10312 sc->sc_device_family = IWX_DEVICE_FAMILY_22000; 10313 sc->sc_integrated = 1; 10314 sc->sc_ltr_delay = IWX_SOC_FLAGS_LTR_APPLY_DELAY_200; 10315 sc->sc_low_latency_xtal = 0; 10316 sc->sc_xtal_latency = 500; 10317 sc->sc_tx_with_siso_diversity = 0; 10318 sc->sc_uhb_supported = 0; 10319 break; 10320 case PCI_PRODUCT_INTEL_WL_22500_4: 10321 case PCI_PRODUCT_INTEL_WL_22500_7: 10322 case PCI_PRODUCT_INTEL_WL_22500_8: 10323 if (sc->sc_hw_rev == IWX_CSR_HW_REV_TYPE_QU_C0) 10324 sc->sc_fwname = IWX_QU_C_HR_B_FW; 10325 else if (sc->sc_hw_rev == IWX_CSR_HW_REV_TYPE_QUZ) 10326 sc->sc_fwname = IWX_QUZ_A_HR_B_FW; 10327 else 10328 sc->sc_fwname = IWX_QU_B_HR_B_FW; 10329 sc->sc_device_family = IWX_DEVICE_FAMILY_22000; 10330 sc->sc_integrated = 1; 10331 sc->sc_ltr_delay = IWX_SOC_FLAGS_LTR_APPLY_DELAY_1820; 10332 sc->sc_low_latency_xtal = 0; 10333 sc->sc_xtal_latency = 1820; 10334 sc->sc_tx_with_siso_diversity = 0; 10335 sc->sc_uhb_supported = 0; 10336 break; 10337 case PCI_PRODUCT_INTEL_WL_22500_6: 10338 if (sc->sc_hw_rev == IWX_CSR_HW_REV_TYPE_QU_C0) 10339 sc->sc_fwname = IWX_QU_C_HR_B_FW; 10340 else if (sc->sc_hw_rev == IWX_CSR_HW_REV_TYPE_QUZ) 10341 sc->sc_fwname = IWX_QUZ_A_HR_B_FW; 10342 else 10343 sc->sc_fwname = IWX_QU_B_HR_B_FW; 10344 sc->sc_device_family = IWX_DEVICE_FAMILY_22000; 10345 sc->sc_integrated = 1; 10346 sc->sc_ltr_delay = IWX_SOC_FLAGS_LTR_APPLY_DELAY_2500; 10347 sc->sc_low_latency_xtal = 1; 10348 sc->sc_xtal_latency = 12000; 10349 sc->sc_tx_with_siso_diversity = 0; 10350 sc->sc_uhb_supported = 0; 10351 break; 10352 case PCI_PRODUCT_INTEL_WL_22500_9: 10353 case PCI_PRODUCT_INTEL_WL_22500_10: 10354 case PCI_PRODUCT_INTEL_WL_22500_11: 10355 case PCI_PRODUCT_INTEL_WL_22500_13: 10356 /* _14 is an MA device, not yet supported */ 10357 case PCI_PRODUCT_INTEL_WL_22500_15: 10358 case PCI_PRODUCT_INTEL_WL_22500_16: 10359 sc->sc_fwname = IWX_SO_A_GF_A_FW; 10360 sc->sc_pnvm_name = IWX_SO_A_GF_A_PNVM; 10361 sc->sc_device_family = IWX_DEVICE_FAMILY_AX210; 10362 sc->sc_integrated = 0; 10363 sc->sc_ltr_delay = IWX_SOC_FLAGS_LTR_APPLY_DELAY_NONE; 10364 sc->sc_low_latency_xtal = 0; 10365 sc->sc_xtal_latency = 0; 10366 sc->sc_tx_with_siso_diversity = 0; 10367 sc->sc_uhb_supported = 1; 10368 break; 10369 case PCI_PRODUCT_INTEL_WL_22500_12: 10370 case PCI_PRODUCT_INTEL_WL_22500_17: 10371 sc->sc_fwname = IWX_SO_A_GF_A_FW; 10372 sc->sc_pnvm_name = IWX_SO_A_GF_A_PNVM; 10373 sc->sc_device_family = IWX_DEVICE_FAMILY_AX210; 10374 sc->sc_integrated = 1; 10375 sc->sc_ltr_delay = IWX_SOC_FLAGS_LTR_APPLY_DELAY_2500; 10376 sc->sc_low_latency_xtal = 1; 10377 sc->sc_xtal_latency = 12000; 10378 sc->sc_tx_with_siso_diversity = 0; 10379 sc->sc_uhb_supported = 0; 10380 sc->sc_imr_enabled = 1; 10381 break; 10382 default: 10383 device_printf(dev, "unknown adapter type\n"); 10384 return (ENXIO); 10385 } 10386 10387 cfg = iwx_find_device_cfg(sc); 10388 DPRINTF(("%s: cfg=%p\n", __func__, cfg)); 10389 if (cfg) { 10390 sc->sc_fwname = cfg->fw_name; 10391 sc->sc_pnvm_name = cfg->pnvm_name; 10392 sc->sc_tx_with_siso_diversity = cfg->tx_with_siso_diversity; 10393 sc->sc_uhb_supported = cfg->uhb_supported; 10394 if (cfg->xtal_latency) { 10395 sc->sc_xtal_latency = cfg->xtal_latency; 10396 sc->sc_low_latency_xtal = cfg->low_latency_xtal; 10397 } 10398 } 10399 10400 sc->mac_addr_from_csr = 0x380; /* differs on BZ hw generation */ 10401 10402 if (sc->sc_device_family >= IWX_DEVICE_FAMILY_AX210) { 10403 sc->sc_umac_prph_offset = 0x300000; 10404 sc->max_tfd_queue_size = IWX_TFD_QUEUE_SIZE_MAX_GEN3; 10405 } else 10406 sc->max_tfd_queue_size = IWX_TFD_QUEUE_SIZE_MAX; 10407 10408 /* Allocate DMA memory for loading firmware. */ 10409 if (sc->sc_device_family >= IWX_DEVICE_FAMILY_AX210) 10410 ctxt_info_size = sizeof(struct iwx_context_info_gen3); 10411 else 10412 ctxt_info_size = sizeof(struct iwx_context_info); 10413 err = iwx_dma_contig_alloc(sc->sc_dmat, &sc->ctxt_info_dma, 10414 ctxt_info_size, 1); 10415 if (err) { 10416 device_printf(dev, 10417 "could not allocate memory for loading firmware\n"); 10418 return (ENXIO); 10419 } 10420 10421 if (sc->sc_device_family >= IWX_DEVICE_FAMILY_AX210) { 10422 err = iwx_dma_contig_alloc(sc->sc_dmat, &sc->prph_scratch_dma, 10423 sizeof(struct iwx_prph_scratch), 1); 10424 if (err) { 10425 device_printf(dev, 10426 "could not allocate prph scratch memory\n"); 10427 goto fail1; 10428 } 10429 10430 /* 10431 * Allocate prph information. The driver doesn't use this. 10432 * We use the second half of this page to give the device 10433 * some dummy TR/CR tail pointers - which shouldn't be 10434 * necessary as we don't use this, but the hardware still 10435 * reads/writes there and we can't let it go do that with 10436 * a NULL pointer. 10437 */ 10438 KASSERT((sizeof(struct iwx_prph_info) < PAGE_SIZE / 2), 10439 ("iwx_prph_info has wrong size")); 10440 err = iwx_dma_contig_alloc(sc->sc_dmat, &sc->prph_info_dma, 10441 PAGE_SIZE, 1); 10442 if (err) { 10443 device_printf(dev, 10444 "could not allocate prph info memory\n"); 10445 goto fail1; 10446 } 10447 } 10448 10449 /* Allocate interrupt cause table (ICT).*/ 10450 err = iwx_dma_contig_alloc(sc->sc_dmat, &sc->ict_dma, 10451 IWX_ICT_SIZE, 1<<IWX_ICT_PADDR_SHIFT); 10452 if (err) { 10453 device_printf(dev, "could not allocate ICT table\n"); 10454 goto fail1; 10455 } 10456 10457 for (txq_i = 0; txq_i < nitems(sc->txq); txq_i++) { 10458 err = iwx_alloc_tx_ring(sc, &sc->txq[txq_i], txq_i); 10459 if (err) { 10460 device_printf(dev, "could not allocate TX ring %d\n", 10461 txq_i); 10462 goto fail4; 10463 } 10464 } 10465 10466 err = iwx_alloc_rx_ring(sc, &sc->rxq); 10467 if (err) { 10468 device_printf(sc->sc_dev, "could not allocate RX ring\n"); 10469 goto fail4; 10470 } 10471 10472 #ifdef IWX_DEBUG 10473 SYSCTL_ADD_INT(device_get_sysctl_ctx(dev), 10474 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, "debug", 10475 CTLFLAG_RWTUN, &sc->sc_debug, 0, "bitmask to control debugging"); 10476 10477 SYSCTL_ADD_INT(device_get_sysctl_ctx(dev), 10478 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, "himark", 10479 CTLFLAG_RW, &iwx_himark, 0, "queues high watermark"); 10480 SYSCTL_ADD_INT(device_get_sysctl_ctx(dev), 10481 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, "lomark", 10482 CTLFLAG_RW, &iwx_lomark, 0, "queues low watermark"); 10483 10484 SYSCTL_ADD_INT(device_get_sysctl_ctx(dev), 10485 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, "qfullmsk", 10486 CTLFLAG_RD, &sc->qfullmsk, 0, "queue fullmask"); 10487 10488 SYSCTL_ADD_INT(device_get_sysctl_ctx(dev), 10489 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, "queue0", 10490 CTLFLAG_RD, &sc->txq[0].queued, 0, "queue 0"); 10491 SYSCTL_ADD_INT(device_get_sysctl_ctx(dev), 10492 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, "queue1", 10493 CTLFLAG_RD, &sc->txq[1].queued, 0, "queue 1"); 10494 SYSCTL_ADD_INT(device_get_sysctl_ctx(dev), 10495 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, "queue2", 10496 CTLFLAG_RD, &sc->txq[2].queued, 0, "queue 2"); 10497 SYSCTL_ADD_INT(device_get_sysctl_ctx(dev), 10498 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, "queue3", 10499 CTLFLAG_RD, &sc->txq[3].queued, 0, "queue 3"); 10500 SYSCTL_ADD_INT(device_get_sysctl_ctx(dev), 10501 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, "queue4", 10502 CTLFLAG_RD, &sc->txq[4].queued, 0, "queue 4"); 10503 SYSCTL_ADD_INT(device_get_sysctl_ctx(dev), 10504 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, "queue5", 10505 CTLFLAG_RD, &sc->txq[5].queued, 0, "queue 5"); 10506 SYSCTL_ADD_INT(device_get_sysctl_ctx(dev), 10507 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, "queue6", 10508 CTLFLAG_RD, &sc->txq[6].queued, 0, "queue 6"); 10509 SYSCTL_ADD_INT(device_get_sysctl_ctx(dev), 10510 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, "queue7", 10511 CTLFLAG_RD, &sc->txq[7].queued, 0, "queue 7"); 10512 #endif 10513 ic->ic_softc = sc; 10514 ic->ic_name = device_get_nameunit(sc->sc_dev); 10515 ic->ic_phytype = IEEE80211_T_OFDM; /* not only, but not used */ 10516 ic->ic_opmode = IEEE80211_M_STA; /* default to BSS mode */ 10517 10518 /* Set device capabilities. */ 10519 ic->ic_caps = 10520 IEEE80211_C_STA | 10521 IEEE80211_C_MONITOR | 10522 IEEE80211_C_WPA | /* WPA/RSN */ 10523 IEEE80211_C_WME | 10524 IEEE80211_C_PMGT | 10525 IEEE80211_C_SHSLOT | /* short slot time supported */ 10526 IEEE80211_C_SHPREAMBLE | /* short preamble supported */ 10527 IEEE80211_C_BGSCAN /* capable of bg scanning */ 10528 ; 10529 ic->ic_flags_ext = IEEE80211_FEXT_SCAN_OFFLOAD; 10530 /* Enable seqno offload */ 10531 ic->ic_flags_ext |= IEEE80211_FEXT_SEQNO_OFFLOAD; 10532 /* Don't send null data frames; let firmware do it */ 10533 ic->ic_flags_ext |= IEEE80211_FEXT_NO_NULLDATA; 10534 10535 ic->ic_txstream = 2; 10536 ic->ic_rxstream = 2; 10537 ic->ic_htcaps |= IEEE80211_HTC_HT 10538 | IEEE80211_HTCAP_SMPS_OFF 10539 | IEEE80211_HTCAP_SHORTGI20 /* short GI in 20MHz */ 10540 | IEEE80211_HTCAP_SHORTGI40 /* short GI in 40MHz */ 10541 | IEEE80211_HTCAP_CHWIDTH40 /* 40MHz channel width*/ 10542 | IEEE80211_HTC_AMPDU /* tx A-MPDU */ 10543 // | IEEE80211_HTC_RX_AMSDU_AMPDU /* TODO: hw reorder */ 10544 | IEEE80211_HTCAP_MAXAMSDU_3839; /* max A-MSDU length */ 10545 10546 ic->ic_cryptocaps |= IEEE80211_CRYPTO_AES_CCM; 10547 10548 /* 10549 * XXX: setupcurchan() expects vhtcaps to be non-zero 10550 * https://bugs.freebsd.org/274156 10551 */ 10552 ic->ic_vht_cap.vht_cap_info |= IEEE80211_VHTCAP_MAX_MPDU_LENGTH_3895 10553 | IEEE80211_VHTCAP_SHORT_GI_80 10554 | 3 << IEEE80211_VHTCAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK_S 10555 | IEEE80211_VHTCAP_RX_ANTENNA_PATTERN 10556 | IEEE80211_VHTCAP_TX_ANTENNA_PATTERN; 10557 10558 ic->ic_flags_ext |= IEEE80211_FEXT_VHT; 10559 int mcsmap = IEEE80211_VHT_MCS_SUPPORT_0_9 << 0 | 10560 IEEE80211_VHT_MCS_SUPPORT_0_9 << 2 | 10561 IEEE80211_VHT_MCS_NOT_SUPPORTED << 4 | 10562 IEEE80211_VHT_MCS_NOT_SUPPORTED << 6 | 10563 IEEE80211_VHT_MCS_NOT_SUPPORTED << 8 | 10564 IEEE80211_VHT_MCS_NOT_SUPPORTED << 10 | 10565 IEEE80211_VHT_MCS_NOT_SUPPORTED << 12 | 10566 IEEE80211_VHT_MCS_NOT_SUPPORTED << 14; 10567 ic->ic_vht_cap.supp_mcs.tx_mcs_map = htole16(mcsmap); 10568 ic->ic_vht_cap.supp_mcs.rx_mcs_map = htole16(mcsmap); 10569 10570 callout_init_mtx(&sc->watchdog_to, &sc->sc_mtx, 0); 10571 for (i = 0; i < nitems(sc->sc_rxba_data); i++) { 10572 struct iwx_rxba_data *rxba = &sc->sc_rxba_data[i]; 10573 rxba->baid = IWX_RX_REORDER_DATA_INVALID_BAID; 10574 rxba->sc = sc; 10575 for (j = 0; j < nitems(rxba->entries); j++) 10576 mbufq_init(&rxba->entries[j].frames, ifqmaxlen); 10577 } 10578 10579 sc->sc_preinit_hook.ich_func = iwx_attach_hook; 10580 sc->sc_preinit_hook.ich_arg = sc; 10581 if (config_intrhook_establish(&sc->sc_preinit_hook) != 0) { 10582 device_printf(dev, 10583 "config_intrhook_establish failed\n"); 10584 goto fail4; 10585 } 10586 10587 return (0); 10588 10589 fail4: 10590 while (--txq_i >= 0) 10591 iwx_free_tx_ring(sc, &sc->txq[txq_i]); 10592 iwx_free_rx_ring(sc, &sc->rxq); 10593 if (sc->ict_dma.vaddr != NULL) 10594 iwx_dma_contig_free(&sc->ict_dma); 10595 10596 fail1: 10597 iwx_dma_contig_free(&sc->ctxt_info_dma); 10598 iwx_dma_contig_free(&sc->prph_scratch_dma); 10599 iwx_dma_contig_free(&sc->prph_info_dma); 10600 return (ENXIO); 10601 } 10602 10603 static int 10604 iwx_detach(device_t dev) 10605 { 10606 struct iwx_softc *sc = device_get_softc(dev); 10607 int txq_i; 10608 10609 iwx_stop_device(sc); 10610 10611 taskqueue_drain_all(sc->sc_tq); 10612 taskqueue_free(sc->sc_tq); 10613 10614 ieee80211_ifdetach(&sc->sc_ic); 10615 10616 callout_drain(&sc->watchdog_to); 10617 10618 for (txq_i = 0; txq_i < nitems(sc->txq); txq_i++) 10619 iwx_free_tx_ring(sc, &sc->txq[txq_i]); 10620 iwx_free_rx_ring(sc, &sc->rxq); 10621 10622 if (sc->sc_fwp != NULL) { 10623 firmware_put(sc->sc_fwp, FIRMWARE_UNLOAD); 10624 sc->sc_fwp = NULL; 10625 } 10626 10627 if (sc->sc_pnvm != NULL) { 10628 firmware_put(sc->sc_pnvm, FIRMWARE_UNLOAD); 10629 sc->sc_pnvm = NULL; 10630 } 10631 10632 if (sc->sc_irq != NULL) { 10633 bus_teardown_intr(dev, sc->sc_irq, sc->sc_ih); 10634 bus_release_resource(dev, SYS_RES_IRQ, 10635 rman_get_rid(sc->sc_irq), sc->sc_irq); 10636 pci_release_msi(dev); 10637 } 10638 if (sc->sc_mem != NULL) 10639 bus_release_resource(dev, SYS_RES_MEMORY, 10640 rman_get_rid(sc->sc_mem), sc->sc_mem); 10641 10642 IWX_LOCK_DESTROY(sc); 10643 10644 return (0); 10645 } 10646 10647 static void 10648 iwx_radiotap_attach(struct iwx_softc *sc) 10649 { 10650 struct ieee80211com *ic = &sc->sc_ic; 10651 10652 IWX_DPRINTF(sc, IWX_DEBUG_RESET | IWX_DEBUG_TRACE, 10653 "->%s begin\n", __func__); 10654 10655 ieee80211_radiotap_attach(ic, 10656 &sc->sc_txtap.wt_ihdr, sizeof(sc->sc_txtap), 10657 IWX_TX_RADIOTAP_PRESENT, 10658 &sc->sc_rxtap.wr_ihdr, sizeof(sc->sc_rxtap), 10659 IWX_RX_RADIOTAP_PRESENT); 10660 10661 IWX_DPRINTF(sc, IWX_DEBUG_RESET | IWX_DEBUG_TRACE, 10662 "->%s end\n", __func__); 10663 } 10664 10665 struct ieee80211vap * 10666 iwx_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit, 10667 enum ieee80211_opmode opmode, int flags, 10668 const uint8_t bssid[IEEE80211_ADDR_LEN], 10669 const uint8_t mac[IEEE80211_ADDR_LEN]) 10670 { 10671 struct iwx_vap *ivp; 10672 struct ieee80211vap *vap; 10673 10674 if (!TAILQ_EMPTY(&ic->ic_vaps)) /* only one at a time */ 10675 return NULL; 10676 ivp = malloc(sizeof(struct iwx_vap), M_80211_VAP, M_WAITOK | M_ZERO); 10677 vap = &ivp->iv_vap; 10678 ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid); 10679 vap->iv_bmissthreshold = 10; /* override default */ 10680 /* Override with driver methods. */ 10681 ivp->iv_newstate = vap->iv_newstate; 10682 vap->iv_newstate = iwx_newstate; 10683 10684 ivp->id = IWX_DEFAULT_MACID; 10685 ivp->color = IWX_DEFAULT_COLOR; 10686 10687 ivp->have_wme = TRUE; 10688 ivp->ps_disabled = FALSE; 10689 10690 vap->iv_ampdu_rxmax = IEEE80211_HTCAP_MAXRXAMPDU_64K; 10691 vap->iv_ampdu_density = IEEE80211_HTCAP_MPDUDENSITY_4; 10692 10693 /* h/w crypto support */ 10694 vap->iv_key_alloc = iwx_key_alloc; 10695 vap->iv_key_delete = iwx_key_delete; 10696 vap->iv_key_set = iwx_key_set; 10697 vap->iv_key_update_begin = iwx_key_update_begin; 10698 vap->iv_key_update_end = iwx_key_update_end; 10699 10700 ieee80211_ratectl_init(vap); 10701 /* Complete setup. */ 10702 ieee80211_vap_attach(vap, ieee80211_media_change, 10703 ieee80211_media_status, mac); 10704 ic->ic_opmode = opmode; 10705 10706 return vap; 10707 } 10708 10709 static void 10710 iwx_vap_delete(struct ieee80211vap *vap) 10711 { 10712 struct iwx_vap *ivp = IWX_VAP(vap); 10713 10714 ieee80211_ratectl_deinit(vap); 10715 ieee80211_vap_detach(vap); 10716 free(ivp, M_80211_VAP); 10717 } 10718 10719 static void 10720 iwx_parent(struct ieee80211com *ic) 10721 { 10722 struct iwx_softc *sc = ic->ic_softc; 10723 IWX_LOCK(sc); 10724 10725 if (sc->sc_flags & IWX_FLAG_HW_INITED) { 10726 iwx_stop(sc); 10727 sc->sc_flags &= ~IWX_FLAG_HW_INITED; 10728 } else { 10729 iwx_init(sc); 10730 ieee80211_start_all(ic); 10731 } 10732 IWX_UNLOCK(sc); 10733 } 10734 10735 static int 10736 iwx_suspend(device_t dev) 10737 { 10738 struct iwx_softc *sc = device_get_softc(dev); 10739 struct ieee80211com *ic = &sc->sc_ic; 10740 10741 /* 10742 * Suspend everything first, then shutdown hardware if it's 10743 * still up. 10744 */ 10745 ieee80211_suspend_all(ic); 10746 10747 if (sc->sc_flags & IWX_FLAG_HW_INITED) { 10748 iwx_stop(sc); 10749 sc->sc_flags &= ~IWX_FLAG_HW_INITED; 10750 } 10751 return (0); 10752 } 10753 10754 static int 10755 iwx_resume(device_t dev) 10756 { 10757 struct iwx_softc *sc = device_get_softc(dev); 10758 struct ieee80211com *ic = &sc->sc_ic; 10759 10760 /* 10761 * We disable the RETRY_TIMEOUT register (0x41) to keep 10762 * PCI Tx retries from interfering with C3 CPU state. 10763 */ 10764 pci_write_config(dev, PCI_CFG_RETRY_TIMEOUT, 0x00, 1); 10765 10766 IWX_LOCK(sc); 10767 10768 /* Stop the hardware here if it's still thought of as "up" */ 10769 if (sc->sc_flags & IWX_FLAG_HW_INITED) { 10770 iwx_stop(sc); 10771 sc->sc_flags &= ~IWX_FLAG_HW_INITED; 10772 } 10773 10774 IWX_UNLOCK(sc); 10775 10776 /* Start the VAPs, which will bring the hardware back up again */ 10777 ieee80211_resume_all(ic); 10778 return (0); 10779 } 10780 10781 static void 10782 iwx_scan_start(struct ieee80211com *ic) 10783 { 10784 struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); 10785 struct iwx_softc *sc = ic->ic_softc; 10786 int err; 10787 10788 IWX_LOCK(sc); 10789 if ((ic->ic_flags_ext & IEEE80211_FEXT_BGSCAN) == 0) 10790 err = iwx_scan(sc); 10791 else 10792 err = iwx_bgscan(ic); 10793 IWX_UNLOCK(sc); 10794 if (err) 10795 ieee80211_cancel_scan(vap); 10796 10797 return; 10798 } 10799 10800 static void 10801 iwx_update_mcast(struct ieee80211com *ic) 10802 { 10803 } 10804 10805 static void 10806 iwx_scan_curchan(struct ieee80211_scan_state *ss, unsigned long maxdwell) 10807 { 10808 } 10809 10810 static void 10811 iwx_scan_mindwell(struct ieee80211_scan_state *ss) 10812 { 10813 } 10814 10815 static void 10816 iwx_scan_end(struct ieee80211com *ic) 10817 { 10818 iwx_endscan(ic->ic_softc); 10819 } 10820 10821 static void 10822 iwx_set_channel(struct ieee80211com *ic) 10823 { 10824 #if 0 10825 struct iwx_softc *sc = ic->ic_softc; 10826 struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); 10827 10828 IWX_DPRINTF(sc, IWX_DEBUG_NI , "%s:%d NOT IMPLEMENTED\n", __func__, __LINE__); 10829 iwx_phy_ctxt_task((void *)sc); 10830 #endif 10831 } 10832 10833 static void 10834 iwx_endscan_cb(void *arg, int pending) 10835 { 10836 struct iwx_softc *sc = arg; 10837 struct ieee80211com *ic = &sc->sc_ic; 10838 10839 DPRINTF(("scan ended\n")); 10840 ieee80211_scan_done(TAILQ_FIRST(&ic->ic_vaps)); 10841 } 10842 10843 static int 10844 iwx_wme_update(struct ieee80211com *ic) 10845 { 10846 return 0; 10847 } 10848 10849 static int 10850 iwx_raw_xmit(struct ieee80211_node *ni, struct mbuf *m, 10851 const struct ieee80211_bpf_params *params) 10852 { 10853 struct ieee80211com *ic = ni->ni_ic; 10854 struct iwx_softc *sc = ic->ic_softc; 10855 int err; 10856 10857 IWX_LOCK(sc); 10858 if (sc->sc_flags & IWX_FLAG_STA_ACTIVE) { 10859 err = iwx_tx(sc, m, ni); 10860 IWX_UNLOCK(sc); 10861 return err; 10862 } else { 10863 IWX_UNLOCK(sc); 10864 return EIO; 10865 } 10866 } 10867 10868 static int 10869 iwx_transmit(struct ieee80211com *ic, struct mbuf *m) 10870 { 10871 struct iwx_softc *sc = ic->ic_softc; 10872 int error; 10873 10874 // TODO: mbufq_enqueue in iwm 10875 // TODO dequeue in iwm_start, counters, locking 10876 IWX_LOCK(sc); 10877 error = mbufq_enqueue(&sc->sc_snd, m); 10878 if (error) { 10879 IWX_UNLOCK(sc); 10880 return (error); 10881 } 10882 10883 iwx_start(sc); 10884 IWX_UNLOCK(sc); 10885 return (0); 10886 } 10887 10888 static int 10889 iwx_ampdu_rx_start(struct ieee80211_node *ni, struct ieee80211_rx_ampdu *rap, 10890 int baparamset, int batimeout, int baseqctl) 10891 { 10892 struct ieee80211com *ic = ni->ni_ic; 10893 struct iwx_softc *sc = ic->ic_softc; 10894 int tid; 10895 10896 tid = _IEEE80211_MASKSHIFT(le16toh(baparamset), IEEE80211_BAPS_TID); 10897 sc->ni_rx_ba[tid].ba_winstart = 10898 _IEEE80211_MASKSHIFT(le16toh(baseqctl), IEEE80211_BASEQ_START); 10899 sc->ni_rx_ba[tid].ba_winsize = 10900 _IEEE80211_MASKSHIFT(le16toh(baparamset), IEEE80211_BAPS_BUFSIZ); 10901 sc->ni_rx_ba[tid].ba_timeout_val = batimeout; 10902 10903 if (sc->sc_rx_ba_sessions >= IWX_MAX_RX_BA_SESSIONS || 10904 tid >= IWX_MAX_TID_COUNT) 10905 return ENOSPC; 10906 10907 if (sc->ba_rx.start_tidmask & (1 << tid)) { 10908 DPRINTF(("%s: tid %d already added\n", __func__, tid)); 10909 return EBUSY; 10910 } 10911 DPRINTF(("%s: sc->ba_rx.start_tidmask=%x\n", __func__, sc->ba_rx.start_tidmask)); 10912 10913 sc->ba_rx.start_tidmask |= (1 << tid); 10914 DPRINTF(("%s: tid=%i\n", __func__, tid)); 10915 DPRINTF(("%s: ba_winstart=%i\n", __func__, sc->ni_rx_ba[tid].ba_winstart)); 10916 DPRINTF(("%s: ba_winsize=%i\n", __func__, sc->ni_rx_ba[tid].ba_winsize)); 10917 DPRINTF(("%s: ba_timeout_val=%i\n", __func__, sc->ni_rx_ba[tid].ba_timeout_val)); 10918 10919 taskqueue_enqueue(sc->sc_tq, &sc->ba_rx_task); 10920 10921 // TODO:misha move to ba_task (serialize) 10922 sc->sc_ampdu_rx_start(ni, rap, baparamset, batimeout, baseqctl); 10923 10924 return (0); 10925 } 10926 10927 static void 10928 iwx_ampdu_rx_stop(struct ieee80211_node *ni, struct ieee80211_rx_ampdu *rap) 10929 { 10930 return; 10931 } 10932 10933 /** 10934 * @brief Called by net80211 to request an A-MPDU session be established. 10935 * 10936 * This is called by net80211 to see if an A-MPDU session can be established. 10937 * However, the iwx(4) firmware will take care of establishing the BA 10938 * session for us. net80211 doesn't have to send any action frames here; 10939 * it just needs to plumb up the ampdu session once the BA has been sent. 10940 * 10941 * If we return 0 here then the firmware will set up the state but net80211 10942 * will not; so it's on us to actually complete it via a call to 10943 * ieee80211_ampdu_tx_request_active_ext() . 10944 * 10945 * @param ni ieee80211_node to establish A-MPDU session for 10946 * @param tap pointer to the per-TID state struct 10947 * @param dialogtoken dialogtoken field from the BA request 10948 * @param baparamset baparamset field from the BA request 10949 * @param batimeout batimeout field from the BA request 10950 * 10951 * @returns 0 so net80211 doesn't send the BA action frame to establish A-MPDU. 10952 */ 10953 static int 10954 iwx_addba_request(struct ieee80211_node *ni, struct ieee80211_tx_ampdu *tap, 10955 int dialogtoken, int baparamset, int batimeout) 10956 { 10957 struct iwx_softc *sc = ni->ni_ic->ic_softc; 10958 int tid; 10959 10960 tid = _IEEE80211_MASKSHIFT(le16toh(baparamset), IEEE80211_BAPS_TID); 10961 IWX_DPRINTF(sc, IWX_DEBUG_AMPDU_MGMT, 10962 "%s: queuing AMPDU start on tid %i\n", __func__, tid); 10963 10964 /* There's no nice way right now to tell net80211 that we're in the 10965 * middle of an asynchronous ADDBA setup session. So, bump the timeout 10966 * to hz ticks, hopefully we'll get a response by then. 10967 */ 10968 tap->txa_nextrequest = ticks + hz; 10969 10970 IWX_LOCK(sc); 10971 sc->ba_tx.start_tidmask |= (1 << tid); 10972 IWX_UNLOCK(sc); 10973 10974 taskqueue_enqueue(sc->sc_tq, &sc->ba_tx_task); 10975 10976 return (0); 10977 } 10978 10979 10980 static int 10981 iwx_addba_response(struct ieee80211_node *ni, struct ieee80211_tx_ampdu *tap, 10982 int code, int baparamset, int batimeout) 10983 { 10984 return 0; 10985 } 10986 10987 static void 10988 iwx_key_update_begin(struct ieee80211vap *vap) 10989 { 10990 return; 10991 } 10992 10993 static void 10994 iwx_key_update_end(struct ieee80211vap *vap) 10995 { 10996 return; 10997 } 10998 10999 static int 11000 iwx_key_alloc(struct ieee80211vap *vap, struct ieee80211_key *k, 11001 ieee80211_keyix *keyix, ieee80211_keyix *rxkeyix) 11002 { 11003 11004 if (k->wk_cipher->ic_cipher == IEEE80211_CIPHER_AES_CCM) { 11005 return (1); 11006 } 11007 11008 if (ieee80211_is_key_unicast(vap, k)) { 11009 *keyix = 0; /* NB: use key index 0 for ucast key */ 11010 } else if (ieee80211_is_key_global(vap, k)) { 11011 *keyix = ieee80211_crypto_get_key_wepidx(vap, k); 11012 } else { 11013 net80211_vap_printf(vap, "%s: invalid crypto key type\n", 11014 __func__); 11015 return (0); 11016 } 11017 *rxkeyix = IEEE80211_KEYIX_NONE; /* XXX maybe *keyix? */ 11018 return (1); 11019 } 11020 11021 static int 11022 iwx_key_set(struct ieee80211vap *vap, const struct ieee80211_key *k) 11023 { 11024 struct ieee80211com *ic = vap->iv_ic; 11025 struct iwx_softc *sc = ic->ic_softc; 11026 struct iwx_add_sta_key_cmd cmd; 11027 uint32_t status; 11028 int err; 11029 int id; 11030 11031 if (k->wk_cipher->ic_cipher != IEEE80211_CIPHER_AES_CCM) { 11032 return 1; 11033 } 11034 11035 /* 11036 * Keys are stored in 'ni' so 'k' is valid if 'ni' is valid. 11037 * Currently we only implement station mode where 'ni' is always 11038 * ic->ic_bss so there is no need to validate arguments beyond this: 11039 */ 11040 11041 memset(&cmd, 0, sizeof(cmd)); 11042 11043 if (ieee80211_is_key_global(vap, k)) { 11044 id = ieee80211_crypto_get_key_wepidx(vap, k); 11045 IWX_DPRINTF(sc, IWX_DEBUG_KEYMGMT, "%s: adding group key\n", 11046 __func__); 11047 } else if (ieee80211_is_key_unicast(vap, k)) { 11048 IWX_DPRINTF(sc, IWX_DEBUG_KEYMGMT, "%s: adding key\n", 11049 __func__); 11050 id = 0; /* net80211 currently only supports unicast key 0 */ 11051 } else { 11052 net80211_vap_printf(vap, "%s: unknown key type\n", __func__); 11053 return (ENXIO); 11054 } 11055 11056 IWX_LOCK(sc); 11057 11058 cmd.common.key_flags = htole16(IWX_STA_KEY_FLG_CCM | 11059 IWX_STA_KEY_FLG_WEP_KEY_MAP | 11060 ((id << IWX_STA_KEY_FLG_KEYID_POS) & 11061 IWX_STA_KEY_FLG_KEYID_MSK)); 11062 if (ieee80211_is_key_global(vap, k)) { 11063 cmd.common.key_offset = 1; 11064 cmd.common.key_flags |= htole16(IWX_STA_KEY_MULTICAST); 11065 } else if (ieee80211_is_key_unicast(vap, k)) { 11066 cmd.common.key_offset = 0; 11067 } else { 11068 net80211_vap_printf(vap, "%s: unknown key type\n", __func__); 11069 IWX_UNLOCK(sc); 11070 return (ENXIO); 11071 } 11072 memcpy(cmd.common.key, k->wk_key, MIN(sizeof(cmd.common.key), 11073 k->wk_keylen)); 11074 IWX_DPRINTF(sc, IWX_DEBUG_KEYMGMT, "%s: key: id=%d, len=%i, key=%*D\n", 11075 __func__, id, k->wk_keylen, k->wk_keylen, 11076 (const unsigned char *) k->wk_key, ""); 11077 cmd.common.sta_id = IWX_STATION_ID; 11078 11079 cmd.transmit_seq_cnt = htole64(k->wk_keytsc); 11080 IWX_DPRINTF(sc, IWX_DEBUG_KEYMGMT, "%s: k->wk_keytsc=%lu\n", __func__, 11081 k->wk_keytsc); 11082 11083 status = IWX_ADD_STA_SUCCESS; 11084 err = iwx_send_cmd_pdu_status(sc, IWX_ADD_STA_KEY, sizeof(cmd), &cmd, 11085 &status); 11086 if (!err && (status & IWX_ADD_STA_STATUS_MASK) != IWX_ADD_STA_SUCCESS) 11087 err = EIO; 11088 if (err) { 11089 net80211_vap_printf(vap, 11090 "%s: can't set wpa2 keys (error %d)\n", __func__, err); 11091 IWX_UNLOCK(sc); 11092 return err; 11093 } else 11094 IWX_DPRINTF(sc, IWX_DEBUG_KEYMGMT, 11095 "%s: key added successfully\n", __func__); 11096 IWX_UNLOCK(sc); 11097 return (1); 11098 } 11099 11100 static int 11101 iwx_key_delete(struct ieee80211vap *vap, const struct ieee80211_key *k) 11102 { 11103 /* 11104 * Note: since there's no key allocations to track - it's either 11105 * the 4 static WEP keys or the single unicast key - there's nothing 11106 * else to do here. 11107 * 11108 * This would need some further work to support IBSS/mesh/AP modes. 11109 */ 11110 return (1); 11111 } 11112 11113 static device_method_t iwx_pci_methods[] = { 11114 /* Device interface */ 11115 DEVMETHOD(device_probe, iwx_probe), 11116 DEVMETHOD(device_attach, iwx_attach), 11117 DEVMETHOD(device_detach, iwx_detach), 11118 DEVMETHOD(device_suspend, iwx_suspend), 11119 DEVMETHOD(device_resume, iwx_resume), 11120 11121 DEVMETHOD_END 11122 }; 11123 11124 static driver_t iwx_pci_driver = { 11125 "iwx", 11126 iwx_pci_methods, 11127 sizeof (struct iwx_softc) 11128 }; 11129 11130 DRIVER_MODULE(iwx, pci, iwx_pci_driver, NULL, NULL); 11131 MODULE_PNP_INFO("U16:device;D:#;T:vendor=0x8086", pci, iwx_pci_driver, 11132 iwx_devices, nitems(iwx_devices)); 11133 MODULE_DEPEND(iwx, firmware, 1, 1, 1); 11134 MODULE_DEPEND(iwx, pci, 1, 1, 1); 11135 MODULE_DEPEND(iwx, wlan, 1, 1, 1); 11136