Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge tag 'iwlwifi-next-for-kalle-2019-02-14' of git://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi/iwlwifi-next

Fourth batch of iwlwifi patches intended for v5.1

* Work on the new debugging infrastructure continues;
* FTM (Fine Timing Measurement) initiator and responder implementation;
* Support for a new device family started;
* Bump supported FW API to 46;
* General bugfixes;
* Other cleanups;

+2352 -302
+73 -20
drivers/net/wireless/intel/iwlwifi/cfg/22000.c
··· 6 6 * GPL LICENSE SUMMARY 7 7 * 8 8 * Copyright(c) 2015-2017 Intel Deutschland GmbH 9 - * Copyright (C) 2018 Intel Corporation 9 + * Copyright (C) 2018-2019 Intel Corporation 10 10 * 11 11 * This program is free software; you can redistribute it and/or modify 12 12 * it under the terms of version 2 of the GNU General Public License as ··· 20 20 * BSD LICENSE 21 21 * 22 22 * Copyright(c) 2015-2017 Intel Deutschland GmbH 23 - * Copyright (C) 2018 Intel Corporation 23 + * Copyright (C) 2018-2019 Intel Corporation 24 24 * All rights reserved. 25 25 * 26 26 * Redistribution and use in source and binary forms, with or without ··· 56 56 #include "iwl-config.h" 57 57 58 58 /* Highest firmware API version supported */ 59 - #define IWL_22000_UCODE_API_MAX 44 59 + #define IWL_22000_UCODE_API_MAX 46 60 60 61 61 /* Lowest firmware API version supported */ 62 62 #define IWL_22000_UCODE_API_MIN 39 ··· 79 79 #define IWL_22000_HR_B_F0_FW_PRE "iwlwifi-Qu-b0-hr-b0-" 80 80 #define IWL_22000_QU_B_HR_B_FW_PRE "iwlwifi-Qu-b0-hr-b0-" 81 81 #define IWL_22000_HR_B_FW_PRE "iwlwifi-QuQnj-b0-hr-b0-" 82 - #define IWL_22000_JF_B0_FW_PRE "iwlwifi-QuQnj-a0-jf-b0-" 83 82 #define IWL_22000_HR_A0_FW_PRE "iwlwifi-QuQnj-a0-hr-a0-" 84 83 #define IWL_22000_SU_Z0_FW_PRE "iwlwifi-su-z0-" 85 84 #define IWL_QU_B_JF_B_FW_PRE "iwlwifi-Qu-b0-jf-b0-" 85 + #define IWL_QNJ_B_JF_B_FW_PRE "iwlwifi-QuQnj-b0-jf-b0-" 86 86 #define IWL_CC_A_FW_PRE "iwlwifi-cc-a0-" 87 + #define IWL_22000_SO_A_JF_B_FW_PRE "iwlwifi-so-a0-jf-b0-" 88 + #define IWL_22000_SO_A_HR_B_FW_PRE "iwlwifi-so-a0-hr-b0-" 89 + #define IWL_22000_SO_A_GF_A_FW_PRE "iwlwifi-so-a0-gf-a0-" 90 + #define IWL_22000_TY_A_GF_A_FW_PRE "iwlwifi-ty-a0-gf-a0-" 87 91 88 92 #define IWL_22000_HR_MODULE_FIRMWARE(api) \ 89 93 IWL_22000_HR_FW_PRE __stringify(api) ".ucode" ··· 101 97 IWL_22000_QU_B_HR_B_FW_PRE __stringify(api) ".ucode" 102 98 #define IWL_22000_HR_B_QNJ_MODULE_FIRMWARE(api) \ 103 99 IWL_22000_HR_B_FW_PRE __stringify(api) ".ucode" 104 - #define IWL_22000_JF_B0_QNJ_MODULE_FIRMWARE(api) \ 105 - IWL_22000_JF_B0_FW_PRE __stringify(api) ".ucode" 106 100 #define IWL_22000_HR_A0_QNJ_MODULE_FIRMWARE(api) \ 107 101 IWL_22000_HR_A0_FW_PRE __stringify(api) ".ucode" 108 102 #define IWL_22000_SU_Z0_MODULE_FIRMWARE(api) \ 109 103 IWL_22000_SU_Z0_FW_PRE __stringify(api) ".ucode" 110 104 #define IWL_QU_B_JF_B_MODULE_FIRMWARE(api) \ 111 105 IWL_QU_B_JF_B_FW_PRE __stringify(api) ".ucode" 112 - #define IWL_CC_A_MODULE_FIRMWARE(api) \ 106 + #define IWL_QU_B_JF_B_MODULE_FIRMWARE(api) \ 107 + IWL_QU_B_JF_B_FW_PRE __stringify(api) ".ucode" 108 + #define IWL_QNJ_B_JF_B_MODULE_FIRMWARE(api) \ 109 + IWL_QNJ_B_JF_B_FW_PRE __stringify(api) ".ucode" 110 + #define IWL_CC_A_MODULE_FIRMWARE(api) \ 113 111 IWL_CC_A_FW_PRE __stringify(api) ".ucode" 112 + #define IWL_22000_SO_A_JF_B_MODULE_FIRMWARE(api) \ 113 + IWL_22000_SO_A_JF_B_FW_PRE __stringify(api) ".ucode" 114 + #define IWL_22000_SO_A_HR_B_MODULE_FIRMWARE(api) \ 115 + IWL_22000_SO_A_HR_B_FW_PRE __stringify(api) ".ucode" 116 + #define IWL_22000_SO_A_GF_A_MODULE_FIRMWARE(api) \ 117 + IWL_22000_SO_A_GF_A_FW_PRE __stringify(api) ".ucode" 118 + #define IWL_22000_TY_A_GF_A_MODULE_FIRMWARE(api) \ 119 + IWL_22000_TY_A_GF_A_FW_PRE __stringify(api) ".ucode" 114 120 115 121 static const struct iwl_base_params iwl_22000_base_params = { 116 122 .eeprom_size = OTP_LOW_IMAGE_SIZE_32K, ··· 181 167 .d3_debug_data_base_addr = 0x401000, \ 182 168 .d3_debug_data_length = 60 * 1024 183 169 170 + #define IWL_DEVICE_AX200_COMMON \ 171 + IWL_DEVICE_22000_COMMON, \ 172 + .umac_prph_offset = 0x300000 173 + 184 174 #define IWL_DEVICE_22500 \ 185 175 IWL_DEVICE_22000_COMMON, \ 186 176 .device_family = IWL_DEVICE_FAMILY_22000, \ ··· 196 178 .device_family = IWL_DEVICE_FAMILY_22560, \ 197 179 .base_params = &iwl_22560_base_params, \ 198 180 .csr = &iwl_csr_v2 181 + 182 + #define IWL_DEVICE_AX210 \ 183 + IWL_DEVICE_AX200_COMMON, \ 184 + .device_family = IWL_DEVICE_FAMILY_AX210, \ 185 + .base_params = &iwl_22000_base_params, \ 186 + .csr = &iwl_csr_v1, \ 187 + .min_txq_size = 128 199 188 200 189 const struct iwl_cfg iwl22000_2ac_cfg_hr = { 201 190 .name = "Intel(R) Dual Band Wireless AC 22000", ··· 303 278 IWL_DEVICE_22500, 304 279 }; 305 280 281 + const struct iwl_cfg iwl9560_2ac_cfg_qnj_jf_b0 = { 282 + .name = "Intel(R) Wireless-AC 9560 160MHz", 283 + .fw_name_pre = IWL_QNJ_B_JF_B_FW_PRE, 284 + IWL_DEVICE_22500, 285 + /* 286 + * This device doesn't support receiving BlockAck with a large bitmap 287 + * so we need to restrict the size of transmitted aggregation to the 288 + * HT size; mac80211 would otherwise pick the HE max (256) by default. 289 + */ 290 + .max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT, 291 + }; 292 + 306 293 const struct iwl_cfg killer1550i_2ac_cfg_qu_b0_jf_b0 = { 307 294 .name = "Killer (R) Wireless-AC 1550i Wireless Network Adapter (9560NGW)", 308 295 .fw_name_pre = IWL_QU_B_JF_B_FW_PRE, ··· 387 350 .max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT, 388 351 }; 389 352 390 - const struct iwl_cfg iwl22000_2ax_cfg_qnj_jf_b0 = { 391 - .name = "Intel(R) Dual Band Wireless AX 22000", 392 - .fw_name_pre = IWL_22000_JF_B0_FW_PRE, 393 - IWL_DEVICE_22500, 394 - /* 395 - * This device doesn't support receiving BlockAck with a large bitmap 396 - * so we need to restrict the size of transmitted aggregation to the 397 - * HT size; mac80211 would otherwise pick the HE max (256) by default. 398 - */ 399 - .max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT, 400 - }; 401 - 402 353 const struct iwl_cfg iwl22000_2ax_cfg_qnj_hr_a0 = { 403 354 .name = "Intel(R) Dual Band Wireless AX 22000", 404 355 .fw_name_pre = IWL_22000_HR_A0_FW_PRE, ··· 412 387 .max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT, 413 388 }; 414 389 390 + const struct iwl_cfg iwlax210_2ax_cfg_so_jf_a0 = { 391 + .name = "Intel(R) Wireless-AC 9560 160MHz", 392 + .fw_name_pre = IWL_22000_SO_A_JF_B_FW_PRE, 393 + IWL_DEVICE_AX210, 394 + }; 395 + 396 + const struct iwl_cfg iwlax210_2ax_cfg_so_hr_a0 = { 397 + .name = "Intel(R) Wi-Fi 6 AX201 160MHz", 398 + .fw_name_pre = IWL_22000_SO_A_HR_B_FW_PRE, 399 + IWL_DEVICE_AX210, 400 + }; 401 + 402 + const struct iwl_cfg iwlax210_2ax_cfg_so_gf_a0 = { 403 + .name = "Intel(R) Wi-Fi 7 AX211 160MHz", 404 + .fw_name_pre = IWL_22000_SO_A_GF_A_FW_PRE, 405 + IWL_DEVICE_AX210, 406 + }; 407 + 408 + const struct iwl_cfg iwlax210_2ax_cfg_ty_gf_a0 = { 409 + .name = "Intel(R) Wi-Fi 7 AX210 160MHz", 410 + .fw_name_pre = IWL_22000_TY_A_GF_A_FW_PRE, 411 + IWL_DEVICE_AX210, 412 + }; 413 + 415 414 MODULE_FIRMWARE(IWL_22000_HR_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX)); 416 415 MODULE_FIRMWARE(IWL_22000_JF_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX)); 417 416 MODULE_FIRMWARE(IWL_22000_HR_A_F0_QNJ_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX)); 418 417 MODULE_FIRMWARE(IWL_22000_HR_B_F0_QNJ_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX)); 419 418 MODULE_FIRMWARE(IWL_22000_HR_B_QNJ_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX)); 420 - MODULE_FIRMWARE(IWL_22000_JF_B0_QNJ_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX)); 421 419 MODULE_FIRMWARE(IWL_22000_HR_A0_QNJ_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX)); 422 420 MODULE_FIRMWARE(IWL_22000_SU_Z0_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX)); 423 421 MODULE_FIRMWARE(IWL_QU_B_JF_B_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX)); 422 + MODULE_FIRMWARE(IWL_QNJ_B_JF_B_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX)); 424 423 MODULE_FIRMWARE(IWL_CC_A_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX)); 424 + MODULE_FIRMWARE(IWL_22000_SO_A_JF_B_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX)); 425 + MODULE_FIRMWARE(IWL_22000_SO_A_HR_B_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX)); 426 + MODULE_FIRMWARE(IWL_22000_SO_A_GF_A_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX)); 427 + MODULE_FIRMWARE(IWL_22000_TY_A_GF_A_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX));
+1 -1
drivers/net/wireless/intel/iwlwifi/cfg/9000.c
··· 57 57 #include "fw/file.h" 58 58 59 59 /* Highest firmware API version supported */ 60 - #define IWL9000_UCODE_API_MAX 44 60 + #define IWL9000_UCODE_API_MAX 46 61 61 62 62 /* Lowest firmware API version supported */ 63 63 #define IWL9000_UCODE_API_MIN 30
+7 -7
drivers/net/wireless/intel/iwlwifi/dvm/main.c
··· 1881 1881 return pos; 1882 1882 } 1883 1883 1884 - if (!(iwl_have_debug_level(IWL_DL_FW_ERRORS)) && !full_log) 1884 + if (!(iwl_have_debug_level(IWL_DL_FW)) && !full_log) 1885 1885 size = (size > DEFAULT_DUMP_EVENT_LOG_ENTRIES) 1886 1886 ? DEFAULT_DUMP_EVENT_LOG_ENTRIES : size; 1887 1887 IWL_ERR(priv, "Start IWL Event Log Dump: display last %u entries\n", ··· 1897 1897 if (!*buf) 1898 1898 return -ENOMEM; 1899 1899 } 1900 - if (iwl_have_debug_level(IWL_DL_FW_ERRORS) || full_log) { 1900 + if (iwl_have_debug_level(IWL_DL_FW) || full_log) { 1901 1901 /* 1902 1902 * if uCode has wrapped back to top of log, 1903 1903 * start at the oldest entry, ··· 1927 1927 unsigned int reload_msec; 1928 1928 unsigned long reload_jiffies; 1929 1929 1930 - if (iwl_have_debug_level(IWL_DL_FW_ERRORS)) 1930 + if (iwl_have_debug_level(IWL_DL_FW)) 1931 1931 iwl_print_rx_config_cmd(priv, IWL_RXON_CTX_BSS); 1932 1932 1933 1933 /* uCode is no longer loaded. */ ··· 1965 1965 1966 1966 if (!test_bit(STATUS_EXIT_PENDING, &priv->status)) { 1967 1967 if (iwlwifi_mod_params.fw_restart) { 1968 - IWL_DEBUG_FW_ERRORS(priv, 1969 - "Restarting adapter due to uCode error.\n"); 1968 + IWL_DEBUG_FW(priv, 1969 + "Restarting adapter due to uCode error.\n"); 1970 1970 queue_work(priv->workqueue, &priv->restart); 1971 1971 } else 1972 - IWL_DEBUG_FW_ERRORS(priv, 1973 - "Detected FW error, but not restarting\n"); 1972 + IWL_DEBUG_FW(priv, 1973 + "Detected FW error, but not restarting\n"); 1974 1974 } 1975 1975 } 1976 1976
+32
drivers/net/wireless/intel/iwlwifi/fw/acpi.c
··· 6 6 * GPL LICENSE SUMMARY 7 7 * 8 8 * Copyright(c) 2017 Intel Deutschland GmbH 9 + * Copyright (C) 2019 Intel Corporation 9 10 * 10 11 * This program is free software; you can redistribute it and/or modify 11 12 * it under the terms of version 2 of the GNU General Public License as ··· 27 26 * BSD LICENSE 28 27 * 29 28 * Copyright(c) 2017 Intel Deutschland GmbH 29 + * Copyright (C) 2019 Intel Corporation 30 30 * All rights reserved. 31 31 * 32 32 * Redistribution and use in source and binary forms, with or without ··· 207 205 return dflt_pwr_limit; 208 206 } 209 207 IWL_EXPORT_SYMBOL(iwl_acpi_get_pwr_limit); 208 + 209 + int iwl_acpi_get_eckv(struct device *dev, u32 *extl_clk) 210 + { 211 + union acpi_object *wifi_pkg, *data; 212 + int ret; 213 + 214 + data = iwl_acpi_get_object(dev, ACPI_ECKV_METHOD); 215 + if (IS_ERR(data)) 216 + return PTR_ERR(data); 217 + 218 + wifi_pkg = iwl_acpi_get_wifi_pkg(dev, data, ACPI_ECKV_WIFI_DATA_SIZE); 219 + if (IS_ERR(wifi_pkg)) { 220 + ret = PTR_ERR(wifi_pkg); 221 + goto out_free; 222 + } 223 + 224 + if (wifi_pkg->package.elements[1].type != ACPI_TYPE_INTEGER) { 225 + ret = -EINVAL; 226 + goto out_free; 227 + } 228 + 229 + *extl_clk = wifi_pkg->package.elements[1].integer.value; 230 + 231 + ret = 0; 232 + 233 + out_free: 234 + kfree(data); 235 + return ret; 236 + } 237 + IWL_EXPORT_SYMBOL(iwl_acpi_get_eckv);
+20 -2
drivers/net/wireless/intel/iwlwifi/fw/acpi.h
··· 6 6 * GPL LICENSE SUMMARY 7 7 * 8 8 * Copyright(c) 2017 Intel Deutschland GmbH 9 - * Copyright(c) 2018 Intel Corporation 9 + * Copyright(c) 2018 - 2019 Intel Corporation 10 10 * 11 11 * This program is free software; you can redistribute it and/or modify 12 12 * it under the terms of version 2 of the GNU General Public License as ··· 27 27 * BSD LICENSE 28 28 * 29 29 * Copyright(c) 2017 Intel Deutschland GmbH 30 - * Copyright(c) 2018 Intel Corporation 30 + * Copyright(c) 2018 - 2019 Intel Corporation 31 31 * All rights reserved. 32 32 * 33 33 * Redistribution and use in source and binary forms, with or without ··· 67 67 #define ACPI_WGDS_METHOD "WGDS" 68 68 #define ACPI_WRDD_METHOD "WRDD" 69 69 #define ACPI_SPLC_METHOD "SPLC" 70 + #define ACPI_ECKV_METHOD "ECKV" 70 71 71 72 #define ACPI_WIFI_DOMAIN (0x07) 72 73 ··· 87 86 #define ACPI_WGDS_WIFI_DATA_SIZE 19 88 87 #define ACPI_WRDD_WIFI_DATA_SIZE 2 89 88 #define ACPI_SPLC_WIFI_DATA_SIZE 2 89 + #define ACPI_ECKV_WIFI_DATA_SIZE 2 90 90 91 91 #define ACPI_WGDS_NUM_BANDS 2 92 92 #define ACPI_WGDS_TABLE_SIZE 3 ··· 111 109 112 110 u64 iwl_acpi_get_pwr_limit(struct device *dev); 113 111 112 + /* 113 + * iwl_acpi_get_eckv - read external clock validation from ACPI, if available 114 + * 115 + * @dev: the struct device 116 + * @extl_clk: output var (2 bytes) that will get the clk indication. 117 + * 118 + * This function tries to read the external clock indication 119 + * from ACPI if available. 120 + */ 121 + int iwl_acpi_get_eckv(struct device *dev, u32 *extl_clk); 122 + 114 123 #else /* CONFIG_ACPI */ 115 124 116 125 static inline void *iwl_acpi_get_object(struct device *dev, acpi_string method) ··· 144 131 static inline u64 iwl_acpi_get_pwr_limit(struct device *dev) 145 132 { 146 133 return 0; 134 + } 135 + 136 + static inline int iwl_acpi_get_eckv(struct device *dev, u32 *extl_clk) 137 + { 138 + return -ENOENT; 147 139 } 148 140 149 141 #endif /* CONFIG_ACPI */
+38 -10
drivers/net/wireless/intel/iwlwifi/fw/api/alive.h
··· 96 96 97 97 #define IWL_ALIVE_FLG_RFKILL BIT(0) 98 98 99 - struct iwl_lmac_alive { 100 - __le32 ucode_major; 101 - __le32 ucode_minor; 102 - u8 ver_subtype; 103 - u8 ver_type; 104 - u8 mac; 105 - u8 opt; 106 - __le32 timestamp; 99 + struct iwl_lmac_debug_addrs { 107 100 __le32 error_event_table_ptr; /* SRAM address for error log */ 108 101 __le32 log_event_table_ptr; /* SRAM address for LMAC event log */ 109 102 __le32 cpu_register_ptr; ··· 105 112 __le32 scd_base_ptr; /* SRAM address for SCD */ 106 113 __le32 st_fwrd_addr; /* pointer to Store and forward */ 107 114 __le32 st_fwrd_size; 115 + } __packed; /* UCODE_DEBUG_ADDRS_API_S_VER_2 */ 116 + 117 + struct iwl_lmac_alive { 118 + __le32 ucode_major; 119 + __le32 ucode_minor; 120 + u8 ver_subtype; 121 + u8 ver_type; 122 + u8 mac; 123 + u8 opt; 124 + __le32 timestamp; 125 + struct iwl_lmac_debug_addrs dbg_ptrs; 108 126 } __packed; /* UCODE_ALIVE_NTFY_API_S_VER_3 */ 127 + 128 + struct iwl_umac_debug_addrs { 129 + __le32 error_info_addr; /* SRAM address for UMAC error log */ 130 + __le32 dbg_print_buff_addr; 131 + } __packed; /* UMAC_DEBUG_ADDRS_API_S_VER_1 */ 109 132 110 133 struct iwl_umac_alive { 111 134 __le32 umac_major; /* UMAC version: major */ 112 135 __le32 umac_minor; /* UMAC version: minor */ 113 - __le32 error_info_addr; /* SRAM address for UMAC error log */ 114 - __le32 dbg_print_buff_addr; 136 + struct iwl_umac_debug_addrs dbg_ptrs; 115 137 } __packed; /* UMAC_ALIVE_DATA_API_S_VER_2 */ 116 138 117 139 struct mvm_alive_resp_v3 { ··· 196 188 struct iwl_card_state_notif { 197 189 __le32 flags; 198 190 } __packed; /* CARD_STATE_NTFY_API_S_VER_1 */ 191 + 192 + /** 193 + * enum iwl_error_recovery_flags - flags for error recovery cmd 194 + * @ERROR_RECOVERY_UPDATE_DB: update db from blob sent 195 + * @ERROR_RECOVERY_END_OF_RECOVERY: end of recovery 196 + */ 197 + enum iwl_error_recovery_flags { 198 + ERROR_RECOVERY_UPDATE_DB = BIT(0), 199 + ERROR_RECOVERY_END_OF_RECOVERY = BIT(1), 200 + }; 201 + 202 + /** 203 + * struct iwl_fw_error_recovery_cmd - recovery cmd sent upon assert 204 + * @flags: &enum iwl_error_recovery_flags 205 + * @buf_size: db buffer size in bytes 206 + */ 207 + struct iwl_fw_error_recovery_cmd { 208 + __le32 flags; 209 + __le32 buf_size; 210 + } __packed; /* ERROR_RECOVERY_CMD_HDR_API_S_VER_1 */ 199 211 200 212 #endif /* __iwl_fw_api_alive_h__ */
+5
drivers/net/wireless/intel/iwlwifi/fw/api/commands.h
··· 643 643 * @INIT_EXTENDED_CFG_CMD: &struct iwl_init_extended_cfg_cmd 644 644 */ 645 645 INIT_EXTENDED_CFG_CMD = 0x03, 646 + 647 + /** 648 + * @FW_ERROR_RECOVERY_CMD: &struct iwl_fw_error_recovery_cmd 649 + */ 650 + FW_ERROR_RECOVERY_CMD = 0x7, 646 651 }; 647 652 648 653 #endif /* __iwl_fw_api_commands_h__ */
+8 -3
drivers/net/wireless/intel/iwlwifi/fw/api/dbg-tlv.h
··· 204 204 * struct iwl_fw_ini_trigger - (IWL_FW_INI_TLV_TYPE_DUMP_CFG) 205 205 * Region sections define IDs and triggers that use those IDs TLV 206 206 * 207 - * @trigger_id: enum &iwl_fw_ini_trigger_id 208 - * @ignore_default: override FW TLV with binary TLV 207 + * @trigger_id: enum &iwl_fw_ini_tigger_id 208 + * @override_trig: determines how apply trigger in case a trigger with the 209 + * same id is already in use. Using the first 2 bytes: 210 + * Byte 0: if 0, override trigger configuration, otherwise use the 211 + * existing configuration. 212 + * Byte 1: if 0, override trigger regions, otherwise append regions to 213 + * existing trigger. 209 214 * @dump_delay: delay from trigger fire to dump, in usec 210 215 * @occurrences: max amount of times to be fired 211 216 * @ignore_consec: ignore consecutive triggers, in usec ··· 222 217 */ 223 218 struct iwl_fw_ini_trigger { 224 219 __le32 trigger_id; 225 - __le32 ignore_default; 220 + __le32 override_trig; 226 221 __le32 dump_delay; 227 222 __le32 occurrences; 228 223 __le32 ignore_consec;
+179 -12
drivers/net/wireless/intel/iwlwifi/fw/api/location.h
··· 7 7 * 8 8 * Copyright(c) 2015 - 2017 Intel Deutschland GmbH 9 9 * Copyright (C) 2018 Intel Corporation 10 + * Copyright (C) 2019 Intel Corporation 10 11 * 11 12 * This program is free software; you can redistribute it and/or modify 12 13 * it under the terms of version 2 of the GNU General Public License as ··· 29 28 * 30 29 * Copyright(c) 2015 - 2017 Intel Deutschland GmbH 31 30 * Copyright (C) 2018 Intel Corporation 31 + * Copyright (C) 2019 Intel Corporation 32 32 * All rights reserved. 33 33 * 34 34 * Redistribution and use in source and binary forms, with or without ··· 324 322 }; 325 323 326 324 /** 327 - * struct iwl_tof_range_req_ap_entry - AP configuration parameters 325 + * struct iwl_tof_range_req_ap_entry_v2 - AP configuration parameters 328 326 * @channel_num: Current AP Channel 329 327 * @bandwidth: Current AP Bandwidth. One of iwl_tof_bandwidth. 330 328 * @tsf_delta_direction: TSF relatively to the subject AP ··· 357 355 * @notify_mcsi: &enum iwl_tof_mcsi_ntfy. 358 356 * @reserved: For alignment and future use 359 357 */ 360 - struct iwl_tof_range_req_ap_entry { 358 + struct iwl_tof_range_req_ap_entry_v2 { 361 359 u8 channel_num; 362 360 u8 bandwidth; 363 361 u8 tsf_delta_direction; ··· 376 374 u8 algo_type; 377 375 u8 notify_mcsi; 378 376 __le16 reserved; 377 + } __packed; /* LOCATION_RANGE_REQ_AP_ENTRY_CMD_API_S_VER_2 */ 378 + 379 + /** 380 + * enum iwl_initiator_ap_flags - per responder FTM configuration flags 381 + * @IWL_INITIATOR_AP_FLAGS_ASAP: Request for ASAP measurement. 382 + * @IWL_INITIATOR_AP_FLAGS_LCI_REQUEST: Request for LCI information 383 + * @IWL_INITIATOR_AP_FLAGS_CIVIC_REQUEST: Request for CIVIC information 384 + * @IWL_INITIATOR_AP_FLAGS_DYN_ACK: Send HT/VHT ack for FTM frames. If not set, 385 + * 20Mhz dup acks will be sent. 386 + * @IWL_INITIATOR_AP_FLAGS_ALGO_LR: Use LR algo type for rtt calculation. 387 + * Default algo type is ML. 388 + * @IWL_INITIATOR_AP_FLAGS_ALGO_FFT: Use FFT algo type for rtt calculation. 389 + * Default algo type is ML. 390 + * @IWL_INITIATOR_AP_FLAGS_MCSI_REPORT: Send the MCSI for each FTM frame to the 391 + * driver. 392 + */ 393 + enum iwl_initiator_ap_flags { 394 + IWL_INITIATOR_AP_FLAGS_ASAP = BIT(1), 395 + IWL_INITIATOR_AP_FLAGS_LCI_REQUEST = BIT(2), 396 + IWL_INITIATOR_AP_FLAGS_CIVIC_REQUEST = BIT(3), 397 + IWL_INITIATOR_AP_FLAGS_DYN_ACK = BIT(4), 398 + IWL_INITIATOR_AP_FLAGS_ALGO_LR = BIT(5), 399 + IWL_INITIATOR_AP_FLAGS_ALGO_FFT = BIT(6), 400 + IWL_INITIATOR_AP_FLAGS_MCSI_REPORT = BIT(8), 401 + }; 402 + 403 + /** 404 + * struct iwl_tof_range_req_ap_entry - AP configuration parameters 405 + * @initiator_ap_flags: see &enum iwl_initiator_ap_flags. 406 + * @channel_num: AP Channel number 407 + * @bandwidth: AP bandwidth. One of iwl_tof_bandwidth. 408 + * @ctrl_ch_position: Coding of the control channel position relative to the 409 + * center frequency, see iwl_mvm_get_ctrl_pos(). 410 + * @ftmr_max_retries: Max number of retries to send the FTMR in case of no 411 + * reply from the AP. 412 + * @bssid: AP's BSSID 413 + * @burst_period: Recommended value to be sent to the AP. Measurement 414 + * periodicity In units of 100ms. ignored if num_of_bursts_exp = 0 415 + * @samples_per_burst: the number of FTMs pairs in single Burst (1-31); 416 + * @num_of_bursts: Recommended value to be sent to the AP. 2s Exponent of 417 + * the number of measurement iterations (min 2^0 = 1, max 2^14) 418 + * @reserved: For alignment and future use 419 + * @tsf_delta: not in use 420 + */ 421 + struct iwl_tof_range_req_ap_entry { 422 + __le32 initiator_ap_flags; 423 + u8 channel_num; 424 + u8 bandwidth; 425 + u8 ctrl_ch_position; 426 + u8 ftmr_max_retries; 427 + u8 bssid[ETH_ALEN]; 428 + __le16 burst_period; 429 + u8 samples_per_burst; 430 + u8 num_of_bursts; 431 + __le16 reserved; 432 + __le32 tsf_delta; 379 433 } __packed; /* LOCATION_RANGE_REQ_AP_ENTRY_CMD_API_S_VER_3 */ 380 434 381 435 /** ··· 461 403 * @IWL_TOF_INITIATOR_FLAGS_TX_CHAIN_SEL_A: use antenna A fo TX ACKs during FTM 462 404 * @IWL_TOF_INITIATOR_FLAGS_TX_CHAIN_SEL_B: use antenna B fo TX ACKs during FTM 463 405 * @IWL_TOF_INITIATOR_FLAGS_TX_CHAIN_SEL_C: use antenna C fo TX ACKs during FTM 464 - * @IWL_TOF_INITIATOR_FLAGS_MINDELTA_NO_PREF: no preference for minDeltaFTM 406 + * @IWL_TOF_INITIATOR_FLAGS_MACADDR_RANDOM: use random mac address for FTM 407 + * @IWL_TOF_INITIATOR_FLAGS_SPECIFIC_CALIB: use the specific calib value from 408 + * the range request command 409 + * @IWL_TOF_INITIATOR_FLAGS_COMMON_CALIB: use the common calib value from the 410 + * ragne request command 411 + * @IWL_TOF_INITIATOR_FLAGS_NON_ASAP_SUPPORT: support non-asap measurements 465 412 */ 466 413 enum iwl_tof_initiator_flags { 467 414 IWL_TOF_INITIATOR_FLAGS_FAST_ALGO_DISABLED = BIT(0), ··· 476 413 IWL_TOF_INITIATOR_FLAGS_TX_CHAIN_SEL_A = BIT(4), 477 414 IWL_TOF_INITIATOR_FLAGS_TX_CHAIN_SEL_B = BIT(5), 478 415 IWL_TOF_INITIATOR_FLAGS_TX_CHAIN_SEL_C = BIT(6), 479 - IWL_TOF_INITIATOR_FLAGS_MINDELTA_NO_PREF = BIT(7), 416 + IWL_TOF_INITIATOR_FLAGS_MACADDR_RANDOM = BIT(7), 417 + IWL_TOF_INITIATOR_FLAGS_SPECIFIC_CALIB = BIT(15), 418 + IWL_TOF_INITIATOR_FLAGS_COMMON_CALIB = BIT(16), 419 + IWL_TOF_INITIATOR_FLAGS_NON_ASAP_SUPPORT = BIT(20), 480 420 }; /* LOCATION_RANGE_REQ_CMD_API_S_VER_5 */ 481 421 482 422 #define IWL_MVM_TOF_MAX_APS 5 483 423 #define IWL_MVM_TOF_MAX_TWO_SIDED_APS 5 484 424 485 425 /** 486 - * struct iwl_tof_range_req_cmd - start measurement cmd 426 + * struct iwl_tof_range_req_cmd_v5 - start measurement cmd 487 427 * @initiator_flags: see flags @ iwl_tof_initiator_flags 488 428 * @request_id: A Token incremented per request. The same Token will be 489 429 * sent back in the range response ··· 514 448 * @specific_calib: The specific calib value to inject to this measurement calc 515 449 * @ap: per-AP request data 516 450 */ 517 - struct iwl_tof_range_req_cmd { 451 + struct iwl_tof_range_req_cmd_v5 { 518 452 __le32 initiator_flags; 519 453 u8 request_id; 520 454 u8 initiator; ··· 531 465 u8 ftm_tx_chains; 532 466 __le16 common_calib; 533 467 __le16 specific_calib; 534 - struct iwl_tof_range_req_ap_entry ap[IWL_MVM_TOF_MAX_APS]; 468 + struct iwl_tof_range_req_ap_entry_v2 ap[IWL_MVM_TOF_MAX_APS]; 535 469 } __packed; 536 470 /* LOCATION_RANGE_REQ_CMD_API_S_VER_5 */ 471 + 472 + /** 473 + * struct iwl_tof_range_req_cmd - start measurement cmd 474 + * @initiator_flags: see flags @ iwl_tof_initiator_flags 475 + * @request_id: A Token incremented per request. The same Token will be 476 + * sent back in the range response 477 + * @num_of_ap: Number of APs to measure (error if > IWL_MVM_TOF_MAX_APS) 478 + * @range_req_bssid: ranging request BSSID 479 + * @macaddr_mask: Bits set to 0 shall be copied from the MAC address template. 480 + * Bits set to 1 shall be randomized by the UMAC 481 + * @macaddr_template: MAC address template to use for non-randomized bits 482 + * @req_timeout_ms: Requested timeout of the response in units of milliseconds. 483 + * This is the session time for completing the measurement. 484 + * @tsf_mac_id: report the measurement start time for each ap in terms of the 485 + * TSF of this mac id. 0xff to disable TSF reporting. 486 + * @common_calib: The common calib value to inject to this measurement calc 487 + * @specific_calib: The specific calib value to inject to this measurement calc 488 + * @ap: per-AP request data, see &struct iwl_tof_range_req_ap_entry_v2. 489 + */ 490 + struct iwl_tof_range_req_cmd { 491 + __le32 initiator_flags; 492 + u8 request_id; 493 + u8 num_of_ap; 494 + u8 range_req_bssid[ETH_ALEN]; 495 + u8 macaddr_mask[ETH_ALEN]; 496 + u8 macaddr_template[ETH_ALEN]; 497 + __le32 req_timeout_ms; 498 + __le32 tsf_mac_id; 499 + __le16 common_calib; 500 + __le16 specific_calib; 501 + struct iwl_tof_range_req_ap_entry ap[IWL_MVM_TOF_MAX_APS]; 502 + } __packed; /* LOCATION_RANGE_REQ_CMD_API_S_VER_7 */ 537 503 538 504 /* 539 505 * enum iwl_tof_range_request_status - status of the sent request ··· 626 528 }; /* LOCATION_RANGE_RSP_AP_ENTRY_NTFY_API_S_VER_2 */ 627 529 628 530 /** 629 - * struct iwl_tof_range_rsp_ap_entry_ntfy - AP parameters (response) 531 + * struct iwl_tof_range_rsp_ap_entry_ntfy_v3 - AP parameters (response) 630 532 * @bssid: BSSID of the AP 631 533 * @measure_status: current APs measurement status, one of 632 534 * &enum iwl_tof_entry_status. ··· 653 555 * @papd_calib_output: The result of the tof papd calibration that was injected 654 556 * into the algorithm. 655 557 */ 656 - struct iwl_tof_range_rsp_ap_entry_ntfy { 558 + struct iwl_tof_range_rsp_ap_entry_ntfy_v3 { 657 559 u8 bssid[ETH_ALEN]; 658 560 u8 measure_status; 659 561 u8 measure_bw; ··· 675 577 } __packed; /* LOCATION_RANGE_RSP_AP_ETRY_NTFY_API_S_VER_3 */ 676 578 677 579 /** 580 + * struct iwl_tof_range_rsp_ap_entry_ntfy - AP parameters (response) 581 + * @bssid: BSSID of the AP 582 + * @measure_status: current APs measurement status, one of 583 + * &enum iwl_tof_entry_status. 584 + * @measure_bw: Current AP Bandwidth: 0 20MHz, 1 40MHz, 2 80MHz 585 + * @rtt: The Round Trip Time that took for the last measurement for 586 + * current AP [pSec] 587 + * @rtt_variance: The Variance of the RTT values measured for current AP 588 + * @rtt_spread: The Difference between the maximum and the minimum RTT 589 + * values measured for current AP in the current session [pSec] 590 + * @rssi: RSSI as uploaded in the Channel Estimation notification 591 + * @rssi_spread: The Difference between the maximum and the minimum RSSI values 592 + * measured for current AP in the current session 593 + * @last_burst: 1 if no more FTM sessions are scheduled for this responder 594 + * @refusal_period: refusal period in case of 595 + * @IWL_TOF_ENTRY_RESPONDER_CANNOT_COLABORATE [sec] 596 + * @timestamp: The GP2 Clock [usec] where Channel Estimation notification was 597 + * uploaded by the LMAC 598 + * @start_tsf: measurement start time in TSF of the mac specified in the range 599 + * request 600 + * @rx_rate_n_flags: rate and flags of the last FTM frame received from this 601 + * responder 602 + * @tx_rate_n_flags: rate and flags of the last ack sent to this responder 603 + * @t2t3_initiator: as calculated from the algo in the initiator 604 + * @t1t4_responder: as calculated from the algo in the responder 605 + * @common_calib: Calib val that was used in for this AP measurement 606 + * @specific_calib: val that was used in for this AP measurement 607 + * @papd_calib_output: The result of the tof papd calibration that was injected 608 + * into the algorithm. 609 + */ 610 + struct iwl_tof_range_rsp_ap_entry_ntfy { 611 + u8 bssid[ETH_ALEN]; 612 + u8 measure_status; 613 + u8 measure_bw; 614 + __le32 rtt; 615 + __le32 rtt_variance; 616 + __le32 rtt_spread; 617 + s8 rssi; 618 + u8 rssi_spread; 619 + u8 last_burst; 620 + u8 refusal_period; 621 + __le32 timestamp; 622 + __le32 start_tsf; 623 + __le32 rx_rate_n_flags; 624 + __le32 tx_rate_n_flags; 625 + __le32 t2t3_initiator; 626 + __le32 t1t4_responder; 627 + __le16 common_calib; 628 + __le16 specific_calib; 629 + __le32 papd_calib_output; 630 + } __packed; /* LOCATION_RANGE_RSP_AP_ETRY_NTFY_API_S_VER_4 */ 631 + 632 + /** 678 633 * enum iwl_tof_response_status - tof response status 679 634 * 680 635 * @IWL_TOF_RESPONSE_SUCCESS: successful range. ··· 744 593 }; /* LOCATION_RNG_RSP_STATUS */ 745 594 746 595 /** 747 - * struct iwl_tof_range_rsp_ntfy - ranging response notification 596 + * struct iwl_tof_range_rsp_ntfy_v5 - ranging response notification 748 597 * @request_id: A Token ID of the corresponding Range request 749 598 * @request_status: status of current measurement session, one of 750 599 * &enum iwl_tof_response_status. ··· 752 601 * @num_of_aps: Number of APs to measure (error if > IWL_MVM_TOF_MAX_APS) 753 602 * @ap: per-AP data 754 603 */ 755 - struct iwl_tof_range_rsp_ntfy { 604 + struct iwl_tof_range_rsp_ntfy_v5 { 756 605 u8 request_id; 757 606 u8 request_status; 758 607 u8 last_in_batch; 759 608 u8 num_of_aps; 609 + struct iwl_tof_range_rsp_ap_entry_ntfy_v3 ap[IWL_MVM_TOF_MAX_APS]; 610 + } __packed; /* LOCATION_RANGE_RSP_NTFY_API_S_VER_5 */ 611 + 612 + /** 613 + * struct iwl_tof_range_rsp_ntfy - ranging response notification 614 + * @request_id: A Token ID of the corresponding Range request 615 + * @num_of_aps: Number of APs results 616 + * @last_report: 1 if no more FTM sessions are scheduled, 0 otherwise. 617 + * @reserved: reserved 618 + * @ap: per-AP data 619 + */ 620 + struct iwl_tof_range_rsp_ntfy { 621 + u8 request_id; 622 + u8 num_of_aps; 623 + u8 last_report; 624 + u8 reserved; 760 625 struct iwl_tof_range_rsp_ap_entry_ntfy ap[IWL_MVM_TOF_MAX_APS]; 761 - } __packed; 626 + } __packed; /* LOCATION_RANGE_RSP_NTFY_API_S_VER_6 */ 762 627 763 628 #define IWL_MVM_TOF_MCSI_BUF_SIZE (245) 764 629 /**
+10 -3
drivers/net/wireless/intel/iwlwifi/fw/api/power.h
··· 8 8 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. 9 9 * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH 10 10 * Copyright(c) 2015 - 2017 Intel Deutschland GmbH 11 - * Copyright (C) 2018 Intel Corporation 11 + * Copyright (C) 2018 - 2019 Intel Corporation 12 12 * 13 13 * This program is free software; you can redistribute it and/or modify 14 14 * it under the terms of version 2 of the GNU General Public License as ··· 31 31 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. 32 32 * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH 33 33 * Copyright(c) 2015 - 2017 Intel Deutschland GmbH 34 - * Copyright (C) 2018 Intel Corporation 34 + * Copyright (C) 2018 - 2019 Intel Corporation 35 35 * All rights reserved. 36 36 * 37 37 * Redistribution and use in source and binary forms, with or without ··· 200 200 * @DEVICE_POWER_FLAGS_POWER_SAVE_ENA_MSK: 201 201 * '1' Allow to save power by turning off 202 202 * receiver and transmitter. '0' - does not allow. 203 + * @DEVICE_POWER_FLAGS_ALLOW_MEM_RETENTION_MSK: 204 + * Device Retention indication, '1' indicate retention is enabled. 205 + * @DEVICE_POWER_FLAGS_32K_CLK_VALID_MSK: 206 + * 32Khz external slow clock valid indication, '1' indicate cloack is 207 + * valid. 203 208 */ 204 209 enum iwl_device_power_flags { 205 - DEVICE_POWER_FLAGS_POWER_SAVE_ENA_MSK = BIT(0), 210 + DEVICE_POWER_FLAGS_POWER_SAVE_ENA_MSK = BIT(0), 211 + DEVICE_POWER_FLAGS_ALLOW_MEM_RETENTION_MSK = BIT(1), 212 + DEVICE_POWER_FLAGS_32K_CLK_VALID_MSK = BIT(12), 206 213 }; 207 214 208 215 /**
+3 -3
drivers/net/wireless/intel/iwlwifi/fw/api/scan.h
··· 8 8 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. 9 9 * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH 10 10 * Copyright(c) 2016 - 2017 Intel Deutschland GmbH 11 - * Copyright(c) 2018 Intel Corporation 11 + * Copyright(c) 2018 - 2019 Intel Corporation 12 12 * 13 13 * This program is free software; you can redistribute it and/or modify 14 14 * it under the terms of version 2 of the GNU General Public License as ··· 31 31 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. 32 32 * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH 33 33 * Copyright(c) 2016 - 2017 Intel Deutschland GmbH 34 - * Copyright(c) 2018 Intel Corporation 34 + * Copyright(c) 2018 - 2019 Intel Corporation 35 35 * All rights reserved. 36 36 * 37 37 * Redistribution and use in source and binary forms, with or without ··· 434 434 /* The maximum of either of these cannot exceed 8, because we use an 435 435 * 8-bit mask (see IWL_MVM_SCAN_MASK in mvm.h). 436 436 */ 437 - #define IWL_MVM_MAX_UMAC_SCANS 8 437 + #define IWL_MVM_MAX_UMAC_SCANS 4 438 438 #define IWL_MVM_MAX_LMAC_SCANS 1 439 439 440 440 enum scan_config_flags {
+182 -60
drivers/net/wireless/intel/iwlwifi/fw/dbg.c
··· 8 8 * Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved. 9 9 * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH 10 10 * Copyright(c) 2015 - 2017 Intel Deutschland GmbH 11 - * Copyright(c) 2018 Intel Corporation 11 + * Copyright(c) 2018 - 2019 Intel Corporation 12 12 * 13 13 * This program is free software; you can redistribute it and/or modify 14 14 * it under the terms of version 2 of the GNU General Public License as ··· 31 31 * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved. 32 32 * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH 33 33 * Copyright(c) 2015 - 2017 Intel Deutschland GmbH 34 - * Copyright(c) 2018 Intel Corporation 34 + * Copyright(c) 2018 - 2019 Intel Corporation 35 35 * All rights reserved. 36 36 * 37 37 * Redistribution and use in source and binary forms, with or without ··· 242 242 cfg->lmac[0].rxfifo1_size, 0, 0); 243 243 /* Pull RXF2 */ 244 244 iwl_fwrt_dump_rxf(fwrt, dump_data, cfg->rxfifo2_size, 245 - RXF_DIFF_FROM_PREV, 1); 245 + RXF_DIFF_FROM_PREV + 246 + fwrt->trans->cfg->umac_prph_offset, 1); 246 247 /* Pull LMAC2 RXF1 */ 247 248 if (fwrt->smem_cfg.num_lmacs > 1) 248 249 iwl_fwrt_dump_rxf(fwrt, dump_data, ··· 674 673 { 675 674 u32 range_len; 676 675 677 - if (fwrt->trans->cfg->device_family >= IWL_DEVICE_FAMILY_22000) { 676 + if (fwrt->trans->cfg->device_family >= IWL_DEVICE_FAMILY_AX210) { 677 + /* TODO */ 678 + } else if (fwrt->trans->cfg->device_family >= IWL_DEVICE_FAMILY_22000) { 678 679 range_len = ARRAY_SIZE(iwl_prph_dump_addr_22000); 679 680 handler(fwrt, iwl_prph_dump_addr_22000, range_len, ptr); 680 681 } else { ··· 1135 1132 return le32_to_cpu(range->range_data_size); 1136 1133 } 1137 1134 1135 + static int 1136 + iwl_dump_ini_mon_dram_iter(struct iwl_fw_runtime *fwrt, 1137 + struct iwl_fw_ini_error_dump_range *range, 1138 + struct iwl_fw_ini_region_cfg *reg, 1139 + int idx) 1140 + { 1141 + u32 start_addr = iwl_read_umac_prph(fwrt->trans, 1142 + MON_BUFF_BASE_ADDR_VER2); 1143 + 1144 + if (start_addr == 0x5a5a5a5a) 1145 + return -1; 1146 + 1147 + range->start_addr = cpu_to_le32(start_addr); 1148 + range->range_data_size = cpu_to_le32(fwrt->trans->fw_mon[idx].size); 1149 + 1150 + memcpy(range->data, fwrt->trans->fw_mon[idx].block, 1151 + fwrt->trans->fw_mon[idx].size); 1152 + 1153 + return le32_to_cpu(range->range_data_size); 1154 + } 1155 + 1138 1156 static struct iwl_fw_ini_error_dump_range 1139 1157 *iwl_dump_ini_mem_fill_header(struct iwl_fw_runtime *fwrt, void *data) 1140 1158 { 1141 1159 struct iwl_fw_ini_error_dump *dump = data; 1142 1160 1143 1161 return dump->ranges; 1162 + } 1163 + 1164 + static struct iwl_fw_ini_error_dump_range 1165 + *iwl_dump_ini_mon_dram_fill_header(struct iwl_fw_runtime *fwrt, void *data) 1166 + { 1167 + struct iwl_fw_ini_monitor_dram_dump *mon_dump = (void *)data; 1168 + u32 write_ptr, cycle_cnt; 1169 + unsigned long flags; 1170 + 1171 + if (!iwl_trans_grab_nic_access(fwrt->trans, &flags)) { 1172 + IWL_ERR(fwrt, "Failed to get DRAM monitor header\n"); 1173 + return NULL; 1174 + } 1175 + write_ptr = iwl_read_umac_prph_no_grab(fwrt->trans, 1176 + MON_BUFF_WRPTR_VER2); 1177 + cycle_cnt = iwl_read_umac_prph_no_grab(fwrt->trans, 1178 + MON_BUFF_CYCLE_CNT_VER2); 1179 + iwl_trans_release_nic_access(fwrt->trans, &flags); 1180 + 1181 + mon_dump->write_ptr = cpu_to_le32(write_ptr); 1182 + mon_dump->cycle_cnt = cpu_to_le32(cycle_cnt); 1183 + 1184 + return mon_dump->ranges; 1144 1185 } 1145 1186 1146 1187 static u32 iwl_dump_ini_mem_get_size(struct iwl_fw_runtime *fwrt, ··· 1216 1169 return size; 1217 1170 } 1218 1171 1172 + static u32 iwl_dump_ini_mon_dram_get_size(struct iwl_fw_runtime *fwrt, 1173 + struct iwl_fw_ini_region_cfg *reg) 1174 + { 1175 + return fwrt->trans->num_blocks ? fwrt->trans->fw_mon[0].size : 0; 1176 + } 1177 + 1219 1178 static u32 iwl_dump_ini_mem_ranges(struct iwl_fw_runtime *fwrt, 1220 1179 struct iwl_fw_ini_region_cfg *reg) 1221 1180 { ··· 1238 1185 struct iwl_fw_ini_region_cfg *reg) 1239 1186 { 1240 1187 return fwrt->num_of_paging_blk; 1188 + } 1189 + 1190 + static u32 iwl_dump_ini_mon_dram_ranges(struct iwl_fw_runtime *fwrt, 1191 + struct iwl_fw_ini_region_cfg *reg) 1192 + { 1193 + return 1; 1241 1194 } 1242 1195 1243 1196 /** ··· 1343 1284 case IWL_FW_INI_REGION_PERIPHERY_MAC: 1344 1285 case IWL_FW_INI_REGION_PERIPHERY_PHY: 1345 1286 case IWL_FW_INI_REGION_PERIPHERY_AUX: 1287 + case IWL_FW_INI_REGION_INTERNAL_BUFFER: 1346 1288 case IWL_FW_INI_REGION_CSR: 1347 1289 size += hdr_len + dump_header_len + range_header_len * 1348 1290 iwl_dump_ini_mem_ranges(fwrt, reg) + ··· 1371 1311 break; 1372 1312 } 1373 1313 case IWL_FW_INI_REGION_DRAM_BUFFER: 1374 - /* Transport takes care of DRAM dumping */ 1375 - case IWL_FW_INI_REGION_INTERNAL_BUFFER: 1314 + if (!fwrt->trans->num_blocks) 1315 + break; 1316 + size += hdr_len + 1317 + sizeof(struct iwl_fw_ini_monitor_dram_dump) * 1318 + iwl_dump_ini_mon_dram_ranges(fwrt, reg) + 1319 + iwl_dump_ini_mon_dram_get_size(fwrt, reg); 1320 + break; 1376 1321 case IWL_FW_INI_REGION_DRAM_IMR: 1377 1322 /* Undefined yet */ 1378 1323 default: ··· 1389 1324 1390 1325 static void iwl_fw_ini_dump_trigger(struct iwl_fw_runtime *fwrt, 1391 1326 struct iwl_fw_ini_trigger *trigger, 1392 - struct iwl_fw_error_dump_data **data, 1393 - u32 *dump_mask) 1327 + struct iwl_fw_error_dump_data **data) 1394 1328 { 1395 1329 int i, num = le32_to_cpu(trigger->num_regions); 1396 1330 ··· 1410 1346 type = le32_to_cpu(reg->region_type); 1411 1347 switch (type) { 1412 1348 case IWL_FW_INI_REGION_DEVICE_MEMORY: 1349 + case IWL_FW_INI_REGION_INTERNAL_BUFFER: 1413 1350 ops.get_num_of_ranges = iwl_dump_ini_mem_ranges; 1414 1351 ops.get_size = iwl_dump_ini_mem_get_size; 1415 1352 ops.fill_mem_hdr = iwl_dump_ini_mem_fill_header; ··· 1427 1362 iwl_dump_ini_mem(fwrt, type, data, reg, &ops); 1428 1363 break; 1429 1364 case IWL_FW_INI_REGION_DRAM_BUFFER: 1430 - *dump_mask |= BIT(IWL_FW_ERROR_DUMP_FW_MONITOR); 1365 + ops.get_num_of_ranges = iwl_dump_ini_mon_dram_ranges; 1366 + ops.get_size = iwl_dump_ini_mon_dram_get_size; 1367 + ops.fill_mem_hdr = iwl_dump_ini_mon_dram_fill_header; 1368 + ops.fill_range = iwl_dump_ini_mon_dram_iter; 1369 + iwl_dump_ini_mem(fwrt, type, data, reg, &ops); 1431 1370 break; 1432 1371 case IWL_FW_INI_REGION_PAGING: { 1433 1372 ops.fill_mem_hdr = iwl_dump_ini_mem_fill_header; ··· 1465 1396 iwl_dump_ini_mem(fwrt, type, data, reg, &ops); 1466 1397 break; 1467 1398 case IWL_FW_INI_REGION_DRAM_IMR: 1468 - case IWL_FW_INI_REGION_INTERNAL_BUFFER: 1469 1399 /* This is undefined yet */ 1470 1400 default: 1471 1401 break; ··· 1474 1406 1475 1407 static struct iwl_fw_error_dump_file * 1476 1408 _iwl_fw_error_ini_dump(struct iwl_fw_runtime *fwrt, 1477 - struct iwl_fw_dump_ptrs *fw_error_dump, 1478 - u32 *dump_mask) 1409 + struct iwl_fw_dump_ptrs *fw_error_dump) 1479 1410 { 1480 1411 int size, id = le32_to_cpu(fwrt->dump.desc->trig_desc.type); 1481 1412 struct iwl_fw_error_dump_data *dump_data; 1482 1413 struct iwl_fw_error_dump_file *dump_file; 1483 - struct iwl_fw_ini_trigger *trigger, *ext; 1414 + struct iwl_fw_ini_trigger *trigger; 1484 1415 1485 1416 if (id == FW_DBG_TRIGGER_FW_ASSERT) 1486 1417 id = IWL_FW_TRIGGER_ID_FW_ASSERT; 1487 1418 1488 - if (WARN_ON(id >= ARRAY_SIZE(fwrt->dump.active_trigs))) 1419 + if (!iwl_fw_ini_trigger_on(fwrt, id)) 1489 1420 return NULL; 1490 1421 1491 - trigger = fwrt->dump.active_trigs[id].conf; 1492 - ext = fwrt->dump.active_trigs[id].conf_ext; 1422 + trigger = fwrt->dump.active_trigs[id].trig; 1493 1423 1494 1424 size = sizeof(*dump_file); 1495 1425 size += iwl_fw_ini_get_trigger_len(fwrt, trigger); 1496 - size += iwl_fw_ini_get_trigger_len(fwrt, ext); 1497 1426 1498 1427 if (!size) 1499 1428 return NULL; ··· 1505 1440 dump_data = (void *)dump_file->data; 1506 1441 dump_file->file_len = cpu_to_le32(size); 1507 1442 1508 - *dump_mask = 0; 1509 - if (trigger) 1510 - iwl_fw_ini_dump_trigger(fwrt, trigger, &dump_data, dump_mask); 1511 - if (ext) 1512 - iwl_fw_ini_dump_trigger(fwrt, ext, &dump_data, dump_mask); 1443 + iwl_fw_ini_dump_trigger(fwrt, trigger, &dump_data); 1513 1444 1514 1445 return dump_file; 1515 1446 } ··· 1531 1470 goto out; 1532 1471 1533 1472 if (fwrt->trans->ini_valid) 1534 - dump_file = _iwl_fw_error_ini_dump(fwrt, fw_error_dump, 1535 - &dump_mask); 1473 + dump_file = _iwl_fw_error_ini_dump(fwrt, fw_error_dump); 1536 1474 else 1537 1475 dump_file = _iwl_fw_error_dump(fwrt, fw_error_dump); 1538 1476 ··· 1543 1483 if (!fwrt->trans->ini_valid && fwrt->dump.monitor_only) 1544 1484 dump_mask &= IWL_FW_ERROR_DUMP_FW_MONITOR; 1545 1485 1546 - fw_error_dump->trans_ptr = iwl_trans_dump_data(fwrt->trans, dump_mask); 1486 + if (!fwrt->trans->ini_valid) 1487 + fw_error_dump->trans_ptr = 1488 + iwl_trans_dump_data(fwrt->trans, dump_mask); 1489 + 1547 1490 file_len = le32_to_cpu(dump_file->file_len); 1548 1491 fw_error_dump->fwrt_len = file_len; 1549 1492 if (fw_error_dump->trans_ptr) { ··· 1620 1557 fwrt->dump.desc = desc; 1621 1558 fwrt->dump.monitor_only = monitor_only; 1622 1559 1623 - schedule_delayed_work(&fwrt->dump.wk, delay); 1560 + schedule_delayed_work(&fwrt->dump.wk, usecs_to_jiffies(delay)); 1624 1561 1625 1562 return 0; 1626 1563 } ··· 1676 1613 } 1677 1614 1678 1615 trigger->occurrences = cpu_to_le16(occurrences); 1679 - delay = le16_to_cpu(trigger->trig_dis_ms); 1680 1616 monitor_only = trigger->mode & IWL_FW_DBG_TRIGGER_MONITOR_ONLY; 1617 + 1618 + /* convert msec to usec */ 1619 + delay = le32_to_cpu(trigger->stop_delay) * USEC_PER_MSEC; 1681 1620 } 1682 1621 1683 1622 desc = kzalloc(sizeof(*desc) + len, GFP_ATOMIC); ··· 1699 1634 u32 id, const char *str, size_t len) 1700 1635 { 1701 1636 struct iwl_fw_dump_desc *desc; 1637 + struct iwl_fw_ini_active_triggers *active; 1702 1638 u32 occur, delay; 1703 1639 1704 1640 if (!fwrt->trans->ini_valid) ··· 1708 1642 if (id == FW_DBG_TRIGGER_USER) 1709 1643 id = IWL_FW_TRIGGER_ID_USER_TRIGGER; 1710 1644 1711 - if (WARN_ON(!fwrt->dump.active_trigs[id].active)) 1645 + active = &fwrt->dump.active_trigs[id]; 1646 + 1647 + if (WARN_ON(!active->active)) 1712 1648 return -EINVAL; 1713 1649 1714 - delay = le32_to_cpu(fwrt->dump.active_trigs[id].conf->dump_delay); 1715 - occur = le32_to_cpu(fwrt->dump.active_trigs[id].conf->occurrences); 1650 + delay = le32_to_cpu(active->trig->dump_delay); 1651 + occur = le32_to_cpu(active->trig->occurrences); 1716 1652 if (!occur) 1717 1653 return 0; 1718 1654 1719 - if (le32_to_cpu(fwrt->dump.active_trigs[id].conf->force_restart)) { 1655 + if (le32_to_cpu(active->trig->force_restart)) { 1720 1656 IWL_WARN(fwrt, "Force restart: trigger %d fired.\n", id); 1721 1657 iwl_force_nmi(fwrt->trans); 1722 1658 return 0; ··· 1728 1660 if (!desc) 1729 1661 return -ENOMEM; 1730 1662 1731 - occur--; 1732 - fwrt->dump.active_trigs[id].conf->occurrences = cpu_to_le32(occur); 1663 + active->trig->occurrences = cpu_to_le32(--occur); 1733 1664 1734 1665 desc->len = len; 1735 1666 desc->trig_desc.type = cpu_to_le32(id); ··· 1920 1853 } 1921 1854 1922 1855 static void iwl_fw_dbg_buffer_apply(struct iwl_fw_runtime *fwrt, 1923 - struct iwl_fw_ini_allocation_data *alloc) 1856 + struct iwl_fw_ini_allocation_data *alloc, 1857 + enum iwl_fw_ini_apply_point pnt) 1924 1858 { 1925 1859 struct iwl_trans *trans = fwrt->trans; 1926 1860 struct iwl_ldbg_config_cmd ldbg_cmd = { ··· 1935 1867 .len[0] = sizeof(ldbg_cmd), 1936 1868 }; 1937 1869 int block_idx = trans->num_blocks; 1870 + u32 buf_location = le32_to_cpu(alloc->tlv.buffer_location); 1938 1871 1939 - if (le32_to_cpu(alloc->tlv.buffer_location) != 1940 - IWL_FW_INI_LOCATION_DRAM_PATH) 1872 + if (buf_location == IWL_FW_INI_LOCATION_SRAM_PATH) { 1873 + if (!WARN(pnt != IWL_FW_INI_APPLY_EARLY, 1874 + "Invalid apply point %d for SMEM buffer allocation", 1875 + pnt)) 1876 + /* set sram monitor by enabling bit 7 */ 1877 + iwl_set_bit(fwrt->trans, CSR_HW_IF_CONFIG_REG, 1878 + CSR_HW_IF_CONFIG_REG_BIT_MONITOR_SRAM); 1879 + return; 1880 + } 1881 + 1882 + if (buf_location != IWL_FW_INI_LOCATION_DRAM_PATH) 1941 1883 return; 1942 1884 1943 1885 if (!alloc->is_alloc) { ··· 2027 1949 } 2028 1950 } 2029 1951 1952 + static int iwl_fw_dbg_trig_realloc(struct iwl_fw_runtime *fwrt, 1953 + struct iwl_fw_ini_active_triggers *active, 1954 + u32 id, int size) 1955 + { 1956 + void *ptr; 1957 + 1958 + if (size <= active->size) 1959 + return 0; 1960 + 1961 + ptr = krealloc(active->trig, size, GFP_KERNEL); 1962 + if (!ptr) { 1963 + IWL_ERR(fwrt, "Failed to allocate memory for trigger %d\n", id); 1964 + return -ENOMEM; 1965 + } 1966 + active->trig = ptr; 1967 + active->size = size; 1968 + 1969 + return 0; 1970 + } 1971 + 2030 1972 static void iwl_fw_dbg_update_triggers(struct iwl_fw_runtime *fwrt, 2031 1973 struct iwl_fw_ini_trigger_tlv *tlv, 2032 1974 bool ext, ··· 2059 1961 struct iwl_fw_ini_trigger *trig = iter; 2060 1962 struct iwl_fw_ini_active_triggers *active; 2061 1963 int id = le32_to_cpu(trig->trigger_id); 2062 - u32 num; 1964 + u32 trig_regs_size = le32_to_cpu(trig->num_regions) * 1965 + sizeof(__le32); 2063 1966 2064 1967 if (WARN_ON(id >= ARRAY_SIZE(fwrt->dump.active_trigs))) 2065 1968 break; 2066 1969 2067 1970 active = &fwrt->dump.active_trigs[id]; 2068 1971 2069 - if (active->apply_point != apply_point) { 2070 - active->conf = NULL; 2071 - active->conf_ext = NULL; 2072 - } 1972 + if (!active->active) { 1973 + size_t trig_size = sizeof(*trig) + trig_regs_size; 2073 1974 2074 - num = le32_to_cpu(trig->num_regions); 1975 + if (iwl_fw_dbg_trig_realloc(fwrt, active, id, 1976 + trig_size)) 1977 + goto next; 2075 1978 2076 - if (ext && active->apply_point == apply_point) { 2077 - num += le32_to_cpu(active->conf->num_regions); 2078 - if (trig->ignore_default) { 2079 - active->conf_ext = active->conf; 2080 - active->conf = trig; 2081 - } else { 2082 - active->conf_ext = trig; 2083 - } 1979 + memcpy(active->trig, trig, trig_size); 1980 + 2084 1981 } else { 2085 - active->conf = trig; 1982 + u32 conf_override = 1983 + !(le32_to_cpu(trig->override_trig) & 0xff); 1984 + u32 region_override = 1985 + !(le32_to_cpu(trig->override_trig) & 0xff00); 1986 + u32 offset = 0; 1987 + u32 active_regs = 1988 + le32_to_cpu(active->trig->num_regions); 1989 + u32 new_regs = le32_to_cpu(trig->num_regions); 1990 + int mem_to_add = trig_regs_size; 1991 + 1992 + if (region_override) { 1993 + mem_to_add -= active_regs * sizeof(__le32); 1994 + } else { 1995 + offset += active_regs; 1996 + new_regs += active_regs; 1997 + } 1998 + 1999 + if (iwl_fw_dbg_trig_realloc(fwrt, active, id, 2000 + active->size + mem_to_add)) 2001 + goto next; 2002 + 2003 + if (conf_override) 2004 + memcpy(active->trig, trig, sizeof(*trig)); 2005 + 2006 + memcpy(active->trig->data + offset, trig->data, 2007 + trig_regs_size); 2008 + active->trig->num_regions = cpu_to_le32(new_regs); 2086 2009 } 2087 2010 2088 2011 /* Since zero means infinity - just set to -1 */ 2089 - if (!le32_to_cpu(trig->occurrences)) 2090 - trig->occurrences = cpu_to_le32(-1); 2091 - if (!le32_to_cpu(trig->ignore_consec)) 2092 - trig->ignore_consec = cpu_to_le32(-1); 2012 + if (!le32_to_cpu(active->trig->occurrences)) 2013 + active->trig->occurrences = cpu_to_le32(-1); 2014 + if (!le32_to_cpu(active->trig->ignore_consec)) 2015 + active->trig->ignore_consec = cpu_to_le32(-1); 2093 2016 2094 - iter += sizeof(*trig) + 2095 - le32_to_cpu(trig->num_regions) * sizeof(__le32); 2017 + active->active = true; 2018 + next: 2019 + iter += sizeof(*trig) + trig_regs_size; 2096 2020 2097 - active->active = num; 2098 - active->apply_point = apply_point; 2099 2021 } 2100 2022 } 2101 2023 ··· 2135 2017 case IWL_UCODE_TLV_TYPE_BUFFER_ALLOCATION: { 2136 2018 struct iwl_fw_ini_allocation_data *buf_alloc = ini_tlv; 2137 2019 2138 - iwl_fw_dbg_buffer_apply(fwrt, ini_tlv); 2020 + iwl_fw_dbg_buffer_apply(fwrt, ini_tlv, pnt); 2139 2021 iter += sizeof(buf_alloc->is_alloc); 2140 2022 break; 2141 2023 } ··· 2174 2056 if (apply_point == IWL_FW_INI_APPLY_EARLY) { 2175 2057 for (i = 0; i < IWL_FW_INI_MAX_REGION_ID; i++) 2176 2058 fwrt->dump.active_regs[i] = NULL; 2059 + 2060 + /* disable the triggers, used in recovery flow */ 2061 + for (i = 0; i < IWL_FW_TRIGGER_ID_NUM; i++) 2062 + fwrt->dump.active_trigs[i].active = false; 2177 2063 } 2178 2064 2179 2065 _iwl_fw_dbg_apply_point(fwrt, data, apply_point, false);
+47 -31
drivers/net/wireless/intel/iwlwifi/fw/dbg.h
··· 8 8 * Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved. 9 9 * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH 10 10 * Copyright(c) 2015 - 2017 Intel Deutschland GmbH 11 - * Copyright(c) 2018 Intel Corporation 11 + * Copyright(c) 2018 - 2019 Intel Corporation 12 12 * 13 13 * This program is free software; you can redistribute it and/or modify 14 14 * it under the terms of version 2 of the GNU General Public License as ··· 31 31 * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved. 32 32 * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH 33 33 * Copyright(c) 2015 - 2017 Intel Deutschland GmbH 34 - * Copyright(c) 2018 Intel Corporation 34 + * Copyright(c) 2018 - 2019 Intel Corporation 35 35 * All rights reserved. 36 36 * 37 37 * Redistribution and use in source and binary forms, with or without ··· 162 162 } 163 163 164 164 static inline bool 165 - iwl_fw_dbg_no_trig_window(struct iwl_fw_runtime *fwrt, u32 id, u32 dis_ms) 165 + iwl_fw_dbg_no_trig_window(struct iwl_fw_runtime *fwrt, u32 id, u32 dis_usec) 166 166 { 167 - unsigned long wind_jiff = msecs_to_jiffies(dis_ms); 167 + unsigned long wind_jiff = usecs_to_jiffies(dis_usec); 168 168 169 169 /* If this is the first event checked, jump to update start ts */ 170 170 if (fwrt->dump.non_collect_ts_start[id] && ··· 181 181 struct wireless_dev *wdev, 182 182 struct iwl_fw_dbg_trigger_tlv *trig) 183 183 { 184 + u32 usec = le16_to_cpu(trig->trig_dis_ms) * USEC_PER_MSEC; 185 + 184 186 if (wdev && !iwl_fw_dbg_trigger_vif_match(trig, wdev)) 185 187 return false; 186 188 187 - if (iwl_fw_dbg_no_trig_window(fwrt, le32_to_cpu(trig->id), 188 - le16_to_cpu(trig->trig_dis_ms))) { 189 + if (iwl_fw_dbg_no_trig_window(fwrt, le32_to_cpu(trig->id), usec)) { 189 190 IWL_WARN(fwrt, "Trigger %d occurred while no-collect window.\n", 190 191 trig->id); 191 192 return false; ··· 223 222 }) 224 223 225 224 static inline bool 226 - _iwl_fw_ini_trigger_on(struct iwl_fw_runtime *fwrt, 227 - const enum iwl_fw_dbg_trigger id) 225 + iwl_fw_ini_trigger_on(struct iwl_fw_runtime *fwrt, 226 + enum iwl_fw_ini_trigger_id id) 228 227 { 229 - struct iwl_fw_ini_active_triggers *trig = &fwrt->dump.active_trigs[id]; 230 - u32 ms; 228 + struct iwl_fw_ini_trigger *trig; 229 + u32 usec; 231 230 232 - if (!fwrt->trans->ini_valid) 231 + 232 + 233 + if (!fwrt->trans->ini_valid || id >= IWL_FW_TRIGGER_ID_NUM || 234 + !fwrt->dump.active_trigs[id].active) 233 235 return false; 234 236 235 - if (!trig || !trig->active) 236 - return false; 237 + trig = fwrt->dump.active_trigs[id].trig; 238 + usec = le32_to_cpu(trig->ignore_consec); 237 239 238 - ms = le32_to_cpu(trig->conf->ignore_consec); 239 - if (ms) 240 - ms /= USEC_PER_MSEC; 241 - 242 - if (iwl_fw_dbg_no_trig_window(fwrt, id, ms)) { 240 + if (iwl_fw_dbg_no_trig_window(fwrt, id, usec)) { 243 241 IWL_WARN(fwrt, "Trigger %d fired in no-collect window\n", id); 244 242 return false; 245 243 } 246 244 247 245 return true; 248 246 } 249 - 250 - #define iwl_fw_ini_trigger_on(fwrt, wdev, id) ({ \ 251 - BUILD_BUG_ON(!__builtin_constant_p(id)); \ 252 - BUILD_BUG_ON((id) >= IWL_FW_TRIGGER_ID_NUM); \ 253 - _iwl_fw_ini_trigger_on((fwrt), (wdev), (id)); \ 254 - }) 255 247 256 248 static inline void 257 249 _iwl_fw_dbg_trigger_simple_stop(struct iwl_fw_runtime *fwrt, ··· 292 298 } 293 299 294 300 if (params) { 295 - params->in_sample = iwl_read_prph(trans, DBGC_IN_SAMPLE); 296 - params->out_ctrl = iwl_read_prph(trans, DBGC_OUT_CTRL); 301 + params->in_sample = iwl_read_umac_prph(trans, DBGC_IN_SAMPLE); 302 + params->out_ctrl = iwl_read_umac_prph(trans, DBGC_OUT_CTRL); 297 303 } 298 304 299 - iwl_write_prph(trans, DBGC_IN_SAMPLE, 0); 305 + iwl_write_umac_prph(trans, DBGC_IN_SAMPLE, 0); 300 306 udelay(100); 301 - iwl_write_prph(trans, DBGC_OUT_CTRL, 0); 307 + iwl_write_umac_prph(trans, DBGC_OUT_CTRL, 0); 302 308 #ifdef CONFIG_IWLWIFI_DEBUGFS 303 309 trans->dbg_rec_on = false; 304 310 #endif ··· 326 332 iwl_clear_bits_prph(trans, MON_BUFF_SAMPLE_CTL, 0x1); 327 333 iwl_set_bits_prph(trans, MON_BUFF_SAMPLE_CTL, 0x1); 328 334 } else { 329 - iwl_write_prph(trans, DBGC_IN_SAMPLE, params->in_sample); 335 + iwl_write_umac_prph(trans, DBGC_IN_SAMPLE, params->in_sample); 330 336 udelay(100); 331 - iwl_write_prph(trans, DBGC_OUT_CTRL, params->out_ctrl); 337 + iwl_write_umac_prph(trans, DBGC_OUT_CTRL, params->out_ctrl); 332 338 } 333 339 } 334 340 ··· 369 375 { 370 376 return fw_has_capa(&fwrt->fw->ucode_capa, 371 377 IWL_UCODE_TLV_CAPA_D3_DEBUG) && 372 - fwrt->trans->cfg->d3_debug_data_length && 378 + fwrt->trans->cfg->d3_debug_data_length && fwrt->ops && 379 + fwrt->ops->d3_debug_enable && 380 + fwrt->ops->d3_debug_enable(fwrt->ops_ctx) && 373 381 iwl_fw_dbg_type_on(fwrt, IWL_FW_ERROR_DUMP_D3_DEBUG_DATA); 374 382 } 375 383 ··· 437 441 enum iwl_fw_ini_apply_point apply_point); 438 442 439 443 void iwl_fwrt_stop_device(struct iwl_fw_runtime *fwrt); 444 + 445 + static inline void iwl_fw_lmac1_set_alive_err_table(struct iwl_trans *trans, 446 + u32 lmac_error_event_table) 447 + { 448 + if (!(trans->error_event_table_tlv_status & 449 + IWL_ERROR_EVENT_TABLE_LMAC1) || 450 + WARN_ON(trans->lmac_error_event_table[0] != 451 + lmac_error_event_table)) 452 + trans->lmac_error_event_table[0] = lmac_error_event_table; 453 + } 454 + 455 + static inline void iwl_fw_umac_set_alive_err_table(struct iwl_trans *trans, 456 + u32 umac_error_event_table) 457 + { 458 + if (!(trans->error_event_table_tlv_status & 459 + IWL_ERROR_EVENT_TABLE_UMAC) || 460 + WARN_ON(trans->umac_error_event_table != 461 + umac_error_event_table)) 462 + trans->umac_error_event_table = umac_error_event_table; 463 + } 440 464 441 465 /* This bit is used to differentiate the legacy dump from the ini dump */ 442 466 #define INI_DUMP_BIT BIT(31)
+15 -1
drivers/net/wireless/intel/iwlwifi/fw/error-dump.h
··· 301 301 /** 302 302 * struct iwl_fw_ini_error_dump - ini region dump 303 303 * @header: the header of this region 304 - * @ranges: the memory ranges of this this region 304 + * @ranges: the memory ranges of this region 305 305 */ 306 306 struct iwl_fw_ini_error_dump { 307 307 struct iwl_fw_ini_error_dump_header header; ··· 321 321 __le32 reserved; 322 322 u8 data[]; 323 323 }; 324 + 325 + /** 326 + * struct iwl_fw_ini_monitor_dram_dump - ini dram monitor dump 327 + * @header - header of the region 328 + * @write_ptr - write pointer position in the dram 329 + * @cycle_cnt - cycles count 330 + * @ranges - the memory ranges of this this region 331 + */ 332 + struct iwl_fw_ini_monitor_dram_dump { 333 + struct iwl_fw_ini_error_dump_header header; 334 + __le32 write_ptr; 335 + __le32 cycle_cnt; 336 + struct iwl_fw_ini_error_dump_range ranges[]; 337 + } __packed; 324 338 325 339 /** 326 340 * struct iwl_fw_error_dump_paging - content of the UMAC's image page
+17
drivers/net/wireless/intel/iwlwifi/fw/file.h
··· 9 9 * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH 10 10 * Copyright(c) 2016 - 2017 Intel Deutschland GmbH 11 11 * Copyright(c) 2018 Intel Corporation 12 + * Copyright(c) 2019 Intel Corporation 12 13 * 13 14 * This program is free software; you can redistribute it and/or modify 14 15 * it under the terms of version 2 of the GNU General Public License as ··· 33 32 * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH 34 33 * Copyright(c) 2016 - 2017 Intel Deutschland GmbH 35 34 * Copyright(c) 2018 Intel Corporation 35 + * Copyright(c) 2019 Intel Corporation 36 36 * All rights reserved. 37 37 * 38 38 * Redistribution and use in source and binary forms, with or without ··· 145 143 IWL_UCODE_TLV_FW_GSCAN_CAPA = 50, 146 144 IWL_UCODE_TLV_FW_MEM_SEG = 51, 147 145 IWL_UCODE_TLV_IML = 52, 146 + IWL_UCODE_TLV_UMAC_DEBUG_ADDRS = 54, 147 + IWL_UCODE_TLV_LMAC_DEBUG_ADDRS = 55, 148 + IWL_UCODE_TLV_FW_RECOVERY_INFO = 57, 148 149 IWL_UCODE_TLV_TYPE_BUFFER_ALLOCATION = IWL_UCODE_INI_TLV_GROUP | 0x1, 149 150 IWL_UCODE_TLV_TYPE_HCMD = IWL_UCODE_INI_TLV_GROUP | 0x2, 150 151 IWL_UCODE_TLV_TYPE_REGIONS = IWL_UCODE_INI_TLV_GROUP | 0x3, ··· 272 267 * version of the beacon notification. 273 268 * @IWL_UCODE_TLV_API_BEACON_FILTER_V4: This ucode supports v4 of 274 269 * BEACON_FILTER_CONFIG_API_S_VER_4. 270 + * @IWL_UCODE_TLV_API_FTM_NEW_RANGE_REQ: This ucode supports v7 of 271 + * LOCATION_RANGE_REQ_CMD_API_S and v6 of LOCATION_RANGE_RESP_NTFY_API_S. 275 272 * 276 273 * @NUM_IWL_UCODE_TLV_API: number of bits used 277 274 */ ··· 300 293 IWL_UCODE_TLV_API_REDUCE_TX_POWER = (__force iwl_ucode_tlv_api_t)45, 301 294 IWL_UCODE_TLV_API_SHORT_BEACON_NOTIF = (__force iwl_ucode_tlv_api_t)46, 302 295 IWL_UCODE_TLV_API_BEACON_FILTER_V4 = (__force iwl_ucode_tlv_api_t)47, 296 + IWL_UCODE_TLV_API_FTM_NEW_RANGE_REQ = (__force iwl_ucode_tlv_api_t)49, 303 297 304 298 NUM_IWL_UCODE_TLV_API 305 299 #ifdef __CHECKER__ ··· 378 370 * capability. 379 371 * @IWL_UCODE_TLV_CAPA_CSI_REPORTING: firmware is capable of being configured 380 372 * to report the CSI information with (certain) RX frames 373 + * @IWL_UCODE_TLV_CAPA_FTM_CALIBRATED: has FTM calibrated and thus supports both 374 + * initiator and responder 381 375 * 382 376 * @IWL_UCODE_TLV_CAPA_MLME_OFFLOAD: supports MLME offload 383 377 * 384 378 * @NUM_IWL_UCODE_TLV_CAPA: number of bits used 385 379 */ 386 380 enum iwl_ucode_tlv_capa { 381 + /* set 0 */ 387 382 IWL_UCODE_TLV_CAPA_D0I3_SUPPORT = (__force iwl_ucode_tlv_capa_t)0, 388 383 IWL_UCODE_TLV_CAPA_LAR_SUPPORT = (__force iwl_ucode_tlv_capa_t)1, 389 384 IWL_UCODE_TLV_CAPA_UMAC_SCAN = (__force iwl_ucode_tlv_capa_t)2, ··· 408 397 IWL_UCODE_TLV_CAPA_LAR_MULTI_MCC = (__force iwl_ucode_tlv_capa_t)29, 409 398 IWL_UCODE_TLV_CAPA_BT_COEX_RRC = (__force iwl_ucode_tlv_capa_t)30, 410 399 IWL_UCODE_TLV_CAPA_GSCAN_SUPPORT = (__force iwl_ucode_tlv_capa_t)31, 400 + 401 + /* set 1 */ 411 402 IWL_UCODE_TLV_CAPA_STA_PM_NOTIF = (__force iwl_ucode_tlv_capa_t)38, 412 403 IWL_UCODE_TLV_CAPA_BINDING_CDB_SUPPORT = (__force iwl_ucode_tlv_capa_t)39, 413 404 IWL_UCODE_TLV_CAPA_CDB_SUPPORT = (__force iwl_ucode_tlv_capa_t)40, ··· 419 406 IWL_UCODE_TLV_CAPA_COEX_SCHEMA_2 = (__force iwl_ucode_tlv_capa_t)45, 420 407 IWL_UCODE_TLV_CAPA_CHANNEL_SWITCH_CMD = (__force iwl_ucode_tlv_capa_t)46, 421 408 IWL_UCODE_TLV_CAPA_ULTRA_HB_CHANNELS = (__force iwl_ucode_tlv_capa_t)48, 409 + IWL_UCODE_TLV_CAPA_FTM_CALIBRATED = (__force iwl_ucode_tlv_capa_t)47, 410 + 411 + /* set 2 */ 422 412 IWL_UCODE_TLV_CAPA_EXTENDED_DTS_MEASURE = (__force iwl_ucode_tlv_capa_t)64, 423 413 IWL_UCODE_TLV_CAPA_SHORT_PM_TIMEOUTS = (__force iwl_ucode_tlv_capa_t)65, 424 414 IWL_UCODE_TLV_CAPA_BT_MPLUT_SUPPORT = (__force iwl_ucode_tlv_capa_t)67, ··· 442 426 IWL_UCODE_TLV_CAPA_MCC_UPDATE_11AX_SUPPORT = (__force iwl_ucode_tlv_capa_t)89, 443 427 IWL_UCODE_TLV_CAPA_CSI_REPORTING = (__force iwl_ucode_tlv_capa_t)90, 444 428 429 + /* set 3 */ 445 430 IWL_UCODE_TLV_CAPA_MLME_OFFLOAD = (__force iwl_ucode_tlv_capa_t)96, 446 431 447 432 NUM_IWL_UCODE_TLV_CAPA
+6 -6
drivers/net/wireless/intel/iwlwifi/fw/img.h
··· 105 105 u32 n_scan_channels; 106 106 u32 standard_phy_calibration_size; 107 107 u32 flags; 108 + u32 error_log_addr; 109 + u32 error_log_size; 108 110 unsigned long _api[BITS_TO_LONGS(NUM_IWL_UCODE_TLV_API)]; 109 111 unsigned long _capa[BITS_TO_LONGS(NUM_IWL_UCODE_TLV_CAPA)]; 110 112 }; ··· 236 234 /** 237 235 * struct iwl_fw_ini_active_triggers 238 236 * @active: is this trigger active 239 - * @apply_point: last apply point that updated this trigger 240 - * @conf: active trigger 241 - * @conf_ext: second trigger, contains extra regions to dump 237 + * @size: allocated memory size of the trigger 238 + * @trig: trigger 242 239 */ 243 240 struct iwl_fw_ini_active_triggers { 244 241 bool active; 245 - enum iwl_fw_ini_apply_point apply_point; 246 - struct iwl_fw_ini_trigger *conf; 247 - struct iwl_fw_ini_trigger *conf_ext; 242 + size_t size; 243 + struct iwl_fw_ini_trigger *trig; 248 244 }; 249 245 250 246 /**
+16 -3
drivers/net/wireless/intel/iwlwifi/fw/runtime.h
··· 6 6 * GPL LICENSE SUMMARY 7 7 * 8 8 * Copyright(c) 2017 Intel Deutschland GmbH 9 - * Copyright(c) 2018 Intel Corporation 9 + * Copyright (C) 2018-2019 Intel Corporation 10 10 * 11 11 * This program is free software; you can redistribute it and/or modify 12 12 * it under the terms of version 2 of the GNU General Public License as ··· 27 27 * BSD LICENSE 28 28 * 29 29 * Copyright(c) 2017 Intel Deutschland GmbH 30 - * Copyright(c) 2018 Intel Corporation 30 + * Copyright (C) 2018-2019 Intel Corporation 31 31 * All rights reserved. 32 32 * 33 33 * Redistribution and use in source and binary forms, with or without ··· 73 73 void (*dump_end)(void *ctx); 74 74 bool (*fw_running)(void *ctx); 75 75 int (*send_hcmd)(void *ctx, struct iwl_host_cmd *host_cmd); 76 + bool (*d3_debug_enable)(void *ctx); 76 77 }; 77 78 78 79 #define MAX_NUM_LMAC 2 ··· 138 137 u8 conf; 139 138 140 139 /* ts of the beginning of a non-collect fw dbg data period */ 141 - unsigned long non_collect_ts_start[IWL_FW_TRIGGER_ID_NUM - 1]; 140 + unsigned long non_collect_ts_start[IWL_FW_TRIGGER_ID_NUM]; 142 141 u32 *d3_debug_data; 143 142 struct iwl_fw_ini_region_cfg *active_regs[IWL_FW_INI_MAX_REGION_ID]; 144 143 struct iwl_fw_ini_active_triggers active_trigs[IWL_FW_TRIGGER_ID_NUM]; ··· 161 160 162 161 static inline void iwl_fw_runtime_free(struct iwl_fw_runtime *fwrt) 163 162 { 163 + int i; 164 + 164 165 kfree(fwrt->dump.d3_debug_data); 165 166 fwrt->dump.d3_debug_data = NULL; 167 + 168 + for (i = 0; i < IWL_FW_TRIGGER_ID_NUM; i++) { 169 + struct iwl_fw_ini_active_triggers *active = 170 + &fwrt->dump.active_trigs[i]; 171 + 172 + active->active = false; 173 + active->size = 0; 174 + kfree(active->trig); 175 + active->trig = NULL; 176 + } 166 177 } 167 178 168 179 void iwl_fw_runtime_suspend(struct iwl_fw_runtime *fwrt);
+12 -3
drivers/net/wireless/intel/iwlwifi/iwl-config.h
··· 7 7 * 8 8 * Copyright(c) 2007 - 2014 Intel Corporation. All rights reserved. 9 9 * Copyright (C) 2016 - 2017 Intel Deutschland GmbH 10 - * Copyright(c) 2018 Intel Corporation 10 + * Copyright(c) 2018 - 2019 Intel Corporation 11 11 * 12 12 * This program is free software; you can redistribute it and/or modify 13 13 * it under the terms of version 2 of the GNU General Public License as ··· 29 29 * 30 30 * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved. 31 31 * Copyright (C) 2016 - 2017 Intel Deutschland GmbH 32 - * Copyright(c) 2018 Intel Corporation 32 + * Copyright(c) 2018 - 2019 Intel Corporation 33 33 * All rights reserved. 34 34 * 35 35 * Redistribution and use in source and binary forms, with or without ··· 89 89 IWL_DEVICE_FAMILY_9000, 90 90 IWL_DEVICE_FAMILY_22000, 91 91 IWL_DEVICE_FAMILY_22560, 92 + IWL_DEVICE_FAMILY_AX210, 92 93 }; 93 94 94 95 /* ··· 381 380 * @d3_debug_data_base_addr: base address where D3 debug data is stored 382 381 * @d3_debug_data_length: length of the D3 debug data 383 382 * @bisr_workaround: BISR hardware workaround (for 22260 series devices) 383 + * @min_txq_size: minimum number of slots required in a TX queue 384 + * @umac_prph_offset: offset to add to UMAC periphery address 384 385 * 385 386 * We enable the driver to be backward compatible wrt. hardware features. 386 387 * API differences in uCode shouldn't be handled here but through TLVs ··· 448 445 u32 extra_phy_cfg_flags; 449 446 u32 d3_debug_data_base_addr; 450 447 u32 d3_debug_data_length; 448 + u32 min_txq_size; 449 + u32 umac_prph_offset; 451 450 }; 452 451 453 452 extern const struct iwl_csr_params iwl_csr_v1; ··· 565 560 extern const struct iwl_cfg iwl22000_2ax_cfg_qnj_hr_a0_f0; 566 561 extern const struct iwl_cfg iwl22000_2ax_cfg_qnj_hr_b0_f0; 567 562 extern const struct iwl_cfg iwl22000_2ax_cfg_qnj_hr_b0; 568 - extern const struct iwl_cfg iwl22000_2ax_cfg_qnj_jf_b0; 563 + extern const struct iwl_cfg iwl9560_2ac_cfg_qnj_jf_b0; 569 564 extern const struct iwl_cfg iwl22000_2ax_cfg_qnj_hr_a0; 570 565 extern const struct iwl_cfg iwl22560_2ax_cfg_su_cdb; 566 + extern const struct iwl_cfg iwlax210_2ax_cfg_so_jf_a0; 567 + extern const struct iwl_cfg iwlax210_2ax_cfg_so_hr_a0; 568 + extern const struct iwl_cfg iwlax210_2ax_cfg_so_gf_a0; 569 + extern const struct iwl_cfg iwlax210_2ax_cfg_ty_gf_a0; 571 570 #endif /* CPTCFG_IWLMVM || CPTCFG_IWLFMAC */ 572 571 573 572 #endif /* __IWL_CONFIG_H__ */
+5
drivers/net/wireless/intel/iwlwifi/iwl-csr.h
··· 180 180 /* Bits for CSR_HW_IF_CONFIG_REG */ 181 181 #define CSR_HW_IF_CONFIG_REG_MSK_MAC_DASH (0x00000003) 182 182 #define CSR_HW_IF_CONFIG_REG_MSK_MAC_STEP (0x0000000C) 183 + #define CSR_HW_IF_CONFIG_REG_BIT_MONITOR_SRAM (0x00000080) 183 184 #define CSR_HW_IF_CONFIG_REG_MSK_BOARD_VER (0x000000C0) 184 185 #define CSR_HW_IF_CONFIG_REG_BIT_MAC_SI (0x00000100) 185 186 #define CSR_HW_IF_CONFIG_REG_BIT_RADIO_SI (0x00000200) ··· 328 327 #define CSR_HW_REV_TYPE_QNJ (0x0000360) 329 328 #define CSR_HW_REV_TYPE_QNJ_B0 (0x0000364) 330 329 #define CSR_HW_REV_TYPE_HR_CDB (0x0000340) 330 + #define CSR_HW_REV_TYPE_SO (0x0000370) 331 + #define CSR_HW_REV_TYPE_TY (0x0000420) 331 332 332 333 /* RF_ID value */ 333 334 #define CSR_HW_RF_ID_TYPE_JF (0x00105100) 334 335 #define CSR_HW_RF_ID_TYPE_HR (0x0010A000) 335 336 #define CSR_HW_RF_ID_TYPE_HRCDB (0x00109F00) 337 + #define CSR_HW_RF_ID_TYPE_GF (0x0010D000) 336 338 337 339 /* HW_RF CHIP ID */ 338 340 #define CSR_HW_RF_ID_TYPE_CHIP_ID(_val) (((_val) >> 12) & 0xFFF) ··· 597 593 MSIX_HW_INT_CAUSES_REG_ALIVE = BIT(0), 598 594 MSIX_HW_INT_CAUSES_REG_WAKEUP = BIT(1), 599 595 MSIX_HW_INT_CAUSES_REG_IPC = BIT(1), 596 + MSIX_HW_INT_CAUSES_REG_IML = BIT(2), 600 597 MSIX_HW_INT_CAUSES_REG_SW_ERR_V2 = BIT(5), 601 598 MSIX_HW_INT_CAUSES_REG_CT_KILL = BIT(6), 602 599 MSIX_HW_INT_CAUSES_REG_RF_KILL = BIT(7),
+3 -2
drivers/net/wireless/intel/iwlwifi/iwl-debug.h
··· 1 1 /****************************************************************************** 2 2 * 3 3 * Copyright(c) 2003 - 2014 Intel Corporation. All rights reserved. 4 + * Copyright (C) 2018 Intel Corporation 4 5 * 5 6 * Portions of this file are derived from the ipw3945 project. 6 7 * ··· 160 159 /* 0x000F0000 - 0x00010000 */ 161 160 #define IWL_DL_FW 0x00010000 162 161 #define IWL_DL_RF_KILL 0x00020000 163 - #define IWL_DL_FW_ERRORS 0x00040000 162 + #define IWL_DL_TPT 0x00040000 164 163 /* 0x00F00000 - 0x00100000 */ 165 164 #define IWL_DL_RATE 0x00100000 166 165 #define IWL_DL_CALIB 0x00200000 ··· 194 193 #define IWL_DEBUG_CALIB(p, f, a...) IWL_DEBUG(p, IWL_DL_CALIB, f, ## a) 195 194 #define IWL_DEBUG_FW(p, f, a...) IWL_DEBUG(p, IWL_DL_FW, f, ## a) 196 195 #define IWL_DEBUG_RF_KILL(p, f, a...) IWL_DEBUG(p, IWL_DL_RF_KILL, f, ## a) 197 - #define IWL_DEBUG_FW_ERRORS(p, f, a...) IWL_DEBUG(p, IWL_DL_FW_ERRORS, f, ## a) 198 196 #define IWL_DEBUG_DROP(p, f, a...) IWL_DEBUG(p, IWL_DL_DROP, f, ## a) 199 197 #define IWL_DEBUG_DROP_LIMIT(p, f, a...) \ 200 198 IWL_DEBUG_LIMIT(p, IWL_DL_DROP, f, ## a) ··· 215 215 #define IWL_DEBUG_DEV_RADIO(p, f, a...) IWL_DEBUG_DEV(p, IWL_DL_RADIO, f, ## a) 216 216 #define IWL_DEBUG_POWER(p, f, a...) IWL_DEBUG(p, IWL_DL_POWER, f, ## a) 217 217 #define IWL_DEBUG_11H(p, f, a...) IWL_DEBUG(p, IWL_DL_11H, f, ## a) 218 + #define IWL_DEBUG_TPT(p, f, a...) IWL_DEBUG(p, IWL_DL_TPT, f, ## a) 218 219 #define IWL_DEBUG_RPM(p, f, a...) IWL_DEBUG(p, IWL_DL_RPM, f, ## a) 219 220 #define IWL_DEBUG_LAR(p, f, a...) IWL_DEBUG(p, IWL_DL_LAR, f, ## a) 220 221
+53 -2
drivers/net/wireless/intel/iwlwifi/iwl-drv.c
··· 8 8 * Copyright(c) 2007 - 2014 Intel Corporation. All rights reserved. 9 9 * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH 10 10 * Copyright(c) 2016 - 2017 Intel Deutschland GmbH 11 + * Copyright(c) 2018 - 2019 Intel Corporation 11 12 * 12 13 * This program is free software; you can redistribute it and/or modify 13 14 * it under the terms of version 2 of the GNU General Public License as ··· 31 30 * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved. 32 31 * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH 33 32 * Copyright(c) 2016 - 2017 Intel Deutschland GmbH 33 + * Copyright(c) 2018 - 2019 Intel Corporation 34 34 * All rights reserved. 35 35 * 36 36 * Redistribution and use in source and binary forms, with or without ··· 77 75 #include "iwl-dbg-tlv.h" 78 76 #include "iwl-config.h" 79 77 #include "iwl-modparams.h" 78 + #include "fw/api/alive.h" 80 79 81 80 /****************************************************************************** 82 81 * ··· 591 588 return 0; 592 589 } 593 590 591 + #define FW_ADDR_CACHE_CONTROL 0xC0000000 592 + 594 593 static int iwl_parse_tlv_firmware(struct iwl_drv *drv, 595 594 const struct firmware *ucode_raw, 596 595 struct iwl_firmware_pieces *pieces, ··· 1090 1085 return -ENOMEM; 1091 1086 break; 1092 1087 } 1088 + case IWL_UCODE_TLV_FW_RECOVERY_INFO: { 1089 + struct { 1090 + __le32 buf_addr; 1091 + __le32 buf_size; 1092 + } *recov_info = (void *)tlv_data; 1093 + 1094 + if (tlv_len != sizeof(*recov_info)) 1095 + goto invalid_tlv_len; 1096 + capa->error_log_addr = 1097 + le32_to_cpu(recov_info->buf_addr); 1098 + capa->error_log_size = 1099 + le32_to_cpu(recov_info->buf_size); 1100 + } 1101 + break; 1102 + case IWL_UCODE_TLV_UMAC_DEBUG_ADDRS: { 1103 + struct iwl_umac_debug_addrs *dbg_ptrs = 1104 + (void *)tlv_data; 1105 + 1106 + if (tlv_len != sizeof(*dbg_ptrs)) 1107 + goto invalid_tlv_len; 1108 + if (drv->trans->cfg->device_family < 1109 + IWL_DEVICE_FAMILY_22000) 1110 + break; 1111 + drv->trans->umac_error_event_table = 1112 + le32_to_cpu(dbg_ptrs->error_info_addr) & 1113 + ~FW_ADDR_CACHE_CONTROL; 1114 + drv->trans->error_event_table_tlv_status |= 1115 + IWL_ERROR_EVENT_TABLE_UMAC; 1116 + break; 1117 + } 1118 + case IWL_UCODE_TLV_LMAC_DEBUG_ADDRS: { 1119 + struct iwl_lmac_debug_addrs *dbg_ptrs = 1120 + (void *)tlv_data; 1121 + 1122 + if (tlv_len != sizeof(*dbg_ptrs)) 1123 + goto invalid_tlv_len; 1124 + if (drv->trans->cfg->device_family < 1125 + IWL_DEVICE_FAMILY_22000) 1126 + break; 1127 + drv->trans->lmac_error_event_table[0] = 1128 + le32_to_cpu(dbg_ptrs->error_event_table_ptr) & 1129 + ~FW_ADDR_CACHE_CONTROL; 1130 + drv->trans->error_event_table_tlv_status |= 1131 + IWL_ERROR_EVENT_TABLE_LMAC1; 1132 + break; 1133 + } 1093 1134 case IWL_UCODE_TLV_TYPE_BUFFER_ALLOCATION: 1094 1135 case IWL_UCODE_TLV_TYPE_HCMD: 1095 1136 case IWL_UCODE_TLV_TYPE_REGIONS: ··· 1313 1262 fw->ucode_capa.standard_phy_calibration_size = 1314 1263 IWL_DEFAULT_STANDARD_PHY_CALIBRATE_TBL_SIZE; 1315 1264 fw->ucode_capa.n_scan_channels = IWL_DEFAULT_SCAN_CHANNELS; 1316 - /* dump all fw memory areas by default except d3 debug data */ 1317 - fw->dbg.dump_mask = 0xfffdffff; 1265 + /* dump all fw memory areas by default */ 1266 + fw->dbg.dump_mask = 0xffffffff; 1318 1267 1319 1268 pieces = kzalloc(sizeof(*pieces), GFP_KERNEL); 1320 1269 if (!pieces)
+7 -4
drivers/net/wireless/intel/iwlwifi/iwl-io.c
··· 7 7 * 8 8 * Copyright(c) 2003 - 2014 Intel Corporation. All rights reserved. 9 9 * Copyright(c) 2015 - 2016 Intel Deutschland GmbH 10 - * Copyright (C) 2018 Intel Corporation 10 + * Copyright(C) 2018 - 2019 Intel Corporation 11 11 * 12 12 * This program is free software; you can redistribute it and/or modify it 13 13 * under the terms of version 2 of the GNU General Public License as ··· 29 29 * 30 30 * Copyright(c) 2003 - 2014 Intel Corporation. All rights reserved. 31 31 * Copyright(c) 2015 - 2016 Intel Deutschland GmbH 32 - * Copyright (C) 2018 Intel Corporation 32 + * Copyright (C) 2018 - 2019 Intel Corporation 33 33 * All rights reserved. 34 34 * 35 35 * Redistribution and use in source and binary forms, with or without ··· 307 307 if (trans->cfg->device_family < IWL_DEVICE_FAMILY_9000) 308 308 iwl_write_prph(trans, DEVICE_SET_NMI_REG, 309 309 DEVICE_SET_NMI_VAL_DRV); 310 + else if (trans->cfg->device_family < IWL_DEVICE_FAMILY_AX210) 311 + iwl_write_umac_prph(trans, UREG_NIC_SET_NMI_DRIVER, 312 + UREG_NIC_SET_NMI_DRIVER_NMI_FROM_DRIVER_MSK); 310 313 else 311 - iwl_write_prph(trans, UREG_NIC_SET_NMI_DRIVER, 312 - UREG_NIC_SET_NMI_DRIVER_NMI_FROM_DRIVER_MSK); 314 + iwl_write_umac_prph(trans, UREG_DOORBELL_TO_ISR6, 315 + UREG_DOORBELL_TO_ISR6_NMI_BIT); 313 316 } 314 317 IWL_EXPORT_SYMBOL(iwl_force_nmi); 315 318
+41 -2
drivers/net/wireless/intel/iwlwifi/iwl-io.h
··· 5 5 * 6 6 * GPL LICENSE SUMMARY 7 7 * 8 - * Copyright (C) 2018 Intel Corporation 8 + * Copyright (C) 2018 - 2019 Intel Corporation 9 9 * 10 10 * This program is free software; you can redistribute it and/or modify it 11 11 * under the terms of version 2 of the GNU General Public License as ··· 25 25 * 26 26 * BSD LICENSE 27 27 * 28 - * Copyright (C) 2018 Intel Corporation 28 + * Copyright (C) 2018 - 2019 Intel Corporation 29 29 * All rights reserved. 30 30 * 31 31 * Redistribution and use in source and binary forms, with or without ··· 103 103 104 104 /* Error handling */ 105 105 int iwl_dump_fh(struct iwl_trans *trans, char **buf); 106 + 107 + /* 108 + * UMAC periphery address space changed from 0xA00000 to 0xD00000 starting from 109 + * device family AX200. So peripheries used in families above and below AX200 110 + * should go through iwl_..._umac_..._prph. 111 + */ 112 + static inline u32 iwl_umac_prph(struct iwl_trans *trans, u32 ofs) 113 + { 114 + return ofs + trans->cfg->umac_prph_offset; 115 + } 116 + 117 + static inline u32 iwl_read_umac_prph_no_grab(struct iwl_trans *trans, u32 ofs) 118 + { 119 + return iwl_read_prph_no_grab(trans, ofs + trans->cfg->umac_prph_offset); 120 + } 121 + 122 + static inline u32 iwl_read_umac_prph(struct iwl_trans *trans, u32 ofs) 123 + { 124 + return iwl_read_prph(trans, ofs + trans->cfg->umac_prph_offset); 125 + } 126 + 127 + static inline void iwl_write_umac_prph_no_grab(struct iwl_trans *trans, u32 ofs, 128 + u32 val) 129 + { 130 + iwl_write_prph_no_grab(trans, ofs + trans->cfg->umac_prph_offset, val); 131 + } 132 + 133 + static inline void iwl_write_umac_prph(struct iwl_trans *trans, u32 ofs, 134 + u32 val) 135 + { 136 + iwl_write_prph(trans, ofs + trans->cfg->umac_prph_offset, val); 137 + } 138 + 139 + static inline int iwl_poll_umac_prph_bit(struct iwl_trans *trans, u32 addr, 140 + u32 bits, u32 mask, int timeout) 141 + { 142 + return iwl_poll_prph_bit(trans, addr + trans->cfg->umac_prph_offset, 143 + bits, mask, timeout); 144 + } 106 145 107 146 #endif
+3 -3
drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c
··· 1102 1102 int max_num_ch = cfg->nvm_type == IWL_NVM_EXT ? 1103 1103 IWL_NVM_NUM_CHANNELS_EXT : IWL_NVM_NUM_CHANNELS; 1104 1104 1105 - if (WARN_ON_ONCE(num_of_ch > NL80211_MAX_SUPP_REG_RULES)) 1106 - return ERR_PTR(-EINVAL); 1107 - 1108 1105 if (WARN_ON(num_of_ch > max_num_ch)) 1109 1106 num_of_ch = max_num_ch; 1107 + 1108 + if (WARN_ON_ONCE(num_of_ch > NL80211_MAX_SUPP_REG_RULES)) 1109 + return ERR_PTR(-EINVAL); 1110 1110 1111 1111 IWL_DEBUG_DEV(dev, IWL_DL_LAR, "building regdom for %d channels\n", 1112 1112 num_of_ch);
+5 -2
drivers/net/wireless/intel/iwlwifi/iwl-prph.h
··· 8 8 * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved. 9 9 * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH 10 10 * Copyright(c) 2016 Intel Deutschland GmbH 11 - * Copyright (C) 2018 Intel Corporation 11 + * Copyright (C) 2018 - 2019 Intel Corporation 12 12 * 13 13 * This program is free software; you can redistribute it and/or modify 14 14 * it under the terms of version 2 of the GNU General Public License as ··· 31 31 * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved. 32 32 * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH 33 33 * Copyright(c) 2016 Intel Deutschland GmbH 34 - * Copyright (C) 2018 Intel Corporation 34 + * Copyright (C) 2018 - 2019 Intel Corporation 35 35 * All rights reserved. 36 36 * 37 37 * Redistribution and use in source and binary forms, with or without ··· 433 433 #define HPM_DEBUG 0xA03440 434 434 #define PERSISTENCE_BIT BIT(12) 435 435 #define PREG_WFPM_ACCESS BIT(12) 436 + 437 + #define UREG_DOORBELL_TO_ISR6 0xA05C04 438 + #define UREG_DOORBELL_TO_ISR6_NMI_BIT BIT(0) 436 439 #endif /* __iwl_prph_h__ */
+10
drivers/net/wireless/intel/iwlwifi/iwl-trans.h
··· 232 232 IWL_HCMD_DFL_DUP = BIT(1), 233 233 }; 234 234 235 + enum iwl_error_event_table_status { 236 + IWL_ERROR_EVENT_TABLE_LMAC1 = BIT(0), 237 + IWL_ERROR_EVENT_TABLE_LMAC2 = BIT(1), 238 + IWL_ERROR_EVENT_TABLE_UMAC = BIT(2), 239 + }; 240 + 235 241 /** 236 242 * struct iwl_host_cmd - Host command to the uCode 237 243 * ··· 765 759 * mode is set during the initialization phase and is not 766 760 * supposed to change during runtime. 767 761 * @dbg_rec_on: true iff there is a fw debug recording currently active 762 + * @lmac_error_event_table: addrs of lmacs error tables 763 + * @umac_error_event_table: addr of umac error table 764 + * @error_event_table_tlv_status: bitmap that indicates what error table 765 + * pointers was recevied via TLV. use enum &iwl_error_event_table_status 768 766 */ 769 767 struct iwl_trans { 770 768 const struct iwl_trans_ops *ops;
+1
drivers/net/wireless/intel/iwlwifi/mvm/Makefile
··· 5 5 iwlmvm-y += scan.o time-event.o rs.o rs-fw.o 6 6 iwlmvm-y += power.o coex.o 7 7 iwlmvm-y += tt.o offloading.o tdls.o 8 + iwlmvm-y += ftm-responder.o ftm-initiator.o 8 9 iwlmvm-$(CONFIG_IWLWIFI_DEBUGFS) += debugfs.o debugfs-vif.o 9 10 iwlmvm-$(CONFIG_IWLWIFI_LEDS) += led.o 10 11 iwlmvm-$(CONFIG_PM) += d3.o
+6
drivers/net/wireless/intel/iwlwifi/mvm/constants.h
··· 8 8 * Copyright(c) 2013 - 2014 Intel Corporation. All rights reserved. 9 9 * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH 10 10 * Copyright(c) 2015 Intel Deutschland GmbH 11 + * Copyright(c) 2018 - 2019 Intel Corporation 11 12 * 12 13 * This program is free software; you can redistribute it and/or modify 13 14 * it under the terms of version 2 of the GNU General Public License as ··· 31 30 * Copyright(c) 2013 - 2014 Intel Corporation. All rights reserved. 32 31 * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH 33 32 * Copyright(c) 2015 Intel Deutschland GmbH 33 + * Copyright(c) 2018 - 2019 Intel Corporation 34 34 * All rights reserved. 35 35 * 36 36 * Redistribution and use in source and binary forms, with or without ··· 65 63 #define __MVM_CONSTANTS_H 66 64 67 65 #include <linux/ieee80211.h> 66 + #include "fw-api.h" 68 67 69 68 #define IWL_MVM_UAPSD_NOAGG_BSSIDS_NUM 20 70 69 ··· 148 145 #define IWL_MVM_RS_TPC_SR_NO_INCREASE 85 /* percent */ 149 146 #define IWL_MVM_RS_TPC_TX_POWER_STEP 3 150 147 #define IWL_MVM_ENABLE_EBS 1 148 + #define IWL_MVM_FTM_INITIATOR_ALGO IWL_TOF_ALGO_TYPE_MAX_LIKE 149 + #define IWL_MVM_FTM_INITIATOR_DYNACK true 150 + #define IWL_MVM_D3_DEBUG false 151 151 152 152 #endif /* __MVM_CONSTANTS_H */
+1 -1
drivers/net/wireless/intel/iwlwifi/mvm/d3.c
··· 1899 1899 static int iwl_mvm_check_rt_status(struct iwl_mvm *mvm, 1900 1900 struct ieee80211_vif *vif) 1901 1901 { 1902 - u32 base = mvm->error_event_table[0]; 1902 + u32 base = mvm->trans->lmac_error_event_table[0]; 1903 1903 struct error_table_start { 1904 1904 /* cf. struct iwl_error_event_table */ 1905 1905 u32 valid;
+106
drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c
··· 1188 1188 return ret ?: count; 1189 1189 } 1190 1190 1191 + static int _iwl_dbgfs_inject_beacon_ie(struct iwl_mvm *mvm, char *bin, int len) 1192 + { 1193 + struct ieee80211_vif *vif; 1194 + struct iwl_mvm_vif *mvmvif; 1195 + struct sk_buff *beacon; 1196 + struct ieee80211_tx_info *info; 1197 + struct iwl_mac_beacon_cmd beacon_cmd = {}; 1198 + u8 rate; 1199 + u16 flags; 1200 + int i; 1201 + 1202 + len /= 2; 1203 + 1204 + /* Element len should be represented by u8 */ 1205 + if (len >= U8_MAX) 1206 + return -EINVAL; 1207 + 1208 + if (!iwl_mvm_firmware_running(mvm)) 1209 + return -EIO; 1210 + 1211 + if (!iwl_mvm_has_new_tx_api(mvm) && 1212 + !fw_has_api(&mvm->fw->ucode_capa, 1213 + IWL_UCODE_TLV_API_NEW_BEACON_TEMPLATE)) 1214 + return -EINVAL; 1215 + 1216 + rcu_read_lock(); 1217 + 1218 + for (i = 0; i < NUM_MAC_INDEX_DRIVER; i++) { 1219 + vif = iwl_mvm_rcu_dereference_vif_id(mvm, i, true); 1220 + if (!vif) 1221 + continue; 1222 + 1223 + if (vif->type == NL80211_IFTYPE_AP) 1224 + break; 1225 + } 1226 + 1227 + if (i == NUM_MAC_INDEX_DRIVER || !vif) 1228 + goto out_err; 1229 + 1230 + mvm->hw->extra_beacon_tailroom = len; 1231 + 1232 + beacon = ieee80211_beacon_get_template(mvm->hw, vif, NULL); 1233 + if (!beacon) 1234 + goto out_err; 1235 + 1236 + if (len && hex2bin(skb_put_zero(beacon, len), bin, len)) { 1237 + dev_kfree_skb(beacon); 1238 + goto out_err; 1239 + } 1240 + 1241 + mvmvif = iwl_mvm_vif_from_mac80211(vif); 1242 + info = IEEE80211_SKB_CB(beacon); 1243 + rate = iwl_mvm_mac_ctxt_get_lowest_rate(info, vif); 1244 + flags = iwl_mvm_mac80211_idx_to_hwrate(rate); 1245 + 1246 + if (rate == IWL_FIRST_CCK_RATE) 1247 + flags |= IWL_MAC_BEACON_CCK; 1248 + 1249 + beacon_cmd.flags = cpu_to_le16(flags); 1250 + beacon_cmd.byte_cnt = cpu_to_le16((u16)beacon->len); 1251 + beacon_cmd.template_id = cpu_to_le32((u32)mvmvif->id); 1252 + 1253 + iwl_mvm_mac_ctxt_set_tim(mvm, &beacon_cmd.tim_idx, 1254 + &beacon_cmd.tim_size, 1255 + beacon->data, beacon->len); 1256 + 1257 + mutex_lock(&mvm->mutex); 1258 + iwl_mvm_mac_ctxt_send_beacon_cmd(mvm, beacon, &beacon_cmd, 1259 + sizeof(beacon_cmd)); 1260 + mutex_unlock(&mvm->mutex); 1261 + 1262 + dev_kfree_skb(beacon); 1263 + 1264 + rcu_read_unlock(); 1265 + return 0; 1266 + 1267 + out_err: 1268 + rcu_read_unlock(); 1269 + return -EINVAL; 1270 + } 1271 + 1272 + static ssize_t iwl_dbgfs_inject_beacon_ie_write(struct iwl_mvm *mvm, 1273 + char *buf, size_t count, 1274 + loff_t *ppos) 1275 + { 1276 + int ret = _iwl_dbgfs_inject_beacon_ie(mvm, buf, count); 1277 + 1278 + mvm->hw->extra_beacon_tailroom = 0; 1279 + return ret ?: count; 1280 + } 1281 + 1282 + static ssize_t iwl_dbgfs_inject_beacon_ie_restore_write(struct iwl_mvm *mvm, 1283 + char *buf, 1284 + size_t count, 1285 + loff_t *ppos) 1286 + { 1287 + int ret = _iwl_dbgfs_inject_beacon_ie(mvm, NULL, 0); 1288 + 1289 + mvm->hw->extra_beacon_tailroom = 0; 1290 + return ret ?: count; 1291 + } 1292 + 1191 1293 static ssize_t iwl_dbgfs_fw_dbg_conf_read(struct file *file, 1192 1294 char __user *user_buf, 1193 1295 size_t count, loff_t *ppos) ··· 1908 1806 MVM_DEBUGFS_WRITE_FILE_OPS(indirection_tbl, 1909 1807 (IWL_RSS_INDIRECTION_TABLE_SIZE * 2)); 1910 1808 MVM_DEBUGFS_WRITE_FILE_OPS(inject_packet, 512); 1809 + MVM_DEBUGFS_WRITE_FILE_OPS(inject_beacon_ie, 512); 1810 + MVM_DEBUGFS_WRITE_FILE_OPS(inject_beacon_ie_restore, 512); 1911 1811 1912 1812 MVM_DEBUGFS_READ_FILE_OPS(uapsd_noagg_bssids); 1913 1813 ··· 2111 2007 MVM_DEBUGFS_ADD_FILE(send_echo_cmd, mvm->debugfs_dir, 0200); 2112 2008 MVM_DEBUGFS_ADD_FILE(indirection_tbl, mvm->debugfs_dir, 0200); 2113 2009 MVM_DEBUGFS_ADD_FILE(inject_packet, mvm->debugfs_dir, 0200); 2010 + MVM_DEBUGFS_ADD_FILE(inject_beacon_ie, mvm->debugfs_dir, 0200); 2011 + MVM_DEBUGFS_ADD_FILE(inject_beacon_ie_restore, mvm->debugfs_dir, 0200); 2114 2012 #ifdef CONFIG_ACPI 2115 2013 MVM_DEBUGFS_ADD_FILE(sar_geo_profile, dbgfs_dir, 0400); 2116 2014 #endif
+654
drivers/net/wireless/intel/iwlwifi/mvm/ftm-initiator.c
··· 1 + /****************************************************************************** 2 + * 3 + * This file is provided under a dual BSD/GPLv2 license. When using or 4 + * redistributing this file, you may do so under either license. 5 + * 6 + * GPL LICENSE SUMMARY 7 + * 8 + * Copyright(c) 2015 - 2017 Intel Deutschland GmbH 9 + * Copyright (C) 2018 Intel Corporation 10 + * Copyright (C) 2019 Intel Corporation 11 + * 12 + * This program is free software; you can redistribute it and/or modify 13 + * it under the terms of version 2 of the GNU General Public License as 14 + * published by the Free Software Foundation. 15 + * 16 + * This program is distributed in the hope that it will be useful, but 17 + * WITHOUT ANY WARRANTY; without even the implied warranty of 18 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 19 + * General Public License for more details. 20 + * 21 + * The full GNU General Public License is included in this distribution 22 + * in the file called COPYING. 23 + * 24 + * Contact Information: 25 + * Intel Linux Wireless <linuxwifi@intel.com> 26 + * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 27 + * 28 + * BSD LICENSE 29 + * 30 + * Copyright(c) 2015 - 2017 Intel Deutschland GmbH 31 + * Copyright (C) 2018 Intel Corporation 32 + * Copyright (C) 2019 Intel Corporation 33 + * All rights reserved. 34 + * 35 + * Redistribution and use in source and binary forms, with or without 36 + * modification, are permitted provided that the following conditions 37 + * are met: 38 + * 39 + * * Redistributions of source code must retain the above copyright 40 + * notice, this list of conditions and the following disclaimer. 41 + * * Redistributions in binary form must reproduce the above copyright 42 + * notice, this list of conditions and the following disclaimer in 43 + * the documentation and/or other materials provided with the 44 + * distribution. 45 + * * Neither the name Intel Corporation nor the names of its 46 + * contributors may be used to endorse or promote products derived 47 + * from this software without specific prior written permission. 48 + * 49 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 50 + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 51 + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 52 + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 53 + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 54 + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 55 + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 56 + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 57 + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 58 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 59 + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 60 + * 61 + *****************************************************************************/ 62 + #include <linux/etherdevice.h> 63 + #include <linux/math64.h> 64 + #include <net/cfg80211.h> 65 + #include "mvm.h" 66 + #include "iwl-io.h" 67 + #include "iwl-prph.h" 68 + #include "constants.h" 69 + 70 + struct iwl_mvm_loc_entry { 71 + struct list_head list; 72 + u8 addr[ETH_ALEN]; 73 + u8 lci_len, civic_len; 74 + u8 buf[]; 75 + }; 76 + 77 + static void iwl_mvm_ftm_reset(struct iwl_mvm *mvm) 78 + { 79 + struct iwl_mvm_loc_entry *e, *t; 80 + 81 + mvm->ftm_initiator.req = NULL; 82 + mvm->ftm_initiator.req_wdev = NULL; 83 + memset(mvm->ftm_initiator.responses, 0, 84 + sizeof(mvm->ftm_initiator.responses)); 85 + list_for_each_entry_safe(e, t, &mvm->ftm_initiator.loc_list, list) { 86 + list_del(&e->list); 87 + kfree(e); 88 + } 89 + } 90 + 91 + void iwl_mvm_ftm_restart(struct iwl_mvm *mvm) 92 + { 93 + struct cfg80211_pmsr_result result = { 94 + .status = NL80211_PMSR_STATUS_FAILURE, 95 + .final = 1, 96 + .host_time = ktime_get_boot_ns(), 97 + .type = NL80211_PMSR_TYPE_FTM, 98 + }; 99 + int i; 100 + 101 + lockdep_assert_held(&mvm->mutex); 102 + 103 + if (!mvm->ftm_initiator.req) 104 + return; 105 + 106 + for (i = 0; i < mvm->ftm_initiator.req->n_peers; i++) { 107 + memcpy(result.addr, mvm->ftm_initiator.req->peers[i].addr, 108 + ETH_ALEN); 109 + result.ftm.burst_index = mvm->ftm_initiator.responses[i]; 110 + 111 + cfg80211_pmsr_report(mvm->ftm_initiator.req_wdev, 112 + mvm->ftm_initiator.req, 113 + &result, GFP_KERNEL); 114 + } 115 + 116 + cfg80211_pmsr_complete(mvm->ftm_initiator.req_wdev, 117 + mvm->ftm_initiator.req, GFP_KERNEL); 118 + iwl_mvm_ftm_reset(mvm); 119 + } 120 + 121 + static int 122 + iwl_ftm_range_request_status_to_err(enum iwl_tof_range_request_status s) 123 + { 124 + switch (s) { 125 + case IWL_TOF_RANGE_REQUEST_STATUS_SUCCESS: 126 + return 0; 127 + case IWL_TOF_RANGE_REQUEST_STATUS_BUSY: 128 + return -EBUSY; 129 + default: 130 + WARN_ON_ONCE(1); 131 + return -EIO; 132 + } 133 + } 134 + 135 + static void iwl_mvm_ftm_cmd_v5(struct iwl_mvm *mvm, struct ieee80211_vif *vif, 136 + struct iwl_tof_range_req_cmd_v5 *cmd, 137 + struct cfg80211_pmsr_request *req) 138 + { 139 + int i; 140 + 141 + cmd->request_id = req->cookie; 142 + cmd->num_of_ap = req->n_peers; 143 + 144 + /* use maximum for "no timeout" or bigger than what we can do */ 145 + if (!req->timeout || req->timeout > 255 * 100) 146 + cmd->req_timeout = 255; 147 + else 148 + cmd->req_timeout = DIV_ROUND_UP(req->timeout, 100); 149 + 150 + /* 151 + * We treat it always as random, since if not we'll 152 + * have filled our local address there instead. 153 + */ 154 + cmd->macaddr_random = 1; 155 + memcpy(cmd->macaddr_template, req->mac_addr, ETH_ALEN); 156 + for (i = 0; i < ETH_ALEN; i++) 157 + cmd->macaddr_mask[i] = ~req->mac_addr_mask[i]; 158 + 159 + if (vif->bss_conf.assoc) 160 + memcpy(cmd->range_req_bssid, vif->bss_conf.bssid, ETH_ALEN); 161 + else 162 + eth_broadcast_addr(cmd->range_req_bssid); 163 + } 164 + 165 + static void iwl_mvm_ftm_cmd(struct iwl_mvm *mvm, struct ieee80211_vif *vif, 166 + struct iwl_tof_range_req_cmd *cmd, 167 + struct cfg80211_pmsr_request *req) 168 + { 169 + int i; 170 + 171 + cmd->initiator_flags = 172 + cpu_to_le32(IWL_TOF_INITIATOR_FLAGS_MACADDR_RANDOM | 173 + IWL_TOF_INITIATOR_FLAGS_NON_ASAP_SUPPORT); 174 + cmd->request_id = req->cookie; 175 + cmd->num_of_ap = req->n_peers; 176 + 177 + /* 178 + * Use a large value for "no timeout". Don't use the maximum value 179 + * because of fw limitations. 180 + */ 181 + if (req->timeout) 182 + cmd->req_timeout_ms = cpu_to_le32(req->timeout); 183 + else 184 + cmd->req_timeout_ms = cpu_to_le32(0xfffff); 185 + 186 + memcpy(cmd->macaddr_template, req->mac_addr, ETH_ALEN); 187 + for (i = 0; i < ETH_ALEN; i++) 188 + cmd->macaddr_mask[i] = ~req->mac_addr_mask[i]; 189 + 190 + if (vif->bss_conf.assoc) 191 + memcpy(cmd->range_req_bssid, vif->bss_conf.bssid, ETH_ALEN); 192 + else 193 + eth_broadcast_addr(cmd->range_req_bssid); 194 + 195 + /* TODO: fill in tsf_mac_id if needed */ 196 + cmd->tsf_mac_id = cpu_to_le32(0xff); 197 + } 198 + 199 + static int iwl_mvm_ftm_target_chandef(struct iwl_mvm *mvm, 200 + struct cfg80211_pmsr_request_peer *peer, 201 + u8 *channel, u8 *bandwidth, 202 + u8 *ctrl_ch_position) 203 + { 204 + u32 freq = peer->chandef.chan->center_freq; 205 + 206 + *channel = ieee80211_frequency_to_channel(freq); 207 + 208 + switch (peer->chandef.width) { 209 + case NL80211_CHAN_WIDTH_20_NOHT: 210 + *bandwidth = IWL_TOF_BW_20_LEGACY; 211 + break; 212 + case NL80211_CHAN_WIDTH_20: 213 + *bandwidth = IWL_TOF_BW_20_HT; 214 + break; 215 + case NL80211_CHAN_WIDTH_40: 216 + *bandwidth = IWL_TOF_BW_40; 217 + break; 218 + case NL80211_CHAN_WIDTH_80: 219 + *bandwidth = IWL_TOF_BW_80; 220 + break; 221 + default: 222 + IWL_ERR(mvm, "Unsupported BW in FTM request (%d)\n", 223 + peer->chandef.width); 224 + return -EINVAL; 225 + } 226 + 227 + *ctrl_ch_position = (peer->chandef.width > NL80211_CHAN_WIDTH_20) ? 228 + iwl_mvm_get_ctrl_pos(&peer->chandef) : 0; 229 + 230 + return 0; 231 + } 232 + 233 + static int 234 + iwl_mvm_ftm_put_target_v2(struct iwl_mvm *mvm, 235 + struct cfg80211_pmsr_request_peer *peer, 236 + struct iwl_tof_range_req_ap_entry_v2 *target) 237 + { 238 + int ret; 239 + 240 + ret = iwl_mvm_ftm_target_chandef(mvm, peer, &target->channel_num, 241 + &target->bandwidth, 242 + &target->ctrl_ch_position); 243 + if (ret) 244 + return ret; 245 + 246 + memcpy(target->bssid, peer->addr, ETH_ALEN); 247 + target->burst_period = 248 + cpu_to_le16(peer->ftm.burst_period); 249 + target->samples_per_burst = peer->ftm.ftms_per_burst; 250 + target->num_of_bursts = peer->ftm.num_bursts_exp; 251 + target->measure_type = 0; /* regular two-sided FTM */ 252 + target->retries_per_sample = peer->ftm.ftmr_retries; 253 + target->asap_mode = peer->ftm.asap; 254 + target->enable_dyn_ack = IWL_MVM_FTM_INITIATOR_DYNACK; 255 + 256 + if (peer->ftm.request_lci) 257 + target->location_req |= IWL_TOF_LOC_LCI; 258 + if (peer->ftm.request_civicloc) 259 + target->location_req |= IWL_TOF_LOC_CIVIC; 260 + 261 + target->algo_type = IWL_MVM_FTM_INITIATOR_ALGO; 262 + 263 + return 0; 264 + } 265 + 266 + #define FTM_PUT_FLAG(flag) (target->initiator_ap_flags |= \ 267 + cpu_to_le32(IWL_INITIATOR_AP_FLAGS_##flag)) 268 + 269 + static int iwl_mvm_ftm_put_target(struct iwl_mvm *mvm, 270 + struct cfg80211_pmsr_request_peer *peer, 271 + struct iwl_tof_range_req_ap_entry *target) 272 + { 273 + int ret; 274 + 275 + ret = iwl_mvm_ftm_target_chandef(mvm, peer, &target->channel_num, 276 + &target->bandwidth, 277 + &target->ctrl_ch_position); 278 + if (ret) 279 + return ret; 280 + 281 + memcpy(target->bssid, peer->addr, ETH_ALEN); 282 + target->burst_period = 283 + cpu_to_le16(peer->ftm.burst_period); 284 + target->samples_per_burst = peer->ftm.ftms_per_burst; 285 + target->num_of_bursts = peer->ftm.num_bursts_exp; 286 + target->ftmr_max_retries = peer->ftm.ftmr_retries; 287 + target->initiator_ap_flags = cpu_to_le32(0); 288 + 289 + if (peer->ftm.asap) 290 + FTM_PUT_FLAG(ASAP); 291 + 292 + if (peer->ftm.request_lci) 293 + FTM_PUT_FLAG(LCI_REQUEST); 294 + 295 + if (peer->ftm.request_civicloc) 296 + FTM_PUT_FLAG(CIVIC_REQUEST); 297 + 298 + if (IWL_MVM_FTM_INITIATOR_DYNACK) 299 + FTM_PUT_FLAG(DYN_ACK); 300 + 301 + if (IWL_MVM_FTM_INITIATOR_ALGO == IWL_TOF_ALGO_TYPE_LINEAR_REG) 302 + FTM_PUT_FLAG(ALGO_LR); 303 + else if (IWL_MVM_FTM_INITIATOR_ALGO == IWL_TOF_ALGO_TYPE_FFT) 304 + FTM_PUT_FLAG(ALGO_FFT); 305 + 306 + return 0; 307 + } 308 + 309 + int iwl_mvm_ftm_start(struct iwl_mvm *mvm, struct ieee80211_vif *vif, 310 + struct cfg80211_pmsr_request *req) 311 + { 312 + struct iwl_tof_range_req_cmd_v5 cmd_v5; 313 + struct iwl_tof_range_req_cmd cmd; 314 + bool new_api = fw_has_api(&mvm->fw->ucode_capa, 315 + IWL_UCODE_TLV_API_FTM_NEW_RANGE_REQ); 316 + u8 num_of_ap; 317 + struct iwl_host_cmd hcmd = { 318 + .id = iwl_cmd_id(TOF_RANGE_REQ_CMD, LOCATION_GROUP, 0), 319 + .dataflags[0] = IWL_HCMD_DFL_DUP, 320 + }; 321 + u32 status = 0; 322 + int err, i; 323 + 324 + lockdep_assert_held(&mvm->mutex); 325 + 326 + if (mvm->ftm_initiator.req) 327 + return -EBUSY; 328 + 329 + if (new_api) { 330 + iwl_mvm_ftm_cmd(mvm, vif, &cmd, req); 331 + hcmd.data[0] = &cmd; 332 + hcmd.len[0] = sizeof(cmd); 333 + num_of_ap = cmd.num_of_ap; 334 + } else { 335 + iwl_mvm_ftm_cmd_v5(mvm, vif, &cmd_v5, req); 336 + hcmd.data[0] = &cmd_v5; 337 + hcmd.len[0] = sizeof(cmd_v5); 338 + num_of_ap = cmd_v5.num_of_ap; 339 + } 340 + 341 + for (i = 0; i < num_of_ap; i++) { 342 + struct cfg80211_pmsr_request_peer *peer = &req->peers[i]; 343 + 344 + if (new_api) 345 + err = iwl_mvm_ftm_put_target(mvm, peer, &cmd.ap[i]); 346 + else 347 + err = iwl_mvm_ftm_put_target_v2(mvm, peer, 348 + &cmd_v5.ap[i]); 349 + 350 + if (err) 351 + return err; 352 + } 353 + 354 + err = iwl_mvm_send_cmd_status(mvm, &hcmd, &status); 355 + if (!err && status) { 356 + IWL_ERR(mvm, "FTM range request command failure, status: %u\n", 357 + status); 358 + err = iwl_ftm_range_request_status_to_err(status); 359 + } 360 + 361 + if (!err) { 362 + mvm->ftm_initiator.req = req; 363 + mvm->ftm_initiator.req_wdev = ieee80211_vif_to_wdev(vif); 364 + } 365 + 366 + return err; 367 + } 368 + 369 + void iwl_mvm_ftm_abort(struct iwl_mvm *mvm, struct cfg80211_pmsr_request *req) 370 + { 371 + struct iwl_tof_range_abort_cmd cmd = { 372 + .request_id = req->cookie, 373 + }; 374 + 375 + lockdep_assert_held(&mvm->mutex); 376 + 377 + if (req != mvm->ftm_initiator.req) 378 + return; 379 + 380 + if (iwl_mvm_send_cmd_pdu(mvm, iwl_cmd_id(TOF_RANGE_ABORT_CMD, 381 + LOCATION_GROUP, 0), 382 + 0, sizeof(cmd), &cmd)) 383 + IWL_ERR(mvm, "failed to abort FTM process\n"); 384 + } 385 + 386 + static int iwl_mvm_ftm_find_peer(struct cfg80211_pmsr_request *req, 387 + const u8 *addr) 388 + { 389 + int i; 390 + 391 + for (i = 0; i < req->n_peers; i++) { 392 + struct cfg80211_pmsr_request_peer *peer = &req->peers[i]; 393 + 394 + if (ether_addr_equal_unaligned(peer->addr, addr)) 395 + return i; 396 + } 397 + 398 + return -ENOENT; 399 + } 400 + 401 + static u64 iwl_mvm_ftm_get_host_time(struct iwl_mvm *mvm, __le32 fw_gp2_ts) 402 + { 403 + u32 gp2_ts = le32_to_cpu(fw_gp2_ts); 404 + u32 curr_gp2, diff; 405 + u64 now_from_boot_ns; 406 + 407 + iwl_mvm_get_sync_time(mvm, &curr_gp2, &now_from_boot_ns); 408 + 409 + if (curr_gp2 >= gp2_ts) 410 + diff = curr_gp2 - gp2_ts; 411 + else 412 + diff = curr_gp2 + (U32_MAX - gp2_ts + 1); 413 + 414 + return now_from_boot_ns - (u64)diff * 1000; 415 + } 416 + 417 + static void iwl_mvm_ftm_get_lci_civic(struct iwl_mvm *mvm, 418 + struct cfg80211_pmsr_result *res) 419 + { 420 + struct iwl_mvm_loc_entry *entry; 421 + 422 + list_for_each_entry(entry, &mvm->ftm_initiator.loc_list, list) { 423 + if (!ether_addr_equal_unaligned(res->addr, entry->addr)) 424 + continue; 425 + 426 + if (entry->lci_len) { 427 + res->ftm.lci_len = entry->lci_len; 428 + res->ftm.lci = entry->buf; 429 + } 430 + 431 + if (entry->civic_len) { 432 + res->ftm.civicloc_len = entry->civic_len; 433 + res->ftm.civicloc = entry->buf + entry->lci_len; 434 + } 435 + 436 + /* we found the entry we needed */ 437 + break; 438 + } 439 + } 440 + 441 + static int iwl_mvm_ftm_range_resp_valid(struct iwl_mvm *mvm, u8 request_id, 442 + u8 num_of_aps) 443 + { 444 + lockdep_assert_held(&mvm->mutex); 445 + 446 + if (request_id != (u8)mvm->ftm_initiator.req->cookie) { 447 + IWL_ERR(mvm, "Request ID mismatch, got %u, active %u\n", 448 + request_id, (u8)mvm->ftm_initiator.req->cookie); 449 + return -EINVAL; 450 + } 451 + 452 + if (num_of_aps > mvm->ftm_initiator.req->n_peers) { 453 + IWL_ERR(mvm, "FTM range response invalid\n"); 454 + return -EINVAL; 455 + } 456 + 457 + return 0; 458 + } 459 + 460 + static void iwl_mvm_debug_range_resp(struct iwl_mvm *mvm, u8 index, 461 + struct cfg80211_pmsr_result *res) 462 + { 463 + s64 rtt_avg = res->ftm.rtt_avg * 100; 464 + 465 + do_div(rtt_avg, 6666); 466 + 467 + IWL_DEBUG_INFO(mvm, "entry %d\n", index); 468 + IWL_DEBUG_INFO(mvm, "\tstatus: %d\n", res->status); 469 + IWL_DEBUG_INFO(mvm, "\tBSSID: %pM\n", res->addr); 470 + IWL_DEBUG_INFO(mvm, "\thost time: %llu\n", res->host_time); 471 + IWL_DEBUG_INFO(mvm, "\tburst index: %hhu\n", res->ftm.burst_index); 472 + IWL_DEBUG_INFO(mvm, "\tsuccess num: %u\n", res->ftm.num_ftmr_successes); 473 + IWL_DEBUG_INFO(mvm, "\trssi: %d\n", res->ftm.rssi_avg); 474 + IWL_DEBUG_INFO(mvm, "\trssi spread: %hhu\n", res->ftm.rssi_spread); 475 + IWL_DEBUG_INFO(mvm, "\trtt: %lld\n", res->ftm.rtt_avg); 476 + IWL_DEBUG_INFO(mvm, "\trtt var: %llu\n", res->ftm.rtt_variance); 477 + IWL_DEBUG_INFO(mvm, "\trtt spread: %llu\n", res->ftm.rtt_spread); 478 + IWL_DEBUG_INFO(mvm, "\tdistance: %lld\n", rtt_avg); 479 + } 480 + 481 + void iwl_mvm_ftm_range_resp(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb) 482 + { 483 + struct iwl_rx_packet *pkt = rxb_addr(rxb); 484 + struct iwl_tof_range_rsp_ntfy_v5 *fw_resp_v5 = (void *)pkt->data; 485 + struct iwl_tof_range_rsp_ntfy *fw_resp = (void *)pkt->data; 486 + int i; 487 + bool new_api = fw_has_api(&mvm->fw->ucode_capa, 488 + IWL_UCODE_TLV_API_FTM_NEW_RANGE_REQ); 489 + u8 num_of_aps, last_in_batch; 490 + 491 + lockdep_assert_held(&mvm->mutex); 492 + 493 + if (!mvm->ftm_initiator.req) { 494 + IWL_ERR(mvm, "Got FTM response but have no request?\n"); 495 + return; 496 + } 497 + 498 + if (new_api) { 499 + if (iwl_mvm_ftm_range_resp_valid(mvm, fw_resp->request_id, 500 + fw_resp->num_of_aps)) 501 + return; 502 + 503 + num_of_aps = fw_resp->num_of_aps; 504 + last_in_batch = fw_resp->last_report; 505 + } else { 506 + if (iwl_mvm_ftm_range_resp_valid(mvm, fw_resp_v5->request_id, 507 + fw_resp_v5->num_of_aps)) 508 + return; 509 + 510 + num_of_aps = fw_resp_v5->num_of_aps; 511 + last_in_batch = fw_resp_v5->last_in_batch; 512 + } 513 + 514 + IWL_DEBUG_INFO(mvm, "Range response received\n"); 515 + IWL_DEBUG_INFO(mvm, "request id: %lld, num of entries: %hhu\n", 516 + mvm->ftm_initiator.req->cookie, num_of_aps); 517 + 518 + for (i = 0; i < num_of_aps && i < IWL_MVM_TOF_MAX_APS; i++) { 519 + struct cfg80211_pmsr_result result = {}; 520 + struct iwl_tof_range_rsp_ap_entry_ntfy *fw_ap; 521 + int peer_idx; 522 + 523 + if (new_api) { 524 + fw_ap = &fw_resp->ap[i]; 525 + result.final = fw_resp->ap[i].last_burst; 526 + } else { 527 + /* the first part is the same for old and new APIs */ 528 + fw_ap = (void *)&fw_resp_v5->ap[i]; 529 + /* 530 + * FIXME: the firmware needs to report this, we don't 531 + * even know the number of bursts the responder picked 532 + * (if we asked it to) 533 + */ 534 + result.final = 0; 535 + } 536 + 537 + peer_idx = iwl_mvm_ftm_find_peer(mvm->ftm_initiator.req, 538 + fw_ap->bssid); 539 + if (peer_idx < 0) { 540 + IWL_WARN(mvm, 541 + "Unknown address (%pM, target #%d) in FTM response\n", 542 + fw_ap->bssid, i); 543 + continue; 544 + } 545 + 546 + switch (fw_ap->measure_status) { 547 + case IWL_TOF_ENTRY_SUCCESS: 548 + result.status = NL80211_PMSR_STATUS_SUCCESS; 549 + break; 550 + case IWL_TOF_ENTRY_TIMING_MEASURE_TIMEOUT: 551 + result.status = NL80211_PMSR_STATUS_TIMEOUT; 552 + break; 553 + case IWL_TOF_ENTRY_NO_RESPONSE: 554 + result.status = NL80211_PMSR_STATUS_FAILURE; 555 + result.ftm.failure_reason = 556 + NL80211_PMSR_FTM_FAILURE_NO_RESPONSE; 557 + break; 558 + case IWL_TOF_ENTRY_REQUEST_REJECTED: 559 + result.status = NL80211_PMSR_STATUS_FAILURE; 560 + result.ftm.failure_reason = 561 + NL80211_PMSR_FTM_FAILURE_PEER_BUSY; 562 + result.ftm.busy_retry_time = fw_ap->refusal_period; 563 + break; 564 + default: 565 + result.status = NL80211_PMSR_STATUS_FAILURE; 566 + result.ftm.failure_reason = 567 + NL80211_PMSR_FTM_FAILURE_UNSPECIFIED; 568 + break; 569 + } 570 + memcpy(result.addr, fw_ap->bssid, ETH_ALEN); 571 + result.host_time = iwl_mvm_ftm_get_host_time(mvm, 572 + fw_ap->timestamp); 573 + result.type = NL80211_PMSR_TYPE_FTM; 574 + result.ftm.burst_index = mvm->ftm_initiator.responses[peer_idx]; 575 + mvm->ftm_initiator.responses[peer_idx]++; 576 + result.ftm.rssi_avg = fw_ap->rssi; 577 + result.ftm.rssi_avg_valid = 1; 578 + result.ftm.rssi_spread = fw_ap->rssi_spread; 579 + result.ftm.rssi_spread_valid = 1; 580 + result.ftm.rtt_avg = (s32)le32_to_cpu(fw_ap->rtt); 581 + result.ftm.rtt_avg_valid = 1; 582 + result.ftm.rtt_variance = le32_to_cpu(fw_ap->rtt_variance); 583 + result.ftm.rtt_variance_valid = 1; 584 + result.ftm.rtt_spread = le32_to_cpu(fw_ap->rtt_spread); 585 + result.ftm.rtt_spread_valid = 1; 586 + 587 + iwl_mvm_ftm_get_lci_civic(mvm, &result); 588 + 589 + cfg80211_pmsr_report(mvm->ftm_initiator.req_wdev, 590 + mvm->ftm_initiator.req, 591 + &result, GFP_KERNEL); 592 + 593 + iwl_mvm_debug_range_resp(mvm, i, &result); 594 + } 595 + 596 + if (last_in_batch) { 597 + cfg80211_pmsr_complete(mvm->ftm_initiator.req_wdev, 598 + mvm->ftm_initiator.req, 599 + GFP_KERNEL); 600 + iwl_mvm_ftm_reset(mvm); 601 + } 602 + } 603 + 604 + void iwl_mvm_ftm_lc_notif(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb) 605 + { 606 + struct iwl_rx_packet *pkt = rxb_addr(rxb); 607 + const struct ieee80211_mgmt *mgmt = (void *)pkt->data; 608 + size_t len = iwl_rx_packet_payload_len(pkt); 609 + struct iwl_mvm_loc_entry *entry; 610 + const u8 *ies, *lci, *civic, *msr_ie; 611 + size_t ies_len, lci_len = 0, civic_len = 0; 612 + size_t baselen = IEEE80211_MIN_ACTION_SIZE + 613 + sizeof(mgmt->u.action.u.ftm); 614 + static const u8 rprt_type_lci = IEEE80211_SPCT_MSR_RPRT_TYPE_LCI; 615 + static const u8 rprt_type_civic = IEEE80211_SPCT_MSR_RPRT_TYPE_CIVIC; 616 + 617 + if (len <= baselen) 618 + return; 619 + 620 + lockdep_assert_held(&mvm->mutex); 621 + 622 + ies = mgmt->u.action.u.ftm.variable; 623 + ies_len = len - baselen; 624 + 625 + msr_ie = cfg80211_find_ie_match(WLAN_EID_MEASURE_REPORT, ies, ies_len, 626 + &rprt_type_lci, 1, 4); 627 + if (msr_ie) { 628 + lci = msr_ie + 2; 629 + lci_len = msr_ie[1]; 630 + } 631 + 632 + msr_ie = cfg80211_find_ie_match(WLAN_EID_MEASURE_REPORT, ies, ies_len, 633 + &rprt_type_civic, 1, 4); 634 + if (msr_ie) { 635 + civic = msr_ie + 2; 636 + civic_len = msr_ie[1]; 637 + } 638 + 639 + entry = kmalloc(sizeof(*entry) + lci_len + civic_len, GFP_KERNEL); 640 + if (!entry) 641 + return; 642 + 643 + memcpy(entry->addr, mgmt->bssid, ETH_ALEN); 644 + 645 + entry->lci_len = lci_len; 646 + if (lci_len) 647 + memcpy(entry->buf, lci, lci_len); 648 + 649 + entry->civic_len = civic_len; 650 + if (civic_len) 651 + memcpy(entry->buf + lci_len, civic, civic_len); 652 + 653 + list_add_tail(&entry->list, &mvm->ftm_initiator.loc_list); 654 + }
+244
drivers/net/wireless/intel/iwlwifi/mvm/ftm-responder.c
··· 1 + /****************************************************************************** 2 + * 3 + * This file is provided under a dual BSD/GPLv2 license. When using or 4 + * redistributing this file, you may do so under either license. 5 + * 6 + * GPL LICENSE SUMMARY 7 + * 8 + * Copyright(c) 2015 - 2017 Intel Deutschland GmbH 9 + * Copyright (C) 2018 Intel Corporation 10 + * 11 + * This program is free software; you can redistribute it and/or modify 12 + * it under the terms of version 2 of the GNU General Public License as 13 + * published by the Free Software Foundation. 14 + * 15 + * This program is distributed in the hope that it will be useful, but 16 + * WITHOUT ANY WARRANTY; without even the implied warranty of 17 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 18 + * General Public License for more details. 19 + * 20 + * The full GNU General Public License is included in this distribution 21 + * in the file called COPYING. 22 + * 23 + * Contact Information: 24 + * Intel Linux Wireless <linuxwifi@intel.com> 25 + * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 26 + * 27 + * BSD LICENSE 28 + * 29 + * Copyright(c) 2015 - 2017 Intel Deutschland GmbH 30 + * Copyright (C) 2018 Intel Corporation 31 + * All rights reserved. 32 + * 33 + * Redistribution and use in source and binary forms, with or without 34 + * modification, are permitted provided that the following conditions 35 + * are met: 36 + * 37 + * * Redistributions of source code must retain the above copyright 38 + * notice, this list of conditions and the following disclaimer. 39 + * * Redistributions in binary form must reproduce the above copyright 40 + * notice, this list of conditions and the following disclaimer in 41 + * the documentation and/or other materials provided with the 42 + * distribution. 43 + * * Neither the name Intel Corporation nor the names of its 44 + * contributors may be used to endorse or promote products derived 45 + * from this software without specific prior written permission. 46 + * 47 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 48 + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 49 + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 50 + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 51 + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 52 + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 53 + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 54 + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 55 + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 56 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 57 + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 58 + * 59 + *****************************************************************************/ 60 + #include <net/cfg80211.h> 61 + #include <linux/etherdevice.h> 62 + #include "mvm.h" 63 + #include "constants.h" 64 + 65 + static int 66 + iwl_mvm_ftm_responder_cmd(struct iwl_mvm *mvm, 67 + struct ieee80211_vif *vif, 68 + struct cfg80211_chan_def *chandef) 69 + { 70 + struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); 71 + struct iwl_tof_responder_config_cmd cmd = { 72 + .channel_num = chandef->chan->hw_value, 73 + .cmd_valid_fields = 74 + cpu_to_le32(IWL_TOF_RESPONDER_CMD_VALID_CHAN_INFO | 75 + IWL_TOF_RESPONDER_CMD_VALID_BSSID | 76 + IWL_TOF_RESPONDER_CMD_VALID_STA_ID), 77 + .sta_id = mvmvif->bcast_sta.sta_id, 78 + }; 79 + 80 + lockdep_assert_held(&mvm->mutex); 81 + 82 + switch (chandef->width) { 83 + case NL80211_CHAN_WIDTH_20_NOHT: 84 + cmd.bandwidth = IWL_TOF_BW_20_LEGACY; 85 + break; 86 + case NL80211_CHAN_WIDTH_20: 87 + cmd.bandwidth = IWL_TOF_BW_20_HT; 88 + break; 89 + case NL80211_CHAN_WIDTH_40: 90 + cmd.bandwidth = IWL_TOF_BW_40; 91 + cmd.ctrl_ch_position = iwl_mvm_get_ctrl_pos(chandef); 92 + break; 93 + case NL80211_CHAN_WIDTH_80: 94 + cmd.bandwidth = IWL_TOF_BW_80; 95 + cmd.ctrl_ch_position = iwl_mvm_get_ctrl_pos(chandef); 96 + break; 97 + default: 98 + WARN_ON(1); 99 + return -EINVAL; 100 + } 101 + 102 + memcpy(cmd.bssid, vif->addr, ETH_ALEN); 103 + 104 + return iwl_mvm_send_cmd_pdu(mvm, iwl_cmd_id(TOF_RESPONDER_CONFIG_CMD, 105 + LOCATION_GROUP, 0), 106 + 0, sizeof(cmd), &cmd); 107 + } 108 + 109 + static int 110 + iwl_mvm_ftm_responder_dyn_cfg_cmd(struct iwl_mvm *mvm, 111 + struct ieee80211_vif *vif, 112 + struct ieee80211_ftm_responder_params *params) 113 + { 114 + struct iwl_tof_responder_dyn_config_cmd cmd = { 115 + .lci_len = cpu_to_le32(params->lci_len + 2), 116 + .civic_len = cpu_to_le32(params->civicloc_len + 2), 117 + }; 118 + u8 data[IWL_LCI_CIVIC_IE_MAX_SIZE] = {0}; 119 + struct iwl_host_cmd hcmd = { 120 + .id = iwl_cmd_id(TOF_RESPONDER_DYN_CONFIG_CMD, 121 + LOCATION_GROUP, 0), 122 + .data[0] = &cmd, 123 + .len[0] = sizeof(cmd), 124 + .data[1] = &data, 125 + /* .len[1] set later */ 126 + /* may not be able to DMA from stack */ 127 + .dataflags[1] = IWL_HCMD_DFL_DUP, 128 + }; 129 + u32 aligned_lci_len = ALIGN(params->lci_len + 2, 4); 130 + u32 aligned_civicloc_len = ALIGN(params->civicloc_len + 2, 4); 131 + u8 *pos = data; 132 + 133 + lockdep_assert_held(&mvm->mutex); 134 + 135 + if (aligned_lci_len + aligned_civicloc_len > sizeof(data)) { 136 + IWL_ERR(mvm, "LCI/civicloc data too big (%zd + %zd)\n", 137 + params->lci_len, params->civicloc_len); 138 + return -ENOBUFS; 139 + } 140 + 141 + pos[0] = WLAN_EID_MEASURE_REPORT; 142 + pos[1] = params->lci_len; 143 + memcpy(pos + 2, params->lci, params->lci_len); 144 + 145 + pos += aligned_lci_len; 146 + pos[0] = WLAN_EID_MEASURE_REPORT; 147 + pos[1] = params->civicloc_len; 148 + memcpy(pos + 2, params->civicloc, params->civicloc_len); 149 + 150 + hcmd.len[1] = aligned_lci_len + aligned_civicloc_len; 151 + 152 + return iwl_mvm_send_cmd(mvm, &hcmd); 153 + } 154 + 155 + int iwl_mvm_ftm_start_responder(struct iwl_mvm *mvm, struct ieee80211_vif *vif) 156 + { 157 + struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); 158 + struct ieee80211_ftm_responder_params *params; 159 + struct ieee80211_chanctx_conf ctx, *pctx; 160 + u16 *phy_ctxt_id; 161 + struct iwl_mvm_phy_ctxt *phy_ctxt; 162 + int ret; 163 + 164 + params = vif->bss_conf.ftmr_params; 165 + 166 + lockdep_assert_held(&mvm->mutex); 167 + 168 + if (WARN_ON_ONCE(!vif->bss_conf.ftm_responder)) 169 + return -EINVAL; 170 + 171 + if (vif->p2p || vif->type != NL80211_IFTYPE_AP || 172 + !mvmvif->ap_ibss_active) { 173 + IWL_ERR(mvm, "Cannot start responder, not in AP mode\n"); 174 + return -EIO; 175 + } 176 + 177 + rcu_read_lock(); 178 + pctx = rcu_dereference(vif->chanctx_conf); 179 + /* Copy the ctx to unlock the rcu and send the phy ctxt. We don't care 180 + * about changes in the ctx after releasing the lock because the driver 181 + * is still protected by the mutex. */ 182 + ctx = *pctx; 183 + phy_ctxt_id = (u16 *)pctx->drv_priv; 184 + rcu_read_unlock(); 185 + 186 + phy_ctxt = &mvm->phy_ctxts[*phy_ctxt_id]; 187 + ret = iwl_mvm_phy_ctxt_changed(mvm, phy_ctxt, &ctx.def, 188 + ctx.rx_chains_static, 189 + ctx.rx_chains_dynamic); 190 + if (ret) 191 + return ret; 192 + 193 + ret = iwl_mvm_ftm_responder_cmd(mvm, vif, &ctx.def); 194 + if (ret) 195 + return ret; 196 + 197 + if (params) 198 + ret = iwl_mvm_ftm_responder_dyn_cfg_cmd(mvm, vif, params); 199 + 200 + return ret; 201 + } 202 + 203 + void iwl_mvm_ftm_restart_responder(struct iwl_mvm *mvm, 204 + struct ieee80211_vif *vif) 205 + { 206 + if (!vif->bss_conf.ftm_responder) 207 + return; 208 + 209 + iwl_mvm_ftm_start_responder(mvm, vif); 210 + } 211 + 212 + void iwl_mvm_ftm_responder_stats(struct iwl_mvm *mvm, 213 + struct iwl_rx_cmd_buffer *rxb) 214 + { 215 + struct iwl_rx_packet *pkt = rxb_addr(rxb); 216 + struct iwl_ftm_responder_stats *resp = (void *)pkt->data; 217 + struct cfg80211_ftm_responder_stats *stats = &mvm->ftm_resp_stats; 218 + u32 flags = le32_to_cpu(resp->flags); 219 + 220 + if (resp->success_ftm == resp->ftm_per_burst) 221 + stats->success_num++; 222 + else if (resp->success_ftm >= 2) 223 + stats->partial_num++; 224 + else 225 + stats->failed_num++; 226 + 227 + if ((flags & FTM_RESP_STAT_ASAP_REQ) && 228 + (flags & FTM_RESP_STAT_ASAP_RESP)) 229 + stats->asap_num++; 230 + 231 + if (flags & FTM_RESP_STAT_NON_ASAP_RESP) 232 + stats->non_asap_num++; 233 + 234 + stats->total_duration_ms += le32_to_cpu(resp->duration) / USEC_PER_MSEC; 235 + 236 + if (flags & FTM_RESP_STAT_TRIGGER_UNKNOWN) 237 + stats->unknown_triggers_num++; 238 + 239 + if (flags & FTM_RESP_STAT_DUP) 240 + stats->reschedule_requests_num++; 241 + 242 + if (flags & FTM_RESP_STAT_NON_ASAP_OUT_WIN) 243 + stats->out_of_window_triggers_num++; 244 + }
+80 -14
drivers/net/wireless/intel/iwlwifi/mvm/fw.c
··· 8 8 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. 9 9 * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH 10 10 * Copyright(c) 2016 - 2017 Intel Deutschland GmbH 11 - * Copyright(c) 2018 Intel Corporation 11 + * Copyright(c) 2018 - 2019 Intel Corporation 12 12 * 13 13 * This program is free software; you can redistribute it and/or modify 14 14 * it under the terms of version 2 of the GNU General Public License as ··· 31 31 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. 32 32 * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH 33 33 * Copyright(c) 2016 - 2017 Intel Deutschland GmbH 34 - * Copyright(c) 2018 Intel Corporation 34 + * Copyright(c) 2018 - 2019 Intel Corporation 35 35 * All rights reserved. 36 36 * 37 37 * Redistribution and use in source and binary forms, with or without ··· 218 218 struct iwl_lmac_alive *lmac1; 219 219 struct iwl_lmac_alive *lmac2 = NULL; 220 220 u16 status; 221 - u32 umac_error_event_table; 221 + u32 lmac_error_event_table, umac_error_event_table; 222 222 223 223 if (iwl_rx_packet_payload_len(pkt) == sizeof(*palive)) { 224 224 palive = (void *)pkt->data; ··· 233 233 status = le16_to_cpu(palive3->status); 234 234 } 235 235 236 - mvm->error_event_table[0] = le32_to_cpu(lmac1->error_event_table_ptr); 237 - if (lmac2) 238 - mvm->error_event_table[1] = 239 - le32_to_cpu(lmac2->error_event_table_ptr); 240 - mvm->log_event_table = le32_to_cpu(lmac1->log_event_table_ptr); 236 + lmac_error_event_table = 237 + le32_to_cpu(lmac1->dbg_ptrs.error_event_table_ptr); 238 + iwl_fw_lmac1_set_alive_err_table(mvm->trans, lmac_error_event_table); 241 239 242 - umac_error_event_table = le32_to_cpu(umac->error_info_addr); 240 + if (lmac2) 241 + mvm->trans->lmac_error_event_table[1] = 242 + le32_to_cpu(lmac2->dbg_ptrs.error_event_table_ptr); 243 + 244 + umac_error_event_table = le32_to_cpu(umac->dbg_ptrs.error_info_addr); 243 245 244 246 if (!umac_error_event_table) { 245 247 mvm->support_umac_log = false; 246 248 } else if (umac_error_event_table >= 247 249 mvm->trans->cfg->min_umac_error_event_table) { 248 250 mvm->support_umac_log = true; 249 - mvm->umac_error_event_table = umac_error_event_table; 250 251 } else { 251 252 IWL_ERR(mvm, 252 253 "Not valid error log pointer 0x%08X for %s uCode\n", 253 - mvm->umac_error_event_table, 254 + umac_error_event_table, 254 255 (mvm->fwrt.cur_fw_img == IWL_UCODE_INIT) ? 255 256 "Init" : "RT"); 256 257 mvm->support_umac_log = false; 257 258 } 258 259 259 - alive_data->scd_base_addr = le32_to_cpu(lmac1->scd_base_ptr); 260 + if (mvm->support_umac_log) 261 + iwl_fw_umac_set_alive_err_table(mvm->trans, 262 + umac_error_event_table); 263 + 264 + alive_data->scd_base_addr = le32_to_cpu(lmac1->dbg_ptrs.scd_base_ptr); 260 265 alive_data->valid = status == IWL_ALIVE_STATUS_OK; 261 266 262 267 IWL_DEBUG_FW(mvm, ··· 351 346 if (trans->cfg->device_family >= IWL_DEVICE_FAMILY_22000) 352 347 IWL_ERR(mvm, 353 348 "SecBoot CPU1 Status: 0x%x, CPU2 Status: 0x%x\n", 354 - iwl_read_prph(trans, UMAG_SB_CPU_1_STATUS), 355 - iwl_read_prph(trans, UMAG_SB_CPU_2_STATUS)); 349 + iwl_read_umac_prph(trans, UMAG_SB_CPU_1_STATUS), 350 + iwl_read_umac_prph(trans, 351 + UMAG_SB_CPU_2_STATUS)); 356 352 else if (trans->cfg->device_family >= IWL_DEVICE_FAMILY_8000) 357 353 IWL_ERR(mvm, 358 354 "SecBoot CPU1 Status: 0x%x, CPU2 Status: 0x%x\n", ··· 419 413 iwl_wait_init_complete, 420 414 NULL); 421 415 416 + iwl_fw_dbg_apply_point(&mvm->fwrt, IWL_FW_INI_APPLY_EARLY); 417 + 422 418 /* Will also start the device */ 423 419 ret = iwl_mvm_load_ucode_wait_alive(mvm, IWL_UCODE_REGULAR); 424 420 if (ret) { 425 421 IWL_ERR(mvm, "Failed to start RT ucode: %d\n", ret); 426 422 goto error; 427 423 } 424 + iwl_fw_dbg_apply_point(&mvm->fwrt, IWL_FW_INI_APPLY_AFTER_ALIVE); 428 425 429 426 /* Send init config command to mark that we are sending NVM access 430 427 * commands ··· 980 971 } 981 972 #endif /* CONFIG_ACPI */ 982 973 974 + void iwl_mvm_send_recovery_cmd(struct iwl_mvm *mvm, u32 flags) 975 + { 976 + u32 error_log_size = mvm->fw->ucode_capa.error_log_size; 977 + int ret; 978 + u32 resp; 979 + 980 + struct iwl_fw_error_recovery_cmd recovery_cmd = { 981 + .flags = cpu_to_le32(flags), 982 + .buf_size = 0, 983 + }; 984 + struct iwl_host_cmd host_cmd = { 985 + .id = WIDE_ID(SYSTEM_GROUP, FW_ERROR_RECOVERY_CMD), 986 + .flags = CMD_WANT_SKB, 987 + .data = {&recovery_cmd, }, 988 + .len = {sizeof(recovery_cmd), }, 989 + }; 990 + 991 + /* no error log was defined in TLV */ 992 + if (!error_log_size) 993 + return; 994 + 995 + if (flags & ERROR_RECOVERY_UPDATE_DB) { 996 + /* no buf was allocated while HW reset */ 997 + if (!mvm->error_recovery_buf) 998 + return; 999 + 1000 + host_cmd.data[1] = mvm->error_recovery_buf; 1001 + host_cmd.len[1] = error_log_size; 1002 + host_cmd.dataflags[1] = IWL_HCMD_DFL_NOCOPY; 1003 + recovery_cmd.buf_size = cpu_to_le32(error_log_size); 1004 + } 1005 + 1006 + ret = iwl_mvm_send_cmd(mvm, &host_cmd); 1007 + kfree(mvm->error_recovery_buf); 1008 + mvm->error_recovery_buf = NULL; 1009 + 1010 + if (ret) { 1011 + IWL_ERR(mvm, "Failed to send recovery cmd %d\n", ret); 1012 + return; 1013 + } 1014 + 1015 + /* skb respond is only relevant in ERROR_RECOVERY_UPDATE_DB */ 1016 + if (flags & ERROR_RECOVERY_UPDATE_DB) { 1017 + resp = le32_to_cpu(*(__le32 *)host_cmd.resp_pkt->data); 1018 + if (resp) 1019 + IWL_ERR(mvm, 1020 + "Failed to send recovery cmd blob was invalid %d\n", 1021 + resp); 1022 + } 1023 + } 1024 + 983 1025 static int iwl_mvm_sar_init(struct iwl_mvm *mvm) 984 1026 { 985 1027 int ret; ··· 1266 1206 /* allow FW/transport low power modes if not during restart */ 1267 1207 if (!test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status)) 1268 1208 iwl_mvm_unref(mvm, IWL_MVM_REF_UCODE_DOWN); 1209 + 1210 + if (test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status)) 1211 + iwl_mvm_send_recovery_cmd(mvm, ERROR_RECOVERY_UPDATE_DB); 1212 + 1213 + if (iwl_acpi_get_eckv(mvm->dev, &mvm->ext_clock_valid)) 1214 + IWL_DEBUG_INFO(mvm, "ECKV table doesn't exist in BIOS\n"); 1269 1215 1270 1216 ret = iwl_mvm_sar_init(mvm); 1271 1217 if (ret == 0) {
+11 -11
drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c
··· 811 811 return iwl_mvm_mac_ctxt_send_cmd(mvm, &cmd); 812 812 } 813 813 814 - static void iwl_mvm_mac_ctxt_set_tim(struct iwl_mvm *mvm, 815 - __le32 *tim_index, __le32 *tim_size, 816 - u8 *beacon, u32 frame_size) 814 + void iwl_mvm_mac_ctxt_set_tim(struct iwl_mvm *mvm, 815 + __le32 *tim_index, __le32 *tim_size, 816 + u8 *beacon, u32 frame_size) 817 817 { 818 818 u32 tim_idx; 819 819 struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)beacon; ··· 853 853 return ie - beacon; 854 854 } 855 855 856 - static u8 iwl_mvm_mac_ctxt_get_lowest_rate(struct ieee80211_tx_info *info, 857 - struct ieee80211_vif *vif) 856 + u8 iwl_mvm_mac_ctxt_get_lowest_rate(struct ieee80211_tx_info *info, 857 + struct ieee80211_vif *vif) 858 858 { 859 859 u8 rate; 860 860 ··· 904 904 905 905 } 906 906 907 - static int iwl_mvm_mac_ctxt_send_beacon_cmd(struct iwl_mvm *mvm, 908 - struct sk_buff *beacon, 909 - void *data, int len) 907 + int iwl_mvm_mac_ctxt_send_beacon_cmd(struct iwl_mvm *mvm, 908 + struct sk_buff *beacon, 909 + void *data, int len) 910 910 { 911 911 struct iwl_host_cmd cmd = { 912 912 .id = BEACON_TEMPLATE_CMD, ··· 1009 1009 sizeof(beacon_cmd)); 1010 1010 } 1011 1011 1012 - static int iwl_mvm_mac_ctxt_send_beacon(struct iwl_mvm *mvm, 1013 - struct ieee80211_vif *vif, 1014 - struct sk_buff *beacon) 1012 + int iwl_mvm_mac_ctxt_send_beacon(struct iwl_mvm *mvm, 1013 + struct ieee80211_vif *vif, 1014 + struct sk_buff *beacon) 1015 1015 { 1016 1016 if (WARN_ON(!beacon)) 1017 1017 return -EINVAL;
+161 -7
drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
··· 184 184 }; 185 185 #endif 186 186 187 + static const struct cfg80211_pmsr_capabilities iwl_mvm_pmsr_capa = { 188 + .max_peers = IWL_MVM_TOF_MAX_APS, 189 + .report_ap_tsf = 1, 190 + .randomize_mac_addr = 1, 191 + 192 + .ftm = { 193 + .supported = 1, 194 + .asap = 1, 195 + .non_asap = 1, 196 + .request_lci = 1, 197 + .request_civicloc = 1, 198 + .max_bursts_exponent = -1, /* all supported */ 199 + .max_ftms_per_burst = 0, /* no limits */ 200 + .bandwidths = BIT(NL80211_CHAN_WIDTH_20_NOHT) | 201 + BIT(NL80211_CHAN_WIDTH_20) | 202 + BIT(NL80211_CHAN_WIDTH_40) | 203 + BIT(NL80211_CHAN_WIDTH_80), 204 + .preambles = BIT(NL80211_PREAMBLE_LEGACY) | 205 + BIT(NL80211_PREAMBLE_HT) | 206 + BIT(NL80211_PREAMBLE_VHT), 207 + }, 208 + }; 209 + 187 210 void iwl_mvm_ref(struct iwl_mvm *mvm, enum iwl_mvm_ref_type ref_type) 188 211 { 189 212 if (!iwl_mvm_is_d0i3_supported(mvm)) ··· 443 420 WLAN_CIPHER_SUITE_TKIP, 444 421 WLAN_CIPHER_SUITE_CCMP, 445 422 }; 423 + #ifdef CONFIG_PM_SLEEP 424 + bool unified = fw_has_capa(&mvm->fw->ucode_capa, 425 + IWL_UCODE_TLV_CAPA_CNSLDTD_D3_D0_IMG); 426 + #endif 446 427 447 428 /* Tell mac80211 our characteristics */ 448 429 ieee80211_hw_set(hw, SIGNAL_DBM); ··· 569 542 mvm->hw->cipher_schemes = mvm->cs; 570 543 mvm->ciphers[hw->wiphy->n_cipher_suites] = cs->cipher; 571 544 hw->wiphy->n_cipher_suites++; 545 + } 546 + 547 + if (fw_has_capa(&mvm->fw->ucode_capa, 548 + IWL_UCODE_TLV_CAPA_FTM_CALIBRATED)) { 549 + wiphy_ext_feature_set(hw->wiphy, 550 + NL80211_EXT_FEATURE_ENABLE_FTM_RESPONDER); 551 + hw->wiphy->pmsr_capa = &iwl_mvm_pmsr_capa; 572 552 } 573 553 574 554 ieee80211_hw_set(hw, SINGLE_SCAN_ON_ALL_BANDS); ··· 743 709 hw->wiphy->wowlan = &mvm->wowlan; 744 710 } 745 711 746 - if (mvm->fw->img[IWL_UCODE_WOWLAN].num_sec && 712 + if ((unified || mvm->fw->img[IWL_UCODE_WOWLAN].num_sec) && 747 713 mvm->trans->ops->d3_suspend && 748 714 mvm->trans->ops->d3_resume && 749 715 device_can_wakeup(mvm->trans->dev)) { ··· 1211 1177 iwl_mvm_cleanup_roc_te(mvm); 1212 1178 ieee80211_remain_on_channel_expired(mvm->hw); 1213 1179 1180 + iwl_mvm_ftm_restart(mvm); 1181 + 1214 1182 /* 1215 1183 * cleanup all interfaces, even inactive ones, as some might have 1216 1184 * gone down during the HW restart ··· 1325 1289 1326 1290 /* allow transport/FW low power modes */ 1327 1291 iwl_mvm_unref(mvm, IWL_MVM_REF_UCODE_DOWN); 1292 + 1293 + iwl_mvm_send_recovery_cmd(mvm, ERROR_RECOVERY_END_OF_RECOVERY); 1328 1294 1329 1295 /* 1330 1296 * If we have TDLS peers, remove them. We don't know the last seqno/PN ··· 1690 1652 vif->driver_flags &= ~(IEEE80211_VIF_BEACON_FILTER | 1691 1653 IEEE80211_VIF_SUPPORTS_CQM_RSSI); 1692 1654 } 1655 + 1656 + if (vif->bss_conf.ftm_responder) 1657 + memset(&mvm->ftm_resp_stats, 0, sizeof(mvm->ftm_resp_stats)); 1693 1658 1694 1659 iwl_mvm_vif_dbgfs_clean(mvm, vif); 1695 1660 ··· 2364 2323 * If update fails - SF might be running in associated 2365 2324 * mode while disassociated - which is forbidden. 2366 2325 */ 2367 - WARN_ONCE(iwl_mvm_sf_update(mvm, vif, false), 2326 + ret = iwl_mvm_sf_update(mvm, vif, false); 2327 + WARN_ONCE(ret && 2328 + !test_bit(IWL_MVM_STATUS_HW_RESTART_REQUESTED, 2329 + &mvm->status), 2368 2330 "Failed to update SF upon disassociation\n"); 2369 2331 2370 2332 /* ··· 2588 2544 if (iwl_mvm_phy_ctx_count(mvm) > 1) 2589 2545 iwl_mvm_teardown_tdls_peers(mvm); 2590 2546 2547 + iwl_mvm_ftm_restart_responder(mvm, vif); 2548 + 2591 2549 goto out_unlock; 2592 2550 2593 2551 out_quota_failed: ··· 2701 2655 bss_conf->txpower); 2702 2656 iwl_mvm_set_tx_power(mvm, vif, bss_conf->txpower); 2703 2657 } 2658 + 2659 + if (changes & BSS_CHANGED_FTM_RESPONDER) { 2660 + int ret = iwl_mvm_ftm_start_responder(mvm, vif); 2661 + 2662 + if (ret) 2663 + IWL_WARN(mvm, "Failed to enable FTM responder (%d)\n", 2664 + ret); 2665 + } 2666 + 2704 2667 } 2705 2668 2706 2669 static void iwl_mvm_bss_info_changed(struct ieee80211_hw *hw, ··· 3172 3117 } else if (old_state == IEEE80211_STA_AUTHORIZED && 3173 3118 new_state == IEEE80211_STA_ASSOC) { 3174 3119 /* disable beacon filtering */ 3175 - WARN_ON(iwl_mvm_disable_beacon_filter(mvm, vif, 0)); 3120 + ret = iwl_mvm_disable_beacon_filter(mvm, vif, 0); 3121 + WARN_ON(ret && 3122 + !test_bit(IWL_MVM_STATUS_HW_RESTART_REQUESTED, 3123 + &mvm->status)); 3176 3124 ret = 0; 3177 3125 } else if (old_state == IEEE80211_STA_ASSOC && 3178 3126 new_state == IEEE80211_STA_AUTH) { ··· 3207 3149 mvm_sta->wep_key = NULL; 3208 3150 } 3209 3151 3152 + if (unlikely(ret && 3153 + test_bit(IWL_MVM_STATUS_HW_RESTART_REQUESTED, 3154 + &mvm->status))) 3155 + ret = 0; 3210 3156 } else { 3211 3157 ret = -EIO; 3212 3158 } ··· 3854 3792 return 0; 3855 3793 } 3856 3794 3795 + struct iwl_mvm_ftm_responder_iter_data { 3796 + bool responder; 3797 + struct ieee80211_chanctx_conf *ctx; 3798 + }; 3799 + 3800 + static void iwl_mvm_ftm_responder_chanctx_iter(void *_data, u8 *mac, 3801 + struct ieee80211_vif *vif) 3802 + { 3803 + struct iwl_mvm_ftm_responder_iter_data *data = _data; 3804 + 3805 + if (rcu_access_pointer(vif->chanctx_conf) == data->ctx && 3806 + vif->type == NL80211_IFTYPE_AP && vif->bss_conf.ftmr_params) 3807 + data->responder = true; 3808 + } 3809 + 3810 + static bool iwl_mvm_is_ftm_responder_chanctx(struct iwl_mvm *mvm, 3811 + struct ieee80211_chanctx_conf *ctx) 3812 + { 3813 + struct iwl_mvm_ftm_responder_iter_data data = { 3814 + .responder = false, 3815 + .ctx = ctx, 3816 + }; 3817 + 3818 + ieee80211_iterate_active_interfaces_atomic(mvm->hw, 3819 + IEEE80211_IFACE_ITER_NORMAL, 3820 + iwl_mvm_ftm_responder_chanctx_iter, 3821 + &data); 3822 + return data.responder; 3823 + } 3824 + 3857 3825 static int __iwl_mvm_add_chanctx(struct iwl_mvm *mvm, 3858 3826 struct ieee80211_chanctx_conf *ctx) 3859 3827 { 3860 3828 u16 *phy_ctxt_id = (u16 *)ctx->drv_priv; 3861 3829 struct iwl_mvm_phy_ctxt *phy_ctxt; 3830 + bool responder = iwl_mvm_is_ftm_responder_chanctx(mvm, ctx); 3831 + struct cfg80211_chan_def *def = responder ? &ctx->def : &ctx->min_def; 3862 3832 int ret; 3863 3833 3864 3834 lockdep_assert_held(&mvm->mutex); ··· 3903 3809 goto out; 3904 3810 } 3905 3811 3906 - ret = iwl_mvm_phy_ctxt_changed(mvm, phy_ctxt, &ctx->min_def, 3812 + ret = iwl_mvm_phy_ctxt_changed(mvm, phy_ctxt, def, 3907 3813 ctx->rx_chains_static, 3908 3814 ctx->rx_chains_dynamic); 3909 3815 if (ret) { ··· 3958 3864 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); 3959 3865 u16 *phy_ctxt_id = (u16 *)ctx->drv_priv; 3960 3866 struct iwl_mvm_phy_ctxt *phy_ctxt = &mvm->phy_ctxts[*phy_ctxt_id]; 3867 + bool responder = iwl_mvm_is_ftm_responder_chanctx(mvm, ctx); 3868 + struct cfg80211_chan_def *def = responder ? &ctx->def : &ctx->min_def; 3961 3869 3962 3870 if (WARN_ONCE((phy_ctxt->ref > 1) && 3963 3871 (changed & ~(IEEE80211_CHANCTX_CHANGE_WIDTH | ··· 3974 3878 3975 3879 /* we are only changing the min_width, may be a noop */ 3976 3880 if (changed == IEEE80211_CHANCTX_CHANGE_MIN_WIDTH) { 3977 - if (phy_ctxt->width == ctx->min_def.width) 3881 + if (phy_ctxt->width == def->width) 3978 3882 goto out_unlock; 3979 3883 3980 3884 /* we are just toggling between 20_NOHT and 20 */ 3981 3885 if (phy_ctxt->width <= NL80211_CHAN_WIDTH_20 && 3982 - ctx->min_def.width <= NL80211_CHAN_WIDTH_20) 3886 + def->width <= NL80211_CHAN_WIDTH_20) 3983 3887 goto out_unlock; 3984 3888 } 3985 3889 3986 3890 iwl_mvm_bt_coex_vif_change(mvm); 3987 - iwl_mvm_phy_ctxt_changed(mvm, phy_ctxt, &ctx->min_def, 3891 + iwl_mvm_phy_ctxt_changed(mvm, phy_ctxt, def, 3988 3892 ctx->rx_chains_static, 3989 3893 ctx->rx_chains_dynamic); 3990 3894 ··· 4905 4809 mutex_unlock(&mvm->mutex); 4906 4810 } 4907 4811 4812 + static int 4813 + iwl_mvm_mac_get_ftm_responder_stats(struct ieee80211_hw *hw, 4814 + struct ieee80211_vif *vif, 4815 + struct cfg80211_ftm_responder_stats *stats) 4816 + { 4817 + struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); 4818 + struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); 4819 + 4820 + if (vif->p2p || vif->type != NL80211_IFTYPE_AP || 4821 + !mvmvif->ap_ibss_active || !vif->bss_conf.ftm_responder) 4822 + return -EINVAL; 4823 + 4824 + mutex_lock(&mvm->mutex); 4825 + *stats = mvm->ftm_resp_stats; 4826 + mutex_unlock(&mvm->mutex); 4827 + 4828 + stats->filled = BIT(NL80211_FTM_STATS_SUCCESS_NUM) | 4829 + BIT(NL80211_FTM_STATS_PARTIAL_NUM) | 4830 + BIT(NL80211_FTM_STATS_FAILED_NUM) | 4831 + BIT(NL80211_FTM_STATS_ASAP_NUM) | 4832 + BIT(NL80211_FTM_STATS_NON_ASAP_NUM) | 4833 + BIT(NL80211_FTM_STATS_TOTAL_DURATION_MSEC) | 4834 + BIT(NL80211_FTM_STATS_UNKNOWN_TRIGGERS_NUM) | 4835 + BIT(NL80211_FTM_STATS_RESCHEDULE_REQUESTS_NUM) | 4836 + BIT(NL80211_FTM_STATS_OUT_OF_WINDOW_TRIGGERS_NUM); 4837 + 4838 + return 0; 4839 + } 4840 + 4841 + static int iwl_mvm_start_pmsr(struct ieee80211_hw *hw, 4842 + struct ieee80211_vif *vif, 4843 + struct cfg80211_pmsr_request *request) 4844 + { 4845 + struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); 4846 + int ret; 4847 + 4848 + mutex_lock(&mvm->mutex); 4849 + ret = iwl_mvm_ftm_start(mvm, vif, request); 4850 + mutex_unlock(&mvm->mutex); 4851 + 4852 + return ret; 4853 + } 4854 + 4855 + static void iwl_mvm_abort_pmsr(struct ieee80211_hw *hw, 4856 + struct ieee80211_vif *vif, 4857 + struct cfg80211_pmsr_request *request) 4858 + { 4859 + struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); 4860 + 4861 + mutex_lock(&mvm->mutex); 4862 + iwl_mvm_ftm_abort(mvm, request); 4863 + mutex_unlock(&mvm->mutex); 4864 + } 4865 + 4908 4866 static bool iwl_mvm_can_hw_csum(struct sk_buff *skb) 4909 4867 { 4910 4868 u8 protocol = ip_hdr(skb)->protocol; ··· 5061 4911 #endif 5062 4912 .get_survey = iwl_mvm_mac_get_survey, 5063 4913 .sta_statistics = iwl_mvm_mac_sta_statistics, 4914 + .get_ftm_responder_stats = iwl_mvm_mac_get_ftm_responder_stats, 4915 + .start_pmsr = iwl_mvm_start_pmsr, 4916 + .abort_pmsr = iwl_mvm_abort_pmsr, 4917 + 5064 4918 .can_aggregate_in_amsdu = iwl_mvm_mac_can_aggregate, 5065 4919 #ifdef CONFIG_IWLWIFI_DEBUGFS 5066 4920 .sta_add_debugfs = iwl_mvm_sta_add_debugfs,
+40 -3
drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
··· 879 879 880 880 bool hw_registered; 881 881 bool calibrating; 882 - u32 error_event_table[2]; 883 - u32 log_event_table; 884 - u32 umac_error_event_table; 885 882 bool support_umac_log; 886 883 887 884 u32 ampdu_ref; ··· 1014 1017 1015 1018 /* -1 for always, 0 for never, >0 for that many times */ 1016 1019 s8 fw_restart; 1020 + u8 *error_recovery_buf; 1017 1021 1018 1022 #ifdef CONFIG_IWLWIFI_LEDS 1019 1023 struct led_classdev led; ··· 1104 1106 1105 1107 /* Indicate if device power save is allowed */ 1106 1108 u8 ps_disabled; /* u8 instead of bool to ease debugfs_create_* usage */ 1109 + /* Indicate if 32Khz external clock is valid */ 1110 + u32 ext_clock_valid; 1107 1111 unsigned int max_amsdu_len; /* used for debugfs only */ 1108 1112 1109 1113 struct ieee80211_vif __rcu *csa_vif; ··· 1149 1149 1150 1150 u32 ciphers[IWL_MVM_NUM_CIPHERS]; 1151 1151 struct ieee80211_cipher_scheme cs[IWL_UCODE_MAX_CS]; 1152 + 1153 + struct cfg80211_ftm_responder_stats ftm_resp_stats; 1154 + struct { 1155 + struct cfg80211_pmsr_request *req; 1156 + struct wireless_dev *req_wdev; 1157 + struct list_head loc_list; 1158 + int responses[IWL_MVM_TOF_MAX_APS]; 1159 + } ftm_initiator; 1152 1160 1153 1161 struct ieee80211_vif *nan_vif; 1154 1162 #define IWL_MAX_BAID 32 ··· 1660 1652 void iwl_mvm_rx_tx_cmd(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb); 1661 1653 void iwl_mvm_mfu_assert_dump_notif(struct iwl_mvm *mvm, 1662 1654 struct iwl_rx_cmd_buffer *rxb); 1655 + void iwl_mvm_send_recovery_cmd(struct iwl_mvm *mvm, u32 flags); 1663 1656 void iwl_mvm_rx_ba_notif(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb); 1664 1657 void iwl_mvm_rx_ant_coupling_notif(struct iwl_mvm *mvm, 1665 1658 struct iwl_rx_cmd_buffer *rxb); ··· 1695 1686 int iwl_mvm_mac_ctxt_remove(struct iwl_mvm *mvm, struct ieee80211_vif *vif); 1696 1687 int iwl_mvm_mac_ctxt_beacon_changed(struct iwl_mvm *mvm, 1697 1688 struct ieee80211_vif *vif); 1689 + int iwl_mvm_mac_ctxt_send_beacon(struct iwl_mvm *mvm, 1690 + struct ieee80211_vif *vif, 1691 + struct sk_buff *beacon); 1692 + int iwl_mvm_mac_ctxt_send_beacon_cmd(struct iwl_mvm *mvm, 1693 + struct sk_buff *beacon, 1694 + void *data, int len); 1695 + u8 iwl_mvm_mac_ctxt_get_lowest_rate(struct ieee80211_tx_info *info, 1696 + struct ieee80211_vif *vif); 1697 + void iwl_mvm_mac_ctxt_set_tim(struct iwl_mvm *mvm, 1698 + __le32 *tim_index, __le32 *tim_size, 1699 + u8 *beacon, u32 frame_size); 1698 1700 void iwl_mvm_rx_beacon_notif(struct iwl_mvm *mvm, 1699 1701 struct iwl_rx_cmd_buffer *rxb); 1700 1702 void iwl_mvm_rx_missed_beacons_notif(struct iwl_mvm *mvm, ··· 2079 2059 /* smart fifo */ 2080 2060 int iwl_mvm_sf_update(struct iwl_mvm *mvm, struct ieee80211_vif *vif, 2081 2061 bool added_vif); 2062 + 2063 + /* FTM responder */ 2064 + int iwl_mvm_ftm_start_responder(struct iwl_mvm *mvm, struct ieee80211_vif *vif); 2065 + void iwl_mvm_ftm_restart_responder(struct iwl_mvm *mvm, 2066 + struct ieee80211_vif *vif); 2067 + void iwl_mvm_ftm_responder_stats(struct iwl_mvm *mvm, 2068 + struct iwl_rx_cmd_buffer *rxb); 2069 + 2070 + /* FTM initiator */ 2071 + void iwl_mvm_ftm_restart(struct iwl_mvm *mvm); 2072 + void iwl_mvm_ftm_range_resp(struct iwl_mvm *mvm, 2073 + struct iwl_rx_cmd_buffer *rxb); 2074 + void iwl_mvm_ftm_lc_notif(struct iwl_mvm *mvm, 2075 + struct iwl_rx_cmd_buffer *rxb); 2076 + int iwl_mvm_ftm_start(struct iwl_mvm *mvm, struct ieee80211_vif *vif, 2077 + struct cfg80211_pmsr_request *request); 2078 + void iwl_mvm_ftm_abort(struct iwl_mvm *mvm, struct cfg80211_pmsr_request *req); 2082 2079 2083 2080 /* TDLS */ 2084 2081
+48
drivers/net/wireless/intel/iwlwifi/mvm/ops.c
··· 300 300 RX_HANDLER_ASYNC_LOCKED), 301 301 RX_HANDLER(MFUART_LOAD_NOTIFICATION, iwl_mvm_rx_mfuart_notif, 302 302 RX_HANDLER_SYNC), 303 + RX_HANDLER_GRP(LOCATION_GROUP, TOF_RESPONDER_STATS, 304 + iwl_mvm_ftm_responder_stats, RX_HANDLER_ASYNC_LOCKED), 305 + 306 + RX_HANDLER_GRP(LOCATION_GROUP, TOF_RANGE_RESPONSE_NOTIF, 307 + iwl_mvm_ftm_range_resp, RX_HANDLER_ASYNC_LOCKED), 308 + RX_HANDLER_GRP(LOCATION_GROUP, TOF_LC_NOTIF, 309 + iwl_mvm_ftm_lc_notif, RX_HANDLER_ASYNC_LOCKED), 310 + 303 311 RX_HANDLER_GRP(DEBUG_GROUP, MFU_ASSERT_DUMP_NTF, 304 312 iwl_mvm_mfu_assert_dump_notif, RX_HANDLER_SYNC), 305 313 RX_HANDLER_GRP(PROT_OFFLOAD_GROUP, STORED_BEACON_NTF, ··· 422 414 static const struct iwl_hcmd_names iwl_mvm_system_names[] = { 423 415 HCMD_NAME(SHARED_MEM_CFG_CMD), 424 416 HCMD_NAME(INIT_EXTENDED_CFG_CMD), 417 + HCMD_NAME(FW_ERROR_RECOVERY_CMD), 425 418 }; 426 419 427 420 /* Please keep this array *SORTED* by hex value. ··· 601 592 return ret; 602 593 } 603 594 595 + static bool iwl_mvm_d3_debug_enable(void *ctx) 596 + { 597 + return IWL_MVM_D3_DEBUG; 598 + } 599 + 604 600 static const struct iwl_fw_runtime_ops iwl_mvm_fwrt_ops = { 605 601 .dump_start = iwl_mvm_fwrt_dump_start, 606 602 .dump_end = iwl_mvm_fwrt_dump_end, 607 603 .fw_running = iwl_mvm_fwrt_fw_running, 608 604 .send_hcmd = iwl_mvm_fwrt_send_hcmd, 605 + .d3_debug_enable = iwl_mvm_d3_debug_enable, 609 606 }; 610 607 611 608 static struct iwl_op_mode * ··· 706 691 INIT_LIST_HEAD(&mvm->aux_roc_te_list); 707 692 INIT_LIST_HEAD(&mvm->async_handlers_list); 708 693 spin_lock_init(&mvm->time_event_lock); 694 + INIT_LIST_HEAD(&mvm->ftm_initiator.loc_list); 709 695 710 696 INIT_WORK(&mvm->async_handlers_wk, iwl_mvm_async_handlers_wk); 711 697 INIT_WORK(&mvm->roc_done_wk, iwl_mvm_roc_done_wk); ··· 928 912 kfree(mvm->mcast_filter_cmd); 929 913 mvm->mcast_filter_cmd = NULL; 930 914 915 + kfree(mvm->error_recovery_buf); 916 + mvm->error_recovery_buf = NULL; 917 + 931 918 #if defined(CONFIG_PM_SLEEP) && defined(CONFIG_IWLWIFI_DEBUGFS) 932 919 kfree(mvm->d3_resume_sram); 933 920 #endif ··· 1125 1106 iwl_trans_block_txq_ptrs(mvm->trans, false); 1126 1107 } 1127 1108 1109 + static int iwl_mvm_is_static_queue(struct iwl_mvm *mvm, int queue) 1110 + { 1111 + return queue == mvm->aux_queue || queue == mvm->probe_queue || 1112 + queue == mvm->p2p_dev_queue || queue == mvm->snif_queue; 1113 + } 1114 + 1128 1115 static void iwl_mvm_queue_state_change(struct iwl_op_mode *op_mode, 1129 1116 int hw_queue, bool start) 1130 1117 { ··· 1156 1131 if (IS_ERR_OR_NULL(sta)) 1157 1132 goto out; 1158 1133 mvmsta = iwl_mvm_sta_from_mac80211(sta); 1134 + 1135 + if (iwl_mvm_is_static_queue(mvm, hw_queue)) { 1136 + if (!start) 1137 + ieee80211_stop_queues(mvm->hw); 1138 + else if (mvmsta->sta_state != IEEE80211_STA_NOTEXIST) 1139 + ieee80211_wake_queues(mvm->hw); 1140 + 1141 + goto out; 1142 + } 1159 1143 1160 1144 if (iwl_mvm_has_new_tx_api(mvm)) { 1161 1145 int tid = mvm->tvqm_info[hw_queue].txq_tid; ··· 1325 1291 !test_bit(STATUS_TRANS_DEAD, &mvm->trans->status)) { 1326 1292 /* don't let the transport/FW power down */ 1327 1293 iwl_mvm_ref(mvm, IWL_MVM_REF_UCODE_DOWN); 1294 + 1295 + if (mvm->fw->ucode_capa.error_log_size) { 1296 + u32 src_size = mvm->fw->ucode_capa.error_log_size; 1297 + u32 src_addr = mvm->fw->ucode_capa.error_log_addr; 1298 + u8 *recover_buf = kzalloc(src_size, GFP_ATOMIC); 1299 + 1300 + if (recover_buf) { 1301 + mvm->error_recovery_buf = recover_buf; 1302 + iwl_trans_read_mem_bytes(mvm->trans, 1303 + src_addr, 1304 + recover_buf, 1305 + src_size); 1306 + } 1307 + } 1328 1308 1329 1309 if (fw_error && mvm->fw_restart > 0) 1330 1310 mvm->fw_restart--;
+5 -2
drivers/net/wireless/intel/iwlwifi/mvm/power.c
··· 8 8 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. 9 9 * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH 10 10 * Copyright(c) 2015 - 2017 Intel Deutschland GmbH 11 - * Copyright (C) 2018 Intel Corporation 11 + * Copyright (C) 2018 - 2019 Intel Corporation 12 12 * 13 13 * This program is free software; you can redistribute it and/or modify 14 14 * it under the terms of version 2 of the GNU General Public License as ··· 31 31 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. 32 32 * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH 33 33 * Copyright(c) 2015 - 2017 Intel Deutschland GmbH 34 - * Copyright (C) 2018 Intel Corporation 34 + * Copyright (C) 2018 - 2019 Intel Corporation 35 35 * All rights reserved. 36 36 * 37 37 * Redistribution and use in source and binary forms, with or without ··· 544 544 cmd.flags &= 545 545 cpu_to_le16(~DEVICE_POWER_FLAGS_POWER_SAVE_ENA_MSK); 546 546 #endif 547 + if (mvm->ext_clock_valid) 548 + cmd.flags |= cpu_to_le16(DEVICE_POWER_FLAGS_32K_CLK_VALID_MSK); 549 + 547 550 IWL_DEBUG_POWER(mvm, 548 551 "Sending device power command with flags = 0x%X\n", 549 552 cmd.flags);
+20 -13
drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c
··· 258 258 struct ieee80211_sta *sta, 259 259 bool csi) 260 260 { 261 - struct ieee80211_rx_status *rx_status = IEEE80211_SKB_RXCB(skb); 262 - 263 - if (!(rx_status->flag & RX_FLAG_NO_PSDU) && 264 - iwl_mvm_check_pn(mvm, skb, queue, sta)) 261 + if (iwl_mvm_check_pn(mvm, skb, queue, sta)) 265 262 kfree_skb(skb); 266 263 else 267 264 ieee80211_rx_napi(mvm->hw, sta, skb, napi); ··· 1074 1077 IEEE80211_RADIOTAP_HE_DATA1_SPTL_REUSE2_KNOWN | 1075 1078 IEEE80211_RADIOTAP_HE_DATA1_SPTL_REUSE3_KNOWN | 1076 1079 IEEE80211_RADIOTAP_HE_DATA1_SPTL_REUSE4_KNOWN); 1077 - he->data4 |= le16_encode_bits(le32_get_bits(phy_data->d0, 1080 + he->data4 |= le16_encode_bits(le32_get_bits(phy_data->d2, 1078 1081 IWL_RX_PHY_DATA2_HE_TB_EXT_SPTL_REUSE1), 1079 1082 IEEE80211_RADIOTAP_HE_DATA4_TB_SPTL_REUSE1); 1080 - he->data4 |= le16_encode_bits(le32_get_bits(phy_data->d0, 1083 + he->data4 |= le16_encode_bits(le32_get_bits(phy_data->d2, 1081 1084 IWL_RX_PHY_DATA2_HE_TB_EXT_SPTL_REUSE2), 1082 1085 IEEE80211_RADIOTAP_HE_DATA4_TB_SPTL_REUSE2); 1083 - he->data4 |= le16_encode_bits(le32_get_bits(phy_data->d0, 1086 + he->data4 |= le16_encode_bits(le32_get_bits(phy_data->d2, 1084 1087 IWL_RX_PHY_DATA2_HE_TB_EXT_SPTL_REUSE3), 1085 1088 IEEE80211_RADIOTAP_HE_DATA4_TB_SPTL_REUSE3); 1086 - he->data4 |= le16_encode_bits(le32_get_bits(phy_data->d0, 1089 + he->data4 |= le16_encode_bits(le32_get_bits(phy_data->d2, 1087 1090 IWL_RX_PHY_DATA2_HE_TB_EXT_SPTL_REUSE4), 1088 1091 IEEE80211_RADIOTAP_HE_DATA4_TB_SPTL_REUSE4); 1089 1092 /* fall through */ ··· 1093 1096 case IWL_RX_PHY_INFO_TYPE_HE_TB: 1094 1097 /* HE common */ 1095 1098 he->data1 |= cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA1_LDPC_XSYMSEG_KNOWN | 1096 - IEEE80211_RADIOTAP_HE_DATA1_SPTL_REUSE_KNOWN | 1097 1099 IEEE80211_RADIOTAP_HE_DATA1_DOPPLER_KNOWN | 1098 1100 IEEE80211_RADIOTAP_HE_DATA1_BSS_COLOR_KNOWN); 1099 1101 he->data2 |= cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA2_PRE_FEC_PAD_KNOWN | ··· 1112 1116 he->data3 |= le16_encode_bits(le32_get_bits(phy_data->d0, 1113 1117 IWL_RX_PHY_DATA0_HE_LDPC_EXT_SYM), 1114 1118 IEEE80211_RADIOTAP_HE_DATA3_LDPC_XSYMSEG); 1115 - he->data4 |= le16_encode_bits(le32_get_bits(phy_data->d0, 1116 - IWL_RX_PHY_DATA0_HE_SPATIAL_REUSE_MASK), 1117 - IEEE80211_RADIOTAP_HE_DATA4_SU_MU_SPTL_REUSE); 1118 1119 he->data5 |= le16_encode_bits(le32_get_bits(phy_data->d0, 1119 1120 IWL_RX_PHY_DATA0_HE_PRE_FEC_PAD_MASK), 1120 1121 IEEE80211_RADIOTAP_HE_DATA5_PRE_FEC_PAD); ··· 1127 1134 he->data6 |= le16_encode_bits(le32_get_bits(phy_data->d0, 1128 1135 IWL_RX_PHY_DATA0_HE_DOPPLER), 1129 1136 IEEE80211_RADIOTAP_HE_DATA6_DOPPLER); 1137 + break; 1138 + } 1139 + 1140 + switch (phy_data->info_type) { 1141 + case IWL_RX_PHY_INFO_TYPE_HE_MU_EXT: 1142 + case IWL_RX_PHY_INFO_TYPE_HE_MU: 1143 + case IWL_RX_PHY_INFO_TYPE_HE_SU: 1144 + he->data1 |= cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA1_SPTL_REUSE_KNOWN); 1145 + he->data4 |= le16_encode_bits(le32_get_bits(phy_data->d0, 1146 + IWL_RX_PHY_DATA0_HE_SPATIAL_REUSE_MASK), 1147 + IEEE80211_RADIOTAP_HE_DATA4_SU_MU_SPTL_REUSE); 1148 + break; 1149 + default: 1150 + /* nothing here */ 1130 1151 break; 1131 1152 } 1132 1153 ··· 1807 1800 rx_status->rate_idx = rate; 1808 1801 } 1809 1802 1810 - iwl_mvm_pass_packet_to_mac80211(mvm, napi, skb, queue, sta, false); 1803 + ieee80211_rx_napi(mvm->hw, sta, skb, napi); 1811 1804 out: 1812 1805 rcu_read_unlock(); 1813 1806 }
+7 -2
drivers/net/wireless/intel/iwlwifi/mvm/scan.c
··· 8 8 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. 9 9 * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH 10 10 * Copyright(c) 2016 - 2017 Intel Deutschland GmbH 11 - * Copyright(c) 2018 Intel Corporation 11 + * Copyright(c) 2018 - 2019 Intel Corporation 12 12 * 13 13 * This program is free software; you can redistribute it and/or modify 14 14 * it under the terms of version 2 of the GNU General Public License as ··· 31 31 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. 32 32 * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH 33 33 * Copyright(c) 2016 - 2017 Intel Deutschland GmbH 34 - * Copyright(c) 2018 Intel Corporation 34 + * Copyright(c) 2018 - 2019 Intel Corporation 35 35 * All rights reserved. 36 36 * 37 37 * Redistribution and use in source and binary forms, with or without ··· 1579 1579 * compatibility with old wpa_supplicant that wouldn't stop a 1580 1580 * scheduled scan before starting a normal scan. 1581 1581 */ 1582 + 1583 + /* FW supports only a single periodic scan */ 1584 + if ((type == IWL_MVM_SCAN_SCHED || type == IWL_MVM_SCAN_NETDETECT) && 1585 + mvm->scan_status & (IWL_MVM_SCAN_SCHED | IWL_MVM_SCAN_NETDETECT)) 1586 + return -EBUSY; 1582 1587 1583 1588 if (iwl_mvm_num_scans(mvm) < mvm->max_scans) 1584 1589 return 0;
+2 -1
drivers/net/wireless/intel/iwlwifi/mvm/sta.c
··· 750 750 751 751 if (tid == IWL_MAX_TID_COUNT) { 752 752 tid = IWL_MGMT_TID; 753 - size = IWL_MGMT_QUEUE_SIZE; 753 + size = max_t(u32, IWL_MGMT_QUEUE_SIZE, 754 + mvm->trans->cfg->min_txq_size); 754 755 } 755 756 queue = iwl_trans_txq_alloc(mvm->trans, 756 757 cpu_to_le16(TX_QUEUE_CFG_ENABLE_QUEUE),
+1 -1
drivers/net/wireless/intel/iwlwifi/mvm/time-event.c
··· 85 85 { 86 86 lockdep_assert_held(&mvm->time_event_lock); 87 87 88 - if (!te_data->vif) 88 + if (!te_data || !te_data->vif) 89 89 return; 90 90 91 91 list_del(&te_data->list);
+7 -5
drivers/net/wireless/intel/iwlwifi/mvm/utils.c
··· 457 457 { 458 458 struct iwl_trans *trans = mvm->trans; 459 459 struct iwl_umac_error_event_table table; 460 + u32 base = mvm->trans->umac_error_event_table; 460 461 461 - if (!mvm->support_umac_log) 462 + if (!mvm->support_umac_log && 463 + !(mvm->trans->error_event_table_tlv_status & 464 + IWL_ERROR_EVENT_TABLE_UMAC)) 462 465 return; 463 466 464 - iwl_trans_read_mem_bytes(trans, mvm->umac_error_event_table, &table, 465 - sizeof(table)); 467 + iwl_trans_read_mem_bytes(trans, base, &table, sizeof(table)); 466 468 467 469 if (table.valid) 468 470 mvm->fwrt.dump.umac_err_id = table.error_id; ··· 496 494 { 497 495 struct iwl_trans *trans = mvm->trans; 498 496 struct iwl_error_event_table table; 499 - u32 val, base = mvm->error_event_table[lmac_num]; 497 + u32 val, base = mvm->trans->lmac_error_event_table[lmac_num]; 500 498 501 499 if (mvm->fwrt.cur_fw_img == IWL_UCODE_INIT) { 502 500 if (!base) ··· 592 590 593 591 iwl_mvm_dump_lmac_error_log(mvm, 0); 594 592 595 - if (mvm->error_event_table[1]) 593 + if (mvm->trans->lmac_error_event_table[1]) 596 594 iwl_mvm_dump_lmac_error_log(mvm, 1); 597 595 598 596 iwl_mvm_dump_umac_error_log(mvm);
+11 -5
drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info-gen3.c
··· 5 5 * 6 6 * GPL LICENSE SUMMARY 7 7 * 8 - * Copyright(c) 2018 Intel Corporation 8 + * Copyright(c) 2018 - 2019 Intel Corporation 9 9 * 10 10 * This program is free software; you can redistribute it and/or modify 11 11 * it under the terms of version 2 of the GNU General Public License as ··· 18 18 * 19 19 * BSD LICENSE 20 20 * 21 - * Copyright(c) 2018 Intel Corporation 21 + * Copyright(c) 2018 - 2019 Intel Corporation 22 22 * All rights reserved. 23 23 * 24 24 * Redistribution and use in source and binary forms, with or without ··· 66 66 void *iml_img; 67 67 u32 control_flags = 0; 68 68 int ret; 69 + int cmdq_size = max_t(u32, TFD_CMD_SLOTS, trans->cfg->min_txq_size); 69 70 70 71 /* Allocate prph scratch */ 71 72 prph_scratch = dma_alloc_coherent(trans->dev, sizeof(*prph_scratch), ··· 152 151 ctxt_info_gen3->mcr_base_addr = 153 152 cpu_to_le64(trans_pcie->rxq->used_bd_dma); 154 153 ctxt_info_gen3->mtr_size = 155 - cpu_to_le16(TFD_QUEUE_CB_SIZE(TFD_CMD_SLOTS)); 154 + cpu_to_le16(TFD_QUEUE_CB_SIZE(cmdq_size)); 156 155 ctxt_info_gen3->mcr_size = 157 156 cpu_to_le16(RX_QUEUE_CB_SIZE(MQ_RX_TABLE_SIZE)); 158 157 ··· 176 175 iwl_write64(trans, CSR_IML_DATA_ADDR, 177 176 trans_pcie->iml_dma_addr); 178 177 iwl_write32(trans, CSR_IML_SIZE_ADDR, trans->iml_len); 179 - iwl_set_bit(trans, CSR_CTXT_INFO_BOOT_CTRL, CSR_AUTO_FUNC_BOOT_ENA); 180 - iwl_set_bit(trans, CSR_GP_CNTRL, CSR_AUTO_FUNC_INIT); 178 + 179 + iwl_set_bit(trans, CSR_CTXT_INFO_BOOT_CTRL, 180 + CSR_AUTO_FUNC_BOOT_ENA); 181 + if (trans->cfg->device_family >= IWL_DEVICE_FAMILY_AX210) 182 + iwl_write_umac_prph(trans, UREG_CPU_INIT_RUN, 1); 183 + else 184 + iwl_set_bit(trans, CSR_GP_CNTRL, CSR_AUTO_FUNC_INIT); 181 185 182 186 return 0; 183 187 }
+12 -4
drivers/net/wireless/intel/iwlwifi/pcie/drv.c
··· 8 8 * Copyright(c) 2007 - 2014 Intel Corporation. All rights reserved. 9 9 * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH 10 10 * Copyright(c) 2016-2017 Intel Deutschland GmbH 11 - * Copyright(c) 2018 Intel Corporation 11 + * Copyright(c) 2018 - 2019 Intel Corporation 12 12 * 13 13 * This program is free software; you can redistribute it and/or modify 14 14 * it under the terms of version 2 of the GNU General Public License as ··· 32 32 * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH 33 33 * All rights reserved. 34 34 * Copyright(c) 2017 Intel Deutschland GmbH 35 - * Copyright(c) 2018 Intel Corporation 35 + * Copyright(c) 2018 - 2019 Intel Corporation 36 36 * 37 37 * Redistribution and use in source and binary forms, with or without 38 38 * modification, are permitted provided that the following conditions ··· 872 872 {IWL_PCI_DEVICE(0xA370, 0x40A4, iwl9462_2ac_cfg_soc)}, 873 873 {IWL_PCI_DEVICE(0xA370, 0x4234, iwl9560_2ac_cfg_soc)}, 874 874 {IWL_PCI_DEVICE(0xA370, 0x42A4, iwl9462_2ac_cfg_soc)}, 875 + {IWL_PCI_DEVICE(0x2720, 0x0030, iwl9560_2ac_cfg_qnj_jf_b0)}, 875 876 876 877 /* 22000 Series */ 877 878 {IWL_PCI_DEVICE(0x02F0, 0x0070, iwl22560_2ax_cfg_hr)}, ··· 892 891 {IWL_PCI_DEVICE(0x06F0, 0x1652, killer1650i_2ax_cfg_qu_b0_hr_b0)}, 893 892 {IWL_PCI_DEVICE(0x06F0, 0x4070, iwl22560_2ax_cfg_hr)}, 894 893 {IWL_PCI_DEVICE(0x2720, 0x0000, iwl22560_2ax_cfg_hr)}, 895 - {IWL_PCI_DEVICE(0x2720, 0x0030, iwl9560_2ac_160_cfg_soc)}, 896 894 {IWL_PCI_DEVICE(0x2720, 0x0040, iwl22560_2ax_cfg_hr)}, 897 895 {IWL_PCI_DEVICE(0x2720, 0x0070, iwl22000_2ac_cfg_hr_cdb)}, 898 896 {IWL_PCI_DEVICE(0x2720, 0x0074, iwl22560_2ax_cfg_hr)}, ··· 948 948 {IWL_PCI_DEVICE(0x1a56, 0x1653, killer1650w_2ax_cfg)}, 949 949 {IWL_PCI_DEVICE(0x1a56, 0x1654, killer1650x_2ax_cfg)}, 950 950 951 + {IWL_PCI_DEVICE(0x2725, 0x0090, iwlax210_2ax_cfg_so_hr_a0)}, 952 + {IWL_PCI_DEVICE(0x7A70, 0x0090, iwlax210_2ax_cfg_so_hr_a0)}, 953 + {IWL_PCI_DEVICE(0x7A70, 0x0310, iwlax210_2ax_cfg_so_hr_a0)}, 954 + {IWL_PCI_DEVICE(0x2725, 0x0020, iwlax210_2ax_cfg_so_hr_a0)}, 955 + {IWL_PCI_DEVICE(0x2725, 0x0310, iwlax210_2ax_cfg_so_hr_a0)}, 956 + {IWL_PCI_DEVICE(0x2725, 0x0A10, iwlax210_2ax_cfg_so_hr_a0)}, 957 + {IWL_PCI_DEVICE(0x2725, 0x00B0, iwlax210_2ax_cfg_so_hr_a0)}, 958 + 951 959 #endif /* CONFIG_IWLMVM */ 952 960 953 961 {0} ··· 1007 999 1008 1000 if (rf_id_chp == jf_chp_id) { 1009 1001 if (iwl_trans->hw_rev == CSR_HW_REV_TYPE_QNJ) 1010 - cfg = &iwl22000_2ax_cfg_qnj_jf_b0; 1002 + cfg = &iwl9560_2ac_cfg_qnj_jf_b0; 1011 1003 else 1012 1004 cfg = &iwl22000_2ac_cfg_jf; 1013 1005 } else if (rf_id_chp == hr_chp_id) {
+2
drivers/net/wireless/intel/iwlwifi/pcie/internal.h
··· 400 400 u32 id; 401 401 int low_mark; 402 402 int high_mark; 403 + 404 + bool overflow_tx; 403 405 }; 404 406 405 407 static inline dma_addr_t
+38 -14
drivers/net/wireless/intel/iwlwifi/pcie/rx.c
··· 8 8 * Copyright(c) 2003 - 2014 Intel Corporation. All rights reserved. 9 9 * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH 10 10 * Copyright(c) 2016 - 2017 Intel Deutschland GmbH 11 - * Copyright(c) 2018 Intel Corporation 11 + * Copyright(c) 2018 - 2019 Intel Corporation 12 12 * 13 13 * This program is free software; you can redistribute it and/or modify it 14 14 * under the terms of version 2 of the GNU General Public License as ··· 31 31 * Copyright(c) 2003 - 2014 Intel Corporation. All rights reserved. 32 32 * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH 33 33 * Copyright(c) 2016 - 2017 Intel Deutschland GmbH 34 - * Copyright(c) 2018 Intel Corporation 34 + * Copyright(c) 2018 - 2019 Intel Corporation 35 35 * All rights reserved. 36 36 * 37 37 * Redistribution and use in source and binary forms, with or without ··· 202 202 { 203 203 if (trans->cfg->device_family >= IWL_DEVICE_FAMILY_22560) { 204 204 /* TODO: remove this for 22560 once fw does it */ 205 - iwl_write_prph(trans, RFH_RXF_DMA_CFG_GEN3, 0); 206 - return iwl_poll_prph_bit(trans, RFH_GEN_STATUS_GEN3, 207 - RXF_DMA_IDLE, RXF_DMA_IDLE, 1000); 205 + iwl_write_umac_prph(trans, RFH_RXF_DMA_CFG_GEN3, 0); 206 + return iwl_poll_umac_prph_bit(trans, RFH_GEN_STATUS_GEN3, 207 + RXF_DMA_IDLE, RXF_DMA_IDLE, 1000); 208 208 } else if (trans->cfg->mq_rx_supported) { 209 209 iwl_write_prph(trans, RFH_RXF_DMA_CFG, 0); 210 210 return iwl_poll_prph_bit(trans, RFH_GEN_STATUS, ··· 247 247 } 248 248 249 249 rxq->write_actual = round_down(rxq->write, 8); 250 - if (trans->cfg->device_family >= IWL_DEVICE_FAMILY_22560) 250 + if (trans->cfg->device_family == IWL_DEVICE_FAMILY_22560) 251 251 iwl_write32(trans, HBUS_TARG_WRPTR, 252 252 (rxq->write_actual | 253 253 ((FIRST_RX_QUEUE + rxq->id) << 16))); ··· 538 538 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); 539 539 struct iwl_rb_allocator *rba = &trans_pcie->rba; 540 540 struct list_head local_empty; 541 - int pending = atomic_xchg(&rba->req_pending, 0); 541 + int pending = atomic_read(&rba->req_pending); 542 542 543 - IWL_DEBUG_RX(trans, "Pending allocation requests = %d\n", pending); 543 + IWL_DEBUG_TPT(trans, "Pending allocation requests = %d\n", pending); 544 544 545 545 /* If we were scheduled - there is at least one request */ 546 546 spin_lock(&rba->lock); ··· 593 593 i++; 594 594 } 595 595 596 + atomic_dec(&rba->req_pending); 596 597 pending--; 598 + 597 599 if (!pending) { 598 - pending = atomic_xchg(&rba->req_pending, 0); 599 - IWL_DEBUG_RX(trans, 600 - "Pending allocation requests = %d\n", 601 - pending); 600 + pending = atomic_read(&rba->req_pending); 601 + if (pending) 602 + IWL_DEBUG_TPT(trans, 603 + "Got more pending allocation requests = %d\n", 604 + pending); 602 605 } 603 606 604 607 spin_lock(&rba->lock); ··· 612 609 spin_unlock(&rba->lock); 613 610 614 611 atomic_inc(&rba->req_ready); 612 + 615 613 } 616 614 617 615 spin_lock(&rba->lock); 618 616 /* return unused rbds to the allocator empty list */ 619 617 list_splice_tail(&local_empty, &rba->rbd_empty); 620 618 spin_unlock(&rba->lock); 619 + 620 + IWL_DEBUG_TPT(trans, "%s, exit.\n", __func__); 621 621 } 622 622 623 623 /* ··· 1430 1424 !emergency)) { 1431 1425 iwl_pcie_rx_move_to_allocator(rxq, rba); 1432 1426 emergency = true; 1427 + IWL_DEBUG_TPT(trans, 1428 + "RX path is in emergency. Pending allocations %d\n", 1429 + rb_pending_alloc); 1433 1430 } 1434 1431 1435 1432 IWL_DEBUG_RX(trans, "Q %d: HW = %d, SW = %d\n", rxq->id, r, i); ··· 1462 1453 count++; 1463 1454 if (count == 8) { 1464 1455 count = 0; 1465 - if (rb_pending_alloc < rxq->queue_size / 3) 1456 + if (rb_pending_alloc < rxq->queue_size / 3) { 1457 + IWL_DEBUG_TPT(trans, 1458 + "RX path exited emergency. Pending allocations %d\n", 1459 + rb_pending_alloc); 1466 1460 emergency = false; 1461 + } 1467 1462 1468 1463 rxq->read = i; 1469 1464 spin_unlock(&rxq->lock); ··· 2133 2120 } 2134 2121 } 2135 2122 2136 - if (trans->cfg->device_family >= IWL_DEVICE_FAMILY_22560 && 2123 + if (trans->cfg->device_family == IWL_DEVICE_FAMILY_22560 && 2137 2124 inta_hw & MSIX_HW_INT_CAUSES_REG_IPC) { 2138 2125 /* Reflect IML transfer status */ 2139 2126 int res = iwl_read32(trans, CSR_IML_RESP_ADDR); ··· 2150 2137 iwl_pcie_txq_check_wrptrs(trans); 2151 2138 2152 2139 isr_stats->wakeup++; 2140 + } 2141 + 2142 + if (inta_hw & MSIX_HW_INT_CAUSES_REG_IML) { 2143 + /* Reflect IML transfer status */ 2144 + int res = iwl_read32(trans, CSR_IML_RESP_ADDR); 2145 + 2146 + IWL_DEBUG_ISR(trans, "IML transfer status: %d\n", res); 2147 + if (res == IWL_IMAGE_RESP_FAIL) { 2148 + isr_stats->sw++; 2149 + iwl_pcie_irq_handle_error(trans); 2150 + } 2153 2151 } 2154 2152 2155 2153 /* Chip got too hot and stopped itself */
+4 -3
drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c
··· 171 171 } 172 172 173 173 iwl_pcie_ctxt_info_free_paging(trans); 174 - if (trans->cfg->device_family == IWL_DEVICE_FAMILY_22560) 174 + if (trans->cfg->device_family >= IWL_DEVICE_FAMILY_22560) 175 175 iwl_pcie_ctxt_info_gen3_free(trans); 176 176 else 177 177 iwl_pcie_ctxt_info_free(trans); ··· 234 234 static int iwl_pcie_gen2_nic_init(struct iwl_trans *trans) 235 235 { 236 236 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); 237 + int queue_size = max_t(u32, TFD_CMD_SLOTS, trans->cfg->min_txq_size); 237 238 238 239 /* TODO: most of the logic can be removed in A0 - but not in Z0 */ 239 240 spin_lock(&trans_pcie->irq_lock); ··· 248 247 return -ENOMEM; 249 248 250 249 /* Allocate or reset and init all Tx and Command queues */ 251 - if (iwl_pcie_gen2_tx_init(trans, trans_pcie->cmd_queue, TFD_CMD_SLOTS)) 250 + if (iwl_pcie_gen2_tx_init(trans, trans_pcie->cmd_queue, queue_size)) 252 251 return -ENOMEM; 253 252 254 253 /* enable shadow regs in HW */ ··· 333 332 goto out; 334 333 } 335 334 336 - if (trans->cfg->device_family == IWL_DEVICE_FAMILY_22560) 335 + if (trans->cfg->device_family >= IWL_DEVICE_FAMILY_22560) 337 336 ret = iwl_pcie_ctxt_info_gen3_init(trans, fw); 338 337 else 339 338 ret = iwl_pcie_ctxt_info_init(trans, fw);
+71 -34
drivers/net/wireless/intel/iwlwifi/pcie/trans.c
··· 8 8 * Copyright(c) 2007 - 2015 Intel Corporation. All rights reserved. 9 9 * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH 10 10 * Copyright(c) 2016 - 2017 Intel Deutschland GmbH 11 - * Copyright(c) 2018 Intel Corporation 11 + * Copyright(c) 2018 - 2019 Intel Corporation 12 12 * 13 13 * This program is free software; you can redistribute it and/or modify 14 14 * it under the terms of version 2 of the GNU General Public License as ··· 31 31 * Copyright(c) 2005 - 2015 Intel Corporation. All rights reserved. 32 32 * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH 33 33 * Copyright(c) 2016 - 2017 Intel Deutschland GmbH 34 - * Copyright(c) 2018 Intel Corporation 34 + * Copyright(c) 2018 - 2019 Intel Corporation 35 35 * All rights reserved. 36 36 * 37 37 * Redistribution and use in source and binary forms, with or without ··· 896 896 if (!trans->num_blocks) 897 897 return; 898 898 899 - iwl_write_prph(trans, MON_BUFF_BASE_ADDR_VER2, 900 - trans->fw_mon[0].physical >> 901 - MON_BUFF_SHIFT_VER2); 902 - iwl_write_prph(trans, MON_BUFF_END_ADDR_VER2, 903 - (trans->fw_mon[0].physical + 904 - trans->fw_mon[0].size - 256) >> 905 - MON_BUFF_SHIFT_VER2); 899 + iwl_write_umac_prph(trans, MON_BUFF_BASE_ADDR_VER2, 900 + trans->fw_mon[0].physical >> 901 + MON_BUFF_SHIFT_VER2); 902 + iwl_write_umac_prph(trans, MON_BUFF_END_ADDR_VER2, 903 + (trans->fw_mon[0].physical + 904 + trans->fw_mon[0].size - 256) >> 905 + MON_BUFF_SHIFT_VER2); 906 906 return; 907 907 } 908 908 ··· 1094 1094 {MSIX_FH_INT_CAUSES_FH_ERR, CSR_MSIX_FH_INT_MASK_AD, 0x5}, 1095 1095 {MSIX_HW_INT_CAUSES_REG_ALIVE, CSR_MSIX_HW_INT_MASK_AD, 0x10}, 1096 1096 {MSIX_HW_INT_CAUSES_REG_WAKEUP, CSR_MSIX_HW_INT_MASK_AD, 0x11}, 1097 + {MSIX_HW_INT_CAUSES_REG_IML, CSR_MSIX_HW_INT_MASK_AD, 0x12}, 1097 1098 {MSIX_HW_INT_CAUSES_REG_CT_KILL, CSR_MSIX_HW_INT_MASK_AD, 0x16}, 1098 1099 {MSIX_HW_INT_CAUSES_REG_RF_KILL, CSR_MSIX_HW_INT_MASK_AD, 0x17}, 1099 1100 {MSIX_HW_INT_CAUSES_REG_PERIODIC, CSR_MSIX_HW_INT_MASK_AD, 0x18}, ··· 1127 1126 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); 1128 1127 int val = trans_pcie->def_irq | MSIX_NON_AUTO_CLEAR_CAUSE; 1129 1128 int i, arr_size = 1130 - (trans->cfg->device_family < IWL_DEVICE_FAMILY_22560) ? 1129 + (trans->cfg->device_family != IWL_DEVICE_FAMILY_22560) ? 1131 1130 ARRAY_SIZE(causes_list) : ARRAY_SIZE(causes_list_v2); 1132 1131 1133 1132 /* ··· 1137 1136 */ 1138 1137 for (i = 0; i < arr_size; i++) { 1139 1138 struct iwl_causes_list *causes = 1140 - (trans->cfg->device_family < IWL_DEVICE_FAMILY_22560) ? 1139 + (trans->cfg->device_family != IWL_DEVICE_FAMILY_22560) ? 1141 1140 causes_list : causes_list_v2; 1142 1141 1143 1142 iwl_write8(trans, CSR_MSIX_IVAR(causes[i].addr), val); ··· 1183 1182 if (!trans_pcie->msix_enabled) { 1184 1183 if (trans->cfg->mq_rx_supported && 1185 1184 test_bit(STATUS_DEVICE_ENABLED, &trans->status)) 1186 - iwl_write_prph(trans, UREG_CHICK, 1187 - UREG_CHICK_MSI_ENABLE); 1185 + iwl_write_umac_prph(trans, UREG_CHICK, 1186 + UREG_CHICK_MSI_ENABLE); 1188 1187 return; 1189 1188 } 1190 1189 /* ··· 1193 1192 * prph. 1194 1193 */ 1195 1194 if (test_bit(STATUS_DEVICE_ENABLED, &trans->status)) 1196 - iwl_write_prph(trans, UREG_CHICK, UREG_CHICK_MSIX_ENABLE); 1195 + iwl_write_umac_prph(trans, UREG_CHICK, UREG_CHICK_MSIX_ENABLE); 1197 1196 1198 1197 /* 1199 1198 * Each cause from the causes list above and the RX causes is ··· 1561 1560 } 1562 1561 1563 1562 IWL_DEBUG_POWER(trans, "WFPM value upon resume = 0x%08X\n", 1564 - iwl_read_prph(trans, WFPM_GP2)); 1563 + iwl_read_umac_prph(trans, WFPM_GP2)); 1565 1564 1566 1565 val = iwl_read32(trans, CSR_RESET); 1567 1566 if (val & CSR_RESET_REG_FLAG_NEVO_RESET) ··· 1710 1709 return err; 1711 1710 } 1712 1711 1713 - hpm = iwl_trans_read_prph(trans, HPM_DEBUG); 1712 + hpm = iwl_read_umac_prph_no_grab(trans, HPM_DEBUG); 1714 1713 if (hpm != 0xa5a5a5a0 && (hpm & PERSISTENCE_BIT)) { 1715 - if (iwl_trans_read_prph(trans, PREG_PRPH_WPROT_0) & 1716 - PREG_WFPM_ACCESS) { 1714 + int wfpm_val = iwl_read_umac_prph_no_grab(trans, 1715 + PREG_PRPH_WPROT_0); 1716 + 1717 + if (wfpm_val & PREG_WFPM_ACCESS) { 1717 1718 IWL_ERR(trans, 1718 1719 "Error, can not clear persistence bit\n"); 1719 1720 return -EPERM; 1720 1721 } 1721 - iwl_trans_write_prph(trans, HPM_DEBUG, hpm & ~PERSISTENCE_BIT); 1722 + iwl_write_umac_prph_no_grab(trans, HPM_DEBUG, 1723 + hpm & ~PERSISTENCE_BIT); 1722 1724 } 1723 1725 1724 1726 iwl_trans_pcie_sw_reset(trans); ··· 2243 2239 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); 2244 2240 struct iwl_txq *txq; 2245 2241 unsigned long now = jiffies; 2242 + bool overflow_tx; 2246 2243 u8 wr_ptr; 2247 2244 2248 2245 /* Make sure the NIC is still alive in the bus */ ··· 2255 2250 2256 2251 IWL_DEBUG_TX_QUEUES(trans, "Emptying queue %d...\n", txq_idx); 2257 2252 txq = trans_pcie->txq[txq_idx]; 2253 + 2254 + spin_lock_bh(&txq->lock); 2255 + overflow_tx = txq->overflow_tx || 2256 + !skb_queue_empty(&txq->overflow_q); 2257 + spin_unlock_bh(&txq->lock); 2258 + 2258 2259 wr_ptr = READ_ONCE(txq->write_ptr); 2259 2260 2260 - while (txq->read_ptr != READ_ONCE(txq->write_ptr) && 2261 + while ((txq->read_ptr != READ_ONCE(txq->write_ptr) || 2262 + overflow_tx) && 2261 2263 !time_after(jiffies, 2262 2264 now + msecs_to_jiffies(IWL_FLUSH_WAIT_MS))) { 2263 2265 u8 write_ptr = READ_ONCE(txq->write_ptr); 2264 2266 2265 - if (WARN_ONCE(wr_ptr != write_ptr, 2267 + /* 2268 + * If write pointer moved during the wait, warn only 2269 + * if the TX came from op mode. In case TX came from 2270 + * trans layer (overflow TX) don't warn. 2271 + */ 2272 + if (WARN_ONCE(wr_ptr != write_ptr && !overflow_tx, 2266 2273 "WR pointer moved while flushing %d -> %d\n", 2267 2274 wr_ptr, write_ptr)) 2268 2275 return -ETIMEDOUT; 2276 + wr_ptr = write_ptr; 2277 + 2269 2278 usleep_range(1000, 2000); 2279 + 2280 + spin_lock_bh(&txq->lock); 2281 + overflow_tx = txq->overflow_tx || 2282 + !skb_queue_empty(&txq->overflow_q); 2283 + spin_unlock_bh(&txq->lock); 2270 2284 } 2271 2285 2272 2286 if (txq->read_ptr != txq->write_ptr) { ··· 2971 2947 i += sizeof(u32)) 2972 2948 *val++ = cpu_to_le32(iwl_trans_pcie_read32(trans, i)); 2973 2949 else 2974 - for (i = FH_MEM_LOWER_BOUND_GEN2; i < FH_MEM_UPPER_BOUND_GEN2; 2950 + for (i = iwl_umac_prph(trans, FH_MEM_LOWER_BOUND_GEN2); 2951 + i < iwl_umac_prph(trans, FH_MEM_UPPER_BOUND_GEN2); 2975 2952 i += sizeof(u32)) 2976 2953 *val++ = cpu_to_le32(iwl_trans_pcie_read_prph(trans, 2977 2954 i)); ··· 2997 2972 if (!iwl_trans_grab_nic_access(trans, &flags)) 2998 2973 return 0; 2999 2974 3000 - iwl_write_prph_no_grab(trans, MON_DMARB_RD_CTL_ADDR, 0x1); 2975 + iwl_write_umac_prph_no_grab(trans, MON_DMARB_RD_CTL_ADDR, 0x1); 3001 2976 for (i = 0; i < buf_size_in_dwords; i++) 3002 - buffer[i] = iwl_read_prph_no_grab(trans, 3003 - MON_DMARB_RD_DATA_ADDR); 3004 - iwl_write_prph_no_grab(trans, MON_DMARB_RD_CTL_ADDR, 0x0); 2977 + buffer[i] = iwl_read_umac_prph_no_grab(trans, 2978 + MON_DMARB_RD_DATA_ADDR); 2979 + iwl_write_umac_prph_no_grab(trans, MON_DMARB_RD_CTL_ADDR, 0x0); 3005 2980 3006 2981 iwl_trans_release_nic_access(trans, &flags); 3007 2982 ··· 3016 2991 3017 2992 /* If there was a dest TLV - use the values from there */ 3018 2993 if (trans->ini_valid) { 3019 - base = MON_BUFF_BASE_ADDR_VER2; 3020 - write_ptr = MON_BUFF_WRPTR_VER2; 3021 - wrap_cnt = MON_BUFF_CYCLE_CNT_VER2; 2994 + base = iwl_umac_prph(trans, MON_BUFF_BASE_ADDR_VER2); 2995 + write_ptr = iwl_umac_prph(trans, MON_BUFF_WRPTR_VER2); 2996 + wrap_cnt = iwl_umac_prph(trans, MON_BUFF_CYCLE_CNT_VER2); 3022 2997 } else if (trans->dbg_dest_tlv) { 3023 2998 write_ptr = le32_to_cpu(trans->dbg_dest_tlv->write_ptr_reg); 3024 2999 wrap_cnt = le32_to_cpu(trans->dbg_dest_tlv->wrap_count); ··· 3180 3155 if (dump_mask & BIT(IWL_FW_ERROR_DUMP_FH_REGS)) { 3181 3156 if (trans->cfg->gen2) 3182 3157 len += sizeof(*data) + 3183 - (FH_MEM_UPPER_BOUND_GEN2 - 3184 - FH_MEM_LOWER_BOUND_GEN2); 3158 + (iwl_umac_prph(trans, FH_MEM_UPPER_BOUND_GEN2) - 3159 + iwl_umac_prph(trans, FH_MEM_LOWER_BOUND_GEN2)); 3185 3160 else 3186 3161 len += sizeof(*data) + 3187 3162 (FH_MEM_UPPER_BOUND - ··· 3511 3486 if (iwl_trans_grab_nic_access(trans, &flags)) { 3512 3487 u32 hw_step; 3513 3488 3514 - hw_step = iwl_read_prph_no_grab(trans, WFPM_CTRL_REG); 3489 + hw_step = iwl_read_umac_prph_no_grab(trans, 3490 + WFPM_CTRL_REG); 3515 3491 hw_step |= ENABLE_WFPM; 3516 - iwl_write_prph_no_grab(trans, WFPM_CTRL_REG, hw_step); 3492 + iwl_write_umac_prph_no_grab(trans, WFPM_CTRL_REG, 3493 + hw_step); 3517 3494 hw_step = iwl_read_prph_no_grab(trans, AUX_MISC_REG); 3518 3495 hw_step = (hw_step >> HW_STEP_LOCATION_BITS) & 0xF; 3519 3496 if (hw_step == 0x3) ··· 3530 3503 #if IS_ENABLED(CONFIG_IWLMVM) 3531 3504 trans->hw_rf_id = iwl_read32(trans, CSR_HW_RF_ID); 3532 3505 3533 - if (cfg == &iwl22560_2ax_cfg_hr) { 3506 + if (cfg == &iwlax210_2ax_cfg_so_hr_a0) { 3507 + if (trans->hw_rev == CSR_HW_REV_TYPE_TY) { 3508 + trans->cfg = &iwlax210_2ax_cfg_ty_gf_a0; 3509 + } else if (CSR_HW_RF_ID_TYPE_CHIP_ID(trans->hw_rf_id) == 3510 + CSR_HW_RF_ID_TYPE_CHIP_ID(CSR_HW_RF_ID_TYPE_JF)) { 3511 + trans->cfg = &iwlax210_2ax_cfg_so_jf_a0; 3512 + } else if (CSR_HW_RF_ID_TYPE_CHIP_ID(trans->hw_rf_id) == 3513 + CSR_HW_RF_ID_TYPE_CHIP_ID(CSR_HW_RF_ID_TYPE_GF)) { 3514 + trans->cfg = &iwlax210_2ax_cfg_so_gf_a0; 3515 + } 3516 + } else if (cfg == &iwl22560_2ax_cfg_hr) { 3534 3517 if (CSR_HW_RF_ID_TYPE_CHIP_ID(trans->hw_rf_id) == 3535 3518 CSR_HW_RF_ID_TYPE_CHIP_ID(CSR_HW_RF_ID_TYPE_HR)) { 3536 3519 trans->cfg = &iwl22560_2ax_cfg_hr;
+20 -2
drivers/net/wireless/intel/iwlwifi/pcie/tx.c
··· 995 995 txq_id++) { 996 996 bool cmd_queue = (txq_id == trans_pcie->cmd_queue); 997 997 998 - slots_num = cmd_queue ? TFD_CMD_SLOTS : TFD_TX_CMD_SLOTS; 998 + if (cmd_queue) 999 + slots_num = max_t(u32, TFD_CMD_SLOTS, 1000 + trans->cfg->min_txq_size); 1001 + else 1002 + slots_num = TFD_TX_CMD_SLOTS; 999 1003 trans_pcie->txq[txq_id] = &trans_pcie->txq_memory[txq_id]; 1000 1004 ret = iwl_pcie_txq_alloc(trans, trans_pcie->txq[txq_id], 1001 1005 slots_num, cmd_queue); ··· 1048 1044 txq_id++) { 1049 1045 bool cmd_queue = (txq_id == trans_pcie->cmd_queue); 1050 1046 1051 - slots_num = cmd_queue ? TFD_CMD_SLOTS : TFD_TX_CMD_SLOTS; 1047 + if (cmd_queue) 1048 + slots_num = max_t(u32, TFD_CMD_SLOTS, 1049 + trans->cfg->min_txq_size); 1050 + else 1051 + slots_num = TFD_TX_CMD_SLOTS; 1052 1052 ret = iwl_pcie_txq_init(trans, trans_pcie->txq[txq_id], 1053 1053 slots_num, cmd_queue); 1054 1054 if (ret) { ··· 1182 1174 skb_queue_splice_init(&txq->overflow_q, &overflow_skbs); 1183 1175 1184 1176 /* 1177 + * We are going to transmit from the overflow queue. 1178 + * Remember this state so that wait_for_txq_empty will know we 1179 + * are adding more packets to the TFD queue. It cannot rely on 1180 + * the state of &txq->overflow_q, as we just emptied it, but 1181 + * haven't TXed the content yet. 1182 + */ 1183 + txq->overflow_tx = true; 1184 + 1185 + /* 1185 1186 * This is tricky: we are in reclaim path which is non 1186 1187 * re-entrant, so noone will try to take the access the 1187 1188 * txq data from that path. We stopped tx, so we can't ··· 1218 1201 iwl_wake_queue(trans, txq); 1219 1202 1220 1203 spin_lock_bh(&txq->lock); 1204 + txq->overflow_tx = false; 1221 1205 } 1222 1206 1223 1207 if (txq->read_ptr == txq->write_ptr) {
+2
include/linux/ieee80211.h
··· 2118 2118 #define IEEE80211_SPCT_MSR_RPRT_TYPE_BASIC 0 2119 2119 #define IEEE80211_SPCT_MSR_RPRT_TYPE_CCA 1 2120 2120 #define IEEE80211_SPCT_MSR_RPRT_TYPE_RPI 2 2121 + #define IEEE80211_SPCT_MSR_RPRT_TYPE_LCI 8 2122 + #define IEEE80211_SPCT_MSR_RPRT_TYPE_CIVIC 11 2121 2123 2122 2124 /* 802.11g ERP information element */ 2123 2125 #define WLAN_ERP_NON_ERP_PRESENT (1<<0)