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