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