1 /*- 2 * SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) AND ISC 3 */ 4 5 /* $OpenBSD: if_iwx.c,v 1.184 2024/05/08 14:03:54 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 IWX_DPRINTF(sc, IWX_DEBUG_TXRATE, "%s:%d: rinfo->rate=%i dot11 %d\n", __func__, __LINE__, 5637 rinfo->rate, rs->rs_rates[ieee80211_node_get_txrate_dot11rate(ni)]); 5638 5639 if (sc->sc_rate_n_flags_version >= 2) { 5640 if (rate_flags & IWX_RATE_MCS_LEGACY_OFDM_MSK) { 5641 rate_flags |= (iwx_fw_rateidx_ofdm(rinfo->rate) & 5642 IWX_RATE_LEGACY_RATE_MSK); 5643 } else { 5644 rate_flags |= (iwx_fw_rateidx_cck(rinfo->rate) & 5645 IWX_RATE_LEGACY_RATE_MSK); 5646 } 5647 } else 5648 rate_flags |= rinfo->plcp; 5649 5650 *rate_n_flags = rate_flags; 5651 IWX_DPRINTF(sc, IWX_DEBUG_TXRATE, "%s:%d flags=0x%x\n", 5652 __func__, __LINE__,*flags); 5653 IWX_DPRINTF(sc, IWX_DEBUG_TXRATE, "%s:%d rate_n_flags=0x%x\n", 5654 __func__, __LINE__, *rate_n_flags); 5655 5656 if (sc->sc_debug & IWX_DEBUG_TXRATE) 5657 print_ratenflags(__func__, __LINE__, 5658 *rate_n_flags, sc->sc_rate_n_flags_version); 5659 5660 return rinfo; 5661 } 5662 5663 static void 5664 iwx_tx_update_byte_tbl(struct iwx_softc *sc, struct iwx_tx_ring *txq, 5665 int idx, uint16_t byte_cnt, uint16_t num_tbs) 5666 { 5667 uint8_t filled_tfd_size, num_fetch_chunks; 5668 uint16_t len = byte_cnt; 5669 uint16_t bc_ent; 5670 5671 filled_tfd_size = offsetof(struct iwx_tfh_tfd, tbs) + 5672 num_tbs * sizeof(struct iwx_tfh_tb); 5673 /* 5674 * filled_tfd_size contains the number of filled bytes in the TFD. 5675 * Dividing it by 64 will give the number of chunks to fetch 5676 * to SRAM- 0 for one chunk, 1 for 2 and so on. 5677 * If, for example, TFD contains only 3 TBs then 32 bytes 5678 * of the TFD are used, and only one chunk of 64 bytes should 5679 * be fetched 5680 */ 5681 num_fetch_chunks = howmany(filled_tfd_size, 64) - 1; 5682 5683 if (sc->sc_device_family >= IWX_DEVICE_FAMILY_AX210) { 5684 struct iwx_gen3_bc_tbl_entry *scd_bc_tbl = txq->bc_tbl.vaddr; 5685 /* Starting from AX210, the HW expects bytes */ 5686 bc_ent = htole16(len | (num_fetch_chunks << 14)); 5687 scd_bc_tbl[idx].tfd_offset = bc_ent; 5688 } else { 5689 struct iwx_agn_scd_bc_tbl *scd_bc_tbl = txq->bc_tbl.vaddr; 5690 /* Before AX210, the HW expects DW */ 5691 len = howmany(len, 4); 5692 bc_ent = htole16(len | (num_fetch_chunks << 12)); 5693 scd_bc_tbl->tfd_offset[idx] = bc_ent; 5694 } 5695 5696 bus_dmamap_sync(sc->sc_dmat, txq->bc_tbl.map, BUS_DMASYNC_PREWRITE); 5697 } 5698 5699 static int 5700 iwx_tx(struct iwx_softc *sc, struct mbuf *m, struct ieee80211_node *ni) 5701 { 5702 struct ieee80211com *ic = &sc->sc_ic; 5703 struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); 5704 struct iwx_node *in = (void *)ni; 5705 struct iwx_tx_ring *ring; 5706 struct iwx_tx_data *data; 5707 struct iwx_tfh_tfd *desc; 5708 struct iwx_device_cmd *cmd; 5709 struct ieee80211_frame *wh; 5710 struct ieee80211_key *k = NULL; 5711 const struct iwx_rate *rinfo; 5712 uint64_t paddr; 5713 u_int hdrlen; 5714 uint32_t rate_n_flags; 5715 uint16_t num_tbs, flags, offload_assist = 0; 5716 int i, totlen, err, pad, qid; 5717 #define IWM_MAX_SCATTER 20 5718 bus_dma_segment_t *seg, segs[IWM_MAX_SCATTER]; 5719 int nsegs; 5720 struct mbuf *m1; 5721 size_t txcmd_size; 5722 5723 IWX_ASSERT_LOCKED(sc); 5724 5725 wh = mtod(m, struct ieee80211_frame *); 5726 hdrlen = ieee80211_anyhdrsize(wh); 5727 5728 qid = sc->first_data_qid; 5729 5730 /* Put QoS frames on the data queue which maps to their TID. */ 5731 if (IEEE80211_QOS_HAS_SEQ(wh)) { 5732 uint16_t qos = ieee80211_gettid(wh); 5733 uint8_t tid = qos & IEEE80211_QOS_TID; 5734 struct ieee80211_tx_ampdu *tap = &ni->ni_tx_ampdu[tid]; 5735 5736 /* 5737 * Note: we're currently putting all frames into one queue 5738 * except for A-MPDU queues. We should be able to choose 5739 * other WME queues but first we need to verify they've been 5740 * correctly setup for data. 5741 */ 5742 5743 /* 5744 * Only QoS data goes into an A-MPDU queue; 5745 * don't add QoS null, the other data types, etc. 5746 */ 5747 if (IEEE80211_AMPDU_RUNNING(tap) && 5748 IEEE80211_IS_QOSDATA(wh) && 5749 !IEEE80211_IS_MULTICAST(wh->i_addr1) && 5750 sc->aggqid[tid] != 0) { 5751 qid = sc->aggqid[tid]; 5752 } 5753 } 5754 5755 ring = &sc->txq[qid]; 5756 desc = &ring->desc[ring->cur]; 5757 memset(desc, 0, sizeof(*desc)); 5758 data = &ring->data[ring->cur]; 5759 5760 cmd = &ring->cmd[ring->cur]; 5761 cmd->hdr.code = IWX_TX_CMD; 5762 cmd->hdr.flags = 0; 5763 cmd->hdr.qid = ring->qid; 5764 cmd->hdr.idx = ring->cur; 5765 5766 rinfo = iwx_tx_fill_cmd(sc, in, wh, &flags, &rate_n_flags, m); 5767 if (rinfo == NULL) 5768 return EINVAL; 5769 5770 /* Offloaded sequence number assignment; non-AMPDU case */ 5771 if ((m->m_flags & M_AMPDU_MPDU) == 0) 5772 ieee80211_output_seqno_assign(ni, -1, m); 5773 5774 /* Radiotap */ 5775 if (ieee80211_radiotap_active_vap(vap)) { 5776 struct iwx_tx_radiotap_header *tap = &sc->sc_txtap; 5777 5778 tap->wt_flags = 0; 5779 tap->wt_chan_freq = htole16(ni->ni_chan->ic_freq); 5780 tap->wt_chan_flags = htole16(ni->ni_chan->ic_flags); 5781 tap->wt_rate = rinfo->rate; 5782 if (k != NULL) 5783 tap->wt_flags |= IEEE80211_RADIOTAP_F_WEP; 5784 ieee80211_radiotap_tx(vap, m); 5785 } 5786 5787 /* Encrypt - CCMP via direct HW path, TKIP/WEP indirected openbsd-style for now */ 5788 if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) { 5789 k = ieee80211_crypto_get_txkey(ni, m); 5790 if (k == NULL) { 5791 printf("%s: k is NULL!\n", __func__); 5792 m_freem(m); 5793 return (ENOBUFS); 5794 } else if (k->wk_cipher->ic_cipher == IEEE80211_CIPHER_AES_CCM) { 5795 k->wk_keytsc++; 5796 } else { 5797 k->wk_cipher->ic_encap(k, m); 5798 5799 /* 802.11 headers may have moved */ 5800 wh = mtod(m, struct ieee80211_frame *); 5801 flags |= IWX_TX_FLAGS_ENCRYPT_DIS; 5802 } 5803 } else 5804 flags |= IWX_TX_FLAGS_ENCRYPT_DIS; 5805 5806 totlen = m->m_pkthdr.len; 5807 5808 if (hdrlen & 3) { 5809 /* First segment length must be a multiple of 4. */ 5810 pad = 4 - (hdrlen & 3); 5811 offload_assist |= IWX_TX_CMD_OFFLD_PAD; 5812 } else 5813 pad = 0; 5814 5815 if (sc->sc_device_family >= IWX_DEVICE_FAMILY_AX210) { 5816 struct iwx_tx_cmd_gen3 *tx = (void *)cmd->data; 5817 memset(tx, 0, sizeof(*tx)); 5818 tx->len = htole16(totlen); 5819 tx->offload_assist = htole32(offload_assist); 5820 tx->flags = htole16(flags); 5821 tx->rate_n_flags = htole32(rate_n_flags); 5822 memcpy(tx->hdr, wh, hdrlen); 5823 txcmd_size = sizeof(*tx); 5824 } else { 5825 struct iwx_tx_cmd_gen2 *tx = (void *)cmd->data; 5826 memset(tx, 0, sizeof(*tx)); 5827 tx->len = htole16(totlen); 5828 tx->offload_assist = htole16(offload_assist); 5829 tx->flags = htole32(flags); 5830 tx->rate_n_flags = htole32(rate_n_flags); 5831 memcpy(tx->hdr, wh, hdrlen); 5832 txcmd_size = sizeof(*tx); 5833 } 5834 5835 /* Trim 802.11 header. */ 5836 m_adj(m, hdrlen); 5837 5838 err = bus_dmamap_load_mbuf_sg(ring->data_dmat, data->map, m, segs, 5839 &nsegs, BUS_DMA_NOWAIT); 5840 if (err && err != EFBIG) { 5841 printf("%s: can't map mbuf (error %d)\n", DEVNAME(sc), err); 5842 m_freem(m); 5843 return err; 5844 } 5845 if (err) { 5846 /* Too many DMA segments, linearize mbuf. */ 5847 m1 = m_collapse(m, M_NOWAIT, IWM_MAX_SCATTER - 2); 5848 if (m1 == NULL) { 5849 printf("%s: could not defrag mbufs\n", __func__); 5850 m_freem(m); 5851 return (ENOBUFS); 5852 } 5853 m = m1; 5854 err = bus_dmamap_load_mbuf_sg(ring->data_dmat, data->map, m, 5855 segs, &nsegs, BUS_DMA_NOWAIT); 5856 if (err) { 5857 printf("%s: can't map mbuf (error %d)\n", __func__, 5858 err); 5859 m_freem(m); 5860 return (err); 5861 } 5862 } 5863 data->m = m; 5864 data->in = in; 5865 5866 /* Fill TX descriptor. */ 5867 num_tbs = 2 + nsegs; 5868 desc->num_tbs = htole16(num_tbs); 5869 5870 desc->tbs[0].tb_len = htole16(IWX_FIRST_TB_SIZE); 5871 paddr = htole64(data->cmd_paddr); 5872 memcpy(&desc->tbs[0].addr, &paddr, sizeof(paddr)); 5873 #if __SIZEOF_SIZE_T__ > 4 5874 if (data->cmd_paddr >> 32 != (data->cmd_paddr + 5875 le32toh(desc->tbs[0].tb_len)) >> 32) 5876 DPRINTF(("%s: TB0 crosses 32bit boundary\n", __func__)); 5877 #endif 5878 desc->tbs[1].tb_len = htole16(sizeof(struct iwx_cmd_header) + 5879 txcmd_size + hdrlen + pad - IWX_FIRST_TB_SIZE); 5880 paddr = htole64(data->cmd_paddr + IWX_FIRST_TB_SIZE); 5881 memcpy(&desc->tbs[1].addr, &paddr, sizeof(paddr)); 5882 5883 #if __SIZEOF_SIZE_T__ > 4 5884 if (data->cmd_paddr >> 32 != (data->cmd_paddr + 5885 le32toh(desc->tbs[1].tb_len)) >> 32) 5886 DPRINTF(("%s: TB1 crosses 32bit boundary\n", __func__)); 5887 #endif 5888 5889 /* Other DMA segments are for data payload. */ 5890 for (i = 0; i < nsegs; i++) { 5891 seg = &segs[i]; 5892 desc->tbs[i + 2].tb_len = htole16(seg->ds_len); 5893 paddr = htole64(seg->ds_addr); 5894 memcpy(&desc->tbs[i + 2].addr, &paddr, sizeof(paddr)); 5895 #if __SIZEOF_SIZE_T__ > 4 5896 if (data->cmd_paddr >> 32 != (data->cmd_paddr + 5897 le32toh(desc->tbs[i + 2].tb_len)) >> 32) 5898 DPRINTF(("%s: TB%d crosses 32bit boundary\n", __func__, 5899 i + 2)); 5900 #endif 5901 } 5902 5903 bus_dmamap_sync(ring->data_dmat, data->map, BUS_DMASYNC_PREWRITE); 5904 bus_dmamap_sync(ring->cmd_dma.tag, ring->cmd_dma.map, 5905 BUS_DMASYNC_PREWRITE); 5906 bus_dmamap_sync(ring->desc_dma.tag, ring->desc_dma.map, 5907 BUS_DMASYNC_PREWRITE); 5908 5909 iwx_tx_update_byte_tbl(sc, ring, ring->cur, totlen, num_tbs); 5910 5911 /* Kick TX ring. */ 5912 ring->cur = (ring->cur + 1) % IWX_TX_RING_COUNT; 5913 ring->cur_hw = (ring->cur_hw + 1) % sc->max_tfd_queue_size; 5914 IWX_WRITE(sc, IWX_HBUS_TARG_WRPTR, ring->qid << 16 | ring->cur_hw); 5915 5916 /* Mark TX ring as full if we reach a certain threshold. */ 5917 if (++ring->queued > iwx_himark) { 5918 sc->qfullmsk |= 1 << ring->qid; 5919 } 5920 5921 sc->sc_tx_timer[ring->qid] = 15; 5922 5923 return 0; 5924 } 5925 5926 static int 5927 iwx_flush_sta_tids(struct iwx_softc *sc, int sta_id, uint16_t tids) 5928 { 5929 struct iwx_rx_packet *pkt; 5930 struct iwx_tx_path_flush_cmd_rsp *resp; 5931 struct iwx_tx_path_flush_cmd flush_cmd = { 5932 .sta_id = htole32(sta_id), 5933 .tid_mask = htole16(tids), 5934 }; 5935 struct iwx_host_cmd hcmd = { 5936 .id = IWX_TXPATH_FLUSH, 5937 .len = { sizeof(flush_cmd), }, 5938 .data = { &flush_cmd, }, 5939 .flags = IWX_CMD_WANT_RESP, 5940 .resp_pkt_len = sizeof(*pkt) + sizeof(*resp), 5941 }; 5942 int err, resp_len, i, num_flushed_queues; 5943 5944 err = iwx_send_cmd(sc, &hcmd); 5945 if (err) 5946 return err; 5947 5948 pkt = hcmd.resp_pkt; 5949 if (!pkt || (pkt->hdr.flags & IWX_CMD_FAILED_MSK)) { 5950 err = EIO; 5951 goto out; 5952 } 5953 5954 resp_len = iwx_rx_packet_payload_len(pkt); 5955 /* Some firmware versions don't provide a response. */ 5956 if (resp_len != sizeof(*resp)) { 5957 err = EIO; 5958 goto out; 5959 } 5960 5961 resp = (void *)pkt->data; 5962 5963 if (le16toh(resp->sta_id) != sta_id) { 5964 err = EIO; 5965 goto out; 5966 } 5967 5968 num_flushed_queues = le16toh(resp->num_flushed_queues); 5969 if (num_flushed_queues > IWX_TX_FLUSH_QUEUE_RSP) { 5970 err = EIO; 5971 goto out; 5972 } 5973 5974 for (i = 0; i < num_flushed_queues; i++) { 5975 struct iwx_flush_queue_info *queue_info = &resp->queues[i]; 5976 uint16_t tid = le16toh(queue_info->tid); 5977 uint16_t read_after = le16toh(queue_info->read_after_flush); 5978 uint16_t qid = le16toh(queue_info->queue_num); 5979 struct iwx_tx_ring *txq; 5980 5981 if (qid >= nitems(sc->txq)) 5982 continue; 5983 5984 txq = &sc->txq[qid]; 5985 if (tid != txq->tid) 5986 continue; 5987 5988 iwx_txq_advance(sc, txq, read_after); 5989 } 5990 out: 5991 iwx_free_resp(sc, &hcmd); 5992 return err; 5993 } 5994 5995 #define IWX_FLUSH_WAIT_MS 2000 5996 5997 static int 5998 iwx_drain_sta(struct iwx_softc *sc, struct iwx_node* in, int drain) 5999 { 6000 struct iwx_add_sta_cmd cmd; 6001 int err; 6002 uint32_t status; 6003 6004 memset(&cmd, 0, sizeof(cmd)); 6005 cmd.mac_id_n_color = htole32(IWX_FW_CMD_ID_AND_COLOR(in->in_id, 6006 in->in_color)); 6007 cmd.sta_id = IWX_STATION_ID; 6008 cmd.add_modify = IWX_STA_MODE_MODIFY; 6009 cmd.station_flags = drain ? htole32(IWX_STA_FLG_DRAIN_FLOW) : 0; 6010 cmd.station_flags_msk = htole32(IWX_STA_FLG_DRAIN_FLOW); 6011 6012 status = IWX_ADD_STA_SUCCESS; 6013 err = iwx_send_cmd_pdu_status(sc, IWX_ADD_STA, 6014 sizeof(cmd), &cmd, &status); 6015 if (err) { 6016 printf("%s: could not update sta (error %d)\n", 6017 DEVNAME(sc), err); 6018 return err; 6019 } 6020 6021 switch (status & IWX_ADD_STA_STATUS_MASK) { 6022 case IWX_ADD_STA_SUCCESS: 6023 break; 6024 default: 6025 err = EIO; 6026 printf("%s: Couldn't %s draining for station\n", 6027 DEVNAME(sc), drain ? "enable" : "disable"); 6028 break; 6029 } 6030 6031 return err; 6032 } 6033 6034 static int 6035 iwx_flush_sta(struct iwx_softc *sc, struct iwx_node *in) 6036 { 6037 int err; 6038 6039 IWX_ASSERT_LOCKED(sc); 6040 6041 sc->sc_flags |= IWX_FLAG_TXFLUSH; 6042 6043 err = iwx_drain_sta(sc, in, 1); 6044 if (err) 6045 goto done; 6046 6047 err = iwx_flush_sta_tids(sc, IWX_STATION_ID, 0xffff); 6048 if (err) { 6049 printf("%s: could not flush Tx path (error %d)\n", 6050 DEVNAME(sc), err); 6051 goto done; 6052 } 6053 6054 err = iwx_drain_sta(sc, in, 0); 6055 done: 6056 sc->sc_flags &= ~IWX_FLAG_TXFLUSH; 6057 return err; 6058 } 6059 6060 #define IWX_POWER_KEEP_ALIVE_PERIOD_SEC 25 6061 6062 static int 6063 iwx_beacon_filter_send_cmd(struct iwx_softc *sc, 6064 struct iwx_beacon_filter_cmd *cmd) 6065 { 6066 return iwx_send_cmd_pdu(sc, IWX_REPLY_BEACON_FILTERING_CMD, 6067 0, sizeof(struct iwx_beacon_filter_cmd), cmd); 6068 } 6069 6070 static int 6071 iwx_update_beacon_abort(struct iwx_softc *sc, struct iwx_node *in, int enable) 6072 { 6073 struct iwx_beacon_filter_cmd cmd = { 6074 IWX_BF_CMD_CONFIG_DEFAULTS, 6075 .bf_enable_beacon_filter = htole32(1), 6076 .ba_enable_beacon_abort = htole32(enable), 6077 }; 6078 6079 if (!sc->sc_bf.bf_enabled) 6080 return 0; 6081 6082 sc->sc_bf.ba_enabled = enable; 6083 return iwx_beacon_filter_send_cmd(sc, &cmd); 6084 } 6085 6086 static void 6087 iwx_power_build_cmd(struct iwx_softc *sc, struct iwx_node *in, 6088 struct iwx_mac_power_cmd *cmd) 6089 { 6090 struct ieee80211com *ic = &sc->sc_ic; 6091 struct ieee80211_node *ni = &in->in_ni; 6092 struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); 6093 int dtim_period, dtim_msec, keep_alive; 6094 6095 cmd->id_and_color = htole32(IWX_FW_CMD_ID_AND_COLOR(in->in_id, 6096 in->in_color)); 6097 if (vap->iv_dtim_period) 6098 dtim_period = vap->iv_dtim_period; 6099 else 6100 dtim_period = 1; 6101 6102 /* 6103 * Regardless of power management state the driver must set 6104 * keep alive period. FW will use it for sending keep alive NDPs 6105 * immediately after association. Check that keep alive period 6106 * is at least 3 * DTIM. 6107 */ 6108 dtim_msec = dtim_period * ni->ni_intval; 6109 keep_alive = MAX(3 * dtim_msec, 1000 * IWX_POWER_KEEP_ALIVE_PERIOD_SEC); 6110 keep_alive = roundup(keep_alive, 1000) / 1000; 6111 cmd->keep_alive_seconds = htole16(keep_alive); 6112 6113 if (ic->ic_opmode != IEEE80211_M_MONITOR) 6114 cmd->flags = htole16(IWX_POWER_FLAGS_POWER_SAVE_ENA_MSK); 6115 } 6116 6117 static int 6118 iwx_power_mac_update_mode(struct iwx_softc *sc, struct iwx_node *in) 6119 { 6120 int err; 6121 int ba_enable; 6122 struct iwx_mac_power_cmd cmd; 6123 6124 memset(&cmd, 0, sizeof(cmd)); 6125 6126 iwx_power_build_cmd(sc, in, &cmd); 6127 6128 err = iwx_send_cmd_pdu(sc, IWX_MAC_PM_POWER_TABLE, 0, 6129 sizeof(cmd), &cmd); 6130 if (err != 0) 6131 return err; 6132 6133 ba_enable = !!(cmd.flags & 6134 htole16(IWX_POWER_FLAGS_POWER_MANAGEMENT_ENA_MSK)); 6135 return iwx_update_beacon_abort(sc, in, ba_enable); 6136 } 6137 6138 static int 6139 iwx_power_update_device(struct iwx_softc *sc) 6140 { 6141 struct iwx_device_power_cmd cmd = { }; 6142 struct ieee80211com *ic = &sc->sc_ic; 6143 6144 if (ic->ic_opmode != IEEE80211_M_MONITOR) 6145 cmd.flags = htole16(IWX_DEVICE_POWER_FLAGS_POWER_SAVE_ENA_MSK); 6146 6147 return iwx_send_cmd_pdu(sc, 6148 IWX_POWER_TABLE_CMD, 0, sizeof(cmd), &cmd); 6149 } 6150 #if 0 6151 static int 6152 iwx_enable_beacon_filter(struct iwx_softc *sc, struct iwx_node *in) 6153 { 6154 struct iwx_beacon_filter_cmd cmd = { 6155 IWX_BF_CMD_CONFIG_DEFAULTS, 6156 .bf_enable_beacon_filter = htole32(1), 6157 .ba_enable_beacon_abort = htole32(sc->sc_bf.ba_enabled), 6158 }; 6159 int err; 6160 6161 err = iwx_beacon_filter_send_cmd(sc, &cmd); 6162 if (err == 0) 6163 sc->sc_bf.bf_enabled = 1; 6164 6165 return err; 6166 } 6167 #endif 6168 static int 6169 iwx_disable_beacon_filter(struct iwx_softc *sc) 6170 { 6171 struct iwx_beacon_filter_cmd cmd; 6172 int err; 6173 6174 memset(&cmd, 0, sizeof(cmd)); 6175 6176 err = iwx_beacon_filter_send_cmd(sc, &cmd); 6177 if (err == 0) 6178 sc->sc_bf.bf_enabled = 0; 6179 6180 return err; 6181 } 6182 6183 static int 6184 iwx_add_sta_cmd(struct iwx_softc *sc, struct iwx_node *in, int update) 6185 { 6186 struct iwx_add_sta_cmd add_sta_cmd; 6187 int err, i; 6188 uint32_t status, aggsize; 6189 const uint32_t max_aggsize = (IWX_STA_FLG_MAX_AGG_SIZE_64K >> 6190 IWX_STA_FLG_MAX_AGG_SIZE_SHIFT); 6191 struct ieee80211com *ic = &sc->sc_ic; 6192 struct ieee80211_node *ni = &in->in_ni; 6193 struct ieee80211_htrateset *htrs = &ni->ni_htrates; 6194 6195 if (!update && (sc->sc_flags & IWX_FLAG_STA_ACTIVE)) 6196 panic("STA already added"); 6197 6198 memset(&add_sta_cmd, 0, sizeof(add_sta_cmd)); 6199 6200 if (ic->ic_opmode == IEEE80211_M_MONITOR) { 6201 add_sta_cmd.sta_id = IWX_MONITOR_STA_ID; 6202 add_sta_cmd.station_type = IWX_STA_GENERAL_PURPOSE; 6203 } else { 6204 add_sta_cmd.sta_id = IWX_STATION_ID; 6205 add_sta_cmd.station_type = IWX_STA_LINK; 6206 } 6207 add_sta_cmd.mac_id_n_color 6208 = htole32(IWX_FW_CMD_ID_AND_COLOR(in->in_id, in->in_color)); 6209 if (!update) { 6210 if (ic->ic_opmode == IEEE80211_M_MONITOR) 6211 IEEE80211_ADDR_COPY(&add_sta_cmd.addr, 6212 etheranyaddr); 6213 else 6214 IEEE80211_ADDR_COPY(&add_sta_cmd.addr, 6215 in->in_macaddr); 6216 } 6217 DPRINTF(("%s: add_sta_cmd.addr=%s\n", __func__, 6218 ether_sprintf(add_sta_cmd.addr))); 6219 add_sta_cmd.add_modify = update ? 1 : 0; 6220 add_sta_cmd.station_flags_msk 6221 |= htole32(IWX_STA_FLG_FAT_EN_MSK | IWX_STA_FLG_MIMO_EN_MSK); 6222 6223 if (in->in_ni.ni_flags & IEEE80211_NODE_HT) { 6224 add_sta_cmd.station_flags_msk 6225 |= htole32(IWX_STA_FLG_MAX_AGG_SIZE_MSK | 6226 IWX_STA_FLG_AGG_MPDU_DENS_MSK); 6227 6228 if (iwx_mimo_enabled(sc)) { 6229 if (ni->ni_flags & IEEE80211_NODE_VHT) { 6230 add_sta_cmd.station_flags |= 6231 htole32(IWX_STA_FLG_MIMO_EN_MIMO2); 6232 } else { 6233 int hasmimo = 0; 6234 for (i = 0; i < htrs->rs_nrates; i++) { 6235 if (htrs->rs_rates[i] > 7) { 6236 hasmimo = 1; 6237 break; 6238 } 6239 } 6240 if (hasmimo) { 6241 add_sta_cmd.station_flags |= 6242 htole32(IWX_STA_FLG_MIMO_EN_MIMO2); 6243 } 6244 } 6245 } 6246 6247 if (ni->ni_flags & IEEE80211_NODE_HT && 6248 IEEE80211_IS_CHAN_HT40(ni->ni_chan)) { 6249 add_sta_cmd.station_flags |= htole32( 6250 IWX_STA_FLG_FAT_EN_40MHZ); 6251 } 6252 6253 6254 if (ni->ni_flags & IEEE80211_NODE_VHT) { 6255 if (IEEE80211_IS_CHAN_VHT80(ni->ni_chan)) { 6256 add_sta_cmd.station_flags |= htole32( 6257 IWX_STA_FLG_FAT_EN_80MHZ); 6258 } 6259 // XXX-misha: TODO get real ampdu size 6260 aggsize = max_aggsize; 6261 } else { 6262 aggsize = _IEEE80211_MASKSHIFT(le16toh(ni->ni_htparam), 6263 IEEE80211_HTCAP_MAXRXAMPDU); 6264 } 6265 6266 if (aggsize > max_aggsize) 6267 aggsize = max_aggsize; 6268 add_sta_cmd.station_flags |= htole32((aggsize << 6269 IWX_STA_FLG_MAX_AGG_SIZE_SHIFT) & 6270 IWX_STA_FLG_MAX_AGG_SIZE_MSK); 6271 6272 switch (_IEEE80211_MASKSHIFT(le16toh(ni->ni_htparam), 6273 IEEE80211_HTCAP_MPDUDENSITY)) { 6274 case IEEE80211_HTCAP_MPDUDENSITY_2: 6275 add_sta_cmd.station_flags 6276 |= htole32(IWX_STA_FLG_AGG_MPDU_DENS_2US); 6277 break; 6278 case IEEE80211_HTCAP_MPDUDENSITY_4: 6279 add_sta_cmd.station_flags 6280 |= htole32(IWX_STA_FLG_AGG_MPDU_DENS_4US); 6281 break; 6282 case IEEE80211_HTCAP_MPDUDENSITY_8: 6283 add_sta_cmd.station_flags 6284 |= htole32(IWX_STA_FLG_AGG_MPDU_DENS_8US); 6285 break; 6286 case IEEE80211_HTCAP_MPDUDENSITY_16: 6287 add_sta_cmd.station_flags 6288 |= htole32(IWX_STA_FLG_AGG_MPDU_DENS_16US); 6289 break; 6290 default: 6291 break; 6292 } 6293 } 6294 6295 status = IWX_ADD_STA_SUCCESS; 6296 err = iwx_send_cmd_pdu_status(sc, IWX_ADD_STA, sizeof(add_sta_cmd), 6297 &add_sta_cmd, &status); 6298 if (!err && (status & IWX_ADD_STA_STATUS_MASK) != IWX_ADD_STA_SUCCESS) 6299 err = EIO; 6300 6301 return err; 6302 } 6303 6304 static int 6305 iwx_rm_sta_cmd(struct iwx_softc *sc, struct iwx_node *in) 6306 { 6307 struct ieee80211com *ic = &sc->sc_ic; 6308 struct iwx_rm_sta_cmd rm_sta_cmd; 6309 int err; 6310 6311 if ((sc->sc_flags & IWX_FLAG_STA_ACTIVE) == 0) 6312 panic("sta already removed"); 6313 6314 memset(&rm_sta_cmd, 0, sizeof(rm_sta_cmd)); 6315 if (ic->ic_opmode == IEEE80211_M_MONITOR) 6316 rm_sta_cmd.sta_id = IWX_MONITOR_STA_ID; 6317 else 6318 rm_sta_cmd.sta_id = IWX_STATION_ID; 6319 6320 err = iwx_send_cmd_pdu(sc, IWX_REMOVE_STA, 0, sizeof(rm_sta_cmd), 6321 &rm_sta_cmd); 6322 6323 return err; 6324 } 6325 6326 static int 6327 iwx_rm_sta(struct iwx_softc *sc, struct iwx_node *in) 6328 { 6329 int err, i, cmd_ver; 6330 6331 err = iwx_flush_sta(sc, in); 6332 if (err) { 6333 printf("%s: could not flush Tx path (error %d)\n", 6334 DEVNAME(sc), err); 6335 return err; 6336 } 6337 6338 /* 6339 * New SCD_QUEUE_CONFIG API requires explicit queue removal 6340 * before a station gets removed. 6341 */ 6342 cmd_ver = iwx_lookup_cmd_ver(sc, IWX_DATA_PATH_GROUP, 6343 IWX_SCD_QUEUE_CONFIG_CMD); 6344 if (cmd_ver != 0 && cmd_ver != IWX_FW_CMD_VER_UNKNOWN) { 6345 err = iwx_disable_mgmt_queue(sc); 6346 if (err) 6347 return err; 6348 for (i = IWX_FIRST_AGG_TX_QUEUE; 6349 i < IWX_LAST_AGG_TX_QUEUE; i++) { 6350 struct iwx_tx_ring *ring = &sc->txq[i]; 6351 if ((sc->qenablemsk & (1 << i)) == 0) 6352 continue; 6353 err = iwx_disable_txq(sc, IWX_STATION_ID, 6354 ring->qid, ring->tid); 6355 if (err) { 6356 printf("%s: could not disable Tx queue %d " 6357 "(error %d)\n", DEVNAME(sc), ring->qid, 6358 err); 6359 return err; 6360 } 6361 } 6362 } 6363 6364 err = iwx_rm_sta_cmd(sc, in); 6365 if (err) { 6366 printf("%s: could not remove STA (error %d)\n", 6367 DEVNAME(sc), err); 6368 return err; 6369 } 6370 6371 in->in_flags = 0; 6372 6373 sc->sc_rx_ba_sessions = 0; 6374 sc->ba_rx.start_tidmask = 0; 6375 sc->ba_rx.stop_tidmask = 0; 6376 memset(sc->aggqid, 0, sizeof(sc->aggqid)); 6377 sc->ba_tx.start_tidmask = 0; 6378 sc->ba_tx.stop_tidmask = 0; 6379 for (i = IWX_FIRST_AGG_TX_QUEUE; i < IWX_LAST_AGG_TX_QUEUE; i++) 6380 sc->qenablemsk &= ~(1 << i); 6381 6382 #if 0 6383 for (i = 0; i < IEEE80211_NUM_TID; i++) { 6384 struct ieee80211_tx_ba *ba = &ni->ni_tx_ba[i]; 6385 if (ba->ba_state != IEEE80211_BA_AGREED) 6386 continue; 6387 ieee80211_delba_request(ic, ni, 0, 1, i); 6388 } 6389 #endif 6390 /* Clear ampdu rx state (GOS-1525) */ 6391 for (i = 0; i < IWX_MAX_TID_COUNT; i++) { 6392 struct iwx_rx_ba *ba = &sc->ni_rx_ba[i]; 6393 ba->ba_flags = 0; 6394 } 6395 6396 return 0; 6397 } 6398 6399 static uint8_t 6400 iwx_umac_scan_fill_channels(struct iwx_softc *sc, 6401 struct iwx_scan_channel_cfg_umac *chan, size_t chan_nitems, 6402 int n_ssids, uint32_t channel_cfg_flags) 6403 { 6404 struct ieee80211com *ic = &sc->sc_ic; 6405 struct ieee80211_scan_state *ss = ic->ic_scan; 6406 struct ieee80211_channel *c; 6407 uint8_t nchan; 6408 int j; 6409 6410 for (nchan = j = 0; 6411 j < ss->ss_last && 6412 nchan < sc->sc_capa_n_scan_channels; 6413 j++) { 6414 uint8_t channel_num; 6415 6416 c = ss->ss_chans[j]; 6417 channel_num = ieee80211_mhz2ieee(c->ic_freq, 0); 6418 if (isset(sc->sc_ucode_api, 6419 IWX_UCODE_TLV_API_SCAN_EXT_CHAN_VER)) { 6420 chan->v2.channel_num = channel_num; 6421 if (IEEE80211_IS_CHAN_2GHZ(c)) 6422 chan->v2.band = IWX_PHY_BAND_24; 6423 else 6424 chan->v2.band = IWX_PHY_BAND_5; 6425 chan->v2.iter_count = 1; 6426 chan->v2.iter_interval = 0; 6427 } else { 6428 chan->v1.channel_num = channel_num; 6429 chan->v1.iter_count = 1; 6430 chan->v1.iter_interval = htole16(0); 6431 } 6432 chan->flags |= htole32(channel_cfg_flags); 6433 chan++; 6434 nchan++; 6435 } 6436 6437 return nchan; 6438 } 6439 6440 static int 6441 iwx_fill_probe_req(struct iwx_softc *sc, struct iwx_scan_probe_req *preq) 6442 { 6443 struct ieee80211com *ic = &sc->sc_ic; 6444 struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); 6445 struct ieee80211_frame *wh = (struct ieee80211_frame *)preq->buf; 6446 struct ieee80211_rateset *rs; 6447 size_t remain = sizeof(preq->buf); 6448 uint8_t *frm, *pos; 6449 6450 memset(preq, 0, sizeof(*preq)); 6451 6452 if (remain < sizeof(*wh) + 2) 6453 return ENOBUFS; 6454 6455 /* 6456 * Build a probe request frame. Most of the following code is a 6457 * copy & paste of what is done in net80211. 6458 */ 6459 wh->i_fc[0] = IEEE80211_FC0_VERSION_0 | IEEE80211_FC0_TYPE_MGT | 6460 IEEE80211_FC0_SUBTYPE_PROBE_REQ; 6461 wh->i_fc[1] = IEEE80211_FC1_DIR_NODS; 6462 IEEE80211_ADDR_COPY(wh->i_addr1, etherbroadcastaddr); 6463 IEEE80211_ADDR_COPY(wh->i_addr2, vap ? vap->iv_myaddr : ic->ic_macaddr); 6464 IEEE80211_ADDR_COPY(wh->i_addr3, etherbroadcastaddr); 6465 *(uint16_t *)&wh->i_dur[0] = 0; /* filled by HW */ 6466 *(uint16_t *)&wh->i_seq[0] = 0; /* filled by HW */ 6467 6468 frm = (uint8_t *)(wh + 1); 6469 *frm++ = IEEE80211_ELEMID_SSID; 6470 *frm++ = 0; 6471 /* hardware inserts SSID */ 6472 6473 /* Tell the firmware where the MAC header is. */ 6474 preq->mac_header.offset = 0; 6475 preq->mac_header.len = htole16(frm - (uint8_t *)wh); 6476 remain -= frm - (uint8_t *)wh; 6477 6478 /* Fill in 2GHz IEs and tell firmware where they are. */ 6479 rs = &ic->ic_sup_rates[IEEE80211_MODE_11G]; 6480 if (rs->rs_nrates > IEEE80211_RATE_SIZE) { 6481 if (remain < 4 + rs->rs_nrates) 6482 return ENOBUFS; 6483 } else if (remain < 2 + rs->rs_nrates) 6484 return ENOBUFS; 6485 preq->band_data[0].offset = htole16(frm - (uint8_t *)wh); 6486 pos = frm; 6487 frm = ieee80211_add_rates(frm, rs); 6488 if (rs->rs_nrates > IEEE80211_RATE_SIZE) 6489 frm = ieee80211_add_xrates(frm, rs); 6490 remain -= frm - pos; 6491 6492 if (isset(sc->sc_enabled_capa, 6493 IWX_UCODE_TLV_CAPA_DS_PARAM_SET_IE_SUPPORT)) { 6494 if (remain < 3) 6495 return ENOBUFS; 6496 *frm++ = IEEE80211_ELEMID_DSPARMS; 6497 *frm++ = 1; 6498 *frm++ = 0; 6499 remain -= 3; 6500 } 6501 preq->band_data[0].len = htole16(frm - pos); 6502 6503 if (sc->sc_nvm.sku_cap_band_52GHz_enable) { 6504 /* Fill in 5GHz IEs. */ 6505 rs = &ic->ic_sup_rates[IEEE80211_MODE_11A]; 6506 if (rs->rs_nrates > IEEE80211_RATE_SIZE) { 6507 if (remain < 4 + rs->rs_nrates) 6508 return ENOBUFS; 6509 } else if (remain < 2 + rs->rs_nrates) 6510 return ENOBUFS; 6511 preq->band_data[1].offset = htole16(frm - (uint8_t *)wh); 6512 pos = frm; 6513 frm = ieee80211_add_rates(frm, rs); 6514 if (rs->rs_nrates > IEEE80211_RATE_SIZE) 6515 frm = ieee80211_add_xrates(frm, rs); 6516 preq->band_data[1].len = htole16(frm - pos); 6517 remain -= frm - pos; 6518 if (vap->iv_vht_flags & IEEE80211_FVHT_VHT) { 6519 if (remain < 14) 6520 return ENOBUFS; 6521 frm = ieee80211_add_vhtcap(frm, vap->iv_bss); 6522 remain -= frm - pos; 6523 preq->band_data[1].len = htole16(frm - pos); 6524 } 6525 } 6526 6527 /* Send 11n IEs on both 2GHz and 5GHz bands. */ 6528 preq->common_data.offset = htole16(frm - (uint8_t *)wh); 6529 pos = frm; 6530 if (vap->iv_flags_ht & IEEE80211_FHT_HT) { 6531 if (remain < 28) 6532 return ENOBUFS; 6533 frm = ieee80211_add_htcap(frm, vap->iv_bss); 6534 /* XXX add WME info? */ 6535 remain -= frm - pos; 6536 } 6537 6538 preq->common_data.len = htole16(frm - pos); 6539 6540 return 0; 6541 } 6542 6543 static int 6544 iwx_config_umac_scan_reduced(struct iwx_softc *sc) 6545 { 6546 struct iwx_scan_config scan_cfg; 6547 struct iwx_host_cmd hcmd = { 6548 .id = iwx_cmd_id(IWX_SCAN_CFG_CMD, IWX_LONG_GROUP, 0), 6549 .len[0] = sizeof(scan_cfg), 6550 .data[0] = &scan_cfg, 6551 .flags = 0, 6552 }; 6553 int cmdver; 6554 6555 if (!isset(sc->sc_ucode_api, IWX_UCODE_TLV_API_REDUCED_SCAN_CONFIG)) { 6556 printf("%s: firmware does not support reduced scan config\n", 6557 DEVNAME(sc)); 6558 return ENOTSUP; 6559 } 6560 6561 memset(&scan_cfg, 0, sizeof(scan_cfg)); 6562 6563 /* 6564 * SCAN_CFG version >= 5 implies that the broadcast 6565 * STA ID field is deprecated. 6566 */ 6567 cmdver = iwx_lookup_cmd_ver(sc, IWX_LONG_GROUP, IWX_SCAN_CFG_CMD); 6568 if (cmdver == IWX_FW_CMD_VER_UNKNOWN || cmdver < 5) 6569 scan_cfg.bcast_sta_id = 0xff; 6570 6571 scan_cfg.tx_chains = htole32(iwx_fw_valid_tx_ant(sc)); 6572 scan_cfg.rx_chains = htole32(iwx_fw_valid_rx_ant(sc)); 6573 6574 return iwx_send_cmd(sc, &hcmd); 6575 } 6576 6577 static uint16_t 6578 iwx_scan_umac_flags_v2(struct iwx_softc *sc, int bgscan) 6579 { 6580 struct ieee80211com *ic = &sc->sc_ic; 6581 struct ieee80211_scan_state *ss = ic->ic_scan; 6582 uint16_t flags = 0; 6583 6584 if (ss->ss_nssid == 0) { 6585 DPRINTF(("%s: Passive scan started\n", __func__)); 6586 flags |= IWX_UMAC_SCAN_GEN_FLAGS_V2_FORCE_PASSIVE; 6587 } 6588 6589 flags |= IWX_UMAC_SCAN_GEN_FLAGS_V2_PASS_ALL; 6590 flags |= IWX_UMAC_SCAN_GEN_FLAGS_V2_NTFY_ITER_COMPLETE; 6591 flags |= IWX_UMAC_SCAN_GEN_FLAGS_V2_ADAPTIVE_DWELL; 6592 6593 return flags; 6594 } 6595 6596 #define IWX_SCAN_DWELL_ACTIVE 10 6597 #define IWX_SCAN_DWELL_PASSIVE 110 6598 6599 /* adaptive dwell max budget time [TU] for full scan */ 6600 #define IWX_SCAN_ADWELL_MAX_BUDGET_FULL_SCAN 300 6601 /* adaptive dwell max budget time [TU] for directed scan */ 6602 #define IWX_SCAN_ADWELL_MAX_BUDGET_DIRECTED_SCAN 100 6603 /* adaptive dwell default high band APs number */ 6604 #define IWX_SCAN_ADWELL_DEFAULT_HB_N_APS 8 6605 /* adaptive dwell default low band APs number */ 6606 #define IWX_SCAN_ADWELL_DEFAULT_LB_N_APS 2 6607 /* adaptive dwell default APs number in social channels (1, 6, 11) */ 6608 #define IWX_SCAN_ADWELL_DEFAULT_N_APS_SOCIAL 10 6609 /* adaptive dwell number of APs override for p2p friendly GO channels */ 6610 #define IWX_SCAN_ADWELL_N_APS_GO_FRIENDLY 10 6611 /* adaptive dwell number of APs override for social channels */ 6612 #define IWX_SCAN_ADWELL_N_APS_SOCIAL_CHS 2 6613 6614 static void 6615 iwx_scan_umac_dwell_v10(struct iwx_softc *sc, 6616 struct iwx_scan_general_params_v10 *general_params, int bgscan) 6617 { 6618 uint32_t suspend_time, max_out_time; 6619 uint8_t active_dwell, passive_dwell; 6620 6621 active_dwell = IWX_SCAN_DWELL_ACTIVE; 6622 passive_dwell = IWX_SCAN_DWELL_PASSIVE; 6623 6624 general_params->adwell_default_social_chn = 6625 IWX_SCAN_ADWELL_DEFAULT_N_APS_SOCIAL; 6626 general_params->adwell_default_2g = IWX_SCAN_ADWELL_DEFAULT_LB_N_APS; 6627 general_params->adwell_default_5g = IWX_SCAN_ADWELL_DEFAULT_HB_N_APS; 6628 6629 if (bgscan) 6630 general_params->adwell_max_budget = 6631 htole16(IWX_SCAN_ADWELL_MAX_BUDGET_DIRECTED_SCAN); 6632 else 6633 general_params->adwell_max_budget = 6634 htole16(IWX_SCAN_ADWELL_MAX_BUDGET_FULL_SCAN); 6635 6636 general_params->scan_priority = htole32(IWX_SCAN_PRIORITY_EXT_6); 6637 if (bgscan) { 6638 max_out_time = htole32(120); 6639 suspend_time = htole32(120); 6640 } else { 6641 max_out_time = htole32(0); 6642 suspend_time = htole32(0); 6643 } 6644 general_params->max_out_of_time[IWX_SCAN_LB_LMAC_IDX] = 6645 htole32(max_out_time); 6646 general_params->suspend_time[IWX_SCAN_LB_LMAC_IDX] = 6647 htole32(suspend_time); 6648 general_params->max_out_of_time[IWX_SCAN_HB_LMAC_IDX] = 6649 htole32(max_out_time); 6650 general_params->suspend_time[IWX_SCAN_HB_LMAC_IDX] = 6651 htole32(suspend_time); 6652 6653 general_params->active_dwell[IWX_SCAN_LB_LMAC_IDX] = active_dwell; 6654 general_params->passive_dwell[IWX_SCAN_LB_LMAC_IDX] = passive_dwell; 6655 general_params->active_dwell[IWX_SCAN_HB_LMAC_IDX] = active_dwell; 6656 general_params->passive_dwell[IWX_SCAN_HB_LMAC_IDX] = passive_dwell; 6657 } 6658 6659 static void 6660 iwx_scan_umac_fill_general_p_v10(struct iwx_softc *sc, 6661 struct iwx_scan_general_params_v10 *gp, uint16_t gen_flags, int bgscan) 6662 { 6663 iwx_scan_umac_dwell_v10(sc, gp, bgscan); 6664 6665 gp->flags = htole16(gen_flags); 6666 6667 if (gen_flags & IWX_UMAC_SCAN_GEN_FLAGS_V2_FRAGMENTED_LMAC1) 6668 gp->num_of_fragments[IWX_SCAN_LB_LMAC_IDX] = 3; 6669 if (gen_flags & IWX_UMAC_SCAN_GEN_FLAGS_V2_FRAGMENTED_LMAC2) 6670 gp->num_of_fragments[IWX_SCAN_HB_LMAC_IDX] = 3; 6671 6672 gp->scan_start_mac_id = 0; 6673 } 6674 6675 static void 6676 iwx_scan_umac_fill_ch_p_v6(struct iwx_softc *sc, 6677 struct iwx_scan_channel_params_v6 *cp, uint32_t channel_cfg_flags, 6678 int n_ssid) 6679 { 6680 cp->flags = IWX_SCAN_CHANNEL_FLAG_ENABLE_CHAN_ORDER; 6681 6682 cp->count = iwx_umac_scan_fill_channels(sc, cp->channel_config, 6683 nitems(cp->channel_config), n_ssid, channel_cfg_flags); 6684 6685 cp->n_aps_override[0] = IWX_SCAN_ADWELL_N_APS_GO_FRIENDLY; 6686 cp->n_aps_override[1] = IWX_SCAN_ADWELL_N_APS_SOCIAL_CHS; 6687 } 6688 6689 static int 6690 iwx_umac_scan_v14(struct iwx_softc *sc, int bgscan) 6691 { 6692 struct ieee80211com *ic = &sc->sc_ic; 6693 struct ieee80211_scan_state *ss = ic->ic_scan; 6694 struct iwx_host_cmd hcmd = { 6695 .id = iwx_cmd_id(IWX_SCAN_REQ_UMAC, IWX_LONG_GROUP, 0), 6696 .len = { 0, }, 6697 .data = { NULL, }, 6698 .flags = 0, 6699 }; 6700 struct iwx_scan_req_umac_v14 *cmd = &sc->sc_umac_v14_cmd; 6701 struct iwx_scan_req_params_v14 *scan_p; 6702 int err, async = bgscan, n_ssid = 0; 6703 uint16_t gen_flags; 6704 uint32_t bitmap_ssid = 0; 6705 6706 IWX_ASSERT_LOCKED(sc); 6707 6708 bzero(cmd, sizeof(struct iwx_scan_req_umac_v14)); 6709 6710 scan_p = &cmd->scan_params; 6711 6712 cmd->ooc_priority = htole32(IWX_SCAN_PRIORITY_EXT_6); 6713 cmd->uid = htole32(0); 6714 6715 gen_flags = iwx_scan_umac_flags_v2(sc, bgscan); 6716 iwx_scan_umac_fill_general_p_v10(sc, &scan_p->general_params, 6717 gen_flags, bgscan); 6718 6719 scan_p->periodic_params.schedule[0].interval = htole16(0); 6720 scan_p->periodic_params.schedule[0].iter_count = 1; 6721 6722 err = iwx_fill_probe_req(sc, &scan_p->probe_params.preq); 6723 if (err) { 6724 printf("%s: iwx_fill_probe_req failed (error %d)\n", __func__, 6725 err); 6726 return err; 6727 } 6728 6729 for (int i=0; i < ss->ss_nssid; i++) { 6730 scan_p->probe_params.direct_scan[i].id = IEEE80211_ELEMID_SSID; 6731 scan_p->probe_params.direct_scan[i].len = 6732 MIN(ss->ss_ssid[i].len, IEEE80211_NWID_LEN); 6733 DPRINTF(("%s: Active scan started for ssid ", __func__)); 6734 memcpy(scan_p->probe_params.direct_scan[i].ssid, 6735 ss->ss_ssid[i].ssid, ss->ss_ssid[i].len); 6736 n_ssid++; 6737 bitmap_ssid |= (1 << i); 6738 } 6739 DPRINTF(("%s: bitmap_ssid=0x%x\n", __func__, bitmap_ssid)); 6740 6741 iwx_scan_umac_fill_ch_p_v6(sc, &scan_p->channel_params, bitmap_ssid, 6742 n_ssid); 6743 6744 hcmd.len[0] = sizeof(*cmd); 6745 hcmd.data[0] = (void *)cmd; 6746 hcmd.flags |= async ? IWX_CMD_ASYNC : 0; 6747 6748 err = iwx_send_cmd(sc, &hcmd); 6749 return err; 6750 } 6751 6752 static void 6753 iwx_mcc_update(struct iwx_softc *sc, struct iwx_mcc_chub_notif *notif) 6754 { 6755 char alpha2[3]; 6756 6757 snprintf(alpha2, sizeof(alpha2), "%c%c", 6758 (le16toh(notif->mcc) & 0xff00) >> 8, le16toh(notif->mcc) & 0xff); 6759 6760 IWX_DPRINTF(sc, IWX_DEBUG_FW, "%s: firmware has detected regulatory domain '%s' " 6761 "(0x%x)\n", DEVNAME(sc), alpha2, le16toh(notif->mcc)); 6762 6763 /* TODO: Schedule a task to send MCC_UPDATE_CMD? */ 6764 } 6765 6766 uint8_t 6767 iwx_ridx2rate(struct ieee80211_rateset *rs, int ridx) 6768 { 6769 int i; 6770 uint8_t rval; 6771 6772 for (i = 0; i < rs->rs_nrates; i++) { 6773 rval = (rs->rs_rates[i] & IEEE80211_RATE_VAL); 6774 if (rval == iwx_rates[ridx].rate) 6775 return rs->rs_rates[i]; 6776 } 6777 6778 return 0; 6779 } 6780 6781 static int 6782 iwx_rval2ridx(int rval) 6783 { 6784 int ridx; 6785 6786 for (ridx = 0; ridx < nitems(iwx_rates); ridx++) { 6787 if (iwx_rates[ridx].plcp == IWX_RATE_INVM_PLCP) 6788 continue; 6789 if (rval == iwx_rates[ridx].rate) 6790 break; 6791 } 6792 6793 return ridx; 6794 } 6795 6796 static void 6797 iwx_ack_rates(struct iwx_softc *sc, struct iwx_node *in, int *cck_rates, 6798 int *ofdm_rates) 6799 { 6800 struct ieee80211_node *ni = &in->in_ni; 6801 struct ieee80211_rateset *rs = &ni->ni_rates; 6802 int lowest_present_ofdm = -1; 6803 int lowest_present_cck = -1; 6804 uint8_t cck = 0; 6805 uint8_t ofdm = 0; 6806 int i; 6807 6808 if (ni->ni_chan == IEEE80211_CHAN_ANYC || 6809 IEEE80211_IS_CHAN_2GHZ(ni->ni_chan)) { 6810 for (i = IWX_FIRST_CCK_RATE; i < IWX_FIRST_OFDM_RATE; i++) { 6811 if ((iwx_ridx2rate(rs, i) & IEEE80211_RATE_BASIC) == 0) 6812 continue; 6813 cck |= (1 << i); 6814 if (lowest_present_cck == -1 || lowest_present_cck > i) 6815 lowest_present_cck = i; 6816 } 6817 } 6818 for (i = IWX_FIRST_OFDM_RATE; i <= IWX_LAST_NON_HT_RATE; i++) { 6819 if ((iwx_ridx2rate(rs, i) & IEEE80211_RATE_BASIC) == 0) 6820 continue; 6821 ofdm |= (1 << (i - IWX_FIRST_OFDM_RATE)); 6822 if (lowest_present_ofdm == -1 || lowest_present_ofdm > i) 6823 lowest_present_ofdm = i; 6824 } 6825 6826 /* 6827 * Now we've got the basic rates as bitmaps in the ofdm and cck 6828 * variables. This isn't sufficient though, as there might not 6829 * be all the right rates in the bitmap. E.g. if the only basic 6830 * rates are 5.5 Mbps and 11 Mbps, we still need to add 1 Mbps 6831 * and 6 Mbps because the 802.11-2007 standard says in 9.6: 6832 * 6833 * [...] a STA responding to a received frame shall transmit 6834 * its Control Response frame [...] at the highest rate in the 6835 * BSSBasicRateSet parameter that is less than or equal to the 6836 * rate of the immediately previous frame in the frame exchange 6837 * sequence ([...]) and that is of the same modulation class 6838 * ([...]) as the received frame. If no rate contained in the 6839 * BSSBasicRateSet parameter meets these conditions, then the 6840 * control frame sent in response to a received frame shall be 6841 * transmitted at the highest mandatory rate of the PHY that is 6842 * less than or equal to the rate of the received frame, and 6843 * that is of the same modulation class as the received frame. 6844 * 6845 * As a consequence, we need to add all mandatory rates that are 6846 * lower than all of the basic rates to these bitmaps. 6847 */ 6848 6849 if (IWX_RATE_24M_INDEX < lowest_present_ofdm) 6850 ofdm |= IWX_RATE_BIT_MSK(24) >> IWX_FIRST_OFDM_RATE; 6851 if (IWX_RATE_12M_INDEX < lowest_present_ofdm) 6852 ofdm |= IWX_RATE_BIT_MSK(12) >> IWX_FIRST_OFDM_RATE; 6853 /* 6M already there or needed so always add */ 6854 ofdm |= IWX_RATE_BIT_MSK(6) >> IWX_FIRST_OFDM_RATE; 6855 6856 /* 6857 * CCK is a bit more complex with DSSS vs. HR/DSSS vs. ERP. 6858 * Note, however: 6859 * - if no CCK rates are basic, it must be ERP since there must 6860 * be some basic rates at all, so they're OFDM => ERP PHY 6861 * (or we're in 5 GHz, and the cck bitmap will never be used) 6862 * - if 11M is a basic rate, it must be ERP as well, so add 5.5M 6863 * - if 5.5M is basic, 1M and 2M are mandatory 6864 * - if 2M is basic, 1M is mandatory 6865 * - if 1M is basic, that's the only valid ACK rate. 6866 * As a consequence, it's not as complicated as it sounds, just add 6867 * any lower rates to the ACK rate bitmap. 6868 */ 6869 if (IWX_RATE_11M_INDEX < lowest_present_cck) 6870 cck |= IWX_RATE_BIT_MSK(11) >> IWX_FIRST_CCK_RATE; 6871 if (IWX_RATE_5M_INDEX < lowest_present_cck) 6872 cck |= IWX_RATE_BIT_MSK(5) >> IWX_FIRST_CCK_RATE; 6873 if (IWX_RATE_2M_INDEX < lowest_present_cck) 6874 cck |= IWX_RATE_BIT_MSK(2) >> IWX_FIRST_CCK_RATE; 6875 /* 1M already there or needed so always add */ 6876 cck |= IWX_RATE_BIT_MSK(1) >> IWX_FIRST_CCK_RATE; 6877 6878 *cck_rates = cck; 6879 *ofdm_rates = ofdm; 6880 } 6881 6882 static void 6883 iwx_mac_ctxt_cmd_common(struct iwx_softc *sc, struct iwx_node *in, 6884 struct iwx_mac_ctx_cmd *cmd, uint32_t action) 6885 { 6886 #define IWX_EXP2(x) ((1 << (x)) - 1) /* CWmin = 2^ECWmin - 1 */ 6887 struct ieee80211com *ic = &sc->sc_ic; 6888 struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); 6889 struct ieee80211_node *ni = vap->iv_bss; 6890 int cck_ack_rates, ofdm_ack_rates; 6891 6892 cmd->id_and_color = htole32(IWX_FW_CMD_ID_AND_COLOR(in->in_id, 6893 in->in_color)); 6894 cmd->action = htole32(action); 6895 6896 if (action == IWX_FW_CTXT_ACTION_REMOVE) 6897 return; 6898 6899 if (ic->ic_opmode == IEEE80211_M_MONITOR) 6900 cmd->mac_type = htole32(IWX_FW_MAC_TYPE_LISTENER); 6901 else if (ic->ic_opmode == IEEE80211_M_STA) 6902 cmd->mac_type = htole32(IWX_FW_MAC_TYPE_BSS_STA); 6903 else 6904 panic("unsupported operating mode %d", ic->ic_opmode); 6905 cmd->tsf_id = htole32(IWX_TSF_ID_A); 6906 6907 IEEE80211_ADDR_COPY(cmd->node_addr, vap->iv_myaddr); 6908 DPRINTF(("%s: cmd->node_addr=%s\n", __func__, 6909 ether_sprintf(cmd->node_addr))); 6910 if (ic->ic_opmode == IEEE80211_M_MONITOR) { 6911 IEEE80211_ADDR_COPY(cmd->bssid_addr, etherbroadcastaddr); 6912 return; 6913 } 6914 6915 IEEE80211_ADDR_COPY(cmd->bssid_addr, in->in_macaddr); 6916 DPRINTF(("%s: cmd->bssid_addr=%s\n", __func__, 6917 ether_sprintf(cmd->bssid_addr))); 6918 iwx_ack_rates(sc, in, &cck_ack_rates, &ofdm_ack_rates); 6919 cmd->cck_rates = htole32(cck_ack_rates); 6920 cmd->ofdm_rates = htole32(ofdm_ack_rates); 6921 6922 cmd->cck_short_preamble 6923 = htole32((ic->ic_flags & IEEE80211_F_SHPREAMBLE) 6924 ? IWX_MAC_FLG_SHORT_PREAMBLE : 0); 6925 cmd->short_slot 6926 = htole32((ic->ic_flags & IEEE80211_F_SHSLOT) 6927 ? IWX_MAC_FLG_SHORT_SLOT : 0); 6928 6929 struct chanAccParams chp; 6930 ieee80211_wme_vap_getparams(vap, &chp); 6931 6932 for (int i = 0; i < WME_NUM_AC; i++) { 6933 int txf = iwx_ac_to_tx_fifo[i]; 6934 cmd->ac[txf].cw_min = IWX_EXP2(chp.cap_wmeParams[i].wmep_logcwmin); 6935 cmd->ac[txf].cw_max = IWX_EXP2(chp.cap_wmeParams[i].wmep_logcwmax); 6936 cmd->ac[txf].aifsn = chp.cap_wmeParams[i].wmep_aifsn; 6937 cmd->ac[txf].fifos_mask = (1 << txf); 6938 cmd->ac[txf].edca_txop = chp.cap_wmeParams[i].wmep_txopLimit; 6939 6940 cmd->ac[txf].edca_txop = htole16(chp.cap_wmeParams[i].wmep_txopLimit * 32); 6941 } 6942 6943 if (ni->ni_flags & IEEE80211_NODE_QOS) { 6944 DPRINTF(("%s: === IEEE80211_NODE_QOS\n", __func__)); 6945 cmd->qos_flags |= htole32(IWX_MAC_QOS_FLG_UPDATE_EDCA); 6946 } 6947 6948 if (ni->ni_flags & IEEE80211_NODE_HT) { 6949 switch (vap->iv_curhtprotmode) { 6950 case IEEE80211_HTINFO_OPMODE_PURE: 6951 break; 6952 case IEEE80211_HTINFO_OPMODE_PROTOPT: 6953 case IEEE80211_HTINFO_OPMODE_MIXED: 6954 cmd->protection_flags |= 6955 htole32(IWX_MAC_PROT_FLG_HT_PROT | 6956 IWX_MAC_PROT_FLG_FAT_PROT); 6957 break; 6958 case IEEE80211_HTINFO_OPMODE_HT20PR: 6959 if (in->in_phyctxt && 6960 (in->in_phyctxt->sco == IEEE80211_HTINFO_2NDCHAN_ABOVE || 6961 in->in_phyctxt->sco == IEEE80211_HTINFO_2NDCHAN_BELOW)) { 6962 cmd->protection_flags |= 6963 htole32(IWX_MAC_PROT_FLG_HT_PROT | 6964 IWX_MAC_PROT_FLG_FAT_PROT); 6965 } 6966 break; 6967 default: 6968 break; 6969 } 6970 cmd->qos_flags |= htole32(IWX_MAC_QOS_FLG_TGN); 6971 DPRINTF(("%s: === IWX_MAC_QOS_FLG_TGN\n", __func__)); 6972 } 6973 6974 if (ic->ic_flags & IEEE80211_F_USEPROT) 6975 cmd->protection_flags |= htole32(IWX_MAC_PROT_FLG_TGG_PROTECT); 6976 cmd->filter_flags = htole32(IWX_MAC_FILTER_ACCEPT_GRP); 6977 #undef IWX_EXP2 6978 } 6979 6980 static void 6981 iwx_mac_ctxt_cmd_fill_sta(struct iwx_softc *sc, struct iwx_node *in, 6982 struct iwx_mac_data_sta *sta, int assoc) 6983 { 6984 struct ieee80211_node *ni = &in->in_ni; 6985 struct ieee80211com *ic = &sc->sc_ic; 6986 struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); 6987 uint32_t dtim_off; 6988 uint64_t tsf; 6989 int dtim_period; 6990 6991 dtim_off = ni->ni_dtim_count * ni->ni_intval * IEEE80211_DUR_TU; 6992 tsf = le64toh(ni->ni_tstamp.tsf); 6993 dtim_period = vap->iv_dtim_period; 6994 6995 sta->is_assoc = htole32(assoc); 6996 6997 if (assoc) { 6998 sta->dtim_time = htole32(tsf + dtim_off); 6999 sta->dtim_tsf = htole64(tsf + dtim_off); 7000 // XXX: unset in iwm 7001 sta->assoc_beacon_arrive_time = 0; 7002 } 7003 sta->bi = htole32(ni->ni_intval); 7004 sta->dtim_interval = htole32(ni->ni_intval * dtim_period); 7005 sta->data_policy = htole32(0); 7006 sta->listen_interval = htole32(10); 7007 sta->assoc_id = htole32(ni->ni_associd); 7008 } 7009 7010 static int 7011 iwx_mac_ctxt_cmd(struct iwx_softc *sc, struct iwx_node *in, uint32_t action, 7012 int assoc) 7013 { 7014 struct ieee80211com *ic = &sc->sc_ic; 7015 struct ieee80211_node *ni = &in->in_ni; 7016 struct iwx_mac_ctx_cmd cmd; 7017 int active = (sc->sc_flags & IWX_FLAG_MAC_ACTIVE); 7018 7019 if (action == IWX_FW_CTXT_ACTION_ADD && active) 7020 panic("MAC already added"); 7021 if (action == IWX_FW_CTXT_ACTION_REMOVE && !active) 7022 panic("MAC already removed"); 7023 7024 memset(&cmd, 0, sizeof(cmd)); 7025 7026 iwx_mac_ctxt_cmd_common(sc, in, &cmd, action); 7027 7028 if (action == IWX_FW_CTXT_ACTION_REMOVE) { 7029 return iwx_send_cmd_pdu(sc, IWX_MAC_CONTEXT_CMD, 0, 7030 sizeof(cmd), &cmd); 7031 } 7032 7033 if (ic->ic_opmode == IEEE80211_M_MONITOR) { 7034 cmd.filter_flags |= htole32(IWX_MAC_FILTER_IN_PROMISC | 7035 IWX_MAC_FILTER_IN_CONTROL_AND_MGMT | 7036 IWX_MAC_FILTER_ACCEPT_GRP | 7037 IWX_MAC_FILTER_IN_BEACON | 7038 IWX_MAC_FILTER_IN_PROBE_REQUEST | 7039 IWX_MAC_FILTER_IN_CRC32); 7040 // XXX: dtim period is in vap 7041 } else if (!assoc || !ni->ni_associd /*|| !ni->ni_dtimperiod*/) { 7042 /* 7043 * Allow beacons to pass through as long as we are not 7044 * associated or we do not have dtim period information. 7045 */ 7046 cmd.filter_flags |= htole32(IWX_MAC_FILTER_IN_BEACON); 7047 } 7048 iwx_mac_ctxt_cmd_fill_sta(sc, in, &cmd.sta, assoc); 7049 return iwx_send_cmd_pdu(sc, IWX_MAC_CONTEXT_CMD, 0, sizeof(cmd), &cmd); 7050 } 7051 7052 static int 7053 iwx_clear_statistics(struct iwx_softc *sc) 7054 { 7055 struct iwx_statistics_cmd scmd = { 7056 .flags = htole32(IWX_STATISTICS_FLG_CLEAR) 7057 }; 7058 struct iwx_host_cmd cmd = { 7059 .id = IWX_STATISTICS_CMD, 7060 .len[0] = sizeof(scmd), 7061 .data[0] = &scmd, 7062 .flags = IWX_CMD_WANT_RESP, 7063 .resp_pkt_len = sizeof(struct iwx_notif_statistics), 7064 }; 7065 int err; 7066 7067 err = iwx_send_cmd(sc, &cmd); 7068 if (err) 7069 return err; 7070 7071 iwx_free_resp(sc, &cmd); 7072 return 0; 7073 } 7074 7075 static int 7076 iwx_scan(struct iwx_softc *sc) 7077 { 7078 int err; 7079 err = iwx_umac_scan_v14(sc, 0); 7080 7081 if (err) { 7082 printf("%s: could not initiate scan\n", DEVNAME(sc)); 7083 return err; 7084 } 7085 return 0; 7086 } 7087 7088 static int 7089 iwx_bgscan(struct ieee80211com *ic) 7090 { 7091 struct iwx_softc *sc = ic->ic_softc; 7092 int err; 7093 7094 err = iwx_umac_scan_v14(sc, 1); 7095 if (err) { 7096 printf("%s: could not initiate scan\n", DEVNAME(sc)); 7097 return err; 7098 } 7099 return 0; 7100 } 7101 7102 static int 7103 iwx_enable_mgmt_queue(struct iwx_softc *sc) 7104 { 7105 int err; 7106 7107 sc->first_data_qid = IWX_DQA_CMD_QUEUE + 1; 7108 7109 /* 7110 * Non-QoS frames use the "MGMT" TID and queue. 7111 * Other TIDs and data queues are reserved for QoS data frames. 7112 */ 7113 err = iwx_enable_txq(sc, IWX_STATION_ID, sc->first_data_qid, 7114 IWX_MGMT_TID, IWX_TX_RING_COUNT); 7115 if (err) { 7116 printf("%s: could not enable Tx queue %d (error %d)\n", 7117 DEVNAME(sc), sc->first_data_qid, err); 7118 return err; 7119 } 7120 7121 return 0; 7122 } 7123 7124 static int 7125 iwx_disable_mgmt_queue(struct iwx_softc *sc) 7126 { 7127 int err, cmd_ver; 7128 7129 /* Explicit removal is only required with old SCD_QUEUE_CFG command. */ 7130 cmd_ver = iwx_lookup_cmd_ver(sc, IWX_DATA_PATH_GROUP, 7131 IWX_SCD_QUEUE_CONFIG_CMD); 7132 if (cmd_ver == 0 || cmd_ver == IWX_FW_CMD_VER_UNKNOWN) 7133 return 0; 7134 7135 sc->first_data_qid = IWX_DQA_CMD_QUEUE + 1; 7136 7137 err = iwx_disable_txq(sc, IWX_STATION_ID, sc->first_data_qid, 7138 IWX_MGMT_TID); 7139 if (err) { 7140 printf("%s: could not disable Tx queue %d (error %d)\n", 7141 DEVNAME(sc), sc->first_data_qid, err); 7142 return err; 7143 } 7144 7145 return 0; 7146 } 7147 7148 static int 7149 iwx_rs_rval2idx(uint8_t rval) 7150 { 7151 /* Firmware expects indices which match our 11g rate set. */ 7152 const struct ieee80211_rateset *rs = &ieee80211_std_rateset_11g; 7153 int i; 7154 7155 for (i = 0; i < rs->rs_nrates; i++) { 7156 if ((rs->rs_rates[i] & IEEE80211_RATE_VAL) == rval) 7157 return i; 7158 } 7159 7160 return -1; 7161 } 7162 7163 static uint16_t 7164 iwx_rs_ht_rates(struct iwx_softc *sc, struct ieee80211_node *ni, int rsidx) 7165 { 7166 uint16_t htrates = 0; 7167 struct ieee80211_htrateset *htrs = &ni->ni_htrates; 7168 int i; 7169 7170 if (rsidx == IEEE80211_HT_RATESET_SISO) { 7171 for (i = 0; i < htrs->rs_nrates; i++) { 7172 if (htrs->rs_rates[i] <= 7) 7173 htrates |= (1 << htrs->rs_rates[i]); 7174 } 7175 } else if (rsidx == IEEE80211_HT_RATESET_MIMO2) { 7176 for (i = 0; i < htrs->rs_nrates; i++) { 7177 if (htrs->rs_rates[i] > 7 && htrs->rs_rates[i] <= 15) 7178 htrates |= (1 << (htrs->rs_rates[i] - 8)); 7179 } 7180 } else 7181 panic(("iwx_rs_ht_rates")); 7182 7183 IWX_DPRINTF(sc, IWX_DEBUG_TXRATE, 7184 "%s:%d rsidx=%i htrates=0x%x\n", __func__, __LINE__, rsidx, htrates); 7185 7186 return htrates; 7187 } 7188 7189 uint16_t 7190 iwx_rs_vht_rates(struct iwx_softc *sc, struct ieee80211_node *ni, int num_ss) 7191 { 7192 uint16_t rx_mcs; 7193 int max_mcs = -1; 7194 #define IEEE80211_VHT_MCS_FOR_SS_MASK(n) (0x3 << (2*((n)-1))) 7195 #define IEEE80211_VHT_MCS_FOR_SS_SHIFT(n) (2*((n)-1)) 7196 rx_mcs = (ni->ni_vht_mcsinfo.tx_mcs_map & 7197 IEEE80211_VHT_MCS_FOR_SS_MASK(num_ss)) >> 7198 IEEE80211_VHT_MCS_FOR_SS_SHIFT(num_ss); 7199 7200 switch (rx_mcs) { 7201 case IEEE80211_VHT_MCS_NOT_SUPPORTED: 7202 break; 7203 case IEEE80211_VHT_MCS_SUPPORT_0_7: 7204 max_mcs = 7; 7205 break; 7206 case IEEE80211_VHT_MCS_SUPPORT_0_8: 7207 max_mcs = 8; 7208 break; 7209 case IEEE80211_VHT_MCS_SUPPORT_0_9: 7210 /* Disable VHT MCS 9 for 20MHz-only stations. */ 7211 if ((ni->ni_htcap & IEEE80211_HTCAP_CHWIDTH40) == 0) 7212 max_mcs = 8; 7213 else 7214 max_mcs = 9; 7215 break; 7216 default: 7217 /* Should not happen; Values above cover the possible range. */ 7218 panic("invalid VHT Rx MCS value %u", rx_mcs); 7219 } 7220 7221 return ((1 << (max_mcs + 1)) - 1); 7222 } 7223 7224 static int 7225 iwx_rs_init_v3(struct iwx_softc *sc, struct iwx_node *in) 7226 { 7227 #if 1 7228 panic("iwx: Trying to init rate set on untested version"); 7229 #else 7230 struct ieee80211_node *ni = &in->in_ni; 7231 struct ieee80211_rateset *rs = &ni->ni_rates; 7232 struct iwx_tlc_config_cmd_v3 cfg_cmd; 7233 uint32_t cmd_id; 7234 int i; 7235 size_t cmd_size = sizeof(cfg_cmd); 7236 7237 memset(&cfg_cmd, 0, sizeof(cfg_cmd)); 7238 7239 for (i = 0; i < rs->rs_nrates; i++) { 7240 uint8_t rval = rs->rs_rates[i] & IEEE80211_RATE_VAL; 7241 int idx = iwx_rs_rval2idx(rval); 7242 if (idx == -1) 7243 return EINVAL; 7244 cfg_cmd.non_ht_rates |= (1 << idx); 7245 } 7246 7247 if (ni->ni_flags & IEEE80211_NODE_VHT) { 7248 cfg_cmd.mode = IWX_TLC_MNG_MODE_VHT; 7249 cfg_cmd.ht_rates[IWX_TLC_NSS_1][IWX_TLC_MCS_PER_BW_80] = 7250 htole16(iwx_rs_vht_rates(sc, ni, 1)); 7251 cfg_cmd.ht_rates[IWX_TLC_NSS_2][IWX_TLC_MCS_PER_BW_80] = 7252 htole16(iwx_rs_vht_rates(sc, ni, 2)); 7253 } else if (ni->ni_flags & IEEE80211_NODE_HT) { 7254 cfg_cmd.mode = IWX_TLC_MNG_MODE_HT; 7255 cfg_cmd.ht_rates[IWX_TLC_NSS_1][IWX_TLC_MCS_PER_BW_80] = 7256 htole16(iwx_rs_ht_rates(sc, ni, 7257 IEEE80211_HT_RATESET_SISO)); 7258 cfg_cmd.ht_rates[IWX_TLC_NSS_2][IWX_TLC_MCS_PER_BW_80] = 7259 htole16(iwx_rs_ht_rates(sc, ni, 7260 IEEE80211_HT_RATESET_MIMO2)); 7261 } else 7262 cfg_cmd.mode = IWX_TLC_MNG_MODE_NON_HT; 7263 7264 cfg_cmd.sta_id = IWX_STATION_ID; 7265 if (in->in_phyctxt->vht_chan_width == IEEE80211_VHTOP0_CHAN_WIDTH_80) 7266 cfg_cmd.max_ch_width = IWX_TLC_MNG_CH_WIDTH_80MHZ; 7267 else if (in->in_phyctxt->sco == IEEE80211_HTOP0_SCO_SCA || 7268 in->in_phyctxt->sco == IEEE80211_HTOP0_SCO_SCB) 7269 cfg_cmd.max_ch_width = IWX_TLC_MNG_CH_WIDTH_40MHZ; 7270 else 7271 cfg_cmd.max_ch_width = IWX_TLC_MNG_CH_WIDTH_20MHZ; 7272 cfg_cmd.chains = IWX_TLC_MNG_CHAIN_A_MSK | IWX_TLC_MNG_CHAIN_B_MSK; 7273 if (ni->ni_flags & IEEE80211_NODE_VHT) 7274 cfg_cmd.max_mpdu_len = htole16(3895); 7275 else 7276 cfg_cmd.max_mpdu_len = htole16(3839); 7277 if (ni->ni_flags & IEEE80211_NODE_HT) { 7278 if (ieee80211_node_supports_ht_sgi20(ni)) { 7279 cfg_cmd.sgi_ch_width_supp |= (1 << 7280 IWX_TLC_MNG_CH_WIDTH_20MHZ); 7281 } 7282 if (ieee80211_node_supports_ht_sgi40(ni)) { 7283 cfg_cmd.sgi_ch_width_supp |= (1 << 7284 IWX_TLC_MNG_CH_WIDTH_40MHZ); 7285 } 7286 } 7287 if ((ni->ni_flags & IEEE80211_NODE_VHT) && 7288 ieee80211_node_supports_vht_sgi80(ni)) 7289 cfg_cmd.sgi_ch_width_supp |= (1 << IWX_TLC_MNG_CH_WIDTH_80MHZ); 7290 7291 cmd_id = iwx_cmd_id(IWX_TLC_MNG_CONFIG_CMD, IWX_DATA_PATH_GROUP, 0); 7292 return iwx_send_cmd_pdu(sc, cmd_id, IWX_CMD_ASYNC, cmd_size, &cfg_cmd); 7293 #endif 7294 } 7295 7296 static int 7297 iwx_rs_init_v4(struct iwx_softc *sc, struct iwx_node *in) 7298 { 7299 struct ieee80211_node *ni = &in->in_ni; 7300 struct ieee80211_rateset *rs = &ni->ni_rates; 7301 struct ieee80211_htrateset *htrs = &ni->ni_htrates; 7302 struct iwx_tlc_config_cmd_v4 cfg_cmd; 7303 uint32_t cmd_id; 7304 int i; 7305 int sgi80 = 0; 7306 size_t cmd_size = sizeof(cfg_cmd); 7307 7308 memset(&cfg_cmd, 0, sizeof(cfg_cmd)); 7309 7310 for (i = 0; i < rs->rs_nrates; i++) { 7311 uint8_t rval = rs->rs_rates[i] & IEEE80211_RATE_VAL; 7312 int idx = iwx_rs_rval2idx(rval); 7313 if (idx == -1) 7314 return EINVAL; 7315 cfg_cmd.non_ht_rates |= (1 << idx); 7316 } 7317 for (i = 0; i < htrs->rs_nrates; i++) { 7318 DPRINTF(("%s: htrate=%i\n", __func__, htrs->rs_rates[i])); 7319 } 7320 7321 if (ni->ni_flags & IEEE80211_NODE_VHT) { 7322 cfg_cmd.mode = IWX_TLC_MNG_MODE_VHT; 7323 cfg_cmd.ht_rates[IWX_TLC_NSS_1][IWX_TLC_MCS_PER_BW_80] = 7324 htole16(iwx_rs_vht_rates(sc, ni, 1)); 7325 cfg_cmd.ht_rates[IWX_TLC_NSS_2][IWX_TLC_MCS_PER_BW_80] = 7326 htole16(iwx_rs_vht_rates(sc, ni, 2)); 7327 7328 IWX_DPRINTF(sc, IWX_DEBUG_TXRATE, "%s:%d SISO=0x%x\n", 7329 __func__, __LINE__, 7330 cfg_cmd.ht_rates[IWX_TLC_NSS_1][IWX_TLC_MCS_PER_BW_80]); 7331 IWX_DPRINTF(sc, IWX_DEBUG_TXRATE, "%s:%d MIMO2=0x%x\n", 7332 __func__, __LINE__, 7333 cfg_cmd.ht_rates[IWX_TLC_NSS_2][IWX_TLC_MCS_PER_BW_80]); 7334 } else if (ni->ni_flags & IEEE80211_NODE_HT) { 7335 cfg_cmd.mode = IWX_TLC_MNG_MODE_HT; 7336 cfg_cmd.ht_rates[IWX_TLC_NSS_1][IWX_TLC_MCS_PER_BW_80] = 7337 htole16(iwx_rs_ht_rates(sc, ni, 7338 IEEE80211_HT_RATESET_SISO)); 7339 cfg_cmd.ht_rates[IWX_TLC_NSS_2][IWX_TLC_MCS_PER_BW_80] = 7340 htole16(iwx_rs_ht_rates(sc, ni, 7341 IEEE80211_HT_RATESET_MIMO2)); 7342 7343 IWX_DPRINTF(sc, IWX_DEBUG_TXRATE, "%s:%d SISO=0x%x\n", 7344 __func__, __LINE__, 7345 cfg_cmd.ht_rates[IWX_TLC_NSS_1][IWX_TLC_MCS_PER_BW_80]); 7346 IWX_DPRINTF(sc, IWX_DEBUG_TXRATE, "%s:%d MIMO2=0x%x\n", 7347 __func__, __LINE__, 7348 cfg_cmd.ht_rates[IWX_TLC_NSS_2][IWX_TLC_MCS_PER_BW_80]); 7349 } else 7350 cfg_cmd.mode = IWX_TLC_MNG_MODE_NON_HT; 7351 7352 cfg_cmd.sta_id = IWX_STATION_ID; 7353 #if 0 7354 if (in->in_phyctxt->vht_chan_width == IEEE80211_VHTOP0_CHAN_WIDTH_80) 7355 cfg_cmd.max_ch_width = IWX_TLC_MNG_CH_WIDTH_80MHZ; 7356 else if (in->in_phyctxt->sco == IEEE80211_HTOP0_SCO_SCA || 7357 in->in_phyctxt->sco == IEEE80211_HTOP0_SCO_SCB) 7358 cfg_cmd.max_ch_width = IWX_TLC_MNG_CH_WIDTH_40MHZ; 7359 else 7360 cfg_cmd.max_ch_width = IWX_TLC_MNG_CH_WIDTH_20MHZ; 7361 #endif 7362 if (IEEE80211_IS_CHAN_VHT80(in->in_ni.ni_chan)) { 7363 cfg_cmd.max_ch_width = IWX_TLC_MNG_CH_WIDTH_80MHZ; 7364 } else if (IEEE80211_IS_CHAN_HT40(in->in_ni.ni_chan)) { 7365 cfg_cmd.max_ch_width = IWX_TLC_MNG_CH_WIDTH_40MHZ; 7366 } else { 7367 cfg_cmd.max_ch_width = IWX_TLC_MNG_CH_WIDTH_20MHZ; 7368 } 7369 7370 cfg_cmd.chains = IWX_TLC_MNG_CHAIN_A_MSK | IWX_TLC_MNG_CHAIN_B_MSK; 7371 if (ni->ni_flags & IEEE80211_NODE_VHT) 7372 cfg_cmd.max_mpdu_len = htole16(3895); 7373 else 7374 cfg_cmd.max_mpdu_len = htole16(3839); 7375 if (ni->ni_flags & IEEE80211_NODE_HT) { 7376 if (ni->ni_htcap & IEEE80211_HTCAP_SHORTGI20) { 7377 cfg_cmd.sgi_ch_width_supp |= (1 << 7378 IWX_TLC_MNG_CH_WIDTH_20MHZ); 7379 } 7380 if (ni->ni_htcap & IEEE80211_HTCAP_SHORTGI40) { 7381 cfg_cmd.sgi_ch_width_supp |= (1 << 7382 IWX_TLC_MNG_CH_WIDTH_40MHZ); 7383 } 7384 } 7385 sgi80 = _IEEE80211_MASKSHIFT(ni->ni_vhtcap, 7386 IEEE80211_VHTCAP_SHORT_GI_80); 7387 if ((ni->ni_flags & IEEE80211_NODE_VHT) && sgi80) { 7388 cfg_cmd.sgi_ch_width_supp |= (1 << IWX_TLC_MNG_CH_WIDTH_80MHZ); 7389 } 7390 7391 cmd_id = iwx_cmd_id(IWX_TLC_MNG_CONFIG_CMD, IWX_DATA_PATH_GROUP, 0); 7392 return iwx_send_cmd_pdu(sc, cmd_id, IWX_CMD_ASYNC, cmd_size, &cfg_cmd); 7393 } 7394 7395 static int 7396 iwx_rs_init(struct iwx_softc *sc, struct iwx_node *in) 7397 { 7398 int cmd_ver; 7399 7400 cmd_ver = iwx_lookup_cmd_ver(sc, IWX_DATA_PATH_GROUP, 7401 IWX_TLC_MNG_CONFIG_CMD); 7402 if (cmd_ver == 4) 7403 return iwx_rs_init_v4(sc, in); 7404 else 7405 return iwx_rs_init_v3(sc, in); 7406 } 7407 7408 7409 /** 7410 * @brief Turn the given TX rate control notification into an ieee80211_node_txrate 7411 * 7412 * This populates the given txrate node with the TX rate control notification. 7413 * 7414 * @param sc driver softc 7415 * @param notif firmware notification 7416 * @param ni ieee80211_node update 7417 * @returns true if updated, false if not 7418 */ 7419 static bool 7420 iwx_rs_update_node_txrate(struct iwx_softc *sc, 7421 const struct iwx_tlc_update_notif *notif, struct ieee80211_node *ni) 7422 { 7423 struct ieee80211com *ic = &sc->sc_ic; 7424 /* XXX TODO: create an inline function in if_iwxreg.h? */ 7425 static int cck_idx_to_rate[] = { 2, 4, 11, 22, 2, 2, 2, 2 }; 7426 static int ofdm_idx_to_rate[] = { 12, 18, 24, 36, 48, 72, 96, 108 }; 7427 7428 uint32_t rate_n_flags; 7429 uint32_t type; 7430 7431 /* Extract the rate and command version */ 7432 rate_n_flags = le32toh(notif->rate); 7433 7434 if (sc->sc_rate_n_flags_version != 2) { 7435 net80211_ic_printf(ic, 7436 "%s: unsupported rate_n_flags version (%d)\n", 7437 __func__, 7438 sc->sc_rate_n_flags_version); 7439 return (false); 7440 } 7441 7442 if (sc->sc_debug & IWX_DEBUG_TXRATE) 7443 print_ratenflags(__func__, __LINE__, 7444 rate_n_flags, sc->sc_rate_n_flags_version); 7445 7446 type = (rate_n_flags & IWX_RATE_MCS_MOD_TYPE_MSK); 7447 switch (type) { 7448 case IWX_RATE_MCS_CCK_MSK: 7449 ieee80211_node_set_txrate_dot11rate(ni, 7450 cck_idx_to_rate[rate_n_flags & IWX_RATE_LEGACY_RATE_MSK]); 7451 return (true); 7452 case IWX_RATE_MCS_LEGACY_OFDM_MSK: 7453 ieee80211_node_set_txrate_dot11rate(ni, 7454 ofdm_idx_to_rate[rate_n_flags & IWX_RATE_LEGACY_RATE_MSK]); 7455 return (true); 7456 case IWX_RATE_MCS_HT_MSK: 7457 /* 7458 * TODO: the current API doesn't include channel width 7459 * and other flags, so we can't accurately store them yet! 7460 * 7461 * channel width: (flags & IWX_RATE_MCS_CHAN_WIDTH_MSK) 7462 * >> IWX_RATE_MCS_CHAN_WIDTH_POS) 7463 * LDPC: (flags & (1 << 16)) 7464 */ 7465 ieee80211_node_set_txrate_ht_mcsrate(ni, 7466 IWX_RATE_HT_MCS_INDEX(rate_n_flags)); 7467 return (true); 7468 case IWX_RATE_MCS_VHT_MSK: 7469 /* TODO: same comment on channel width, etc above */ 7470 ieee80211_node_set_txrate_vht_rate(ni, 7471 IWX_RATE_VHT_MCS_CODE(rate_n_flags), 7472 IWX_RATE_VHT_MCS_NSS(rate_n_flags)); 7473 return (true); 7474 default: 7475 net80211_ic_printf(ic, 7476 "%s: unsupported chosen rate type in " 7477 "IWX_RATE_MCS_MOD_TYPE (%d)\n", __func__, 7478 type >> IWX_RATE_MCS_MOD_TYPE_POS); 7479 return (false); 7480 } 7481 7482 /* Default: if we get here, we didn't successfully update anything */ 7483 return (false); 7484 } 7485 7486 /** 7487 * @brief Process a firmware rate control update and update net80211. 7488 * 7489 * Since firmware is doing rate control, this just needs to update 7490 * the txrate in the ieee80211_node entry. 7491 */ 7492 static void 7493 iwx_rs_update(struct iwx_softc *sc, struct iwx_tlc_update_notif *notif) 7494 { 7495 struct ieee80211com *ic = &sc->sc_ic; 7496 struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); 7497 /* XXX TODO: get a node ref! */ 7498 struct ieee80211_node *ni = (void *)vap->iv_bss; 7499 7500 /* 7501 * For now the iwx driver only supports a single vdev with a single 7502 * node; it doesn't yet support ibss/hostap/multiple vdevs. 7503 */ 7504 if (notif->sta_id != IWX_STATION_ID || 7505 (le32toh(notif->flags) & IWX_TLC_NOTIF_FLAG_RATE) == 0) 7506 return; 7507 7508 iwx_rs_update_node_txrate(sc, notif, ni); 7509 } 7510 7511 static int 7512 iwx_phy_send_rlc(struct iwx_softc *sc, struct iwx_phy_ctxt *phyctxt, 7513 uint8_t chains_static, uint8_t chains_dynamic) 7514 { 7515 struct iwx_rlc_config_cmd cmd; 7516 uint32_t cmd_id; 7517 uint8_t active_cnt, idle_cnt; 7518 7519 memset(&cmd, 0, sizeof(cmd)); 7520 7521 idle_cnt = chains_static; 7522 active_cnt = chains_dynamic; 7523 7524 cmd.phy_id = htole32(phyctxt->id); 7525 cmd.rlc.rx_chain_info = htole32(iwx_fw_valid_rx_ant(sc) << 7526 IWX_PHY_RX_CHAIN_VALID_POS); 7527 cmd.rlc.rx_chain_info |= htole32(idle_cnt << IWX_PHY_RX_CHAIN_CNT_POS); 7528 cmd.rlc.rx_chain_info |= htole32(active_cnt << 7529 IWX_PHY_RX_CHAIN_MIMO_CNT_POS); 7530 7531 cmd_id = iwx_cmd_id(IWX_RLC_CONFIG_CMD, IWX_DATA_PATH_GROUP, 2); 7532 return iwx_send_cmd_pdu(sc, cmd_id, 0, sizeof(cmd), &cmd); 7533 } 7534 7535 static int 7536 iwx_phy_ctxt_update(struct iwx_softc *sc, struct iwx_phy_ctxt *phyctxt, 7537 struct ieee80211_channel *chan, uint8_t chains_static, 7538 uint8_t chains_dynamic, uint32_t apply_time, uint8_t sco, 7539 uint8_t vht_chan_width) 7540 { 7541 uint16_t band_flags = (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_5GHZ); 7542 int err; 7543 7544 if (chan == IEEE80211_CHAN_ANYC) { 7545 printf("%s: GOS-3833: IEEE80211_CHAN_ANYC triggered\n", 7546 DEVNAME(sc)); 7547 return EIO; 7548 } 7549 7550 if (isset(sc->sc_enabled_capa, 7551 IWX_UCODE_TLV_CAPA_BINDING_CDB_SUPPORT) && 7552 (phyctxt->channel->ic_flags & band_flags) != 7553 (chan->ic_flags & band_flags)) { 7554 err = iwx_phy_ctxt_cmd(sc, phyctxt, chains_static, 7555 chains_dynamic, IWX_FW_CTXT_ACTION_REMOVE, apply_time, sco, 7556 vht_chan_width); 7557 if (err) { 7558 printf("%s: could not remove PHY context " 7559 "(error %d)\n", DEVNAME(sc), err); 7560 return err; 7561 } 7562 phyctxt->channel = chan; 7563 err = iwx_phy_ctxt_cmd(sc, phyctxt, chains_static, 7564 chains_dynamic, IWX_FW_CTXT_ACTION_ADD, apply_time, sco, 7565 vht_chan_width); 7566 if (err) { 7567 printf("%s: could not add PHY context " 7568 "(error %d)\n", DEVNAME(sc), err); 7569 return err; 7570 } 7571 } else { 7572 phyctxt->channel = chan; 7573 err = iwx_phy_ctxt_cmd(sc, phyctxt, chains_static, 7574 chains_dynamic, IWX_FW_CTXT_ACTION_MODIFY, apply_time, sco, 7575 vht_chan_width); 7576 if (err) { 7577 printf("%s: could not update PHY context (error %d)\n", 7578 DEVNAME(sc), err); 7579 return err; 7580 } 7581 } 7582 7583 phyctxt->sco = sco; 7584 phyctxt->vht_chan_width = vht_chan_width; 7585 7586 DPRINTF(("%s: phyctxt->channel->ic_ieee=%d\n", __func__, 7587 phyctxt->channel->ic_ieee)); 7588 DPRINTF(("%s: phyctxt->sco=%d\n", __func__, phyctxt->sco)); 7589 DPRINTF(("%s: phyctxt->vht_chan_width=%d\n", __func__, 7590 phyctxt->vht_chan_width)); 7591 7592 if (iwx_lookup_cmd_ver(sc, IWX_DATA_PATH_GROUP, 7593 IWX_RLC_CONFIG_CMD) == 2) 7594 return iwx_phy_send_rlc(sc, phyctxt, 7595 chains_static, chains_dynamic); 7596 7597 return 0; 7598 } 7599 7600 static int 7601 iwx_auth(struct ieee80211vap *vap, struct iwx_softc *sc) 7602 { 7603 struct ieee80211com *ic = &sc->sc_ic; 7604 struct iwx_node *in; 7605 struct iwx_vap *ivp = IWX_VAP(vap); 7606 struct ieee80211_node *ni; 7607 uint32_t duration; 7608 int generation = sc->sc_generation, err; 7609 7610 IWX_ASSERT_LOCKED(sc); 7611 7612 ni = ieee80211_ref_node(vap->iv_bss); 7613 in = IWX_NODE(ni); 7614 7615 if (ic->ic_opmode == IEEE80211_M_MONITOR) { 7616 err = iwx_phy_ctxt_update(sc, &sc->sc_phyctxt[0], 7617 ic->ic_bsschan, 1, 1, 0, IEEE80211_HTOP0_SCO_SCN, 7618 IEEE80211_VHTOP0_CHAN_WIDTH_HT); 7619 if (err) 7620 return err; 7621 } else { 7622 err = iwx_phy_ctxt_update(sc, &sc->sc_phyctxt[0], 7623 in->in_ni.ni_chan, 1, 1, 0, IEEE80211_HTOP0_SCO_SCN, 7624 IEEE80211_VHTOP0_CHAN_WIDTH_HT); 7625 if (err) 7626 return err; 7627 } 7628 ivp->phy_ctxt = &sc->sc_phyctxt[0]; 7629 IEEE80211_ADDR_COPY(in->in_macaddr, in->in_ni.ni_macaddr); 7630 DPRINTF(("%s: in-in_macaddr=%s\n", __func__, 7631 ether_sprintf(in->in_macaddr))); 7632 7633 err = iwx_mac_ctxt_cmd(sc, in, IWX_FW_CTXT_ACTION_ADD, 0); 7634 if (err) { 7635 printf("%s: could not add MAC context (error %d)\n", 7636 DEVNAME(sc), err); 7637 return err; 7638 } 7639 sc->sc_flags |= IWX_FLAG_MAC_ACTIVE; 7640 7641 err = iwx_binding_cmd(sc, in, IWX_FW_CTXT_ACTION_ADD); 7642 if (err) { 7643 printf("%s: could not add binding (error %d)\n", 7644 DEVNAME(sc), err); 7645 goto rm_mac_ctxt; 7646 } 7647 sc->sc_flags |= IWX_FLAG_BINDING_ACTIVE; 7648 7649 err = iwx_add_sta_cmd(sc, in, 0); 7650 if (err) { 7651 printf("%s: could not add sta (error %d)\n", 7652 DEVNAME(sc), err); 7653 goto rm_binding; 7654 } 7655 sc->sc_flags |= IWX_FLAG_STA_ACTIVE; 7656 7657 if (ic->ic_opmode == IEEE80211_M_MONITOR) { 7658 err = iwx_enable_txq(sc, IWX_MONITOR_STA_ID, 7659 IWX_DQA_INJECT_MONITOR_QUEUE, IWX_MGMT_TID, 7660 IWX_TX_RING_COUNT); 7661 if (err) 7662 goto rm_sta; 7663 return 0; 7664 } 7665 7666 err = iwx_enable_mgmt_queue(sc); 7667 if (err) 7668 goto rm_sta; 7669 7670 err = iwx_clear_statistics(sc); 7671 if (err) 7672 goto rm_mgmt_queue; 7673 7674 /* 7675 * Prevent the FW from wandering off channel during association 7676 * by "protecting" the session with a time event. 7677 */ 7678 if (in->in_ni.ni_intval) 7679 duration = in->in_ni.ni_intval * 9; 7680 else 7681 duration = 900; 7682 return iwx_schedule_session_protection(sc, in, duration); 7683 7684 rm_mgmt_queue: 7685 if (generation == sc->sc_generation) 7686 iwx_disable_mgmt_queue(sc); 7687 rm_sta: 7688 if (generation == sc->sc_generation) { 7689 iwx_rm_sta_cmd(sc, in); 7690 sc->sc_flags &= ~IWX_FLAG_STA_ACTIVE; 7691 } 7692 rm_binding: 7693 if (generation == sc->sc_generation) { 7694 iwx_binding_cmd(sc, in, IWX_FW_CTXT_ACTION_REMOVE); 7695 sc->sc_flags &= ~IWX_FLAG_BINDING_ACTIVE; 7696 } 7697 rm_mac_ctxt: 7698 if (generation == sc->sc_generation) { 7699 iwx_mac_ctxt_cmd(sc, in, IWX_FW_CTXT_ACTION_REMOVE, 0); 7700 sc->sc_flags &= ~IWX_FLAG_MAC_ACTIVE; 7701 } 7702 return err; 7703 } 7704 7705 static int 7706 iwx_deauth(struct iwx_softc *sc) 7707 { 7708 struct ieee80211com *ic = &sc->sc_ic; 7709 struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); 7710 struct iwx_node *in = IWX_NODE(vap->iv_bss); 7711 int err; 7712 7713 IWX_ASSERT_LOCKED(sc); 7714 7715 iwx_unprotect_session(sc, in); 7716 7717 if (sc->sc_flags & IWX_FLAG_STA_ACTIVE) { 7718 err = iwx_rm_sta(sc, in); 7719 if (err) 7720 return err; 7721 sc->sc_flags &= ~IWX_FLAG_STA_ACTIVE; 7722 } 7723 7724 if (sc->sc_flags & IWX_FLAG_BINDING_ACTIVE) { 7725 err = iwx_binding_cmd(sc, in, IWX_FW_CTXT_ACTION_REMOVE); 7726 if (err) { 7727 printf("%s: could not remove binding (error %d)\n", 7728 DEVNAME(sc), err); 7729 return err; 7730 } 7731 sc->sc_flags &= ~IWX_FLAG_BINDING_ACTIVE; 7732 } 7733 7734 DPRINTF(("%s: IWX_FLAG_MAC_ACTIVE=%d\n", __func__, sc->sc_flags & 7735 IWX_FLAG_MAC_ACTIVE)); 7736 if (sc->sc_flags & IWX_FLAG_MAC_ACTIVE) { 7737 err = iwx_mac_ctxt_cmd(sc, in, IWX_FW_CTXT_ACTION_REMOVE, 0); 7738 if (err) { 7739 printf("%s: could not remove MAC context (error %d)\n", 7740 DEVNAME(sc), err); 7741 return err; 7742 } 7743 sc->sc_flags &= ~IWX_FLAG_MAC_ACTIVE; 7744 } 7745 7746 /* Move unused PHY context to a default channel. */ 7747 //TODO uncommented in obsd, but stays on the way of auth->auth 7748 err = iwx_phy_ctxt_update(sc, &sc->sc_phyctxt[0], 7749 &ic->ic_channels[1], 1, 1, 0, IEEE80211_HTOP0_SCO_SCN, 7750 IEEE80211_VHTOP0_CHAN_WIDTH_HT); 7751 if (err) 7752 return err; 7753 7754 return 0; 7755 } 7756 7757 static int 7758 iwx_run(struct ieee80211vap *vap, struct iwx_softc *sc) 7759 { 7760 struct ieee80211com *ic = &sc->sc_ic; 7761 struct iwx_node *in = IWX_NODE(vap->iv_bss); 7762 struct ieee80211_node *ni = &in->in_ni; 7763 struct iwx_vap *ivp = IWX_VAP(vap); 7764 int err; 7765 7766 IWX_ASSERT_LOCKED(sc); 7767 7768 if (ni->ni_flags & IEEE80211_NODE_HT) { 7769 uint8_t chains = iwx_mimo_enabled(sc) ? 2 : 1; 7770 uint8_t sco, vht_chan_width; 7771 sco = IEEE80211_HTOP0_SCO_SCN; 7772 if ((ni->ni_flags & IEEE80211_NODE_VHT) && 7773 IEEE80211_IS_CHAN_VHT80(ni->ni_chan)) 7774 vht_chan_width = IEEE80211_VHTOP0_CHAN_WIDTH_80; 7775 else 7776 vht_chan_width = IEEE80211_VHTOP0_CHAN_WIDTH_HT; 7777 err = iwx_phy_ctxt_update(sc, ivp->phy_ctxt, 7778 ivp->phy_ctxt->channel, chains, chains, 7779 0, sco, vht_chan_width); 7780 if (err) { 7781 printf("%s: failed to update PHY\n", DEVNAME(sc)); 7782 return err; 7783 } 7784 } 7785 7786 /* Update STA again to apply HT and VHT settings. */ 7787 err = iwx_add_sta_cmd(sc, in, 1); 7788 if (err) { 7789 printf("%s: could not update STA (error %d)\n", 7790 DEVNAME(sc), err); 7791 return err; 7792 } 7793 7794 /* We have now been assigned an associd by the AP. */ 7795 err = iwx_mac_ctxt_cmd(sc, in, IWX_FW_CTXT_ACTION_MODIFY, 1); 7796 if (err) { 7797 printf("%s: failed to update MAC\n", DEVNAME(sc)); 7798 return err; 7799 } 7800 7801 err = iwx_sf_config(sc, IWX_SF_FULL_ON); 7802 if (err) { 7803 printf("%s: could not set sf full on (error %d)\n", 7804 DEVNAME(sc), err); 7805 return err; 7806 } 7807 7808 err = iwx_allow_mcast(sc); 7809 if (err) { 7810 printf("%s: could not allow mcast (error %d)\n", 7811 DEVNAME(sc), err); 7812 return err; 7813 } 7814 7815 err = iwx_power_update_device(sc); 7816 if (err) { 7817 printf("%s: could not send power command (error %d)\n", 7818 DEVNAME(sc), err); 7819 return err; 7820 } 7821 #ifdef notyet 7822 /* 7823 * Disabled for now. Default beacon filter settings 7824 * prevent net80211 from getting ERP and HT protection 7825 * updates from beacons. 7826 */ 7827 err = iwx_enable_beacon_filter(sc, in); 7828 if (err) { 7829 printf("%s: could not enable beacon filter\n", 7830 DEVNAME(sc)); 7831 return err; 7832 } 7833 #endif 7834 if (ic->ic_opmode == IEEE80211_M_MONITOR) 7835 return 0; 7836 7837 err = iwx_power_mac_update_mode(sc, in); 7838 if (err) { 7839 printf("%s: could not update MAC power (error %d)\n", 7840 DEVNAME(sc), err); 7841 return err; 7842 } 7843 7844 err = iwx_rs_init(sc, in); 7845 if (err) { 7846 printf("%s: could not init rate scaling (error %d)\n", 7847 DEVNAME(sc), err); 7848 return err; 7849 } 7850 7851 return 0; 7852 } 7853 7854 static int 7855 iwx_run_stop(struct iwx_softc *sc) 7856 { 7857 struct ieee80211com *ic = &sc->sc_ic; 7858 struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); 7859 struct iwx_node *in = IWX_NODE(vap->iv_bss); 7860 struct ieee80211_node *ni = &in->in_ni; 7861 int err, i; 7862 7863 IWX_ASSERT_LOCKED(sc); 7864 7865 err = iwx_flush_sta(sc, in); 7866 if (err) { 7867 printf("%s: could not flush Tx path (error %d)\n", 7868 DEVNAME(sc), err); 7869 return err; 7870 } 7871 7872 /* 7873 * Stop Rx BA sessions now. We cannot rely on the BA task 7874 * for this when moving out of RUN state since it runs in a 7875 * separate thread. 7876 * Note that in->in_ni (struct ieee80211_node) already represents 7877 * our new access point in case we are roaming between APs. 7878 * This means we cannot rely on struct ieee802111_node to tell 7879 * us which BA sessions exist. 7880 */ 7881 // TODO agg 7882 for (i = 0; i < nitems(sc->sc_rxba_data); i++) { 7883 struct iwx_rxba_data *rxba = &sc->sc_rxba_data[i]; 7884 if (rxba->baid == IWX_RX_REORDER_DATA_INVALID_BAID) 7885 continue; 7886 iwx_sta_rx_agg(sc, ni, rxba->tid, 0, 0, 0, 0); 7887 } 7888 7889 err = iwx_sf_config(sc, IWX_SF_INIT_OFF); 7890 if (err) 7891 return err; 7892 7893 err = iwx_disable_beacon_filter(sc); 7894 if (err) { 7895 printf("%s: could not disable beacon filter (error %d)\n", 7896 DEVNAME(sc), err); 7897 return err; 7898 } 7899 7900 /* Mark station as disassociated. */ 7901 err = iwx_mac_ctxt_cmd(sc, in, IWX_FW_CTXT_ACTION_MODIFY, 0); 7902 if (err) { 7903 printf("%s: failed to update MAC\n", DEVNAME(sc)); 7904 return err; 7905 } 7906 7907 return 0; 7908 } 7909 7910 static struct ieee80211_node * 7911 iwx_node_alloc(struct ieee80211vap *vap, const uint8_t mac[IEEE80211_ADDR_LEN]) 7912 { 7913 return malloc(sizeof (struct iwx_node), M_80211_NODE, 7914 M_NOWAIT | M_ZERO); 7915 } 7916 7917 #if 0 7918 int 7919 iwx_set_key(struct ieee80211com *ic, struct ieee80211_node *ni, 7920 struct ieee80211_key *k) 7921 { 7922 struct iwx_softc *sc = ic->ic_softc; 7923 struct iwx_node *in = (void *)ni; 7924 struct iwx_setkey_task_arg *a; 7925 int err; 7926 7927 if (k->k_cipher != IEEE80211_CIPHER_CCMP) { 7928 /* Fallback to software crypto for other ciphers. */ 7929 err = ieee80211_set_key(ic, ni, k); 7930 if (!err && in != NULL && (k->k_flags & IEEE80211_KEY_GROUP)) 7931 in->in_flags |= IWX_NODE_FLAG_HAVE_GROUP_KEY; 7932 return err; 7933 } 7934 7935 if (sc->setkey_nkeys >= nitems(sc->setkey_arg)) 7936 return ENOSPC; 7937 7938 a = &sc->setkey_arg[sc->setkey_cur]; 7939 a->sta_id = IWX_STATION_ID; 7940 a->ni = ni; 7941 a->k = k; 7942 sc->setkey_cur = (sc->setkey_cur + 1) % nitems(sc->setkey_arg); 7943 sc->setkey_nkeys++; 7944 iwx_add_task(sc, systq, &sc->setkey_task); 7945 return EBUSY; 7946 } 7947 7948 int 7949 iwx_add_sta_key(struct iwx_softc *sc, int sta_id, struct ieee80211_node *ni, 7950 struct ieee80211_key *k) 7951 { 7952 struct ieee80211com *ic = &sc->sc_ic; 7953 struct iwx_node *in = (void *)ni; 7954 struct iwx_add_sta_key_cmd cmd; 7955 uint32_t status; 7956 const int want_keymask = (IWX_NODE_FLAG_HAVE_PAIRWISE_KEY | 7957 IWX_NODE_FLAG_HAVE_GROUP_KEY); 7958 int err; 7959 7960 /* 7961 * Keys are stored in 'ni' so 'k' is valid if 'ni' is valid. 7962 * Currently we only implement station mode where 'ni' is always 7963 * ic->ic_bss so there is no need to validate arguments beyond this: 7964 */ 7965 KASSERT(ni == ic->ic_bss); 7966 7967 memset(&cmd, 0, sizeof(cmd)); 7968 7969 cmd.common.key_flags = htole16(IWX_STA_KEY_FLG_CCM | 7970 IWX_STA_KEY_FLG_WEP_KEY_MAP | 7971 ((k->k_id << IWX_STA_KEY_FLG_KEYID_POS) & 7972 IWX_STA_KEY_FLG_KEYID_MSK)); 7973 if (k->k_flags & IEEE80211_KEY_GROUP) { 7974 cmd.common.key_offset = 1; 7975 cmd.common.key_flags |= htole16(IWX_STA_KEY_MULTICAST); 7976 } else 7977 cmd.common.key_offset = 0; 7978 7979 memcpy(cmd.common.key, k->k_key, MIN(sizeof(cmd.common.key), k->k_len)); 7980 cmd.common.sta_id = sta_id; 7981 7982 cmd.transmit_seq_cnt = htole64(k->k_tsc); 7983 7984 status = IWX_ADD_STA_SUCCESS; 7985 err = iwx_send_cmd_pdu_status(sc, IWX_ADD_STA_KEY, sizeof(cmd), &cmd, 7986 &status); 7987 if (sc->sc_flags & IWX_FLAG_SHUTDOWN) 7988 return ECANCELED; 7989 if (!err && (status & IWX_ADD_STA_STATUS_MASK) != IWX_ADD_STA_SUCCESS) 7990 err = EIO; 7991 if (err) { 7992 IEEE80211_SEND_MGMT(ic, ni, IEEE80211_FC0_SUBTYPE_DEAUTH, 7993 IEEE80211_REASON_AUTH_LEAVE); 7994 ieee80211_new_state(ic, IEEE80211_S_SCAN, -1); 7995 return err; 7996 } 7997 7998 if (k->k_flags & IEEE80211_KEY_GROUP) 7999 in->in_flags |= IWX_NODE_FLAG_HAVE_GROUP_KEY; 8000 else 8001 in->in_flags |= IWX_NODE_FLAG_HAVE_PAIRWISE_KEY; 8002 8003 if ((in->in_flags & want_keymask) == want_keymask) { 8004 DPRINTF(("marking port %s valid\n", 8005 ether_sprintf(ni->ni_macaddr))); 8006 ni->ni_port_valid = 1; 8007 ieee80211_set_link_state(ic, LINK_STATE_UP); 8008 } 8009 8010 return 0; 8011 } 8012 8013 void 8014 iwx_setkey_task(void *arg) 8015 { 8016 struct iwx_softc *sc = arg; 8017 struct iwx_setkey_task_arg *a; 8018 int err = 0, s = splnet(); 8019 8020 while (sc->setkey_nkeys > 0) { 8021 if (err || (sc->sc_flags & IWX_FLAG_SHUTDOWN)) 8022 break; 8023 a = &sc->setkey_arg[sc->setkey_tail]; 8024 err = iwx_add_sta_key(sc, a->sta_id, a->ni, a->k); 8025 a->sta_id = 0; 8026 a->ni = NULL; 8027 a->k = NULL; 8028 sc->setkey_tail = (sc->setkey_tail + 1) % 8029 nitems(sc->setkey_arg); 8030 sc->setkey_nkeys--; 8031 } 8032 8033 refcnt_rele_wake(&sc->task_refs); 8034 splx(s); 8035 } 8036 8037 void 8038 iwx_delete_key(struct ieee80211com *ic, struct ieee80211_node *ni, 8039 struct ieee80211_key *k) 8040 { 8041 struct iwx_softc *sc = ic->ic_softc; 8042 struct iwx_add_sta_key_cmd cmd; 8043 8044 if (k->k_cipher != IEEE80211_CIPHER_CCMP) { 8045 /* Fallback to software crypto for other ciphers. */ 8046 ieee80211_delete_key(ic, ni, k); 8047 return; 8048 } 8049 8050 if ((sc->sc_flags & IWX_FLAG_STA_ACTIVE) == 0) 8051 return; 8052 8053 memset(&cmd, 0, sizeof(cmd)); 8054 8055 cmd.common.key_flags = htole16(IWX_STA_KEY_NOT_VALID | 8056 IWX_STA_KEY_FLG_NO_ENC | IWX_STA_KEY_FLG_WEP_KEY_MAP | 8057 ((k->k_id << IWX_STA_KEY_FLG_KEYID_POS) & 8058 IWX_STA_KEY_FLG_KEYID_MSK)); 8059 memcpy(cmd.common.key, k->k_key, MIN(sizeof(cmd.common.key), k->k_len)); 8060 if (k->k_flags & IEEE80211_KEY_GROUP) 8061 cmd.common.key_offset = 1; 8062 else 8063 cmd.common.key_offset = 0; 8064 cmd.common.sta_id = IWX_STATION_ID; 8065 8066 iwx_send_cmd_pdu(sc, IWX_ADD_STA_KEY, IWX_CMD_ASYNC, sizeof(cmd), &cmd); 8067 } 8068 #endif 8069 8070 static int 8071 iwx_newstate_sub(struct ieee80211vap *vap, enum ieee80211_state nstate) 8072 { 8073 struct ieee80211com *ic = vap->iv_ic; 8074 struct iwx_softc *sc = ic->ic_softc; 8075 enum ieee80211_state ostate = vap->iv_state; 8076 int err = 0; 8077 8078 IWX_LOCK(sc); 8079 if (sc->sc_flags & IWX_FLAG_SHUTDOWN) { 8080 goto out; 8081 } 8082 8083 if (nstate <= ostate || nstate > IEEE80211_S_RUN) { 8084 switch (ostate) { 8085 case IEEE80211_S_RUN: 8086 err = iwx_run_stop(sc); 8087 if (err) 8088 goto out; 8089 /* FALLTHROUGH */ 8090 case IEEE80211_S_ASSOC: 8091 case IEEE80211_S_AUTH: 8092 if (nstate <= IEEE80211_S_AUTH) { 8093 err = iwx_deauth(sc); 8094 if (err) 8095 goto out; 8096 } 8097 /* FALLTHROUGH */ 8098 case IEEE80211_S_SCAN: 8099 case IEEE80211_S_INIT: 8100 default: 8101 break; 8102 } 8103 // 8104 // /* Die now if iwx_stop() was called while we were sleeping. */ 8105 // if (sc->sc_flags & IWX_FLAG_SHUTDOWN) { 8106 // refcnt_rele_wake(&sc->task_refs); 8107 // splx(s); 8108 // return; 8109 // } 8110 } 8111 8112 switch (nstate) { 8113 case IEEE80211_S_INIT: 8114 break; 8115 8116 case IEEE80211_S_SCAN: 8117 break; 8118 8119 case IEEE80211_S_AUTH: 8120 err = iwx_auth(vap, sc); 8121 break; 8122 8123 case IEEE80211_S_ASSOC: 8124 break; 8125 8126 case IEEE80211_S_RUN: 8127 err = iwx_run(vap, sc); 8128 break; 8129 default: 8130 break; 8131 } 8132 8133 out: 8134 IWX_UNLOCK(sc); 8135 8136 return (err); 8137 } 8138 8139 static int 8140 iwx_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) 8141 { 8142 struct iwx_vap *ivp = IWX_VAP(vap); 8143 struct ieee80211com *ic = vap->iv_ic; 8144 enum ieee80211_state ostate = vap->iv_state; 8145 int err; 8146 8147 /* 8148 * Prevent attempts to transition towards the same state, unless 8149 * we are scanning in which case a SCAN -> SCAN transition 8150 * triggers another scan iteration. And AUTH -> AUTH is needed 8151 * to support band-steering. 8152 */ 8153 if (ostate == nstate && nstate != IEEE80211_S_SCAN && 8154 nstate != IEEE80211_S_AUTH) 8155 return 0; 8156 IEEE80211_UNLOCK(ic); 8157 err = iwx_newstate_sub(vap, nstate); 8158 IEEE80211_LOCK(ic); 8159 if (err == 0) 8160 err = ivp->iv_newstate(vap, nstate, arg); 8161 8162 return (err); 8163 } 8164 8165 static void 8166 iwx_endscan(struct iwx_softc *sc) 8167 { 8168 struct ieee80211com *ic = &sc->sc_ic; 8169 struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); 8170 8171 if ((sc->sc_flags & (IWX_FLAG_SCANNING | IWX_FLAG_BGSCAN)) == 0) 8172 return; 8173 8174 sc->sc_flags &= ~(IWX_FLAG_SCANNING | IWX_FLAG_BGSCAN); 8175 8176 ieee80211_scan_done(TAILQ_FIRST(&ic->ic_vaps)); 8177 wakeup(&vap->iv_state); /* wake up iwx_newstate */ 8178 } 8179 8180 /* 8181 * Aging and idle timeouts for the different possible scenarios 8182 * in default configuration 8183 */ 8184 static const uint32_t 8185 iwx_sf_full_timeout_def[IWX_SF_NUM_SCENARIO][IWX_SF_NUM_TIMEOUT_TYPES] = { 8186 { 8187 htole32(IWX_SF_SINGLE_UNICAST_AGING_TIMER_DEF), 8188 htole32(IWX_SF_SINGLE_UNICAST_IDLE_TIMER_DEF) 8189 }, 8190 { 8191 htole32(IWX_SF_AGG_UNICAST_AGING_TIMER_DEF), 8192 htole32(IWX_SF_AGG_UNICAST_IDLE_TIMER_DEF) 8193 }, 8194 { 8195 htole32(IWX_SF_MCAST_AGING_TIMER_DEF), 8196 htole32(IWX_SF_MCAST_IDLE_TIMER_DEF) 8197 }, 8198 { 8199 htole32(IWX_SF_BA_AGING_TIMER_DEF), 8200 htole32(IWX_SF_BA_IDLE_TIMER_DEF) 8201 }, 8202 { 8203 htole32(IWX_SF_TX_RE_AGING_TIMER_DEF), 8204 htole32(IWX_SF_TX_RE_IDLE_TIMER_DEF) 8205 }, 8206 }; 8207 8208 /* 8209 * Aging and idle timeouts for the different possible scenarios 8210 * in single BSS MAC configuration. 8211 */ 8212 static const uint32_t 8213 iwx_sf_full_timeout[IWX_SF_NUM_SCENARIO][IWX_SF_NUM_TIMEOUT_TYPES] = { 8214 { 8215 htole32(IWX_SF_SINGLE_UNICAST_AGING_TIMER), 8216 htole32(IWX_SF_SINGLE_UNICAST_IDLE_TIMER) 8217 }, 8218 { 8219 htole32(IWX_SF_AGG_UNICAST_AGING_TIMER), 8220 htole32(IWX_SF_AGG_UNICAST_IDLE_TIMER) 8221 }, 8222 { 8223 htole32(IWX_SF_MCAST_AGING_TIMER), 8224 htole32(IWX_SF_MCAST_IDLE_TIMER) 8225 }, 8226 { 8227 htole32(IWX_SF_BA_AGING_TIMER), 8228 htole32(IWX_SF_BA_IDLE_TIMER) 8229 }, 8230 { 8231 htole32(IWX_SF_TX_RE_AGING_TIMER), 8232 htole32(IWX_SF_TX_RE_IDLE_TIMER) 8233 }, 8234 }; 8235 8236 static void 8237 iwx_fill_sf_command(struct iwx_softc *sc, struct iwx_sf_cfg_cmd *sf_cmd, 8238 struct ieee80211_node *ni) 8239 { 8240 int i, j, watermark; 8241 8242 sf_cmd->watermark[IWX_SF_LONG_DELAY_ON] = htole32(IWX_SF_W_MARK_SCAN); 8243 8244 /* 8245 * If we are in association flow - check antenna configuration 8246 * capabilities of the AP station, and choose the watermark accordingly. 8247 */ 8248 if (ni) { 8249 if (ni->ni_flags & IEEE80211_NODE_HT) { 8250 struct ieee80211_htrateset *htrs = &ni->ni_htrates; 8251 int hasmimo = 0; 8252 for (i = 0; i < htrs->rs_nrates; i++) { 8253 if (htrs->rs_rates[i] > 7) { 8254 hasmimo = 1; 8255 break; 8256 } 8257 } 8258 if (hasmimo) 8259 watermark = IWX_SF_W_MARK_MIMO2; 8260 else 8261 watermark = IWX_SF_W_MARK_SISO; 8262 } else { 8263 watermark = IWX_SF_W_MARK_LEGACY; 8264 } 8265 /* default watermark value for unassociated mode. */ 8266 } else { 8267 watermark = IWX_SF_W_MARK_MIMO2; 8268 } 8269 sf_cmd->watermark[IWX_SF_FULL_ON] = htole32(watermark); 8270 8271 for (i = 0; i < IWX_SF_NUM_SCENARIO; i++) { 8272 for (j = 0; j < IWX_SF_NUM_TIMEOUT_TYPES; j++) { 8273 sf_cmd->long_delay_timeouts[i][j] = 8274 htole32(IWX_SF_LONG_DELAY_AGING_TIMER); 8275 } 8276 } 8277 8278 if (ni) { 8279 memcpy(sf_cmd->full_on_timeouts, iwx_sf_full_timeout, 8280 sizeof(iwx_sf_full_timeout)); 8281 } else { 8282 memcpy(sf_cmd->full_on_timeouts, iwx_sf_full_timeout_def, 8283 sizeof(iwx_sf_full_timeout_def)); 8284 } 8285 8286 } 8287 8288 static int 8289 iwx_sf_config(struct iwx_softc *sc, int new_state) 8290 { 8291 struct ieee80211com *ic = &sc->sc_ic; 8292 struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); 8293 struct ieee80211_node *ni = vap->iv_bss; 8294 struct iwx_sf_cfg_cmd sf_cmd = { 8295 .state = htole32(new_state), 8296 }; 8297 int err = 0; 8298 8299 switch (new_state) { 8300 case IWX_SF_UNINIT: 8301 case IWX_SF_INIT_OFF: 8302 iwx_fill_sf_command(sc, &sf_cmd, NULL); 8303 break; 8304 case IWX_SF_FULL_ON: 8305 iwx_fill_sf_command(sc, &sf_cmd, ni); 8306 break; 8307 default: 8308 return EINVAL; 8309 } 8310 8311 err = iwx_send_cmd_pdu(sc, IWX_REPLY_SF_CFG_CMD, IWX_CMD_ASYNC, 8312 sizeof(sf_cmd), &sf_cmd); 8313 return err; 8314 } 8315 8316 static int 8317 iwx_send_bt_init_conf(struct iwx_softc *sc) 8318 { 8319 struct iwx_bt_coex_cmd bt_cmd; 8320 8321 bzero(&bt_cmd, sizeof(struct iwx_bt_coex_cmd)); 8322 8323 bt_cmd.mode = htole32(IWX_BT_COEX_NW); 8324 bt_cmd.enabled_modules |= BT_COEX_SYNC2SCO_ENABLED; 8325 bt_cmd.enabled_modules |= BT_COEX_HIGH_BAND_RET; 8326 8327 8328 return iwx_send_cmd_pdu(sc, IWX_BT_CONFIG, 0, sizeof(bt_cmd), 8329 &bt_cmd); 8330 } 8331 8332 static int 8333 iwx_send_soc_conf(struct iwx_softc *sc) 8334 { 8335 struct iwx_soc_configuration_cmd cmd; 8336 int err; 8337 uint32_t cmd_id, flags = 0; 8338 8339 memset(&cmd, 0, sizeof(cmd)); 8340 8341 /* 8342 * In VER_1 of this command, the discrete value is considered 8343 * an integer; In VER_2, it's a bitmask. Since we have only 2 8344 * values in VER_1, this is backwards-compatible with VER_2, 8345 * as long as we don't set any other flag bits. 8346 */ 8347 if (!sc->sc_integrated) { /* VER_1 */ 8348 flags = IWX_SOC_CONFIG_CMD_FLAGS_DISCRETE; 8349 } else { /* VER_2 */ 8350 uint8_t scan_cmd_ver; 8351 if (sc->sc_ltr_delay != IWX_SOC_FLAGS_LTR_APPLY_DELAY_NONE) 8352 flags |= (sc->sc_ltr_delay & 8353 IWX_SOC_FLAGS_LTR_APPLY_DELAY_MASK); 8354 scan_cmd_ver = iwx_lookup_cmd_ver(sc, IWX_LONG_GROUP, 8355 IWX_SCAN_REQ_UMAC); 8356 if (scan_cmd_ver != IWX_FW_CMD_VER_UNKNOWN && 8357 scan_cmd_ver >= 2 && sc->sc_low_latency_xtal) 8358 flags |= IWX_SOC_CONFIG_CMD_FLAGS_LOW_LATENCY; 8359 } 8360 cmd.flags = htole32(flags); 8361 8362 cmd.latency = htole32(sc->sc_xtal_latency); 8363 8364 cmd_id = iwx_cmd_id(IWX_SOC_CONFIGURATION_CMD, IWX_SYSTEM_GROUP, 0); 8365 err = iwx_send_cmd_pdu(sc, cmd_id, 0, sizeof(cmd), &cmd); 8366 if (err) 8367 printf("%s: failed to set soc latency: %d\n", DEVNAME(sc), err); 8368 return err; 8369 } 8370 8371 static int 8372 iwx_send_update_mcc_cmd(struct iwx_softc *sc, const char *alpha2) 8373 { 8374 struct iwx_mcc_update_cmd mcc_cmd; 8375 struct iwx_host_cmd hcmd = { 8376 .id = IWX_MCC_UPDATE_CMD, 8377 .flags = IWX_CMD_WANT_RESP, 8378 .data = { &mcc_cmd }, 8379 }; 8380 struct iwx_rx_packet *pkt; 8381 struct iwx_mcc_update_resp *resp; 8382 size_t resp_len; 8383 int err; 8384 8385 memset(&mcc_cmd, 0, sizeof(mcc_cmd)); 8386 mcc_cmd.mcc = htole16(alpha2[0] << 8 | alpha2[1]); 8387 if (isset(sc->sc_ucode_api, IWX_UCODE_TLV_API_WIFI_MCC_UPDATE) || 8388 isset(sc->sc_enabled_capa, IWX_UCODE_TLV_CAPA_LAR_MULTI_MCC)) 8389 mcc_cmd.source_id = IWX_MCC_SOURCE_GET_CURRENT; 8390 else 8391 mcc_cmd.source_id = IWX_MCC_SOURCE_OLD_FW; 8392 8393 hcmd.len[0] = sizeof(struct iwx_mcc_update_cmd); 8394 hcmd.resp_pkt_len = IWX_CMD_RESP_MAX; 8395 8396 err = iwx_send_cmd(sc, &hcmd); 8397 if (err) 8398 return err; 8399 8400 pkt = hcmd.resp_pkt; 8401 if (!pkt || (pkt->hdr.flags & IWX_CMD_FAILED_MSK)) { 8402 err = EIO; 8403 goto out; 8404 } 8405 8406 resp_len = iwx_rx_packet_payload_len(pkt); 8407 if (resp_len < sizeof(*resp)) { 8408 err = EIO; 8409 goto out; 8410 } 8411 8412 resp = (void *)pkt->data; 8413 if (resp_len != sizeof(*resp) + 8414 resp->n_channels * sizeof(resp->channels[0])) { 8415 err = EIO; 8416 goto out; 8417 } 8418 8419 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", 8420 resp->status, resp->mcc, resp->cap, resp->time, resp->geo_info, resp->source_id, resp->n_channels)); 8421 8422 out: 8423 iwx_free_resp(sc, &hcmd); 8424 8425 return err; 8426 } 8427 8428 static int 8429 iwx_send_temp_report_ths_cmd(struct iwx_softc *sc) 8430 { 8431 struct iwx_temp_report_ths_cmd cmd; 8432 int err; 8433 8434 /* 8435 * In order to give responsibility for critical-temperature-kill 8436 * and TX backoff to FW we need to send an empty temperature 8437 * reporting command at init time. 8438 */ 8439 memset(&cmd, 0, sizeof(cmd)); 8440 8441 err = iwx_send_cmd_pdu(sc, 8442 IWX_WIDE_ID(IWX_PHY_OPS_GROUP, IWX_TEMP_REPORTING_THRESHOLDS_CMD), 8443 0, sizeof(cmd), &cmd); 8444 if (err) 8445 printf("%s: TEMP_REPORT_THS_CMD command failed (error %d)\n", 8446 DEVNAME(sc), err); 8447 8448 return err; 8449 } 8450 8451 static int 8452 iwx_init_hw(struct iwx_softc *sc) 8453 { 8454 struct ieee80211com *ic = &sc->sc_ic; 8455 int err = 0, i; 8456 8457 err = iwx_run_init_mvm_ucode(sc, 0); 8458 if (err) 8459 return err; 8460 8461 if (!iwx_nic_lock(sc)) 8462 return EBUSY; 8463 8464 err = iwx_send_tx_ant_cfg(sc, iwx_fw_valid_tx_ant(sc)); 8465 if (err) { 8466 printf("%s: could not init tx ant config (error %d)\n", 8467 DEVNAME(sc), err); 8468 goto err; 8469 } 8470 8471 if (sc->sc_tx_with_siso_diversity) { 8472 err = iwx_send_phy_cfg_cmd(sc); 8473 if (err) { 8474 printf("%s: could not send phy config (error %d)\n", 8475 DEVNAME(sc), err); 8476 goto err; 8477 } 8478 } 8479 8480 err = iwx_send_bt_init_conf(sc); 8481 if (err) { 8482 printf("%s: could not init bt coex (error %d)\n", 8483 DEVNAME(sc), err); 8484 return err; 8485 } 8486 8487 err = iwx_send_soc_conf(sc); 8488 if (err) { 8489 printf("%s: iwx_send_soc_conf failed\n", __func__); 8490 return err; 8491 } 8492 8493 if (isset(sc->sc_enabled_capa, IWX_UCODE_TLV_CAPA_DQA_SUPPORT)) { 8494 printf("%s: === IWX_UCODE_TLV_CAPA_DQA_SUPPORT\n", __func__); 8495 err = iwx_send_dqa_cmd(sc); 8496 if (err) { 8497 printf("%s: IWX_UCODE_TLV_CAPA_DQA_SUPPORT " 8498 "failed (error %d)\n", __func__, err); 8499 return err; 8500 } 8501 } 8502 // TODO phyctxt 8503 for (i = 0; i < IWX_NUM_PHY_CTX; i++) { 8504 /* 8505 * The channel used here isn't relevant as it's 8506 * going to be overwritten in the other flows. 8507 * For now use the first channel we have. 8508 */ 8509 sc->sc_phyctxt[i].id = i; 8510 sc->sc_phyctxt[i].channel = &ic->ic_channels[1]; 8511 err = iwx_phy_ctxt_cmd(sc, &sc->sc_phyctxt[i], 1, 1, 8512 IWX_FW_CTXT_ACTION_ADD, 0, 0, 0); 8513 if (err) { 8514 printf("%s: could not add phy context %d (error %d)\n", 8515 DEVNAME(sc), i, err); 8516 goto err; 8517 } 8518 if (iwx_lookup_cmd_ver(sc, IWX_DATA_PATH_GROUP, 8519 IWX_RLC_CONFIG_CMD) == 2) { 8520 err = iwx_phy_send_rlc(sc, &sc->sc_phyctxt[i], 1, 1); 8521 if (err) { 8522 printf("%s: could not configure RLC for PHY " 8523 "%d (error %d)\n", DEVNAME(sc), i, err); 8524 goto err; 8525 } 8526 } 8527 } 8528 8529 err = iwx_config_ltr(sc); 8530 if (err) { 8531 printf("%s: PCIe LTR configuration failed (error %d)\n", 8532 DEVNAME(sc), err); 8533 } 8534 8535 if (isset(sc->sc_enabled_capa, IWX_UCODE_TLV_CAPA_CT_KILL_BY_FW)) { 8536 err = iwx_send_temp_report_ths_cmd(sc); 8537 if (err) { 8538 printf("%s: iwx_send_temp_report_ths_cmd failed\n", 8539 __func__); 8540 goto err; 8541 } 8542 } 8543 8544 err = iwx_power_update_device(sc); 8545 if (err) { 8546 printf("%s: could not send power command (error %d)\n", 8547 DEVNAME(sc), err); 8548 goto err; 8549 } 8550 8551 if (sc->sc_nvm.lar_enabled) { 8552 err = iwx_send_update_mcc_cmd(sc, "ZZ"); 8553 if (err) { 8554 printf("%s: could not init LAR (error %d)\n", 8555 DEVNAME(sc), err); 8556 goto err; 8557 } 8558 } 8559 8560 err = iwx_config_umac_scan_reduced(sc); 8561 if (err) { 8562 printf("%s: could not configure scan (error %d)\n", 8563 DEVNAME(sc), err); 8564 goto err; 8565 } 8566 8567 err = iwx_disable_beacon_filter(sc); 8568 if (err) { 8569 printf("%s: could not disable beacon filter (error %d)\n", 8570 DEVNAME(sc), err); 8571 goto err; 8572 } 8573 8574 err: 8575 iwx_nic_unlock(sc); 8576 return err; 8577 } 8578 8579 /* Allow multicast from our BSSID. */ 8580 static int 8581 iwx_allow_mcast(struct iwx_softc *sc) 8582 { 8583 struct ieee80211com *ic = &sc->sc_ic; 8584 struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); 8585 struct iwx_node *in = IWX_NODE(vap->iv_bss); 8586 struct iwx_mcast_filter_cmd *cmd; 8587 size_t size; 8588 int err; 8589 8590 size = roundup(sizeof(*cmd), 4); 8591 cmd = malloc(size, M_DEVBUF, M_NOWAIT | M_ZERO); 8592 if (cmd == NULL) 8593 return ENOMEM; 8594 cmd->filter_own = 1; 8595 cmd->port_id = 0; 8596 cmd->count = 0; 8597 cmd->pass_all = 1; 8598 IEEE80211_ADDR_COPY(cmd->bssid, in->in_macaddr); 8599 8600 err = iwx_send_cmd_pdu(sc, IWX_MCAST_FILTER_CMD, 8601 0, size, cmd); 8602 free(cmd, M_DEVBUF); 8603 return err; 8604 } 8605 8606 static int 8607 iwx_init(struct iwx_softc *sc) 8608 { 8609 int err, generation; 8610 generation = ++sc->sc_generation; 8611 iwx_preinit(sc); 8612 8613 err = iwx_start_hw(sc); 8614 if (err) { 8615 printf("%s: iwx_start_hw failed\n", __func__); 8616 return err; 8617 } 8618 8619 err = iwx_init_hw(sc); 8620 if (err) { 8621 if (generation == sc->sc_generation) 8622 iwx_stop_device(sc); 8623 printf("%s: iwx_init_hw failed (error %d)\n", __func__, err); 8624 return err; 8625 } 8626 8627 sc->sc_flags |= IWX_FLAG_HW_INITED; 8628 callout_reset(&sc->watchdog_to, hz, iwx_watchdog, sc); 8629 8630 return 0; 8631 } 8632 8633 static void 8634 iwx_start(struct iwx_softc *sc) 8635 { 8636 struct ieee80211_node *ni; 8637 struct mbuf *m; 8638 8639 IWX_ASSERT_LOCKED(sc); 8640 8641 while (sc->qfullmsk == 0 && (m = mbufq_dequeue(&sc->sc_snd)) != NULL) { 8642 ni = (struct ieee80211_node *)m->m_pkthdr.rcvif; 8643 if (iwx_tx(sc, m, ni) != 0) { 8644 if_inc_counter(ni->ni_vap->iv_ifp, IFCOUNTER_OERRORS, 1); 8645 continue; 8646 } 8647 } 8648 } 8649 8650 static void 8651 iwx_stop(struct iwx_softc *sc) 8652 { 8653 struct ieee80211com *ic = &sc->sc_ic; 8654 struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); 8655 struct iwx_vap *ivp = IWX_VAP(vap); 8656 8657 iwx_stop_device(sc); 8658 8659 /* Reset soft state. */ 8660 sc->sc_generation++; 8661 ivp->phy_ctxt = NULL; 8662 8663 sc->sc_flags &= ~(IWX_FLAG_SCANNING | IWX_FLAG_BGSCAN); 8664 sc->sc_flags &= ~IWX_FLAG_MAC_ACTIVE; 8665 sc->sc_flags &= ~IWX_FLAG_BINDING_ACTIVE; 8666 sc->sc_flags &= ~IWX_FLAG_STA_ACTIVE; 8667 sc->sc_flags &= ~IWX_FLAG_TE_ACTIVE; 8668 sc->sc_flags &= ~IWX_FLAG_HW_ERR; 8669 sc->sc_flags &= ~IWX_FLAG_SHUTDOWN; 8670 sc->sc_flags &= ~IWX_FLAG_TXFLUSH; 8671 8672 sc->sc_rx_ba_sessions = 0; 8673 sc->ba_rx.start_tidmask = 0; 8674 sc->ba_rx.stop_tidmask = 0; 8675 memset(sc->aggqid, 0, sizeof(sc->aggqid)); 8676 sc->ba_tx.start_tidmask = 0; 8677 sc->ba_tx.stop_tidmask = 0; 8678 } 8679 8680 static void 8681 iwx_watchdog(void *arg) 8682 { 8683 struct iwx_softc *sc = arg; 8684 struct ieee80211com *ic = &sc->sc_ic; 8685 int i; 8686 8687 /* 8688 * We maintain a separate timer for each Tx queue because 8689 * Tx aggregation queues can get "stuck" while other queues 8690 * keep working. The Linux driver uses a similar workaround. 8691 */ 8692 for (i = 0; i < nitems(sc->sc_tx_timer); i++) { 8693 if (sc->sc_tx_timer[i] > 0) { 8694 if (--sc->sc_tx_timer[i] == 0) { 8695 printf("%s: device timeout\n", DEVNAME(sc)); 8696 8697 iwx_nic_error(sc); 8698 iwx_dump_driver_status(sc); 8699 ieee80211_restart_all(ic); 8700 return; 8701 } 8702 } 8703 } 8704 callout_reset(&sc->watchdog_to, hz, iwx_watchdog, sc); 8705 } 8706 8707 /* 8708 * Note: This structure is read from the device with IO accesses, 8709 * and the reading already does the endian conversion. As it is 8710 * read with uint32_t-sized accesses, any members with a different size 8711 * need to be ordered correctly though! 8712 */ 8713 struct iwx_error_event_table { 8714 uint32_t valid; /* (nonzero) valid, (0) log is empty */ 8715 uint32_t error_id; /* type of error */ 8716 uint32_t trm_hw_status0; /* TRM HW status */ 8717 uint32_t trm_hw_status1; /* TRM HW status */ 8718 uint32_t blink2; /* branch link */ 8719 uint32_t ilink1; /* interrupt link */ 8720 uint32_t ilink2; /* interrupt link */ 8721 uint32_t data1; /* error-specific data */ 8722 uint32_t data2; /* error-specific data */ 8723 uint32_t data3; /* error-specific data */ 8724 uint32_t bcon_time; /* beacon timer */ 8725 uint32_t tsf_low; /* network timestamp function timer */ 8726 uint32_t tsf_hi; /* network timestamp function timer */ 8727 uint32_t gp1; /* GP1 timer register */ 8728 uint32_t gp2; /* GP2 timer register */ 8729 uint32_t fw_rev_type; /* firmware revision type */ 8730 uint32_t major; /* uCode version major */ 8731 uint32_t minor; /* uCode version minor */ 8732 uint32_t hw_ver; /* HW Silicon version */ 8733 uint32_t brd_ver; /* HW board version */ 8734 uint32_t log_pc; /* log program counter */ 8735 uint32_t frame_ptr; /* frame pointer */ 8736 uint32_t stack_ptr; /* stack pointer */ 8737 uint32_t hcmd; /* last host command header */ 8738 uint32_t isr0; /* isr status register LMPM_NIC_ISR0: 8739 * rxtx_flag */ 8740 uint32_t isr1; /* isr status register LMPM_NIC_ISR1: 8741 * host_flag */ 8742 uint32_t isr2; /* isr status register LMPM_NIC_ISR2: 8743 * enc_flag */ 8744 uint32_t isr3; /* isr status register LMPM_NIC_ISR3: 8745 * time_flag */ 8746 uint32_t isr4; /* isr status register LMPM_NIC_ISR4: 8747 * wico interrupt */ 8748 uint32_t last_cmd_id; /* last HCMD id handled by the firmware */ 8749 uint32_t wait_event; /* wait event() caller address */ 8750 uint32_t l2p_control; /* L2pControlField */ 8751 uint32_t l2p_duration; /* L2pDurationField */ 8752 uint32_t l2p_mhvalid; /* L2pMhValidBits */ 8753 uint32_t l2p_addr_match; /* L2pAddrMatchStat */ 8754 uint32_t lmpm_pmg_sel; /* indicate which clocks are turned on 8755 * (LMPM_PMG_SEL) */ 8756 uint32_t u_timestamp; /* indicate when the date and time of the 8757 * compilation */ 8758 uint32_t flow_handler; /* FH read/write pointers, RX credit */ 8759 } __packed /* LOG_ERROR_TABLE_API_S_VER_3 */; 8760 8761 /* 8762 * UMAC error struct - relevant starting from family 8000 chip. 8763 * Note: This structure is read from the device with IO accesses, 8764 * and the reading already does the endian conversion. As it is 8765 * read with u32-sized accesses, any members with a different size 8766 * need to be ordered correctly though! 8767 */ 8768 struct iwx_umac_error_event_table { 8769 uint32_t valid; /* (nonzero) valid, (0) log is empty */ 8770 uint32_t error_id; /* type of error */ 8771 uint32_t blink1; /* branch link */ 8772 uint32_t blink2; /* branch link */ 8773 uint32_t ilink1; /* interrupt link */ 8774 uint32_t ilink2; /* interrupt link */ 8775 uint32_t data1; /* error-specific data */ 8776 uint32_t data2; /* error-specific data */ 8777 uint32_t data3; /* error-specific data */ 8778 uint32_t umac_major; 8779 uint32_t umac_minor; 8780 uint32_t frame_pointer; /* core register 27*/ 8781 uint32_t stack_pointer; /* core register 28 */ 8782 uint32_t cmd_header; /* latest host cmd sent to UMAC */ 8783 uint32_t nic_isr_pref; /* ISR status register */ 8784 } __packed; 8785 8786 #define ERROR_START_OFFSET (1 * sizeof(uint32_t)) 8787 #define ERROR_ELEM_SIZE (7 * sizeof(uint32_t)) 8788 8789 static void 8790 iwx_nic_umac_error(struct iwx_softc *sc) 8791 { 8792 struct iwx_umac_error_event_table table; 8793 uint32_t base; 8794 8795 base = sc->sc_uc.uc_umac_error_event_table; 8796 8797 if (base < 0x400000) { 8798 printf("%s: Invalid error log pointer 0x%08x\n", 8799 DEVNAME(sc), base); 8800 return; 8801 } 8802 8803 if (iwx_read_mem(sc, base, &table, sizeof(table)/sizeof(uint32_t))) { 8804 printf("%s: reading errlog failed\n", DEVNAME(sc)); 8805 return; 8806 } 8807 8808 if (ERROR_START_OFFSET <= table.valid * ERROR_ELEM_SIZE) { 8809 printf("%s: Start UMAC Error Log Dump:\n", DEVNAME(sc)); 8810 printf("%s: Status: 0x%x, count: %d\n", DEVNAME(sc), 8811 sc->sc_flags, table.valid); 8812 } 8813 8814 printf("%s: 0x%08X | %s\n", DEVNAME(sc), table.error_id, 8815 iwx_desc_lookup(table.error_id)); 8816 printf("%s: 0x%08X | umac branchlink1\n", DEVNAME(sc), table.blink1); 8817 printf("%s: 0x%08X | umac branchlink2\n", DEVNAME(sc), table.blink2); 8818 printf("%s: 0x%08X | umac interruptlink1\n", DEVNAME(sc), table.ilink1); 8819 printf("%s: 0x%08X | umac interruptlink2\n", DEVNAME(sc), table.ilink2); 8820 printf("%s: 0x%08X | umac data1\n", DEVNAME(sc), table.data1); 8821 printf("%s: 0x%08X | umac data2\n", DEVNAME(sc), table.data2); 8822 printf("%s: 0x%08X | umac data3\n", DEVNAME(sc), table.data3); 8823 printf("%s: 0x%08X | umac major\n", DEVNAME(sc), table.umac_major); 8824 printf("%s: 0x%08X | umac minor\n", DEVNAME(sc), table.umac_minor); 8825 printf("%s: 0x%08X | frame pointer\n", DEVNAME(sc), 8826 table.frame_pointer); 8827 printf("%s: 0x%08X | stack pointer\n", DEVNAME(sc), 8828 table.stack_pointer); 8829 printf("%s: 0x%08X | last host cmd\n", DEVNAME(sc), table.cmd_header); 8830 printf("%s: 0x%08X | isr status reg\n", DEVNAME(sc), 8831 table.nic_isr_pref); 8832 } 8833 8834 #define IWX_FW_SYSASSERT_CPU_MASK 0xf0000000 8835 static struct { 8836 const char *name; 8837 uint8_t num; 8838 } advanced_lookup[] = { 8839 { "NMI_INTERRUPT_WDG", 0x34 }, 8840 { "SYSASSERT", 0x35 }, 8841 { "UCODE_VERSION_MISMATCH", 0x37 }, 8842 { "BAD_COMMAND", 0x38 }, 8843 { "BAD_COMMAND", 0x39 }, 8844 { "NMI_INTERRUPT_DATA_ACTION_PT", 0x3C }, 8845 { "FATAL_ERROR", 0x3D }, 8846 { "NMI_TRM_HW_ERR", 0x46 }, 8847 { "NMI_INTERRUPT_TRM", 0x4C }, 8848 { "NMI_INTERRUPT_BREAK_POINT", 0x54 }, 8849 { "NMI_INTERRUPT_WDG_RXF_FULL", 0x5C }, 8850 { "NMI_INTERRUPT_WDG_NO_RBD_RXF_FULL", 0x64 }, 8851 { "NMI_INTERRUPT_HOST", 0x66 }, 8852 { "NMI_INTERRUPT_LMAC_FATAL", 0x70 }, 8853 { "NMI_INTERRUPT_UMAC_FATAL", 0x71 }, 8854 { "NMI_INTERRUPT_OTHER_LMAC_FATAL", 0x73 }, 8855 { "NMI_INTERRUPT_ACTION_PT", 0x7C }, 8856 { "NMI_INTERRUPT_UNKNOWN", 0x84 }, 8857 { "NMI_INTERRUPT_INST_ACTION_PT", 0x86 }, 8858 { "ADVANCED_SYSASSERT", 0 }, 8859 }; 8860 8861 static const char * 8862 iwx_desc_lookup(uint32_t num) 8863 { 8864 int i; 8865 8866 for (i = 0; i < nitems(advanced_lookup) - 1; i++) 8867 if (advanced_lookup[i].num == 8868 (num & ~IWX_FW_SYSASSERT_CPU_MASK)) 8869 return advanced_lookup[i].name; 8870 8871 /* No entry matches 'num', so it is the last: ADVANCED_SYSASSERT */ 8872 return advanced_lookup[i].name; 8873 } 8874 8875 /* 8876 * Support for dumping the error log seemed like a good idea ... 8877 * but it's mostly hex junk and the only sensible thing is the 8878 * hw/ucode revision (which we know anyway). Since it's here, 8879 * I'll just leave it in, just in case e.g. the Intel guys want to 8880 * help us decipher some "ADVANCED_SYSASSERT" later. 8881 */ 8882 static void 8883 iwx_nic_error(struct iwx_softc *sc) 8884 { 8885 struct iwx_error_event_table table; 8886 uint32_t base; 8887 8888 printf("%s: dumping device error log\n", DEVNAME(sc)); 8889 printf("%s: GOS-3758: 1\n", __func__); 8890 base = sc->sc_uc.uc_lmac_error_event_table[0]; 8891 printf("%s: GOS-3758: 2\n", __func__); 8892 if (base < 0x400000) { 8893 printf("%s: Invalid error log pointer 0x%08x\n", 8894 DEVNAME(sc), base); 8895 return; 8896 } 8897 8898 printf("%s: GOS-3758: 3\n", __func__); 8899 if (iwx_read_mem(sc, base, &table, sizeof(table)/sizeof(uint32_t))) { 8900 printf("%s: reading errlog failed\n", DEVNAME(sc)); 8901 return; 8902 } 8903 8904 printf("%s: GOS-3758: 4\n", __func__); 8905 if (!table.valid) { 8906 printf("%s: errlog not found, skipping\n", DEVNAME(sc)); 8907 return; 8908 } 8909 8910 printf("%s: GOS-3758: 5\n", __func__); 8911 if (ERROR_START_OFFSET <= table.valid * ERROR_ELEM_SIZE) { 8912 printf("%s: Start Error Log Dump:\n", DEVNAME(sc)); 8913 printf("%s: Status: 0x%x, count: %d\n", DEVNAME(sc), 8914 sc->sc_flags, table.valid); 8915 } 8916 8917 printf("%s: GOS-3758: 6\n", __func__); 8918 printf("%s: 0x%08X | %-28s\n", DEVNAME(sc), table.error_id, 8919 iwx_desc_lookup(table.error_id)); 8920 printf("%s: %08X | trm_hw_status0\n", DEVNAME(sc), 8921 table.trm_hw_status0); 8922 printf("%s: %08X | trm_hw_status1\n", DEVNAME(sc), 8923 table.trm_hw_status1); 8924 printf("%s: %08X | branchlink2\n", DEVNAME(sc), table.blink2); 8925 printf("%s: %08X | interruptlink1\n", DEVNAME(sc), table.ilink1); 8926 printf("%s: %08X | interruptlink2\n", DEVNAME(sc), table.ilink2); 8927 printf("%s: %08X | data1\n", DEVNAME(sc), table.data1); 8928 printf("%s: %08X | data2\n", DEVNAME(sc), table.data2); 8929 printf("%s: %08X | data3\n", DEVNAME(sc), table.data3); 8930 printf("%s: %08X | beacon time\n", DEVNAME(sc), table.bcon_time); 8931 printf("%s: %08X | tsf low\n", DEVNAME(sc), table.tsf_low); 8932 printf("%s: %08X | tsf hi\n", DEVNAME(sc), table.tsf_hi); 8933 printf("%s: %08X | time gp1\n", DEVNAME(sc), table.gp1); 8934 printf("%s: %08X | time gp2\n", DEVNAME(sc), table.gp2); 8935 printf("%s: %08X | uCode revision type\n", DEVNAME(sc), 8936 table.fw_rev_type); 8937 printf("%s: %08X | uCode version major\n", DEVNAME(sc), 8938 table.major); 8939 printf("%s: %08X | uCode version minor\n", DEVNAME(sc), 8940 table.minor); 8941 printf("%s: %08X | hw version\n", DEVNAME(sc), table.hw_ver); 8942 printf("%s: %08X | board version\n", DEVNAME(sc), table.brd_ver); 8943 printf("%s: %08X | hcmd\n", DEVNAME(sc), table.hcmd); 8944 printf("%s: %08X | isr0\n", DEVNAME(sc), table.isr0); 8945 printf("%s: %08X | isr1\n", DEVNAME(sc), table.isr1); 8946 printf("%s: %08X | isr2\n", DEVNAME(sc), table.isr2); 8947 printf("%s: %08X | isr3\n", DEVNAME(sc), table.isr3); 8948 printf("%s: %08X | isr4\n", DEVNAME(sc), table.isr4); 8949 printf("%s: %08X | last cmd Id\n", DEVNAME(sc), table.last_cmd_id); 8950 printf("%s: %08X | wait_event\n", DEVNAME(sc), table.wait_event); 8951 printf("%s: %08X | l2p_control\n", DEVNAME(sc), table.l2p_control); 8952 printf("%s: %08X | l2p_duration\n", DEVNAME(sc), table.l2p_duration); 8953 printf("%s: %08X | l2p_mhvalid\n", DEVNAME(sc), table.l2p_mhvalid); 8954 printf("%s: %08X | l2p_addr_match\n", DEVNAME(sc), table.l2p_addr_match); 8955 printf("%s: %08X | lmpm_pmg_sel\n", DEVNAME(sc), table.lmpm_pmg_sel); 8956 printf("%s: %08X | timestamp\n", DEVNAME(sc), table.u_timestamp); 8957 printf("%s: %08X | flow_handler\n", DEVNAME(sc), table.flow_handler); 8958 8959 if (sc->sc_uc.uc_umac_error_event_table) 8960 iwx_nic_umac_error(sc); 8961 } 8962 8963 static void 8964 iwx_dump_driver_status(struct iwx_softc *sc) 8965 { 8966 struct ieee80211com *ic = &sc->sc_ic; 8967 struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); 8968 enum ieee80211_state state = vap->iv_state; 8969 int i; 8970 8971 printf("driver status:\n"); 8972 for (i = 0; i < nitems(sc->txq); i++) { 8973 struct iwx_tx_ring *ring = &sc->txq[i]; 8974 printf(" tx ring %2d: qid=%-2d cur=%-3d " 8975 "cur_hw=%-3d queued=%-3d\n", 8976 i, ring->qid, ring->cur, ring->cur_hw, 8977 ring->queued); 8978 } 8979 printf(" rx ring: cur=%d\n", sc->rxq.cur); 8980 printf(" 802.11 state %s\n", ieee80211_state_name[state]); 8981 } 8982 8983 #define SYNC_RESP_STRUCT(_var_, _pkt_) \ 8984 do { \ 8985 bus_dmamap_sync(sc->rxq.data_dmat, data->map, BUS_DMASYNC_POSTREAD); \ 8986 _var_ = (void *)((_pkt_)+1); \ 8987 } while (/*CONSTCOND*/0) 8988 8989 static int 8990 iwx_rx_pkt_valid(struct iwx_rx_packet *pkt) 8991 { 8992 int qid, idx, code; 8993 8994 qid = pkt->hdr.qid & ~0x80; 8995 idx = pkt->hdr.idx; 8996 code = IWX_WIDE_ID(pkt->hdr.flags, pkt->hdr.code); 8997 8998 return (!(qid == 0 && idx == 0 && code == 0) && 8999 pkt->len_n_flags != htole32(IWX_FH_RSCSR_FRAME_INVALID)); 9000 } 9001 9002 static void 9003 iwx_rx_pkt(struct iwx_softc *sc, struct iwx_rx_data *data, struct mbuf *ml) 9004 { 9005 struct ieee80211com *ic = &sc->sc_ic; 9006 struct iwx_rx_packet *pkt, *nextpkt; 9007 uint32_t offset = 0, nextoff = 0, nmpdu = 0, len; 9008 struct mbuf *m0, *m; 9009 const size_t minsz = sizeof(pkt->len_n_flags) + sizeof(pkt->hdr); 9010 int qid, idx, code, handled = 1; 9011 9012 m0 = data->m; 9013 while (m0 && offset + minsz < IWX_RBUF_SIZE) { 9014 pkt = (struct iwx_rx_packet *)(m0->m_data + offset); 9015 qid = pkt->hdr.qid; 9016 idx = pkt->hdr.idx; 9017 code = IWX_WIDE_ID(pkt->hdr.flags, pkt->hdr.code); 9018 9019 if (!iwx_rx_pkt_valid(pkt)) 9020 break; 9021 9022 /* 9023 * XXX Intel inside (tm) 9024 * Any commands in the LONG_GROUP could actually be in the 9025 * LEGACY group. Firmware API versions >= 50 reject commands 9026 * in group 0, forcing us to use this hack. 9027 */ 9028 if (iwx_cmd_groupid(code) == IWX_LONG_GROUP) { 9029 struct iwx_tx_ring *ring = &sc->txq[qid]; 9030 struct iwx_tx_data *txdata = &ring->data[idx]; 9031 if (txdata->flags & IWX_TXDATA_FLAG_CMD_IS_NARROW) 9032 code = iwx_cmd_opcode(code); 9033 } 9034 9035 len = sizeof(pkt->len_n_flags) + iwx_rx_packet_len(pkt); 9036 if (len < minsz || len > (IWX_RBUF_SIZE - offset)) 9037 break; 9038 9039 // TODO ??? 9040 if (code == IWX_REPLY_RX_MPDU_CMD && ++nmpdu == 1) { 9041 /* Take mbuf m0 off the RX ring. */ 9042 if (iwx_rx_addbuf(sc, IWX_RBUF_SIZE, sc->rxq.cur)) { 9043 break; 9044 } 9045 KASSERT((data->m != m0), ("%s: data->m != m0", __func__)); 9046 } 9047 9048 switch (code) { 9049 case IWX_REPLY_RX_PHY_CMD: 9050 /* XXX-THJ: I've not managed to hit this path in testing */ 9051 iwx_rx_rx_phy_cmd(sc, pkt, data); 9052 break; 9053 9054 case IWX_REPLY_RX_MPDU_CMD: { 9055 size_t maxlen = IWX_RBUF_SIZE - offset - minsz; 9056 nextoff = offset + 9057 roundup(len, IWX_FH_RSCSR_FRAME_ALIGN); 9058 nextpkt = (struct iwx_rx_packet *) 9059 (m0->m_data + nextoff); 9060 /* AX210 devices ship only one packet per Rx buffer. */ 9061 if (sc->sc_device_family >= IWX_DEVICE_FAMILY_AX210 || 9062 nextoff + minsz >= IWX_RBUF_SIZE || 9063 !iwx_rx_pkt_valid(nextpkt)) { 9064 /* No need to copy last frame in buffer. */ 9065 if (offset > 0) 9066 m_adj(m0, offset); 9067 iwx_rx_mpdu_mq(sc, m0, pkt->data, maxlen); 9068 m0 = NULL; /* stack owns m0 now; abort loop */ 9069 } else { 9070 /* 9071 * Create an mbuf which points to the current 9072 * packet. Always copy from offset zero to 9073 * preserve m_pkthdr. 9074 */ 9075 m = m_copym(m0, 0, M_COPYALL, M_NOWAIT); 9076 if (m == NULL) { 9077 m_freem(m0); 9078 m0 = NULL; 9079 break; 9080 } 9081 m_adj(m, offset); 9082 iwx_rx_mpdu_mq(sc, m, pkt->data, maxlen); 9083 } 9084 break; 9085 } 9086 9087 // case IWX_BAR_FRAME_RELEASE: 9088 // iwx_rx_bar_frame_release(sc, pkt, ml); 9089 // break; 9090 // 9091 case IWX_TX_CMD: 9092 iwx_rx_tx_cmd(sc, pkt, data); 9093 break; 9094 9095 case IWX_BA_NOTIF: 9096 iwx_rx_compressed_ba(sc, pkt); 9097 break; 9098 9099 case IWX_MISSED_BEACONS_NOTIFICATION: 9100 IWX_DPRINTF(sc, IWX_DEBUG_BEACON, 9101 "%s: IWX_MISSED_BEACONS_NOTIFICATION\n", 9102 __func__); 9103 iwx_rx_bmiss(sc, pkt, data); 9104 break; 9105 9106 case IWX_MFUART_LOAD_NOTIFICATION: 9107 break; 9108 9109 case IWX_ALIVE: { 9110 struct iwx_alive_resp_v4 *resp4; 9111 struct iwx_alive_resp_v5 *resp5; 9112 struct iwx_alive_resp_v6 *resp6; 9113 9114 DPRINTF(("%s: firmware alive\n", __func__)); 9115 sc->sc_uc.uc_ok = 0; 9116 9117 /* 9118 * For v5 and above, we can check the version, for older 9119 * versions we need to check the size. 9120 */ 9121 if (iwx_lookup_notif_ver(sc, IWX_LEGACY_GROUP, 9122 IWX_ALIVE) == 6) { 9123 SYNC_RESP_STRUCT(resp6, pkt); 9124 if (iwx_rx_packet_payload_len(pkt) != 9125 sizeof(*resp6)) { 9126 sc->sc_uc.uc_intr = 1; 9127 wakeup(&sc->sc_uc); 9128 break; 9129 } 9130 sc->sc_uc.uc_lmac_error_event_table[0] = le32toh( 9131 resp6->lmac_data[0].dbg_ptrs.error_event_table_ptr); 9132 sc->sc_uc.uc_lmac_error_event_table[1] = le32toh( 9133 resp6->lmac_data[1].dbg_ptrs.error_event_table_ptr); 9134 sc->sc_uc.uc_log_event_table = le32toh( 9135 resp6->lmac_data[0].dbg_ptrs.log_event_table_ptr); 9136 sc->sc_uc.uc_umac_error_event_table = le32toh( 9137 resp6->umac_data.dbg_ptrs.error_info_addr); 9138 sc->sc_sku_id[0] = 9139 le32toh(resp6->sku_id.data[0]); 9140 sc->sc_sku_id[1] = 9141 le32toh(resp6->sku_id.data[1]); 9142 sc->sc_sku_id[2] = 9143 le32toh(resp6->sku_id.data[2]); 9144 if (resp6->status == IWX_ALIVE_STATUS_OK) { 9145 sc->sc_uc.uc_ok = 1; 9146 } 9147 } else if (iwx_lookup_notif_ver(sc, IWX_LEGACY_GROUP, 9148 IWX_ALIVE) == 5) { 9149 SYNC_RESP_STRUCT(resp5, pkt); 9150 if (iwx_rx_packet_payload_len(pkt) != 9151 sizeof(*resp5)) { 9152 sc->sc_uc.uc_intr = 1; 9153 wakeup(&sc->sc_uc); 9154 break; 9155 } 9156 sc->sc_uc.uc_lmac_error_event_table[0] = le32toh( 9157 resp5->lmac_data[0].dbg_ptrs.error_event_table_ptr); 9158 sc->sc_uc.uc_lmac_error_event_table[1] = le32toh( 9159 resp5->lmac_data[1].dbg_ptrs.error_event_table_ptr); 9160 sc->sc_uc.uc_log_event_table = le32toh( 9161 resp5->lmac_data[0].dbg_ptrs.log_event_table_ptr); 9162 sc->sc_uc.uc_umac_error_event_table = le32toh( 9163 resp5->umac_data.dbg_ptrs.error_info_addr); 9164 sc->sc_sku_id[0] = 9165 le32toh(resp5->sku_id.data[0]); 9166 sc->sc_sku_id[1] = 9167 le32toh(resp5->sku_id.data[1]); 9168 sc->sc_sku_id[2] = 9169 le32toh(resp5->sku_id.data[2]); 9170 if (resp5->status == IWX_ALIVE_STATUS_OK) 9171 sc->sc_uc.uc_ok = 1; 9172 } else if (iwx_rx_packet_payload_len(pkt) == sizeof(*resp4)) { 9173 SYNC_RESP_STRUCT(resp4, pkt); 9174 sc->sc_uc.uc_lmac_error_event_table[0] = le32toh( 9175 resp4->lmac_data[0].dbg_ptrs.error_event_table_ptr); 9176 sc->sc_uc.uc_lmac_error_event_table[1] = le32toh( 9177 resp4->lmac_data[1].dbg_ptrs.error_event_table_ptr); 9178 sc->sc_uc.uc_log_event_table = le32toh( 9179 resp4->lmac_data[0].dbg_ptrs.log_event_table_ptr); 9180 sc->sc_uc.uc_umac_error_event_table = le32toh( 9181 resp4->umac_data.dbg_ptrs.error_info_addr); 9182 if (resp4->status == IWX_ALIVE_STATUS_OK) 9183 sc->sc_uc.uc_ok = 1; 9184 } else 9185 printf("unknown payload version"); 9186 9187 sc->sc_uc.uc_intr = 1; 9188 wakeup(&sc->sc_uc); 9189 break; 9190 } 9191 9192 /* 9193 * TODO: is this the right struct to use? Look at what 9194 * mvm is doing for statistics notification (eg 9195 * iwl_mvm_handle_rx_statistics() . 9196 */ 9197 case IWX_STATISTICS_NOTIFICATION: { 9198 struct iwx_notif_statistics *stats; 9199 SYNC_RESP_STRUCT(stats, pkt); 9200 memcpy(&sc->sc_stats, stats, sizeof(sc->sc_stats)); 9201 sc->sc_noise = iwx_get_noise(sc, &stats->rx.general); 9202 break; 9203 } 9204 9205 case IWX_DTS_MEASUREMENT_NOTIFICATION: 9206 case IWX_WIDE_ID(IWX_PHY_OPS_GROUP, 9207 IWX_DTS_MEASUREMENT_NOTIF_WIDE): 9208 case IWX_WIDE_ID(IWX_PHY_OPS_GROUP, 9209 IWX_TEMP_REPORTING_THRESHOLDS_CMD): 9210 break; 9211 9212 case IWX_WIDE_ID(IWX_PHY_OPS_GROUP, 9213 IWX_CT_KILL_NOTIFICATION): { 9214 struct iwx_ct_kill_notif *notif; 9215 SYNC_RESP_STRUCT(notif, pkt); 9216 printf("%s: device at critical temperature (%u degC), " 9217 "stopping device\n", 9218 DEVNAME(sc), le16toh(notif->temperature)); 9219 sc->sc_flags |= IWX_FLAG_HW_ERR; 9220 ieee80211_restart_all(ic); 9221 break; 9222 } 9223 9224 case IWX_WIDE_ID(IWX_DATA_PATH_GROUP, 9225 IWX_SCD_QUEUE_CONFIG_CMD): 9226 case IWX_WIDE_ID(IWX_DATA_PATH_GROUP, 9227 IWX_RX_BAID_ALLOCATION_CONFIG_CMD): 9228 case IWX_WIDE_ID(IWX_MAC_CONF_GROUP, 9229 IWX_SESSION_PROTECTION_CMD): 9230 case IWX_WIDE_ID(IWX_REGULATORY_AND_NVM_GROUP, 9231 IWX_NVM_GET_INFO): 9232 case IWX_ADD_STA_KEY: 9233 case IWX_PHY_CONFIGURATION_CMD: 9234 case IWX_TX_ANT_CONFIGURATION_CMD: 9235 case IWX_ADD_STA: 9236 case IWX_MAC_CONTEXT_CMD: 9237 case IWX_REPLY_SF_CFG_CMD: 9238 case IWX_POWER_TABLE_CMD: 9239 case IWX_LTR_CONFIG: 9240 case IWX_PHY_CONTEXT_CMD: 9241 case IWX_BINDING_CONTEXT_CMD: 9242 case IWX_WIDE_ID(IWX_LONG_GROUP, IWX_SCAN_CFG_CMD): 9243 case IWX_WIDE_ID(IWX_LONG_GROUP, IWX_SCAN_REQ_UMAC): 9244 case IWX_WIDE_ID(IWX_LONG_GROUP, IWX_SCAN_ABORT_UMAC): 9245 case IWX_REPLY_BEACON_FILTERING_CMD: 9246 case IWX_MAC_PM_POWER_TABLE: 9247 case IWX_TIME_QUOTA_CMD: 9248 case IWX_REMOVE_STA: 9249 case IWX_TXPATH_FLUSH: 9250 case IWX_BT_CONFIG: 9251 case IWX_MCC_UPDATE_CMD: 9252 case IWX_TIME_EVENT_CMD: 9253 case IWX_STATISTICS_CMD: 9254 case IWX_SCD_QUEUE_CFG: { 9255 size_t pkt_len; 9256 9257 if (sc->sc_cmd_resp_pkt[idx] == NULL) 9258 break; 9259 9260 bus_dmamap_sync(sc->rxq.data_dmat, data->map, 9261 BUS_DMASYNC_POSTREAD); 9262 9263 pkt_len = sizeof(pkt->len_n_flags) + 9264 iwx_rx_packet_len(pkt); 9265 9266 if ((pkt->hdr.flags & IWX_CMD_FAILED_MSK) || 9267 pkt_len < sizeof(*pkt) || 9268 pkt_len > sc->sc_cmd_resp_len[idx]) { 9269 free(sc->sc_cmd_resp_pkt[idx], M_DEVBUF); 9270 sc->sc_cmd_resp_pkt[idx] = NULL; 9271 break; 9272 } 9273 9274 bus_dmamap_sync(sc->rxq.data_dmat, data->map, 9275 BUS_DMASYNC_POSTREAD); 9276 memcpy(sc->sc_cmd_resp_pkt[idx], pkt, pkt_len); 9277 break; 9278 } 9279 9280 case IWX_INIT_COMPLETE_NOTIF: 9281 sc->sc_init_complete |= IWX_INIT_COMPLETE; 9282 wakeup(&sc->sc_init_complete); 9283 break; 9284 9285 case IWX_SCAN_COMPLETE_UMAC: { 9286 DPRINTF(("%s: >>> IWX_SCAN_COMPLETE_UMAC\n", __func__)); 9287 struct iwx_umac_scan_complete *notif __attribute__((unused)); 9288 SYNC_RESP_STRUCT(notif, pkt); 9289 DPRINTF(("%s: scan complete notif->status=%d\n", __func__, 9290 notif->status)); 9291 ieee80211_runtask(&sc->sc_ic, &sc->sc_es_task); 9292 iwx_endscan(sc); 9293 break; 9294 } 9295 9296 case IWX_SCAN_ITERATION_COMPLETE_UMAC: { 9297 DPRINTF(("%s: >>> IWX_SCAN_ITERATION_COMPLETE_UMAC\n", 9298 __func__)); 9299 struct iwx_umac_scan_iter_complete_notif *notif __attribute__((unused)); 9300 SYNC_RESP_STRUCT(notif, pkt); 9301 DPRINTF(("%s: iter scan complete notif->status=%d\n", __func__, 9302 notif->status)); 9303 iwx_endscan(sc); 9304 break; 9305 } 9306 9307 case IWX_MCC_CHUB_UPDATE_CMD: { 9308 struct iwx_mcc_chub_notif *notif; 9309 SYNC_RESP_STRUCT(notif, pkt); 9310 iwx_mcc_update(sc, notif); 9311 break; 9312 } 9313 9314 case IWX_REPLY_ERROR: { 9315 struct iwx_error_resp *resp; 9316 SYNC_RESP_STRUCT(resp, pkt); 9317 printf("%s: firmware error 0x%x, cmd 0x%x\n", 9318 DEVNAME(sc), le32toh(resp->error_type), 9319 resp->cmd_id); 9320 break; 9321 } 9322 9323 case IWX_TIME_EVENT_NOTIFICATION: { 9324 struct iwx_time_event_notif *notif; 9325 uint32_t action; 9326 SYNC_RESP_STRUCT(notif, pkt); 9327 9328 if (sc->sc_time_event_uid != le32toh(notif->unique_id)) 9329 break; 9330 action = le32toh(notif->action); 9331 if (action & IWX_TE_V2_NOTIF_HOST_EVENT_END) 9332 sc->sc_flags &= ~IWX_FLAG_TE_ACTIVE; 9333 break; 9334 } 9335 9336 case IWX_WIDE_ID(IWX_MAC_CONF_GROUP, 9337 IWX_SESSION_PROTECTION_NOTIF): { 9338 struct iwx_session_prot_notif *notif; 9339 uint32_t status, start, conf_id; 9340 9341 SYNC_RESP_STRUCT(notif, pkt); 9342 9343 status = le32toh(notif->status); 9344 start = le32toh(notif->start); 9345 conf_id = le32toh(notif->conf_id); 9346 /* Check for end of successful PROTECT_CONF_ASSOC. */ 9347 if (status == 1 && start == 0 && 9348 conf_id == IWX_SESSION_PROTECT_CONF_ASSOC) 9349 sc->sc_flags &= ~IWX_FLAG_TE_ACTIVE; 9350 break; 9351 } 9352 9353 case IWX_WIDE_ID(IWX_SYSTEM_GROUP, 9354 IWX_FSEQ_VER_MISMATCH_NOTIFICATION): 9355 break; 9356 9357 /* 9358 * Firmware versions 21 and 22 generate some DEBUG_LOG_MSG 9359 * messages. Just ignore them for now. 9360 */ 9361 case IWX_DEBUG_LOG_MSG: 9362 break; 9363 9364 case IWX_MCAST_FILTER_CMD: 9365 break; 9366 9367 case IWX_WIDE_ID(IWX_DATA_PATH_GROUP, IWX_DQA_ENABLE_CMD): 9368 break; 9369 9370 case IWX_WIDE_ID(IWX_SYSTEM_GROUP, IWX_SOC_CONFIGURATION_CMD): 9371 break; 9372 9373 case IWX_WIDE_ID(IWX_SYSTEM_GROUP, IWX_INIT_EXTENDED_CFG_CMD): 9374 break; 9375 9376 case IWX_WIDE_ID(IWX_REGULATORY_AND_NVM_GROUP, 9377 IWX_NVM_ACCESS_COMPLETE): 9378 break; 9379 9380 case IWX_WIDE_ID(IWX_DATA_PATH_GROUP, IWX_RX_NO_DATA_NOTIF): 9381 break; /* happens in monitor mode; ignore for now */ 9382 9383 case IWX_WIDE_ID(IWX_DATA_PATH_GROUP, IWX_TLC_MNG_CONFIG_CMD): 9384 break; 9385 9386 case IWX_WIDE_ID(IWX_DATA_PATH_GROUP, 9387 IWX_TLC_MNG_UPDATE_NOTIF): { 9388 struct iwx_tlc_update_notif *notif; 9389 SYNC_RESP_STRUCT(notif, pkt); 9390 (void)notif; 9391 if (iwx_rx_packet_payload_len(pkt) == sizeof(*notif)) 9392 iwx_rs_update(sc, notif); 9393 break; 9394 } 9395 9396 case IWX_WIDE_ID(IWX_DATA_PATH_GROUP, IWX_RLC_CONFIG_CMD): 9397 break; 9398 9399 /* 9400 * Ignore for now. The Linux driver only acts on this request 9401 * with 160Mhz channels in 11ax mode. 9402 */ 9403 case IWX_WIDE_ID(IWX_DATA_PATH_GROUP, 9404 IWX_THERMAL_DUAL_CHAIN_REQUEST): 9405 DPRINTF(("%s: thermal dual-chain request received\n", 9406 DEVNAME(sc))); 9407 break; 9408 9409 /* undocumented notification from iwx-ty-a0-gf-a0-77 image */ 9410 case IWX_WIDE_ID(IWX_DATA_PATH_GROUP, 0xf8): 9411 break; 9412 9413 case IWX_WIDE_ID(IWX_REGULATORY_AND_NVM_GROUP, 9414 IWX_PNVM_INIT_COMPLETE): 9415 DPRINTF(("%s: IWX_PNVM_INIT_COMPLETE\n", __func__)); 9416 sc->sc_init_complete |= IWX_PNVM_COMPLETE; 9417 wakeup(&sc->sc_init_complete); 9418 break; 9419 9420 default: 9421 handled = 0; 9422 /* XXX wulf: Get rid of bluetooth-related spam */ 9423 if ((code == 0xc2 && pkt->len_n_flags == 0x0000000c) || 9424 (code == 0xce && pkt->len_n_flags == 0x2000002c)) 9425 break; 9426 printf("%s: unhandled firmware response 0x%x/0x%x " 9427 "rx ring %d[%d]\n", 9428 DEVNAME(sc), code, pkt->len_n_flags, 9429 (qid & ~0x80), idx); 9430 break; 9431 } 9432 9433 /* 9434 * uCode sets bit 0x80 when it originates the notification, 9435 * i.e. when the notification is not a direct response to a 9436 * command sent by the driver. 9437 * For example, uCode issues IWX_REPLY_RX when it sends a 9438 * received frame to the driver. 9439 */ 9440 if (handled && !(qid & (1 << 7))) { 9441 iwx_cmd_done(sc, qid, idx, code); 9442 } 9443 9444 offset += roundup(len, IWX_FH_RSCSR_FRAME_ALIGN); 9445 9446 /* AX210 devices ship only one packet per Rx buffer. */ 9447 if (sc->sc_device_family >= IWX_DEVICE_FAMILY_AX210) 9448 break; 9449 } 9450 9451 if (m0 && m0 != data->m) 9452 m_freem(m0); 9453 } 9454 9455 static void 9456 iwx_notif_intr(struct iwx_softc *sc) 9457 { 9458 struct mbuf m; 9459 uint16_t hw; 9460 9461 bus_dmamap_sync(sc->rxq.stat_dma.tag, sc->rxq.stat_dma.map, 9462 BUS_DMASYNC_POSTREAD); 9463 9464 if (sc->sc_device_family >= IWX_DEVICE_FAMILY_AX210) { 9465 uint16_t *status = sc->rxq.stat_dma.vaddr; 9466 hw = le16toh(*status) & 0xfff; 9467 } else 9468 hw = le16toh(sc->rxq.stat->closed_rb_num) & 0xfff; 9469 hw &= (IWX_RX_MQ_RING_COUNT - 1); 9470 while (sc->rxq.cur != hw) { 9471 struct iwx_rx_data *data = &sc->rxq.data[sc->rxq.cur]; 9472 9473 bus_dmamap_sync(sc->rxq.data_dmat, data->map, 9474 BUS_DMASYNC_POSTREAD); 9475 9476 iwx_rx_pkt(sc, data, &m); 9477 sc->rxq.cur = (sc->rxq.cur + 1) % IWX_RX_MQ_RING_COUNT; 9478 } 9479 9480 /* 9481 * Tell the firmware what we have processed. 9482 * Seems like the hardware gets upset unless we align the write by 8?? 9483 */ 9484 hw = (hw == 0) ? IWX_RX_MQ_RING_COUNT - 1 : hw - 1; 9485 IWX_WRITE(sc, IWX_RFH_Q0_FRBDCB_WIDX_TRG, hw & ~7); 9486 } 9487 9488 #if 0 9489 int 9490 iwx_intr(void *arg) 9491 { 9492 struct iwx_softc *sc = arg; 9493 struct ieee80211com *ic = &sc->sc_ic; 9494 struct ifnet *ifp = IC2IFP(ic); 9495 int r1, r2, rv = 0; 9496 9497 IWX_WRITE(sc, IWX_CSR_INT_MASK, 0); 9498 9499 if (sc->sc_flags & IWX_FLAG_USE_ICT) { 9500 uint32_t *ict = sc->ict_dma.vaddr; 9501 int tmp; 9502 9503 tmp = htole32(ict[sc->ict_cur]); 9504 if (!tmp) 9505 goto out_ena; 9506 9507 /* 9508 * ok, there was something. keep plowing until we have all. 9509 */ 9510 r1 = r2 = 0; 9511 while (tmp) { 9512 r1 |= tmp; 9513 ict[sc->ict_cur] = 0; 9514 sc->ict_cur = (sc->ict_cur+1) % IWX_ICT_COUNT; 9515 tmp = htole32(ict[sc->ict_cur]); 9516 } 9517 9518 /* this is where the fun begins. don't ask */ 9519 if (r1 == 0xffffffff) 9520 r1 = 0; 9521 9522 /* i am not expected to understand this */ 9523 if (r1 & 0xc0000) 9524 r1 |= 0x8000; 9525 r1 = (0xff & r1) | ((0xff00 & r1) << 16); 9526 } else { 9527 r1 = IWX_READ(sc, IWX_CSR_INT); 9528 if (r1 == 0xffffffff || (r1 & 0xfffffff0) == 0xa5a5a5a0) 9529 goto out; 9530 r2 = IWX_READ(sc, IWX_CSR_FH_INT_STATUS); 9531 } 9532 if (r1 == 0 && r2 == 0) { 9533 goto out_ena; 9534 } 9535 9536 IWX_WRITE(sc, IWX_CSR_INT, r1 | ~sc->sc_intmask); 9537 9538 if (r1 & IWX_CSR_INT_BIT_ALIVE) { 9539 #if 0 9540 int i; 9541 /* Firmware has now configured the RFH. */ 9542 for (i = 0; i < IWX_RX_MQ_RING_COUNT; i++) 9543 iwx_update_rx_desc(sc, &sc->rxq, i); 9544 #endif 9545 IWX_WRITE(sc, IWX_RFH_Q0_FRBDCB_WIDX_TRG, 8); 9546 } 9547 9548 9549 if (r1 & IWX_CSR_INT_BIT_RF_KILL) { 9550 iwx_check_rfkill(sc); 9551 rv = 1; 9552 goto out_ena; 9553 } 9554 9555 if (r1 & IWX_CSR_INT_BIT_SW_ERR) { 9556 if (ifp->if_flags & IFF_DEBUG) { 9557 iwx_nic_error(sc); 9558 iwx_dump_driver_status(sc); 9559 } 9560 printf("%s: fatal firmware error\n", DEVNAME(sc)); 9561 ieee80211_restart_all(ic); 9562 rv = 1; 9563 goto out; 9564 9565 } 9566 9567 if (r1 & IWX_CSR_INT_BIT_HW_ERR) { 9568 printf("%s: hardware error, stopping device \n", DEVNAME(sc)); 9569 iwx_stop(sc); 9570 rv = 1; 9571 goto out; 9572 } 9573 9574 /* firmware chunk loaded */ 9575 if (r1 & IWX_CSR_INT_BIT_FH_TX) { 9576 IWX_WRITE(sc, IWX_CSR_FH_INT_STATUS, IWX_CSR_FH_INT_TX_MASK); 9577 9578 sc->sc_fw_chunk_done = 1; 9579 wakeup(&sc->sc_fw); 9580 } 9581 9582 if (r1 & (IWX_CSR_INT_BIT_FH_RX | IWX_CSR_INT_BIT_SW_RX | 9583 IWX_CSR_INT_BIT_RX_PERIODIC)) { 9584 if (r1 & (IWX_CSR_INT_BIT_FH_RX | IWX_CSR_INT_BIT_SW_RX)) { 9585 IWX_WRITE(sc, IWX_CSR_FH_INT_STATUS, IWX_CSR_FH_INT_RX_MASK); 9586 } 9587 if (r1 & IWX_CSR_INT_BIT_RX_PERIODIC) { 9588 IWX_WRITE(sc, IWX_CSR_INT, IWX_CSR_INT_BIT_RX_PERIODIC); 9589 } 9590 9591 /* Disable periodic interrupt; we use it as just a one-shot. */ 9592 IWX_WRITE_1(sc, IWX_CSR_INT_PERIODIC_REG, IWX_CSR_INT_PERIODIC_DIS); 9593 9594 /* 9595 * Enable periodic interrupt in 8 msec only if we received 9596 * real RX interrupt (instead of just periodic int), to catch 9597 * any dangling Rx interrupt. If it was just the periodic 9598 * interrupt, there was no dangling Rx activity, and no need 9599 * to extend the periodic interrupt; one-shot is enough. 9600 */ 9601 if (r1 & (IWX_CSR_INT_BIT_FH_RX | IWX_CSR_INT_BIT_SW_RX)) 9602 IWX_WRITE_1(sc, IWX_CSR_INT_PERIODIC_REG, 9603 IWX_CSR_INT_PERIODIC_ENA); 9604 9605 iwx_notif_intr(sc); 9606 } 9607 9608 rv = 1; 9609 9610 out_ena: 9611 iwx_restore_interrupts(sc); 9612 out: 9613 return rv; 9614 } 9615 #endif 9616 9617 static void 9618 iwx_intr_msix(void *arg) 9619 { 9620 struct iwx_softc *sc = arg; 9621 struct ieee80211com *ic = &sc->sc_ic; 9622 uint32_t inta_fh, inta_hw; 9623 int vector = 0; 9624 9625 IWX_LOCK(sc); 9626 9627 inta_fh = IWX_READ(sc, IWX_CSR_MSIX_FH_INT_CAUSES_AD); 9628 inta_hw = IWX_READ(sc, IWX_CSR_MSIX_HW_INT_CAUSES_AD); 9629 IWX_WRITE(sc, IWX_CSR_MSIX_FH_INT_CAUSES_AD, inta_fh); 9630 IWX_WRITE(sc, IWX_CSR_MSIX_HW_INT_CAUSES_AD, inta_hw); 9631 inta_fh &= sc->sc_fh_mask; 9632 inta_hw &= sc->sc_hw_mask; 9633 9634 if (inta_fh & IWX_MSIX_FH_INT_CAUSES_Q0 || 9635 inta_fh & IWX_MSIX_FH_INT_CAUSES_Q1) { 9636 iwx_notif_intr(sc); 9637 } 9638 9639 /* firmware chunk loaded */ 9640 if (inta_fh & IWX_MSIX_FH_INT_CAUSES_D2S_CH0_NUM) { 9641 sc->sc_fw_chunk_done = 1; 9642 wakeup(&sc->sc_fw); 9643 } 9644 9645 if ((inta_fh & IWX_MSIX_FH_INT_CAUSES_FH_ERR) || 9646 (inta_hw & IWX_MSIX_HW_INT_CAUSES_REG_SW_ERR) || 9647 (inta_hw & IWX_MSIX_HW_INT_CAUSES_REG_SW_ERR_V2)) { 9648 if (sc->sc_debug) { 9649 iwx_nic_error(sc); 9650 iwx_dump_driver_status(sc); 9651 } 9652 printf("%s: fatal firmware error\n", DEVNAME(sc)); 9653 ieee80211_restart_all(ic); 9654 goto out; 9655 } 9656 9657 if (inta_hw & IWX_MSIX_HW_INT_CAUSES_REG_RF_KILL) { 9658 iwx_check_rfkill(sc); 9659 } 9660 9661 if (inta_hw & IWX_MSIX_HW_INT_CAUSES_REG_HW_ERR) { 9662 printf("%s: hardware error, stopping device \n", DEVNAME(sc)); 9663 sc->sc_flags |= IWX_FLAG_HW_ERR; 9664 iwx_stop(sc); 9665 goto out; 9666 } 9667 9668 if (inta_hw & IWX_MSIX_HW_INT_CAUSES_REG_ALIVE) { 9669 IWX_DPRINTF(sc, IWX_DEBUG_TRACE, 9670 "%s:%d WARNING: Skipping rx desc update\n", 9671 __func__, __LINE__); 9672 #if 0 9673 /* 9674 * XXX-THJ: we don't have the dma segment handy. This is hacked 9675 * out in the fc release, return to it if we ever get this 9676 * warning. 9677 */ 9678 /* Firmware has now configured the RFH. */ 9679 for (int i = 0; i < IWX_RX_MQ_RING_COUNT; i++) 9680 iwx_update_rx_desc(sc, &sc->rxq, i); 9681 #endif 9682 IWX_WRITE(sc, IWX_RFH_Q0_FRBDCB_WIDX_TRG, 8); 9683 } 9684 9685 /* 9686 * Before sending the interrupt the HW disables it to prevent 9687 * a nested interrupt. This is done by writing 1 to the corresponding 9688 * bit in the mask register. After handling the interrupt, it should be 9689 * re-enabled by clearing this bit. This register is defined as 9690 * write 1 clear (W1C) register, meaning that it's being clear 9691 * by writing 1 to the bit. 9692 */ 9693 IWX_WRITE(sc, IWX_CSR_MSIX_AUTOMASK_ST_AD, 1 << vector); 9694 out: 9695 IWX_UNLOCK(sc); 9696 return; 9697 } 9698 9699 /* 9700 * The device info table below contains device-specific config overrides. 9701 * The most important parameter derived from this table is the name of the 9702 * firmware image to load. 9703 * 9704 * The Linux iwlwifi driver uses an "old" and a "new" device info table. 9705 * The "old" table matches devices based on PCI vendor/product IDs only. 9706 * The "new" table extends this with various device parameters derived 9707 * from MAC type, and RF type. 9708 * 9709 * In iwlwifi "old" and "new" tables share the same array, where "old" 9710 * entries contain dummy values for data defined only for "new" entries. 9711 * As of 2022, Linux developers are still in the process of moving entries 9712 * from "old" to "new" style and it looks like this effort has stalled in 9713 * in some work-in-progress state for quite a while. Linux commits moving 9714 * entries from "old" to "new" have at times been reverted due to regressions. 9715 * Part of this complexity comes from iwlwifi supporting both iwm(4) and iwx(4) 9716 * devices in the same driver. 9717 * 9718 * Our table below contains mostly "new" entries declared in iwlwifi 9719 * with the _IWL_DEV_INFO() macro (with a leading underscore). 9720 * Other devices are matched based on PCI vendor/product ID as usual, 9721 * unless matching specific PCI subsystem vendor/product IDs is required. 9722 * 9723 * Some "old"-style entries are required to identify the firmware image to use. 9724 * Others might be used to print a specific marketing name into Linux dmesg, 9725 * but we can't be sure whether the corresponding devices would be matched 9726 * correctly in the absence of their entries. So we include them just in case. 9727 */ 9728 9729 struct iwx_dev_info { 9730 uint16_t device; 9731 uint16_t subdevice; 9732 uint16_t mac_type; 9733 uint16_t rf_type; 9734 uint8_t mac_step; 9735 uint8_t rf_id; 9736 uint8_t no_160; 9737 uint8_t cores; 9738 uint8_t cdb; 9739 uint8_t jacket; 9740 const struct iwx_device_cfg *cfg; 9741 }; 9742 9743 #define _IWX_DEV_INFO(_device, _subdevice, _mac_type, _mac_step, _rf_type, \ 9744 _rf_id, _no_160, _cores, _cdb, _jacket, _cfg) \ 9745 { .device = (_device), .subdevice = (_subdevice), .cfg = &(_cfg), \ 9746 .mac_type = _mac_type, .rf_type = _rf_type, \ 9747 .no_160 = _no_160, .cores = _cores, .rf_id = _rf_id, \ 9748 .mac_step = _mac_step, .cdb = _cdb, .jacket = _jacket } 9749 9750 #define IWX_DEV_INFO(_device, _subdevice, _cfg) \ 9751 _IWX_DEV_INFO(_device, _subdevice, IWX_CFG_ANY, IWX_CFG_ANY, \ 9752 IWX_CFG_ANY, IWX_CFG_ANY, IWX_CFG_ANY, IWX_CFG_ANY, \ 9753 IWX_CFG_ANY, IWX_CFG_ANY, _cfg) 9754 9755 /* 9756 * When adding entries to this table keep in mind that entries must 9757 * be listed in the same order as in the Linux driver. Code walks this 9758 * table backwards and uses the first matching entry it finds. 9759 * Device firmware must be available in fw_update(8). 9760 */ 9761 static const struct iwx_dev_info iwx_dev_info_table[] = { 9762 /* So with HR */ 9763 IWX_DEV_INFO(0x2725, 0x0090, iwx_2ax_cfg_so_gf_a0), 9764 IWX_DEV_INFO(0x2725, 0x0020, iwx_2ax_cfg_ty_gf_a0), 9765 IWX_DEV_INFO(0x2725, 0x2020, iwx_2ax_cfg_ty_gf_a0), 9766 IWX_DEV_INFO(0x2725, 0x0024, iwx_2ax_cfg_ty_gf_a0), 9767 IWX_DEV_INFO(0x2725, 0x0310, iwx_2ax_cfg_ty_gf_a0), 9768 IWX_DEV_INFO(0x2725, 0x0510, iwx_2ax_cfg_ty_gf_a0), 9769 IWX_DEV_INFO(0x2725, 0x0A10, iwx_2ax_cfg_ty_gf_a0), 9770 IWX_DEV_INFO(0x2725, 0xE020, iwx_2ax_cfg_ty_gf_a0), 9771 IWX_DEV_INFO(0x2725, 0xE024, iwx_2ax_cfg_ty_gf_a0), 9772 IWX_DEV_INFO(0x2725, 0x4020, iwx_2ax_cfg_ty_gf_a0), 9773 IWX_DEV_INFO(0x2725, 0x6020, iwx_2ax_cfg_ty_gf_a0), 9774 IWX_DEV_INFO(0x2725, 0x6024, iwx_2ax_cfg_ty_gf_a0), 9775 IWX_DEV_INFO(0x2725, 0x1673, iwx_2ax_cfg_ty_gf_a0), /* killer_1675w */ 9776 IWX_DEV_INFO(0x2725, 0x1674, iwx_2ax_cfg_ty_gf_a0), /* killer_1675x */ 9777 IWX_DEV_INFO(0x51f0, 0x1691, iwx_2ax_cfg_so_gf4_a0), /* killer_1690s */ 9778 IWX_DEV_INFO(0x51f0, 0x1692, iwx_2ax_cfg_so_gf4_a0), /* killer_1690i */ 9779 IWX_DEV_INFO(0x51f1, 0x1691, iwx_2ax_cfg_so_gf4_a0), 9780 IWX_DEV_INFO(0x51f1, 0x1692, iwx_2ax_cfg_so_gf4_a0), 9781 IWX_DEV_INFO(0x54f0, 0x1691, iwx_2ax_cfg_so_gf4_a0), /* killer_1690s */ 9782 IWX_DEV_INFO(0x54f0, 0x1692, iwx_2ax_cfg_so_gf4_a0), /* killer_1690i */ 9783 IWX_DEV_INFO(0x7a70, 0x0090, iwx_2ax_cfg_so_gf_a0_long), 9784 IWX_DEV_INFO(0x7a70, 0x0098, iwx_2ax_cfg_so_gf_a0_long), 9785 IWX_DEV_INFO(0x7a70, 0x00b0, iwx_2ax_cfg_so_gf4_a0_long), 9786 IWX_DEV_INFO(0x7a70, 0x0310, iwx_2ax_cfg_so_gf_a0_long), 9787 IWX_DEV_INFO(0x7a70, 0x0510, iwx_2ax_cfg_so_gf_a0_long), 9788 IWX_DEV_INFO(0x7a70, 0x0a10, iwx_2ax_cfg_so_gf_a0_long), 9789 IWX_DEV_INFO(0x7af0, 0x0090, iwx_2ax_cfg_so_gf_a0), 9790 IWX_DEV_INFO(0x7af0, 0x0098, iwx_2ax_cfg_so_gf_a0), 9791 IWX_DEV_INFO(0x7af0, 0x00b0, iwx_2ax_cfg_so_gf4_a0), 9792 IWX_DEV_INFO(0x7a70, 0x1691, iwx_2ax_cfg_so_gf4_a0), /* killer_1690s */ 9793 IWX_DEV_INFO(0x7a70, 0x1692, iwx_2ax_cfg_so_gf4_a0), /* killer_1690i */ 9794 IWX_DEV_INFO(0x7af0, 0x0310, iwx_2ax_cfg_so_gf_a0), 9795 IWX_DEV_INFO(0x7af0, 0x0510, iwx_2ax_cfg_so_gf_a0), 9796 IWX_DEV_INFO(0x7af0, 0x0a10, iwx_2ax_cfg_so_gf_a0), 9797 IWX_DEV_INFO(0x7f70, 0x1691, iwx_2ax_cfg_so_gf4_a0), /* killer_1690s */ 9798 IWX_DEV_INFO(0x7f70, 0x1692, iwx_2ax_cfg_so_gf4_a0), /* killer_1690i */ 9799 9800 /* So with GF2 */ 9801 IWX_DEV_INFO(0x2726, 0x1671, iwx_2ax_cfg_so_gf_a0), /* killer_1675s */ 9802 IWX_DEV_INFO(0x2726, 0x1672, iwx_2ax_cfg_so_gf_a0), /* killer_1675i */ 9803 IWX_DEV_INFO(0x51f0, 0x1671, iwx_2ax_cfg_so_gf_a0), /* killer_1675s */ 9804 IWX_DEV_INFO(0x51f0, 0x1672, iwx_2ax_cfg_so_gf_a0), /* killer_1675i */ 9805 IWX_DEV_INFO(0x54f0, 0x1671, iwx_2ax_cfg_so_gf_a0), /* killer_1675s */ 9806 IWX_DEV_INFO(0x54f0, 0x1672, iwx_2ax_cfg_so_gf_a0), /* killer_1675i */ 9807 IWX_DEV_INFO(0x7a70, 0x1671, iwx_2ax_cfg_so_gf_a0), /* killer_1675s */ 9808 IWX_DEV_INFO(0x7a70, 0x1672, iwx_2ax_cfg_so_gf_a0), /* killer_1675i */ 9809 IWX_DEV_INFO(0x7af0, 0x1671, iwx_2ax_cfg_so_gf_a0), /* killer_1675s */ 9810 IWX_DEV_INFO(0x7af0, 0x1672, iwx_2ax_cfg_so_gf_a0), /* killer_1675i */ 9811 IWX_DEV_INFO(0x7f70, 0x1671, iwx_2ax_cfg_so_gf_a0), /* killer_1675s */ 9812 IWX_DEV_INFO(0x7f70, 0x1672, iwx_2ax_cfg_so_gf_a0), /* killer_1675i */ 9813 9814 /* Qu with Jf, C step */ 9815 _IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY, 9816 IWX_CFG_MAC_TYPE_QU, IWX_SILICON_C_STEP, 9817 IWX_CFG_RF_TYPE_JF1, IWX_CFG_RF_ID_JF1, 9818 IWX_CFG_160, IWX_CFG_CORES_BT, IWX_CFG_NO_CDB, 9819 IWX_CFG_ANY, iwx_9560_qu_c0_jf_b0_cfg), /* 9461_160 */ 9820 _IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY, 9821 IWX_CFG_MAC_TYPE_QU, IWX_SILICON_C_STEP, 9822 IWX_CFG_RF_TYPE_JF1, IWX_CFG_RF_ID_JF1, 9823 IWX_CFG_NO_160, IWX_CFG_CORES_BT, IWX_CFG_NO_CDB, 9824 IWX_CFG_ANY, iwx_9560_qu_c0_jf_b0_cfg), /* iwl9461 */ 9825 _IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY, 9826 IWX_CFG_MAC_TYPE_QU, IWX_SILICON_C_STEP, 9827 IWX_CFG_RF_TYPE_JF1, IWX_CFG_RF_ID_JF1_DIV, 9828 IWX_CFG_160, IWX_CFG_CORES_BT, IWX_CFG_NO_CDB, 9829 IWX_CFG_ANY, iwx_9560_qu_c0_jf_b0_cfg), /* 9462_160 */ 9830 _IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY, 9831 IWX_CFG_MAC_TYPE_QU, IWX_SILICON_C_STEP, 9832 IWX_CFG_RF_TYPE_JF1, IWX_CFG_RF_ID_JF1_DIV, 9833 IWX_CFG_NO_160, IWX_CFG_CORES_BT, IWX_CFG_NO_CDB, 9834 IWX_CFG_ANY, iwx_9560_qu_c0_jf_b0_cfg), /* 9462 */ 9835 _IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY, 9836 IWX_CFG_MAC_TYPE_QU, IWX_SILICON_C_STEP, 9837 IWX_CFG_RF_TYPE_JF2, IWX_CFG_RF_ID_JF, 9838 IWX_CFG_160, IWX_CFG_CORES_BT, IWX_CFG_NO_CDB, 9839 IWX_CFG_ANY, iwx_9560_qu_c0_jf_b0_cfg), /* 9560_160 */ 9840 _IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY, 9841 IWX_CFG_MAC_TYPE_QU, IWX_SILICON_C_STEP, 9842 IWX_CFG_RF_TYPE_JF2, IWX_CFG_RF_ID_JF, 9843 IWX_CFG_NO_160, IWX_CFG_CORES_BT, IWX_CFG_NO_CDB, 9844 IWX_CFG_ANY, iwx_9560_qu_c0_jf_b0_cfg), /* 9560 */ 9845 _IWX_DEV_INFO(IWX_CFG_ANY, 0x1551, 9846 IWX_CFG_MAC_TYPE_QU, IWX_SILICON_C_STEP, 9847 IWX_CFG_RF_TYPE_JF2, IWX_CFG_RF_ID_JF, 9848 IWX_CFG_160, IWX_CFG_CORES_BT, IWX_CFG_NO_CDB, 9849 IWX_CFG_ANY, 9850 iwx_9560_qu_c0_jf_b0_cfg), /* 9560_killer_1550s */ 9851 _IWX_DEV_INFO(IWX_CFG_ANY, 0x1552, 9852 IWX_CFG_MAC_TYPE_QU, IWX_SILICON_C_STEP, 9853 IWX_CFG_RF_TYPE_JF2, IWX_CFG_RF_ID_JF, 9854 IWX_CFG_NO_160, IWX_CFG_CORES_BT, IWX_CFG_NO_CDB, 9855 IWX_CFG_ANY, 9856 iwx_9560_qu_c0_jf_b0_cfg), /* 9560_killer_1550i */ 9857 9858 /* QuZ with Jf */ 9859 _IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY, 9860 IWX_CFG_MAC_TYPE_QUZ, IWX_CFG_ANY, 9861 IWX_CFG_RF_TYPE_JF2, IWX_CFG_RF_ID_JF, 9862 IWX_CFG_160, IWX_CFG_CORES_BT, IWX_CFG_NO_CDB, 9863 IWX_CFG_ANY, iwx_9560_quz_a0_jf_b0_cfg), /* 9461_160 */ 9864 _IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY, 9865 IWX_CFG_MAC_TYPE_QUZ, IWX_CFG_ANY, 9866 IWX_CFG_RF_TYPE_JF2, IWX_CFG_RF_ID_JF, 9867 IWX_CFG_NO_160, IWX_CFG_CORES_BT, IWX_CFG_NO_CDB, 9868 IWX_CFG_ANY, iwx_9560_quz_a0_jf_b0_cfg), /* 9461 */ 9869 _IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY, 9870 IWX_CFG_MAC_TYPE_QUZ, IWX_CFG_ANY, 9871 IWX_CFG_RF_TYPE_JF1, IWX_CFG_RF_ID_JF1_DIV, 9872 IWX_CFG_160, IWX_CFG_CORES_BT, IWX_CFG_NO_CDB, 9873 IWX_CFG_ANY, iwx_9560_quz_a0_jf_b0_cfg), /* 9462_160 */ 9874 _IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY, 9875 IWX_CFG_MAC_TYPE_QUZ, IWX_CFG_ANY, 9876 IWX_CFG_RF_TYPE_JF1, IWX_CFG_RF_ID_JF1_DIV, 9877 IWX_CFG_NO_160, IWX_CFG_CORES_BT, IWX_CFG_NO_CDB, 9878 IWX_CFG_ANY, iwx_9560_quz_a0_jf_b0_cfg), /* 9462 */ 9879 _IWX_DEV_INFO(IWX_CFG_ANY, 0x1551, 9880 IWX_CFG_MAC_TYPE_QUZ, IWX_CFG_ANY, 9881 IWX_CFG_RF_TYPE_JF2, IWX_CFG_RF_ID_JF, 9882 IWX_CFG_160, IWX_CFG_CORES_BT, IWX_CFG_NO_CDB, 9883 IWX_CFG_ANY, 9884 iwx_9560_quz_a0_jf_b0_cfg), /* killer_1550s */ 9885 _IWX_DEV_INFO(IWX_CFG_ANY, 0x1552, 9886 IWX_CFG_MAC_TYPE_QUZ, IWX_CFG_ANY, 9887 IWX_CFG_RF_TYPE_JF2, IWX_CFG_RF_ID_JF, 9888 IWX_CFG_NO_160, IWX_CFG_CORES_BT, IWX_CFG_NO_CDB, 9889 IWX_CFG_ANY, 9890 iwx_9560_quz_a0_jf_b0_cfg), /* 9560_killer_1550i */ 9891 9892 /* Qu with Hr, B step */ 9893 _IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY, 9894 IWX_CFG_MAC_TYPE_QU, IWX_SILICON_B_STEP, 9895 IWX_CFG_RF_TYPE_HR1, IWX_CFG_ANY, 9896 IWX_CFG_ANY, IWX_CFG_ANY, IWX_CFG_NO_CDB, IWX_CFG_ANY, 9897 iwx_qu_b0_hr1_b0), /* AX101 */ 9898 _IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY, 9899 IWX_CFG_MAC_TYPE_QU, IWX_SILICON_B_STEP, 9900 IWX_CFG_RF_TYPE_HR2, IWX_CFG_ANY, 9901 IWX_CFG_NO_160, IWX_CFG_ANY, IWX_CFG_NO_CDB, IWX_CFG_ANY, 9902 iwx_qu_b0_hr_b0), /* AX203 */ 9903 9904 /* Qu with Hr, C step */ 9905 _IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY, 9906 IWX_CFG_MAC_TYPE_QU, IWX_SILICON_C_STEP, 9907 IWX_CFG_RF_TYPE_HR1, IWX_CFG_ANY, 9908 IWX_CFG_ANY, IWX_CFG_ANY, IWX_CFG_NO_CDB, IWX_CFG_ANY, 9909 iwx_qu_c0_hr1_b0), /* AX101 */ 9910 _IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY, 9911 IWX_CFG_MAC_TYPE_QU, IWX_SILICON_C_STEP, 9912 IWX_CFG_RF_TYPE_HR2, IWX_CFG_ANY, 9913 IWX_CFG_NO_160, IWX_CFG_ANY, IWX_CFG_NO_CDB, IWX_CFG_ANY, 9914 iwx_qu_c0_hr_b0), /* AX203 */ 9915 _IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY, 9916 IWX_CFG_MAC_TYPE_QU, IWX_SILICON_C_STEP, 9917 IWX_CFG_RF_TYPE_HR2, IWX_CFG_ANY, 9918 IWX_CFG_160, IWX_CFG_ANY, IWX_CFG_NO_CDB, IWX_CFG_ANY, 9919 iwx_qu_c0_hr_b0), /* AX201 */ 9920 9921 /* QuZ with Hr */ 9922 _IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY, 9923 IWX_CFG_MAC_TYPE_QUZ, IWX_CFG_ANY, 9924 IWX_CFG_RF_TYPE_HR1, IWX_CFG_ANY, 9925 IWX_CFG_ANY, IWX_CFG_ANY, IWX_CFG_NO_CDB, IWX_CFG_ANY, 9926 iwx_quz_a0_hr1_b0), /* AX101 */ 9927 _IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY, 9928 IWX_CFG_MAC_TYPE_QUZ, IWX_SILICON_B_STEP, 9929 IWX_CFG_RF_TYPE_HR2, IWX_CFG_ANY, 9930 IWX_CFG_NO_160, IWX_CFG_ANY, IWX_CFG_NO_CDB, IWX_CFG_ANY, 9931 iwx_cfg_quz_a0_hr_b0), /* AX203 */ 9932 9933 /* SoF with JF2 */ 9934 _IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY, 9935 IWX_CFG_MAC_TYPE_SOF, IWX_CFG_ANY, 9936 IWX_CFG_RF_TYPE_JF2, IWX_CFG_RF_ID_JF, 9937 IWX_CFG_160, IWX_CFG_CORES_BT, IWX_CFG_NO_CDB, 9938 IWX_CFG_ANY, iwx_2ax_cfg_so_jf_b0), /* 9560_160 */ 9939 _IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY, 9940 IWX_CFG_MAC_TYPE_SOF, IWX_CFG_ANY, 9941 IWX_CFG_RF_TYPE_JF2, IWX_CFG_RF_ID_JF, 9942 IWX_CFG_NO_160, IWX_CFG_CORES_BT, IWX_CFG_NO_CDB, 9943 IWX_CFG_ANY, iwx_2ax_cfg_so_jf_b0), /* 9560 */ 9944 9945 /* SoF with JF */ 9946 _IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY, 9947 IWX_CFG_MAC_TYPE_SOF, IWX_CFG_ANY, 9948 IWX_CFG_RF_TYPE_JF1, IWX_CFG_RF_ID_JF1, 9949 IWX_CFG_160, IWX_CFG_CORES_BT, IWX_CFG_NO_CDB, 9950 IWX_CFG_ANY, iwx_2ax_cfg_so_jf_b0), /* 9461_160 */ 9951 _IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY, 9952 IWX_CFG_MAC_TYPE_SOF, IWX_CFG_ANY, 9953 IWX_CFG_RF_TYPE_JF1, IWX_CFG_RF_ID_JF1_DIV, 9954 IWX_CFG_160, IWX_CFG_CORES_BT, IWX_CFG_NO_CDB, 9955 IWX_CFG_ANY, iwx_2ax_cfg_so_jf_b0), /* 9462_160 */ 9956 _IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY, 9957 IWX_CFG_MAC_TYPE_SOF, IWX_CFG_ANY, 9958 IWX_CFG_RF_TYPE_JF1, IWX_CFG_RF_ID_JF1, 9959 IWX_CFG_NO_160, IWX_CFG_CORES_BT, IWX_CFG_NO_CDB, 9960 IWX_CFG_ANY, iwx_2ax_cfg_so_jf_b0), /* 9461_name */ 9961 _IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY, 9962 IWX_CFG_MAC_TYPE_SOF, IWX_CFG_ANY, 9963 IWX_CFG_RF_TYPE_JF1, IWX_CFG_RF_ID_JF1_DIV, 9964 IWX_CFG_NO_160, IWX_CFG_CORES_BT, IWX_CFG_NO_CDB, 9965 IWX_CFG_ANY, iwx_2ax_cfg_so_jf_b0), /* 9462 */ 9966 9967 /* So with Hr */ 9968 _IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY, 9969 IWX_CFG_MAC_TYPE_SO, IWX_CFG_ANY, 9970 IWX_CFG_RF_TYPE_HR2, IWX_CFG_ANY, 9971 IWX_CFG_NO_160, IWX_CFG_ANY, IWX_CFG_NO_CDB, IWX_CFG_ANY, 9972 iwx_cfg_so_a0_hr_b0), /* AX203 */ 9973 _IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY, 9974 IWX_CFG_MAC_TYPE_SO, IWX_CFG_ANY, 9975 IWX_CFG_RF_TYPE_HR1, IWX_CFG_ANY, 9976 IWX_CFG_NO_160, IWX_CFG_ANY, IWX_CFG_NO_CDB, IWX_CFG_ANY, 9977 iwx_cfg_so_a0_hr_b0), /* ax101 */ 9978 _IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY, 9979 IWX_CFG_MAC_TYPE_SO, IWX_CFG_ANY, 9980 IWX_CFG_RF_TYPE_HR2, IWX_CFG_ANY, 9981 IWX_CFG_160, IWX_CFG_ANY, IWX_CFG_NO_CDB, IWX_CFG_ANY, 9982 iwx_cfg_so_a0_hr_b0), /* ax201 */ 9983 9984 /* So-F with Hr */ 9985 _IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY, 9986 IWX_CFG_MAC_TYPE_SOF, IWX_CFG_ANY, 9987 IWX_CFG_RF_TYPE_HR2, IWX_CFG_ANY, 9988 IWX_CFG_NO_160, IWX_CFG_ANY, IWX_CFG_NO_CDB, IWX_CFG_ANY, 9989 iwx_cfg_so_a0_hr_b0), /* AX203 */ 9990 _IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY, 9991 IWX_CFG_MAC_TYPE_SOF, IWX_CFG_ANY, 9992 IWX_CFG_RF_TYPE_HR1, IWX_CFG_ANY, 9993 IWX_CFG_NO_160, IWX_CFG_ANY, IWX_CFG_NO_CDB, IWX_CFG_ANY, 9994 iwx_cfg_so_a0_hr_b0), /* AX101 */ 9995 _IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY, 9996 IWX_CFG_MAC_TYPE_SOF, IWX_CFG_ANY, 9997 IWX_CFG_RF_TYPE_HR2, IWX_CFG_ANY, 9998 IWX_CFG_160, IWX_CFG_ANY, IWX_CFG_NO_CDB, IWX_CFG_ANY, 9999 iwx_cfg_so_a0_hr_b0), /* AX201 */ 10000 10001 /* So-F with GF */ 10002 _IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY, 10003 IWX_CFG_MAC_TYPE_SOF, IWX_CFG_ANY, 10004 IWX_CFG_RF_TYPE_GF, IWX_CFG_ANY, 10005 IWX_CFG_160, IWX_CFG_ANY, IWX_CFG_NO_CDB, IWX_CFG_ANY, 10006 iwx_2ax_cfg_so_gf_a0), /* AX211 */ 10007 _IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY, 10008 IWX_CFG_MAC_TYPE_SOF, IWX_CFG_ANY, 10009 IWX_CFG_RF_TYPE_GF, IWX_CFG_ANY, 10010 IWX_CFG_160, IWX_CFG_ANY, IWX_CFG_CDB, IWX_CFG_ANY, 10011 iwx_2ax_cfg_so_gf4_a0), /* AX411 */ 10012 10013 /* So with GF */ 10014 _IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY, 10015 IWX_CFG_MAC_TYPE_SO, IWX_CFG_ANY, 10016 IWX_CFG_RF_TYPE_GF, IWX_CFG_ANY, 10017 IWX_CFG_160, IWX_CFG_ANY, IWX_CFG_NO_CDB, IWX_CFG_ANY, 10018 iwx_2ax_cfg_so_gf_a0), /* AX211 */ 10019 _IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY, 10020 IWX_CFG_MAC_TYPE_SO, IWX_CFG_ANY, 10021 IWX_CFG_RF_TYPE_GF, IWX_CFG_ANY, 10022 IWX_CFG_160, IWX_CFG_ANY, IWX_CFG_CDB, IWX_CFG_ANY, 10023 iwx_2ax_cfg_so_gf4_a0), /* AX411 */ 10024 10025 /* So with JF2 */ 10026 _IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY, 10027 IWX_CFG_MAC_TYPE_SO, IWX_CFG_ANY, 10028 IWX_CFG_RF_TYPE_JF2, IWX_CFG_RF_ID_JF, 10029 IWX_CFG_160, IWX_CFG_CORES_BT, IWX_CFG_NO_CDB, 10030 IWX_CFG_ANY, iwx_2ax_cfg_so_jf_b0), /* 9560_160 */ 10031 _IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY, 10032 IWX_CFG_MAC_TYPE_SO, IWX_CFG_ANY, 10033 IWX_CFG_RF_TYPE_JF2, IWX_CFG_RF_ID_JF, 10034 IWX_CFG_NO_160, IWX_CFG_CORES_BT, IWX_CFG_NO_CDB, 10035 IWX_CFG_ANY, iwx_2ax_cfg_so_jf_b0), /* 9560 */ 10036 10037 /* So with JF */ 10038 _IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY, 10039 IWX_CFG_MAC_TYPE_SO, IWX_CFG_ANY, 10040 IWX_CFG_RF_TYPE_JF1, IWX_CFG_RF_ID_JF1, 10041 IWX_CFG_160, IWX_CFG_CORES_BT, IWX_CFG_NO_CDB, 10042 IWX_CFG_ANY, iwx_2ax_cfg_so_jf_b0), /* 9461_160 */ 10043 _IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY, 10044 IWX_CFG_MAC_TYPE_SO, IWX_CFG_ANY, 10045 IWX_CFG_RF_TYPE_JF1, IWX_CFG_RF_ID_JF1_DIV, 10046 IWX_CFG_160, IWX_CFG_CORES_BT, IWX_CFG_NO_CDB, 10047 IWX_CFG_ANY, iwx_2ax_cfg_so_jf_b0), /* 9462_160 */ 10048 _IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY, 10049 IWX_CFG_MAC_TYPE_SO, IWX_CFG_ANY, 10050 IWX_CFG_RF_TYPE_JF1, IWX_CFG_RF_ID_JF1, 10051 IWX_CFG_NO_160, IWX_CFG_CORES_BT, IWX_CFG_NO_CDB, 10052 IWX_CFG_ANY, iwx_2ax_cfg_so_jf_b0), /* iwl9461 */ 10053 _IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY, 10054 IWX_CFG_MAC_TYPE_SO, IWX_CFG_ANY, 10055 IWX_CFG_RF_TYPE_JF1, IWX_CFG_RF_ID_JF1_DIV, 10056 IWX_CFG_NO_160, IWX_CFG_CORES_BT, IWX_CFG_NO_CDB, 10057 IWX_CFG_ANY, iwx_2ax_cfg_so_jf_b0), /* 9462 */ 10058 }; 10059 10060 static int 10061 iwx_preinit(struct iwx_softc *sc) 10062 { 10063 struct ieee80211com *ic = &sc->sc_ic; 10064 int err; 10065 10066 err = iwx_prepare_card_hw(sc); 10067 if (err) { 10068 printf("%s: could not initialize hardware\n", DEVNAME(sc)); 10069 return err; 10070 } 10071 10072 if (sc->attached) { 10073 return 0; 10074 } 10075 10076 err = iwx_start_hw(sc); 10077 if (err) { 10078 printf("%s: could not initialize hardware\n", DEVNAME(sc)); 10079 return err; 10080 } 10081 10082 err = iwx_run_init_mvm_ucode(sc, 1); 10083 iwx_stop_device(sc); 10084 if (err) { 10085 printf("%s: failed to stop device\n", DEVNAME(sc)); 10086 return err; 10087 } 10088 10089 /* Print version info and MAC address on first successful fw load. */ 10090 sc->attached = 1; 10091 if (sc->sc_pnvm_ver) { 10092 printf("%s: hw rev 0x%x, fw %s, pnvm %08x, " 10093 "address %s\n", 10094 DEVNAME(sc), sc->sc_hw_rev & IWX_CSR_HW_REV_TYPE_MSK, 10095 sc->sc_fwver, sc->sc_pnvm_ver, 10096 ether_sprintf(sc->sc_nvm.hw_addr)); 10097 } else { 10098 printf("%s: hw rev 0x%x, fw %s, address %s\n", 10099 DEVNAME(sc), sc->sc_hw_rev & IWX_CSR_HW_REV_TYPE_MSK, 10100 sc->sc_fwver, ether_sprintf(sc->sc_nvm.hw_addr)); 10101 } 10102 10103 /* not all hardware can do 5GHz band */ 10104 if (!sc->sc_nvm.sku_cap_band_52GHz_enable) 10105 memset(&ic->ic_sup_rates[IEEE80211_MODE_11A], 0, 10106 sizeof(ic->ic_sup_rates[IEEE80211_MODE_11A])); 10107 10108 return 0; 10109 } 10110 10111 static void 10112 iwx_attach_hook(void *self) 10113 { 10114 struct iwx_softc *sc = (void *)self; 10115 struct ieee80211com *ic = &sc->sc_ic; 10116 int err; 10117 10118 IWX_LOCK(sc); 10119 err = iwx_preinit(sc); 10120 IWX_UNLOCK(sc); 10121 if (err != 0) 10122 goto out; 10123 10124 iwx_init_channel_map(ic, IEEE80211_CHAN_MAX, &ic->ic_nchans, 10125 ic->ic_channels); 10126 10127 ieee80211_ifattach(ic); 10128 ic->ic_vap_create = iwx_vap_create; 10129 ic->ic_vap_delete = iwx_vap_delete; 10130 ic->ic_raw_xmit = iwx_raw_xmit; 10131 ic->ic_node_alloc = iwx_node_alloc; 10132 ic->ic_scan_start = iwx_scan_start; 10133 ic->ic_scan_end = iwx_scan_end; 10134 ic->ic_update_mcast = iwx_update_mcast; 10135 ic->ic_getradiocaps = iwx_init_channel_map; 10136 10137 ic->ic_set_channel = iwx_set_channel; 10138 ic->ic_scan_curchan = iwx_scan_curchan; 10139 ic->ic_scan_mindwell = iwx_scan_mindwell; 10140 ic->ic_wme.wme_update = iwx_wme_update; 10141 ic->ic_parent = iwx_parent; 10142 ic->ic_transmit = iwx_transmit; 10143 10144 sc->sc_ampdu_rx_start = ic->ic_ampdu_rx_start; 10145 ic->ic_ampdu_rx_start = iwx_ampdu_rx_start; 10146 sc->sc_ampdu_rx_stop = ic->ic_ampdu_rx_stop; 10147 ic->ic_ampdu_rx_stop = iwx_ampdu_rx_stop; 10148 10149 sc->sc_addba_request = ic->ic_addba_request; 10150 ic->ic_addba_request = iwx_addba_request; 10151 sc->sc_addba_response = ic->ic_addba_response; 10152 ic->ic_addba_response = iwx_addba_response; 10153 10154 iwx_radiotap_attach(sc); 10155 ieee80211_announce(ic); 10156 out: 10157 config_intrhook_disestablish(&sc->sc_preinit_hook); 10158 } 10159 10160 const struct iwx_device_cfg * 10161 iwx_find_device_cfg(struct iwx_softc *sc) 10162 { 10163 uint16_t sdev_id, mac_type, rf_type; 10164 uint8_t mac_step, cdb, jacket, rf_id, no_160, cores; 10165 int i; 10166 10167 sdev_id = pci_get_subdevice(sc->sc_dev); 10168 mac_type = IWX_CSR_HW_REV_TYPE(sc->sc_hw_rev); 10169 mac_step = IWX_CSR_HW_REV_STEP(sc->sc_hw_rev << 2); 10170 rf_type = IWX_CSR_HW_RFID_TYPE(sc->sc_hw_rf_id); 10171 cdb = IWX_CSR_HW_RFID_IS_CDB(sc->sc_hw_rf_id); 10172 jacket = IWX_CSR_HW_RFID_IS_JACKET(sc->sc_hw_rf_id); 10173 10174 rf_id = IWX_SUBDEVICE_RF_ID(sdev_id); 10175 no_160 = IWX_SUBDEVICE_NO_160(sdev_id); 10176 cores = IWX_SUBDEVICE_CORES(sdev_id); 10177 10178 for (i = nitems(iwx_dev_info_table) - 1; i >= 0; i--) { 10179 const struct iwx_dev_info *dev_info = &iwx_dev_info_table[i]; 10180 10181 if (dev_info->device != (uint16_t)IWX_CFG_ANY && 10182 dev_info->device != sc->sc_pid) 10183 continue; 10184 10185 if (dev_info->subdevice != (uint16_t)IWX_CFG_ANY && 10186 dev_info->subdevice != sdev_id) 10187 continue; 10188 10189 if (dev_info->mac_type != (uint16_t)IWX_CFG_ANY && 10190 dev_info->mac_type != mac_type) 10191 continue; 10192 10193 if (dev_info->mac_step != (uint8_t)IWX_CFG_ANY && 10194 dev_info->mac_step != mac_step) 10195 continue; 10196 10197 if (dev_info->rf_type != (uint16_t)IWX_CFG_ANY && 10198 dev_info->rf_type != rf_type) 10199 continue; 10200 10201 if (dev_info->cdb != (uint8_t)IWX_CFG_ANY && 10202 dev_info->cdb != cdb) 10203 continue; 10204 10205 if (dev_info->jacket != (uint8_t)IWX_CFG_ANY && 10206 dev_info->jacket != jacket) 10207 continue; 10208 10209 if (dev_info->rf_id != (uint8_t)IWX_CFG_ANY && 10210 dev_info->rf_id != rf_id) 10211 continue; 10212 10213 if (dev_info->no_160 != (uint8_t)IWX_CFG_ANY && 10214 dev_info->no_160 != no_160) 10215 continue; 10216 10217 if (dev_info->cores != (uint8_t)IWX_CFG_ANY && 10218 dev_info->cores != cores) 10219 continue; 10220 10221 return dev_info->cfg; 10222 } 10223 10224 return NULL; 10225 } 10226 10227 static int 10228 iwx_probe(device_t dev) 10229 { 10230 int i; 10231 10232 for (i = 0; i < nitems(iwx_devices); i++) { 10233 if (pci_get_vendor(dev) == PCI_VENDOR_INTEL && 10234 pci_get_device(dev) == iwx_devices[i].device) { 10235 device_set_desc(dev, iwx_devices[i].name); 10236 10237 /* 10238 * Due to significant existing deployments using 10239 * iwlwifi lower the priority of iwx. 10240 * 10241 * This inverts the advice in bus.h where drivers 10242 * supporting newer hardware should return 10243 * BUS_PROBE_DEFAULT and drivers for older devices 10244 * return BUS_PROBE_LOW_PRIORITY. 10245 * 10246 */ 10247 return (BUS_PROBE_LOW_PRIORITY); 10248 } 10249 } 10250 10251 return (ENXIO); 10252 } 10253 10254 static int 10255 iwx_attach(device_t dev) 10256 { 10257 struct iwx_softc *sc = device_get_softc(dev); 10258 struct ieee80211com *ic = &sc->sc_ic; 10259 const struct iwx_device_cfg *cfg; 10260 int err; 10261 int txq_i, i, j; 10262 size_t ctxt_info_size; 10263 int rid; 10264 int count; 10265 int error; 10266 sc->sc_dev = dev; 10267 sc->sc_pid = pci_get_device(dev); 10268 sc->sc_dmat = bus_get_dma_tag(sc->sc_dev); 10269 10270 TASK_INIT(&sc->sc_es_task, 0, iwx_endscan_cb, sc); 10271 IWX_LOCK_INIT(sc); 10272 mbufq_init(&sc->sc_snd, ifqmaxlen); 10273 TASK_INIT(&sc->ba_rx_task, 0, iwx_ba_rx_task, sc); 10274 TASK_INIT(&sc->ba_tx_task, 0, iwx_ba_tx_task, sc); 10275 sc->sc_tq = taskqueue_create("iwm_taskq", M_WAITOK, 10276 taskqueue_thread_enqueue, &sc->sc_tq); 10277 error = taskqueue_start_threads(&sc->sc_tq, 1, 0, "iwm_taskq"); 10278 if (error != 0) { 10279 device_printf(dev, "can't start taskq thread, error %d\n", 10280 error); 10281 return (ENXIO); 10282 } 10283 10284 pci_find_cap(dev, PCIY_EXPRESS, &sc->sc_cap_off); 10285 if (sc->sc_cap_off == 0) { 10286 device_printf(dev, "PCIe capability structure not found!\n"); 10287 return (ENXIO); 10288 } 10289 10290 /* 10291 * We disable the RETRY_TIMEOUT register (0x41) to keep 10292 * PCI Tx retries from interfering with C3 CPU state. 10293 */ 10294 pci_write_config(dev, PCI_CFG_RETRY_TIMEOUT, 0x00, 1); 10295 10296 if (pci_msix_count(dev)) { 10297 sc->sc_msix = 1; 10298 } else { 10299 device_printf(dev, "no MSI-X found\n"); 10300 return (ENXIO); 10301 } 10302 10303 pci_enable_busmaster(dev); 10304 rid = PCIR_BAR(0); 10305 sc->sc_mem = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, 10306 RF_ACTIVE); 10307 if (sc->sc_mem == NULL) { 10308 device_printf(sc->sc_dev, "can't map mem space\n"); 10309 return (ENXIO); 10310 } 10311 sc->sc_st = rman_get_bustag(sc->sc_mem); 10312 sc->sc_sh = rman_get_bushandle(sc->sc_mem); 10313 10314 count = 1; 10315 rid = 0; 10316 if (pci_alloc_msix(dev, &count) == 0) 10317 rid = 1; 10318 DPRINTF(("%s: count=%d\n", __func__, count)); 10319 sc->sc_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, RF_ACTIVE | 10320 (rid != 0 ? 0 : RF_SHAREABLE)); 10321 if (sc->sc_irq == NULL) { 10322 device_printf(dev, "can't map interrupt\n"); 10323 return (ENXIO); 10324 } 10325 error = bus_setup_intr(dev, sc->sc_irq, INTR_TYPE_NET | INTR_MPSAFE, 10326 NULL, iwx_intr_msix, sc, &sc->sc_ih); 10327 if (error != 0) { 10328 device_printf(dev, "can't establish interrupt\n"); 10329 return (ENXIO); 10330 } 10331 10332 /* Clear pending interrupts. */ 10333 IWX_WRITE(sc, IWX_CSR_INT_MASK, 0); 10334 IWX_WRITE(sc, IWX_CSR_INT, ~0); 10335 IWX_WRITE(sc, IWX_CSR_FH_INT_STATUS, ~0); 10336 10337 sc->sc_hw_rev = IWX_READ(sc, IWX_CSR_HW_REV); 10338 DPRINTF(("%s: sc->sc_hw_rev=%d\n", __func__, sc->sc_hw_rev)); 10339 sc->sc_hw_rf_id = IWX_READ(sc, IWX_CSR_HW_RF_ID); 10340 DPRINTF(("%s: sc->sc_hw_rf_id =%d\n", __func__, sc->sc_hw_rf_id)); 10341 10342 /* 10343 * In the 8000 HW family the format of the 4 bytes of CSR_HW_REV have 10344 * changed, and now the revision step also includes bit 0-1 (no more 10345 * "dash" value). To keep hw_rev backwards compatible - we'll store it 10346 * in the old format. 10347 */ 10348 sc->sc_hw_rev = (sc->sc_hw_rev & 0xfff0) | 10349 (IWX_CSR_HW_REV_STEP(sc->sc_hw_rev << 2) << 2); 10350 10351 switch (sc->sc_pid) { 10352 case PCI_PRODUCT_INTEL_WL_22500_1: 10353 sc->sc_fwname = IWX_CC_A_FW; 10354 sc->sc_device_family = IWX_DEVICE_FAMILY_22000; 10355 sc->sc_integrated = 0; 10356 sc->sc_ltr_delay = IWX_SOC_FLAGS_LTR_APPLY_DELAY_NONE; 10357 sc->sc_low_latency_xtal = 0; 10358 sc->sc_xtal_latency = 0; 10359 sc->sc_tx_with_siso_diversity = 0; 10360 sc->sc_uhb_supported = 0; 10361 break; 10362 case PCI_PRODUCT_INTEL_WL_22500_2: 10363 case PCI_PRODUCT_INTEL_WL_22500_5: 10364 /* These devices should be QuZ only. */ 10365 if (sc->sc_hw_rev != IWX_CSR_HW_REV_TYPE_QUZ) { 10366 device_printf(dev, "unsupported AX201 adapter\n"); 10367 return (ENXIO); 10368 } 10369 sc->sc_fwname = IWX_QUZ_A_HR_B_FW; 10370 sc->sc_device_family = IWX_DEVICE_FAMILY_22000; 10371 sc->sc_integrated = 1; 10372 sc->sc_ltr_delay = IWX_SOC_FLAGS_LTR_APPLY_DELAY_200; 10373 sc->sc_low_latency_xtal = 0; 10374 sc->sc_xtal_latency = 500; 10375 sc->sc_tx_with_siso_diversity = 0; 10376 sc->sc_uhb_supported = 0; 10377 break; 10378 case PCI_PRODUCT_INTEL_WL_22500_3: 10379 if (sc->sc_hw_rev == IWX_CSR_HW_REV_TYPE_QU_C0) 10380 sc->sc_fwname = IWX_QU_C_HR_B_FW; 10381 else if (sc->sc_hw_rev == IWX_CSR_HW_REV_TYPE_QUZ) 10382 sc->sc_fwname = IWX_QUZ_A_HR_B_FW; 10383 else 10384 sc->sc_fwname = IWX_QU_B_HR_B_FW; 10385 sc->sc_device_family = IWX_DEVICE_FAMILY_22000; 10386 sc->sc_integrated = 1; 10387 sc->sc_ltr_delay = IWX_SOC_FLAGS_LTR_APPLY_DELAY_200; 10388 sc->sc_low_latency_xtal = 0; 10389 sc->sc_xtal_latency = 500; 10390 sc->sc_tx_with_siso_diversity = 0; 10391 sc->sc_uhb_supported = 0; 10392 break; 10393 case PCI_PRODUCT_INTEL_WL_22500_4: 10394 case PCI_PRODUCT_INTEL_WL_22500_7: 10395 case PCI_PRODUCT_INTEL_WL_22500_8: 10396 if (sc->sc_hw_rev == IWX_CSR_HW_REV_TYPE_QU_C0) 10397 sc->sc_fwname = IWX_QU_C_HR_B_FW; 10398 else if (sc->sc_hw_rev == IWX_CSR_HW_REV_TYPE_QUZ) 10399 sc->sc_fwname = IWX_QUZ_A_HR_B_FW; 10400 else 10401 sc->sc_fwname = IWX_QU_B_HR_B_FW; 10402 sc->sc_device_family = IWX_DEVICE_FAMILY_22000; 10403 sc->sc_integrated = 1; 10404 sc->sc_ltr_delay = IWX_SOC_FLAGS_LTR_APPLY_DELAY_1820; 10405 sc->sc_low_latency_xtal = 0; 10406 sc->sc_xtal_latency = 1820; 10407 sc->sc_tx_with_siso_diversity = 0; 10408 sc->sc_uhb_supported = 0; 10409 break; 10410 case PCI_PRODUCT_INTEL_WL_22500_6: 10411 if (sc->sc_hw_rev == IWX_CSR_HW_REV_TYPE_QU_C0) 10412 sc->sc_fwname = IWX_QU_C_HR_B_FW; 10413 else if (sc->sc_hw_rev == IWX_CSR_HW_REV_TYPE_QUZ) 10414 sc->sc_fwname = IWX_QUZ_A_HR_B_FW; 10415 else 10416 sc->sc_fwname = IWX_QU_B_HR_B_FW; 10417 sc->sc_device_family = IWX_DEVICE_FAMILY_22000; 10418 sc->sc_integrated = 1; 10419 sc->sc_ltr_delay = IWX_SOC_FLAGS_LTR_APPLY_DELAY_2500; 10420 sc->sc_low_latency_xtal = 1; 10421 sc->sc_xtal_latency = 12000; 10422 sc->sc_tx_with_siso_diversity = 0; 10423 sc->sc_uhb_supported = 0; 10424 break; 10425 case PCI_PRODUCT_INTEL_WL_22500_9: 10426 case PCI_PRODUCT_INTEL_WL_22500_10: 10427 case PCI_PRODUCT_INTEL_WL_22500_11: 10428 case PCI_PRODUCT_INTEL_WL_22500_13: 10429 /* _14 is an MA device, not yet supported */ 10430 case PCI_PRODUCT_INTEL_WL_22500_15: 10431 case PCI_PRODUCT_INTEL_WL_22500_16: 10432 sc->sc_fwname = IWX_SO_A_GF_A_FW; 10433 sc->sc_pnvm_name = IWX_SO_A_GF_A_PNVM; 10434 sc->sc_device_family = IWX_DEVICE_FAMILY_AX210; 10435 sc->sc_integrated = 0; 10436 sc->sc_ltr_delay = IWX_SOC_FLAGS_LTR_APPLY_DELAY_NONE; 10437 sc->sc_low_latency_xtal = 0; 10438 sc->sc_xtal_latency = 0; 10439 sc->sc_tx_with_siso_diversity = 0; 10440 sc->sc_uhb_supported = 1; 10441 break; 10442 case PCI_PRODUCT_INTEL_WL_22500_12: 10443 case PCI_PRODUCT_INTEL_WL_22500_17: 10444 sc->sc_fwname = IWX_SO_A_GF_A_FW; 10445 sc->sc_pnvm_name = IWX_SO_A_GF_A_PNVM; 10446 sc->sc_device_family = IWX_DEVICE_FAMILY_AX210; 10447 sc->sc_integrated = 1; 10448 sc->sc_ltr_delay = IWX_SOC_FLAGS_LTR_APPLY_DELAY_2500; 10449 sc->sc_low_latency_xtal = 1; 10450 sc->sc_xtal_latency = 12000; 10451 sc->sc_tx_with_siso_diversity = 0; 10452 sc->sc_uhb_supported = 0; 10453 sc->sc_imr_enabled = 1; 10454 break; 10455 default: 10456 device_printf(dev, "unknown adapter type\n"); 10457 return (ENXIO); 10458 } 10459 10460 cfg = iwx_find_device_cfg(sc); 10461 DPRINTF(("%s: cfg=%p\n", __func__, cfg)); 10462 if (cfg) { 10463 sc->sc_fwname = cfg->fw_name; 10464 sc->sc_pnvm_name = cfg->pnvm_name; 10465 sc->sc_tx_with_siso_diversity = cfg->tx_with_siso_diversity; 10466 sc->sc_uhb_supported = cfg->uhb_supported; 10467 if (cfg->xtal_latency) { 10468 sc->sc_xtal_latency = cfg->xtal_latency; 10469 sc->sc_low_latency_xtal = cfg->low_latency_xtal; 10470 } 10471 } 10472 10473 sc->mac_addr_from_csr = 0x380; /* differs on BZ hw generation */ 10474 10475 if (sc->sc_device_family >= IWX_DEVICE_FAMILY_AX210) { 10476 sc->sc_umac_prph_offset = 0x300000; 10477 sc->max_tfd_queue_size = IWX_TFD_QUEUE_SIZE_MAX_GEN3; 10478 } else 10479 sc->max_tfd_queue_size = IWX_TFD_QUEUE_SIZE_MAX; 10480 10481 /* Allocate DMA memory for loading firmware. */ 10482 if (sc->sc_device_family >= IWX_DEVICE_FAMILY_AX210) 10483 ctxt_info_size = sizeof(struct iwx_context_info_gen3); 10484 else 10485 ctxt_info_size = sizeof(struct iwx_context_info); 10486 err = iwx_dma_contig_alloc(sc->sc_dmat, &sc->ctxt_info_dma, 10487 ctxt_info_size, 1); 10488 if (err) { 10489 device_printf(dev, 10490 "could not allocate memory for loading firmware\n"); 10491 return (ENXIO); 10492 } 10493 10494 if (sc->sc_device_family >= IWX_DEVICE_FAMILY_AX210) { 10495 err = iwx_dma_contig_alloc(sc->sc_dmat, &sc->prph_scratch_dma, 10496 sizeof(struct iwx_prph_scratch), 1); 10497 if (err) { 10498 device_printf(dev, 10499 "could not allocate prph scratch memory\n"); 10500 goto fail1; 10501 } 10502 10503 /* 10504 * Allocate prph information. The driver doesn't use this. 10505 * We use the second half of this page to give the device 10506 * some dummy TR/CR tail pointers - which shouldn't be 10507 * necessary as we don't use this, but the hardware still 10508 * reads/writes there and we can't let it go do that with 10509 * a NULL pointer. 10510 */ 10511 KASSERT((sizeof(struct iwx_prph_info) < PAGE_SIZE / 2), 10512 ("iwx_prph_info has wrong size")); 10513 err = iwx_dma_contig_alloc(sc->sc_dmat, &sc->prph_info_dma, 10514 PAGE_SIZE, 1); 10515 if (err) { 10516 device_printf(dev, 10517 "could not allocate prph info memory\n"); 10518 goto fail1; 10519 } 10520 } 10521 10522 /* Allocate interrupt cause table (ICT).*/ 10523 err = iwx_dma_contig_alloc(sc->sc_dmat, &sc->ict_dma, 10524 IWX_ICT_SIZE, 1<<IWX_ICT_PADDR_SHIFT); 10525 if (err) { 10526 device_printf(dev, "could not allocate ICT table\n"); 10527 goto fail1; 10528 } 10529 10530 for (txq_i = 0; txq_i < nitems(sc->txq); txq_i++) { 10531 err = iwx_alloc_tx_ring(sc, &sc->txq[txq_i], txq_i); 10532 if (err) { 10533 device_printf(dev, "could not allocate TX ring %d\n", 10534 txq_i); 10535 goto fail4; 10536 } 10537 } 10538 10539 err = iwx_alloc_rx_ring(sc, &sc->rxq); 10540 if (err) { 10541 device_printf(sc->sc_dev, "could not allocate RX ring\n"); 10542 goto fail4; 10543 } 10544 10545 #ifdef IWX_DEBUG 10546 SYSCTL_ADD_INT(device_get_sysctl_ctx(dev), 10547 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, "debug", 10548 CTLFLAG_RWTUN, &sc->sc_debug, 0, "bitmask to control debugging"); 10549 10550 SYSCTL_ADD_INT(device_get_sysctl_ctx(dev), 10551 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, "himark", 10552 CTLFLAG_RW, &iwx_himark, 0, "queues high watermark"); 10553 SYSCTL_ADD_INT(device_get_sysctl_ctx(dev), 10554 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, "lomark", 10555 CTLFLAG_RW, &iwx_lomark, 0, "queues low watermark"); 10556 10557 SYSCTL_ADD_INT(device_get_sysctl_ctx(dev), 10558 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, "qfullmsk", 10559 CTLFLAG_RD, &sc->qfullmsk, 0, "queue fullmask"); 10560 10561 SYSCTL_ADD_INT(device_get_sysctl_ctx(dev), 10562 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, "queue0", 10563 CTLFLAG_RD, &sc->txq[0].queued, 0, "queue 0"); 10564 SYSCTL_ADD_INT(device_get_sysctl_ctx(dev), 10565 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, "queue1", 10566 CTLFLAG_RD, &sc->txq[1].queued, 0, "queue 1"); 10567 SYSCTL_ADD_INT(device_get_sysctl_ctx(dev), 10568 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, "queue2", 10569 CTLFLAG_RD, &sc->txq[2].queued, 0, "queue 2"); 10570 SYSCTL_ADD_INT(device_get_sysctl_ctx(dev), 10571 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, "queue3", 10572 CTLFLAG_RD, &sc->txq[3].queued, 0, "queue 3"); 10573 SYSCTL_ADD_INT(device_get_sysctl_ctx(dev), 10574 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, "queue4", 10575 CTLFLAG_RD, &sc->txq[4].queued, 0, "queue 4"); 10576 SYSCTL_ADD_INT(device_get_sysctl_ctx(dev), 10577 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, "queue5", 10578 CTLFLAG_RD, &sc->txq[5].queued, 0, "queue 5"); 10579 SYSCTL_ADD_INT(device_get_sysctl_ctx(dev), 10580 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, "queue6", 10581 CTLFLAG_RD, &sc->txq[6].queued, 0, "queue 6"); 10582 SYSCTL_ADD_INT(device_get_sysctl_ctx(dev), 10583 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, "queue7", 10584 CTLFLAG_RD, &sc->txq[7].queued, 0, "queue 7"); 10585 #endif 10586 ic->ic_softc = sc; 10587 ic->ic_name = device_get_nameunit(sc->sc_dev); 10588 ic->ic_phytype = IEEE80211_T_OFDM; /* not only, but not used */ 10589 ic->ic_opmode = IEEE80211_M_STA; /* default to BSS mode */ 10590 10591 /* Set device capabilities. */ 10592 ic->ic_caps = 10593 IEEE80211_C_STA | 10594 IEEE80211_C_MONITOR | 10595 IEEE80211_C_WPA | /* WPA/RSN */ 10596 IEEE80211_C_WME | 10597 IEEE80211_C_PMGT | 10598 IEEE80211_C_SHSLOT | /* short slot time supported */ 10599 IEEE80211_C_SHPREAMBLE | /* short preamble supported */ 10600 IEEE80211_C_BGSCAN /* capable of bg scanning */ 10601 ; 10602 ic->ic_flags_ext = IEEE80211_FEXT_SCAN_OFFLOAD; 10603 /* Enable seqno offload */ 10604 ic->ic_flags_ext |= IEEE80211_FEXT_SEQNO_OFFLOAD; 10605 /* Don't send null data frames; let firmware do it */ 10606 ic->ic_flags_ext |= IEEE80211_FEXT_NO_NULLDATA; 10607 10608 ic->ic_txstream = 2; 10609 ic->ic_rxstream = 2; 10610 ic->ic_htcaps |= IEEE80211_HTC_HT 10611 | IEEE80211_HTCAP_SMPS_OFF 10612 | IEEE80211_HTCAP_SHORTGI20 /* short GI in 20MHz */ 10613 | IEEE80211_HTCAP_SHORTGI40 /* short GI in 40MHz */ 10614 | IEEE80211_HTCAP_CHWIDTH40 /* 40MHz channel width*/ 10615 | IEEE80211_HTC_AMPDU /* tx A-MPDU */ 10616 // | IEEE80211_HTC_RX_AMSDU_AMPDU /* TODO: hw reorder */ 10617 | IEEE80211_HTCAP_MAXAMSDU_3839; /* max A-MSDU length */ 10618 10619 ic->ic_cryptocaps |= IEEE80211_CRYPTO_AES_CCM; 10620 10621 /* 10622 * XXX: setupcurchan() expects vhtcaps to be non-zero 10623 * https://bugs.freebsd.org/274156 10624 */ 10625 ic->ic_vht_cap.vht_cap_info |= IEEE80211_VHTCAP_MAX_MPDU_LENGTH_3895 10626 | IEEE80211_VHTCAP_SHORT_GI_80 10627 | 3 << IEEE80211_VHTCAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK_S 10628 | IEEE80211_VHTCAP_RX_ANTENNA_PATTERN 10629 | IEEE80211_VHTCAP_TX_ANTENNA_PATTERN; 10630 10631 ic->ic_flags_ext |= IEEE80211_FEXT_VHT; 10632 int mcsmap = IEEE80211_VHT_MCS_SUPPORT_0_9 << 0 | 10633 IEEE80211_VHT_MCS_SUPPORT_0_9 << 2 | 10634 IEEE80211_VHT_MCS_NOT_SUPPORTED << 4 | 10635 IEEE80211_VHT_MCS_NOT_SUPPORTED << 6 | 10636 IEEE80211_VHT_MCS_NOT_SUPPORTED << 8 | 10637 IEEE80211_VHT_MCS_NOT_SUPPORTED << 10 | 10638 IEEE80211_VHT_MCS_NOT_SUPPORTED << 12 | 10639 IEEE80211_VHT_MCS_NOT_SUPPORTED << 14; 10640 ic->ic_vht_cap.supp_mcs.tx_mcs_map = htole16(mcsmap); 10641 ic->ic_vht_cap.supp_mcs.rx_mcs_map = htole16(mcsmap); 10642 10643 callout_init_mtx(&sc->watchdog_to, &sc->sc_mtx, 0); 10644 for (i = 0; i < nitems(sc->sc_rxba_data); i++) { 10645 struct iwx_rxba_data *rxba = &sc->sc_rxba_data[i]; 10646 rxba->baid = IWX_RX_REORDER_DATA_INVALID_BAID; 10647 rxba->sc = sc; 10648 for (j = 0; j < nitems(rxba->entries); j++) 10649 mbufq_init(&rxba->entries[j].frames, ifqmaxlen); 10650 } 10651 10652 /* Initialize to something to have a chance to get S:N values. */ 10653 sc->sc_noise = IWX_DEFAULT_NF; 10654 10655 sc->sc_preinit_hook.ich_func = iwx_attach_hook; 10656 sc->sc_preinit_hook.ich_arg = sc; 10657 if (config_intrhook_establish(&sc->sc_preinit_hook) != 0) { 10658 device_printf(dev, 10659 "config_intrhook_establish failed\n"); 10660 goto fail4; 10661 } 10662 10663 return (0); 10664 10665 fail4: 10666 while (--txq_i >= 0) 10667 iwx_free_tx_ring(sc, &sc->txq[txq_i]); 10668 iwx_free_rx_ring(sc, &sc->rxq); 10669 if (sc->ict_dma.vaddr != NULL) 10670 iwx_dma_contig_free(&sc->ict_dma); 10671 10672 fail1: 10673 iwx_dma_contig_free(&sc->ctxt_info_dma); 10674 iwx_dma_contig_free(&sc->prph_scratch_dma); 10675 iwx_dma_contig_free(&sc->prph_info_dma); 10676 return (ENXIO); 10677 } 10678 10679 static int 10680 iwx_detach(device_t dev) 10681 { 10682 struct iwx_softc *sc = device_get_softc(dev); 10683 int txq_i; 10684 10685 iwx_stop_device(sc); 10686 sc->sc_flags |= IWX_FLAG_SHUTDOWN; 10687 10688 taskqueue_drain_all(sc->sc_tq); 10689 taskqueue_free(sc->sc_tq); 10690 10691 ieee80211_ifdetach(&sc->sc_ic); 10692 10693 callout_drain(&sc->watchdog_to); 10694 10695 for (txq_i = 0; txq_i < nitems(sc->txq); txq_i++) 10696 iwx_free_tx_ring(sc, &sc->txq[txq_i]); 10697 iwx_free_rx_ring(sc, &sc->rxq); 10698 10699 if (sc->sc_fwp != NULL) { 10700 firmware_put(sc->sc_fwp, FIRMWARE_UNLOAD); 10701 sc->sc_fwp = NULL; 10702 } 10703 10704 if (sc->sc_pnvm != NULL) { 10705 firmware_put(sc->sc_pnvm, FIRMWARE_UNLOAD); 10706 sc->sc_pnvm = NULL; 10707 } 10708 10709 if (sc->sc_irq != NULL) { 10710 bus_teardown_intr(dev, sc->sc_irq, sc->sc_ih); 10711 bus_release_resource(dev, SYS_RES_IRQ, 10712 rman_get_rid(sc->sc_irq), sc->sc_irq); 10713 pci_release_msi(dev); 10714 } 10715 if (sc->sc_mem != NULL) 10716 bus_release_resource(dev, SYS_RES_MEMORY, 10717 rman_get_rid(sc->sc_mem), sc->sc_mem); 10718 10719 IWX_LOCK_DESTROY(sc); 10720 10721 return (0); 10722 } 10723 10724 static void 10725 iwx_radiotap_attach(struct iwx_softc *sc) 10726 { 10727 struct ieee80211com *ic = &sc->sc_ic; 10728 10729 IWX_DPRINTF(sc, IWX_DEBUG_RESET | IWX_DEBUG_TRACE, 10730 "->%s begin\n", __func__); 10731 10732 ieee80211_radiotap_attach(ic, 10733 &sc->sc_txtap.wt_ihdr, sizeof(sc->sc_txtap), 10734 IWX_TX_RADIOTAP_PRESENT, 10735 &sc->sc_rxtap.wr_ihdr, sizeof(sc->sc_rxtap), 10736 IWX_RX_RADIOTAP_PRESENT); 10737 10738 IWX_DPRINTF(sc, IWX_DEBUG_RESET | IWX_DEBUG_TRACE, 10739 "->%s end\n", __func__); 10740 } 10741 10742 struct ieee80211vap * 10743 iwx_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit, 10744 enum ieee80211_opmode opmode, int flags, 10745 const uint8_t bssid[IEEE80211_ADDR_LEN], 10746 const uint8_t mac[IEEE80211_ADDR_LEN]) 10747 { 10748 struct iwx_vap *ivp; 10749 struct ieee80211vap *vap; 10750 10751 if (!TAILQ_EMPTY(&ic->ic_vaps)) /* only one at a time */ 10752 return NULL; 10753 ivp = malloc(sizeof(struct iwx_vap), M_80211_VAP, M_WAITOK | M_ZERO); 10754 vap = &ivp->iv_vap; 10755 ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid); 10756 vap->iv_bmissthreshold = 10; /* override default */ 10757 /* Override with driver methods. */ 10758 ivp->iv_newstate = vap->iv_newstate; 10759 vap->iv_newstate = iwx_newstate; 10760 10761 ivp->id = IWX_DEFAULT_MACID; 10762 ivp->color = IWX_DEFAULT_COLOR; 10763 10764 ivp->have_wme = TRUE; 10765 ivp->ps_disabled = FALSE; 10766 10767 vap->iv_ampdu_rxmax = IEEE80211_HTCAP_MAXRXAMPDU_64K; 10768 vap->iv_ampdu_density = IEEE80211_HTCAP_MPDUDENSITY_4; 10769 10770 /* h/w crypto support */ 10771 vap->iv_key_alloc = iwx_key_alloc; 10772 vap->iv_key_delete = iwx_key_delete; 10773 vap->iv_key_set = iwx_key_set; 10774 vap->iv_key_update_begin = iwx_key_update_begin; 10775 vap->iv_key_update_end = iwx_key_update_end; 10776 10777 ieee80211_ratectl_init(vap); 10778 /* Complete setup. */ 10779 ieee80211_vap_attach(vap, ieee80211_media_change, 10780 ieee80211_media_status, mac); 10781 ic->ic_opmode = opmode; 10782 10783 return vap; 10784 } 10785 10786 static void 10787 iwx_vap_delete(struct ieee80211vap *vap) 10788 { 10789 struct iwx_vap *ivp = IWX_VAP(vap); 10790 10791 ieee80211_ratectl_deinit(vap); 10792 ieee80211_vap_detach(vap); 10793 free(ivp, M_80211_VAP); 10794 } 10795 10796 static void 10797 iwx_parent(struct ieee80211com *ic) 10798 { 10799 struct iwx_softc *sc = ic->ic_softc; 10800 IWX_LOCK(sc); 10801 10802 if (sc->sc_flags & IWX_FLAG_HW_INITED) { 10803 iwx_stop(sc); 10804 sc->sc_flags &= ~IWX_FLAG_HW_INITED; 10805 } else { 10806 iwx_init(sc); 10807 ieee80211_start_all(ic); 10808 } 10809 IWX_UNLOCK(sc); 10810 } 10811 10812 static int 10813 iwx_suspend(device_t dev) 10814 { 10815 struct iwx_softc *sc = device_get_softc(dev); 10816 struct ieee80211com *ic = &sc->sc_ic; 10817 10818 /* 10819 * Suspend everything first, then shutdown hardware if it's 10820 * still up. 10821 */ 10822 ieee80211_suspend_all(ic); 10823 10824 if (sc->sc_flags & IWX_FLAG_HW_INITED) { 10825 iwx_stop(sc); 10826 sc->sc_flags &= ~IWX_FLAG_HW_INITED; 10827 } 10828 return (0); 10829 } 10830 10831 static int 10832 iwx_resume(device_t dev) 10833 { 10834 struct iwx_softc *sc = device_get_softc(dev); 10835 struct ieee80211com *ic = &sc->sc_ic; 10836 10837 /* 10838 * We disable the RETRY_TIMEOUT register (0x41) to keep 10839 * PCI Tx retries from interfering with C3 CPU state. 10840 */ 10841 pci_write_config(dev, PCI_CFG_RETRY_TIMEOUT, 0x00, 1); 10842 10843 IWX_LOCK(sc); 10844 10845 /* Stop the hardware here if it's still thought of as "up" */ 10846 if (sc->sc_flags & IWX_FLAG_HW_INITED) { 10847 iwx_stop(sc); 10848 sc->sc_flags &= ~IWX_FLAG_HW_INITED; 10849 } 10850 10851 IWX_UNLOCK(sc); 10852 10853 /* Start the VAPs, which will bring the hardware back up again */ 10854 ieee80211_resume_all(ic); 10855 return (0); 10856 } 10857 10858 static void 10859 iwx_scan_start(struct ieee80211com *ic) 10860 { 10861 struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); 10862 struct iwx_softc *sc = ic->ic_softc; 10863 int err; 10864 10865 IWX_LOCK(sc); 10866 if ((ic->ic_flags_ext & IEEE80211_FEXT_BGSCAN) == 0) 10867 err = iwx_scan(sc); 10868 else 10869 err = iwx_bgscan(ic); 10870 IWX_UNLOCK(sc); 10871 if (err) 10872 ieee80211_cancel_scan(vap); 10873 10874 return; 10875 } 10876 10877 static void 10878 iwx_update_mcast(struct ieee80211com *ic) 10879 { 10880 } 10881 10882 static void 10883 iwx_scan_curchan(struct ieee80211_scan_state *ss, unsigned long maxdwell) 10884 { 10885 } 10886 10887 static void 10888 iwx_scan_mindwell(struct ieee80211_scan_state *ss) 10889 { 10890 } 10891 10892 static void 10893 iwx_scan_end(struct ieee80211com *ic) 10894 { 10895 iwx_endscan(ic->ic_softc); 10896 } 10897 10898 static void 10899 iwx_set_channel(struct ieee80211com *ic) 10900 { 10901 #if 0 10902 struct iwx_softc *sc = ic->ic_softc; 10903 struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); 10904 10905 IWX_DPRINTF(sc, IWX_DEBUG_NI , "%s:%d NOT IMPLEMENTED\n", __func__, __LINE__); 10906 iwx_phy_ctxt_task((void *)sc); 10907 #endif 10908 } 10909 10910 static void 10911 iwx_endscan_cb(void *arg, int pending) 10912 { 10913 struct iwx_softc *sc = arg; 10914 struct ieee80211com *ic = &sc->sc_ic; 10915 10916 DPRINTF(("scan ended\n")); 10917 ieee80211_scan_done(TAILQ_FIRST(&ic->ic_vaps)); 10918 } 10919 10920 static int 10921 iwx_wme_update(struct ieee80211com *ic) 10922 { 10923 return 0; 10924 } 10925 10926 static int 10927 iwx_raw_xmit(struct ieee80211_node *ni, struct mbuf *m, 10928 const struct ieee80211_bpf_params *params) 10929 { 10930 struct ieee80211com *ic = ni->ni_ic; 10931 struct iwx_softc *sc = ic->ic_softc; 10932 int err; 10933 10934 IWX_LOCK(sc); 10935 if (sc->sc_flags & IWX_FLAG_STA_ACTIVE) { 10936 err = iwx_tx(sc, m, ni); 10937 IWX_UNLOCK(sc); 10938 return err; 10939 } else { 10940 IWX_UNLOCK(sc); 10941 return EIO; 10942 } 10943 } 10944 10945 static int 10946 iwx_transmit(struct ieee80211com *ic, struct mbuf *m) 10947 { 10948 struct iwx_softc *sc = ic->ic_softc; 10949 int error; 10950 10951 // TODO: mbufq_enqueue in iwm 10952 // TODO dequeue in iwm_start, counters, locking 10953 IWX_LOCK(sc); 10954 error = mbufq_enqueue(&sc->sc_snd, m); 10955 if (error) { 10956 IWX_UNLOCK(sc); 10957 return (error); 10958 } 10959 10960 iwx_start(sc); 10961 IWX_UNLOCK(sc); 10962 return (0); 10963 } 10964 10965 static int 10966 iwx_ampdu_rx_start(struct ieee80211_node *ni, struct ieee80211_rx_ampdu *rap, 10967 int baparamset, int batimeout, int baseqctl) 10968 { 10969 struct ieee80211com *ic = ni->ni_ic; 10970 struct iwx_softc *sc = ic->ic_softc; 10971 int tid; 10972 10973 tid = _IEEE80211_MASKSHIFT(le16toh(baparamset), IEEE80211_BAPS_TID); 10974 sc->ni_rx_ba[tid].ba_winstart = 10975 _IEEE80211_MASKSHIFT(le16toh(baseqctl), IEEE80211_BASEQ_START); 10976 sc->ni_rx_ba[tid].ba_winsize = 10977 _IEEE80211_MASKSHIFT(le16toh(baparamset), IEEE80211_BAPS_BUFSIZ); 10978 sc->ni_rx_ba[tid].ba_timeout_val = batimeout; 10979 10980 if (sc->sc_rx_ba_sessions >= IWX_MAX_RX_BA_SESSIONS || 10981 tid >= IWX_MAX_TID_COUNT) 10982 return ENOSPC; 10983 10984 if (sc->ba_rx.start_tidmask & (1 << tid)) { 10985 DPRINTF(("%s: tid %d already added\n", __func__, tid)); 10986 return EBUSY; 10987 } 10988 DPRINTF(("%s: sc->ba_rx.start_tidmask=%x\n", __func__, sc->ba_rx.start_tidmask)); 10989 10990 sc->ba_rx.start_tidmask |= (1 << tid); 10991 DPRINTF(("%s: tid=%i\n", __func__, tid)); 10992 DPRINTF(("%s: ba_winstart=%i\n", __func__, sc->ni_rx_ba[tid].ba_winstart)); 10993 DPRINTF(("%s: ba_winsize=%i\n", __func__, sc->ni_rx_ba[tid].ba_winsize)); 10994 DPRINTF(("%s: ba_timeout_val=%i\n", __func__, sc->ni_rx_ba[tid].ba_timeout_val)); 10995 10996 taskqueue_enqueue(sc->sc_tq, &sc->ba_rx_task); 10997 10998 // TODO:misha move to ba_task (serialize) 10999 sc->sc_ampdu_rx_start(ni, rap, baparamset, batimeout, baseqctl); 11000 11001 return (0); 11002 } 11003 11004 static void 11005 iwx_ampdu_rx_stop(struct ieee80211_node *ni, struct ieee80211_rx_ampdu *rap) 11006 { 11007 return; 11008 } 11009 11010 /** 11011 * @brief Called by net80211 to request an A-MPDU session be established. 11012 * 11013 * This is called by net80211 to see if an A-MPDU session can be established. 11014 * However, the iwx(4) firmware will take care of establishing the BA 11015 * session for us. net80211 doesn't have to send any action frames here; 11016 * it just needs to plumb up the ampdu session once the BA has been sent. 11017 * 11018 * If we return 0 here then the firmware will set up the state but net80211 11019 * will not; so it's on us to actually complete it via a call to 11020 * ieee80211_ampdu_tx_request_active_ext() . 11021 * 11022 * @param ni ieee80211_node to establish A-MPDU session for 11023 * @param tap pointer to the per-TID state struct 11024 * @param dialogtoken dialogtoken field from the BA request 11025 * @param baparamset baparamset field from the BA request 11026 * @param batimeout batimeout field from the BA request 11027 * 11028 * @returns 0 so net80211 doesn't send the BA action frame to establish A-MPDU. 11029 */ 11030 static int 11031 iwx_addba_request(struct ieee80211_node *ni, struct ieee80211_tx_ampdu *tap, 11032 int dialogtoken, int baparamset, int batimeout) 11033 { 11034 struct iwx_softc *sc = ni->ni_ic->ic_softc; 11035 int tid; 11036 11037 tid = _IEEE80211_MASKSHIFT(le16toh(baparamset), IEEE80211_BAPS_TID); 11038 IWX_DPRINTF(sc, IWX_DEBUG_AMPDU_MGMT, 11039 "%s: queuing AMPDU start on tid %i\n", __func__, tid); 11040 11041 /* There's no nice way right now to tell net80211 that we're in the 11042 * middle of an asynchronous ADDBA setup session. So, bump the timeout 11043 * to hz ticks, hopefully we'll get a response by then. 11044 */ 11045 tap->txa_nextrequest = ticks + hz; 11046 11047 IWX_LOCK(sc); 11048 sc->ba_tx.start_tidmask |= (1 << tid); 11049 IWX_UNLOCK(sc); 11050 11051 taskqueue_enqueue(sc->sc_tq, &sc->ba_tx_task); 11052 11053 return (0); 11054 } 11055 11056 11057 static int 11058 iwx_addba_response(struct ieee80211_node *ni, struct ieee80211_tx_ampdu *tap, 11059 int code, int baparamset, int batimeout) 11060 { 11061 return 0; 11062 } 11063 11064 static void 11065 iwx_key_update_begin(struct ieee80211vap *vap) 11066 { 11067 return; 11068 } 11069 11070 static void 11071 iwx_key_update_end(struct ieee80211vap *vap) 11072 { 11073 return; 11074 } 11075 11076 static int 11077 iwx_key_alloc(struct ieee80211vap *vap, struct ieee80211_key *k, 11078 ieee80211_keyix *keyix, ieee80211_keyix *rxkeyix) 11079 { 11080 11081 if (k->wk_cipher->ic_cipher == IEEE80211_CIPHER_AES_CCM) { 11082 return (1); 11083 } 11084 11085 if (ieee80211_is_key_unicast(vap, k)) { 11086 *keyix = 0; /* NB: use key index 0 for ucast key */ 11087 } else if (ieee80211_is_key_global(vap, k)) { 11088 *keyix = ieee80211_crypto_get_key_wepidx(vap, k); 11089 } else { 11090 net80211_vap_printf(vap, "%s: invalid crypto key type\n", 11091 __func__); 11092 return (0); 11093 } 11094 *rxkeyix = IEEE80211_KEYIX_NONE; /* XXX maybe *keyix? */ 11095 return (1); 11096 } 11097 11098 static int 11099 iwx_key_set(struct ieee80211vap *vap, const struct ieee80211_key *k) 11100 { 11101 struct ieee80211com *ic = vap->iv_ic; 11102 struct iwx_softc *sc = ic->ic_softc; 11103 struct iwx_add_sta_key_cmd cmd; 11104 uint32_t status; 11105 int err; 11106 int id; 11107 11108 if (k->wk_cipher->ic_cipher != IEEE80211_CIPHER_AES_CCM) { 11109 return 1; 11110 } 11111 11112 /* 11113 * Keys are stored in 'ni' so 'k' is valid if 'ni' is valid. 11114 * Currently we only implement station mode where 'ni' is always 11115 * ic->ic_bss so there is no need to validate arguments beyond this: 11116 */ 11117 11118 memset(&cmd, 0, sizeof(cmd)); 11119 11120 if (ieee80211_is_key_global(vap, k)) { 11121 id = ieee80211_crypto_get_key_wepidx(vap, k); 11122 IWX_DPRINTF(sc, IWX_DEBUG_KEYMGMT, "%s: adding group key\n", 11123 __func__); 11124 } else if (ieee80211_is_key_unicast(vap, k)) { 11125 IWX_DPRINTF(sc, IWX_DEBUG_KEYMGMT, "%s: adding key\n", 11126 __func__); 11127 id = 0; /* net80211 currently only supports unicast key 0 */ 11128 } else { 11129 net80211_vap_printf(vap, "%s: unknown key type\n", __func__); 11130 return (ENXIO); 11131 } 11132 11133 IWX_LOCK(sc); 11134 11135 cmd.common.key_flags = htole16(IWX_STA_KEY_FLG_CCM | 11136 IWX_STA_KEY_FLG_WEP_KEY_MAP | 11137 ((id << IWX_STA_KEY_FLG_KEYID_POS) & 11138 IWX_STA_KEY_FLG_KEYID_MSK)); 11139 if (ieee80211_is_key_global(vap, k)) { 11140 cmd.common.key_offset = 1; 11141 cmd.common.key_flags |= htole16(IWX_STA_KEY_MULTICAST); 11142 } else if (ieee80211_is_key_unicast(vap, k)) { 11143 cmd.common.key_offset = 0; 11144 } else { 11145 net80211_vap_printf(vap, "%s: unknown key type\n", __func__); 11146 IWX_UNLOCK(sc); 11147 return (ENXIO); 11148 } 11149 memcpy(cmd.common.key, ieee80211_crypto_get_key_data(k), 11150 MIN(sizeof(cmd.common.key), ieee80211_crypto_get_key_len(k))); 11151 IWX_DPRINTF(sc, IWX_DEBUG_KEYMGMT, "%s: key: id=%d, len=%i, key=%*D\n", 11152 __func__, id, 11153 ieee80211_crypto_get_key_len(k), 11154 ieee80211_crypto_get_key_len(k), 11155 (const unsigned char *) ieee80211_crypto_get_key_data(k), ""); 11156 cmd.common.sta_id = IWX_STATION_ID; 11157 11158 cmd.transmit_seq_cnt = htole64(k->wk_keytsc); 11159 IWX_DPRINTF(sc, IWX_DEBUG_KEYMGMT, "%s: k->wk_keytsc=%" PRIu64 "\n", 11160 __func__, k->wk_keytsc); 11161 11162 status = IWX_ADD_STA_SUCCESS; 11163 err = iwx_send_cmd_pdu_status(sc, IWX_ADD_STA_KEY, sizeof(cmd), &cmd, 11164 &status); 11165 if (!err && (status & IWX_ADD_STA_STATUS_MASK) != IWX_ADD_STA_SUCCESS) 11166 err = EIO; 11167 if (err) { 11168 net80211_vap_printf(vap, 11169 "%s: can't set wpa2 keys (error %d)\n", __func__, err); 11170 IWX_UNLOCK(sc); 11171 return err; 11172 } else 11173 IWX_DPRINTF(sc, IWX_DEBUG_KEYMGMT, 11174 "%s: key added successfully\n", __func__); 11175 IWX_UNLOCK(sc); 11176 return (1); 11177 } 11178 11179 static int 11180 iwx_key_delete(struct ieee80211vap *vap, const struct ieee80211_key *k) 11181 { 11182 /* 11183 * Note: since there's no key allocations to track - it's either 11184 * the 4 static WEP keys or the single unicast key - there's nothing 11185 * else to do here. 11186 * 11187 * This would need some further work to support IBSS/mesh/AP modes. 11188 */ 11189 return (1); 11190 } 11191 11192 static device_method_t iwx_pci_methods[] = { 11193 /* Device interface */ 11194 DEVMETHOD(device_probe, iwx_probe), 11195 DEVMETHOD(device_attach, iwx_attach), 11196 DEVMETHOD(device_detach, iwx_detach), 11197 DEVMETHOD(device_suspend, iwx_suspend), 11198 DEVMETHOD(device_resume, iwx_resume), 11199 11200 DEVMETHOD_END 11201 }; 11202 11203 static driver_t iwx_pci_driver = { 11204 "iwx", 11205 iwx_pci_methods, 11206 sizeof (struct iwx_softc) 11207 }; 11208 11209 DRIVER_MODULE(iwx, pci, iwx_pci_driver, NULL, NULL); 11210 MODULE_PNP_INFO("U16:device;D:#;T:vendor=0x8086", pci, iwx_pci_driver, 11211 iwx_devices, nitems(iwx_devices)); 11212 MODULE_DEPEND(iwx, firmware, 1, 1, 1); 11213 MODULE_DEPEND(iwx, pci, 1, 1, 1); 11214 MODULE_DEPEND(iwx, wlan, 1, 1, 1); 11215