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